Versioning
How the protocol, each pack and the reference SDK are versioned apart, what each version promises about compatibility, and how deprecation works.
HCP versions the protocol, each pack and each implementation independently. HCP/1.1 is the current draft and may still change by RFC, but every wire element listed below stays stable across HCP/1.x, and packs that conformed to HCP/1 still conform.
Protocol versions#
The protocol is versioned as HCP/<major>.<minor>.
| Version | Status | Contents |
|---|---|---|
| HCP/1 | Draft, implemented | Pack lattice (three files), Execute twin face, Policy (operation, privacy.land), Binding modes, five capability grants, sandbox default, CLI bootstrap pack (hcp-cli), Skill copy on activate |
| HCP/1.1 | Draft, implemented (current) | Wrap hardening (RFC 0001): named-or-pass-through lint, installer command family (setup.status / setup.apply / setup.update), land local, Binding hub and mock, binding.degraded enum, plane: control, transports[], four-faces naming rule. Wrap exec plane (RFC 0003): wrap.workspace |
| HCP/1.2 | Proposed | Pack version + $schema, extension namespaces, error code registry, path containment. See Roadmap |
| HCP/2 | Planned | Registry install, capability-grant wire profile, optional MCP export profile, WASM adapters |
The protocol repository tagged v0.1.0 (HCP/1 with RFC 0001), and HCP/1.x stays
a draft until the specification is declared stable. A minor version adds only
optional fields, lint rules that fail new constructs alone, and recommended
families, while a major version may change required fields or wire shapes and
comes with a migration note.
Declaring protocol affinity#
A pack declares the protocol version it targets in the hcp field of its
manifest metadata, and HCP/1.x packs use 1.
{ "hcp": 1, "pack_id": "transit", "adapter_kind": "wrap" }A runtime rejects a pack whose hcp value it does not support and reports the
unsupported version. The reference SDK exposes the constants
HCP_PROTOCOL_ID = 'hcp' and HCP_VERSION = 1.
Pack versions#
A pack's identity is its pack_id, and in HCP/1.x its repository owns its
versions (one living repo per pack_id, per
L12).
The runtime store keeps whatever was installed, and hcpx install from a newer
checkout replaces it.
Adding a command is backward compatible on the wire, because an Invoker that
does not know the new verb_key never calls it and availability reports it per
command. Removing or renaming a command breaks the Skills and host projections
that referenced it, so treat it as a breaking change. A semver version field
in the manifest is proposed for HCP/1.2, and a registry that resolves
pack_id@version for HCP/2.
Wire compatibility#
| Element | Stability promise |
|---|---|
{ pack_id, verb_key, args } exec envelope | Stable across HCP/1.x. surface_id accepted as an alias of pack_id |
{ ok, result?, error? } result envelope | Stable across HCP/1.x |
Policy tokens read / write, personal / brain / local | Stable across HCP/1.x; new tokens only by RFC |
Capability ids (pack.install, pack.connect, verb.exec.read, verb.exec.write, sense.enable) | Stable across HCP/1.x |
| Binding modes and hubs | Stable across HCP/1.x |
Availability flags (installed, activated, connected, executable) | Stable across HCP/1.x |
Host tool naming (<pack_id>__<verb_key>, dots as underscores) and the single hcp tool | Stable across HCP/1.x |
Manifest filename surface.json and field name verbs | Retained for compatibility; a rename would be a major version |
Implementation versions#
The reference TypeScript SDK (@harnesscontextprotocol/sdk) and CLI follow
semver independently of the protocol, and each SDK release states which
protocol versions it implements. Conformance vectors for each protocol version
ship with the SDK, as Conformance describes.
Deprecation policy#
A field, token or command family is deprecated by RFC and keeps working for at
least one minor version, and lint warns about a deprecated construct before any
version removes it. Wire aliases such as surface_id are accepted indefinitely
within a major version.