Schemas
Seven JSON Schemas, each live at its $id, for validating surface.json, policy.json, the envelopes, grants, availability and hcp.eval.json.
These schemas are the machine-readable form of the
Specification, derived from the Zod definitions in the
SDK. They use JSON Schema draft 2020-12, and
each $id is a live URL that serves the schema as application/schema+json
to any origin, so an editor or validator can fetch it directly. The $ids stay
stable within HCP/1.x, and the files are the blocks on this page, so the two
cannot drift. Every gold pack's surface.json, policy.json and
hcp.eval.json validates against them. Where a schema and the specification
text disagree, the text governs, so open an issue.
| Schema | URL |
|---|---|
| Manifest | /schemas/1/surface.json |
| Policy | /schemas/1/policy.json |
| Exec envelope | /schemas/1/exec.json |
| Result envelope | /schemas/1/result.json |
| Grant | /schemas/1/grant.json |
| Availability | /schemas/1/availability.json |
| Eval cases | /schemas/hcp.eval.json |
surface.json#
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/1/surface.json",
"type": "object",
"required": ["id", "verbs"],
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[a-z0-9][a-z0-9-]*$" },
"name": { "type": "string" },
"cliBin": { "type": "string" },
"kind": { "$ref": "#/$defs/adapterKind" },
"adapter_kind": { "$ref": "#/$defs/adapterKind" },
"binding": { "$ref": "#/$defs/binding" },
"wrap": { "$ref": "#/$defs/wrap" },
"openapi": { "$ref": "#/$defs/openapi" },
"pass_through": { "$ref": "#/$defs/passThrough" },
"plane": { "enum": ["runtime", "control"] },
"transports": { "type": "array", "maxItems": 4, "items": { "enum": ["cli", "json_exec", "mcp"] } },
"skill_url": { "type": "string", "format": "uri" },
"harness": { "type": "string", "deprecated": true },
"verbs": {
"type": "object",
"propertyNames": { "pattern": "^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$" },
"additionalProperties": { "$ref": "#/$defs/command" }
},
"stimulusTriggers": {
"type": "array",
"items": { "type": "object", "required": ["ref"], "properties": { "ref": { "type": "string", "minLength": 1 } }, "additionalProperties": false }
},
"hcp": { "$ref": "#/$defs/meta" }
},
"$defs": {
"adapterKind": { "enum": ["composite", "wrap", "openapi", "sense_only"] },
"binding": {
"type": "object", "additionalProperties": false,
"properties": {
"family": { "type": "string", "minLength": 1, "maxLength": 128 },
"mode": { "enum": ["user", "mothership", "local", "public", "mock"] },
"hub": { "enum": ["keyring", "local-credential", "public", "none"] },
"connect_provider_id": { "type": "string", "minLength": 1, "maxLength": 128 }
}
},
"wrap": {
"type": "object", "additionalProperties": false, "required": ["bin"],
"properties": {
"bin": { "type": "string", "minLength": 1, "maxLength": 128 },
"argv_template": { "type": "array", "maxItems": 64, "items": { "type": "string" } },
"agent_env": { "type": "object", "additionalProperties": { "type": "string" } },
"workspace": { "$ref": "#/$defs/workspace" },
"json_flag": { "type": "array", "maxItems": 8, "items": { "type": "string", "maxLength": 64 } }
}
},
"workspace": {
"type": "object", "additionalProperties": false,
"properties": {
"mode": { "enum": ["none", "ephemeral", "workspace", "project"] },
"home_env": { "type": "array", "maxItems": 8, "items": { "type": "string", "minLength": 1, "maxLength": 64 } },
"file_flags": { "type": "array", "maxItems": 16, "items": { "type": "string", "minLength": 1, "maxLength": 32 } }
}
},
"openapi": {
"type": "object", "additionalProperties": false,
"properties": { "url": { "type": "string", "format": "uri" }, "path": { "type": "string", "minLength": 1, "maxLength": 512 } },
"anyOf": [{ "required": ["url"] }, { "required": ["path"] }]
},
"passThrough": {
"type": "object", "additionalProperties": false, "required": ["allowedSubcommands", "maxArgv"],
"properties": {
"allowedSubcommands": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } },
"maxArgv": { "type": "integer", "minimum": 1 }
}
},
"command": {
"type": "object",
"properties": {
"description": { "type": "string" },
"args": { "type": "object", "description": "JSON Schema: properties (description, examples, x-position) and required" },
"cli": { "type": "array", "items": { "type": "string" } },
"policy": { "type": "string" },
"json_flag": { "type": "array", "items": { "type": "string" } },
"title": {
"type": "object",
"properties": {
"live": { "$ref": "#/$defs/templates" },
"done": { "$ref": "#/$defs/templates" }
}
},
"preview": {
"type": "object", "required": ["kind"],
"properties": {
"kind": { "enum": ["message", "payment", "event", "removal", "publish", "record", "fields"] },
"title": { "type": "string" },
"fields": { "type": "object", "additionalProperties": { "type": "string" } }
}
}
}
},
"templates": {
"oneOf": [
{ "type": "string", "minLength": 1 },
{ "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }
]
},
"meta": {
"type": "object", "additionalProperties": false,
"required": ["hcp", "pack_id", "adapter_kind"],
"properties": {
"hcp": { "const": 1 },
"pack_id": { "type": "string", "minLength": 1, "maxLength": 128 },
"adapter_kind": { "$ref": "#/$defs/adapterKind" },
"binding": { "$ref": "#/$defs/binding" },
"wrap": { "$ref": "#/$defs/wrap" },
"openapi": { "$ref": "#/$defs/openapi" },
"pass_through": { "$ref": "#/$defs/passThrough" },
"plane": { "enum": ["runtime", "control"] },
"transports": { "type": "array", "maxItems": 4, "items": { "enum": ["cli", "json_exec", "mcp"] } },
"skill_url": { "type": "string", "format": "uri" }
}
}
}
}Lint enforces what the schema cannot express (§3.6):
hcp.pack_id === id, the wrap adapter requires wrap.bin, the openapi
adapter requires the openapi block, sense_only requires one trigger, wrap
requires named commands or pass_through, and the control plane requires
Binding mothership. hcpx check adds two more: preview and title
placeholders must be arguments of the command, and {{result.…}} belongs in
title.done only.
policy.json#
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/1/policy.json",
"type": "object", "additionalProperties": false,
"required": ["surface_id", "verbs"],
"properties": {
"surface_id": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": { "const": 1, "default": 1 },
"verbs": { "type": "object", "additionalProperties": { "$ref": "#/$defs/entry" } },
"stimuli": { "type": "object", "additionalProperties": { "$ref": "#/$defs/entry" }, "default": {} }
},
"$defs": {
"entry": {
"type": "object", "additionalProperties": false,
"required": ["operation", "privacy"],
"properties": {
"operation": { "enum": ["read", "write"] },
"privacy": {
"type": "object", "additionalProperties": false, "required": ["land"],
"properties": { "land": { "enum": ["personal", "brain", "local"] } }
},
"confirm": { "oneOf": [{ "type": "boolean" }, { "const": "always" }] }
}
}
}
}Lint enforces the coverage rules of §4.6: the
verbs keys are exactly the manifest's commands, the stimuli keys are exactly
its triggers, and surface_id === id.
Exec envelope#
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/1/exec.json",
"type": "object", "required": ["verb_key"],
"properties": {
"pack_id": { "type": "string" },
"surface_id": { "type": "string", "description": "Alias of pack_id" },
"verb_key": { "type": "string" },
"args": {
"type": "object", "default": {},
"properties": {
"confirm": { "type": "boolean" },
"apply": { "type": "boolean" },
"mode": { "enum": ["mock"] }
}
}
},
"anyOf": [{ "required": ["pack_id"] }, { "required": ["surface_id"] }]
}Result envelope#
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/1/result.json",
"type": "object", "required": ["ok", "pack_id", "verb_key"],
"properties": {
"ok": { "type": "boolean" },
"pack_id": { "type": "string" },
"verb_key": { "type": "string" },
"result": {},
"error": { "type": "string" },
"code": { "type": "string", "description": "Stable reason when ok is false" },
"hint": { "type": "string", "description": "What to do next, written for an agent" },
"preview": { "type": "object", "description": "On confirm_required: command, args, cli" },
"approval": { "type": "object", "description": "On confirm_required: the request a host shows a person" },
"approval_id": { "type": "string" },
"access": { "type": "object", "description": "On confirm_required: mode, reason, approvals" },
"stdout": { "type": "string" },
"stderr": { "type": "string" }
},
"if": { "properties": { "ok": { "const": false } } },
"then": { "required": ["error"] }
}Errors lists the code values, and
Access describes the approval
request.
Grant#
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/1/grant.json",
"type": "object", "required": ["capability"],
"properties": {
"capability": { "enum": ["pack.install", "pack.connect", "verb.exec.read", "verb.exec.write", "sense.enable"] },
"pack_id": { "type": "string" },
"verb_keys": { "type": "array", "items": { "type": "string" } }
}
}Availability#
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/1/availability.json",
"type": "object",
"required": ["pack_id", "status", "installed", "activated", "connected", "verbs", "capabilities"],
"properties": {
"pack_id": { "type": "string" },
"status": { "type": "array", "items": { "enum": ["available", "installed", "activated", "connected", "executable", "unavailable"] } },
"installed": { "type": "boolean" }, "activated": { "type": "boolean" }, "connected": { "type": "boolean" },
"verbs": { "type": "array", "items": {
"type": "object", "required": ["verb_key", "operation", "land", "executable"],
"properties": {
"verb_key": { "type": "string" }, "operation": { "enum": ["read", "write"] },
"land": { "enum": ["personal", "brain", "local"] }, "executable": { "type": "boolean" },
"reason": { "type": "string" }
} } },
"capabilities": { "type": "array", "items": {
"type": "object", "required": ["capability", "granted"],
"properties": {
"capability": { "enum": ["pack.install", "pack.connect", "verb.exec.read", "verb.exec.write", "sense.enable"] },
"granted": { "type": "boolean" }
} } },
"adapter_kind": { "enum": ["composite", "wrap", "openapi", "sense_only"] },
"binding_mode": { "enum": ["user", "mothership", "local", "public", "mock"] },
"skill_present": { "type": "boolean" },
"connect_needed": { "type": "boolean", "description": "Commands fail until someone runs hcpx connect" },
"ready": { "type": "boolean", "description": "Activated and, if it needs a login, connected" }
}
}hcp.eval.json#
This file holds the cases that
hcpx check and hcpx eval run, and
hcpx check --init-evals writes this $id as its $schema.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnesscontextprotocol.io/schemas/hcp.eval.json",
"type": "object",
"properties": {
"$schema": { "type": "string" },
"cases": {
"type": "array",
"items": {
"type": "object", "required": ["name", "verb"],
"properties": {
"name": { "type": "string" },
"verb": { "type": "string", "description": "A command in surface.json" },
"args": { "type": "object" },
"expect": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"error": { "type": "string" },
"contains": { "type": "array", "items": { "type": "string" } },
"not_contains": { "type": "array", "items": { "type": "string" } },
"json": { "type": "boolean" },
"max_ms": { "type": "number" },
"max_tokens": { "type": "number" }
}
}
}
}
}
}
}Generating from source#
Zod generates each schema from the SDK's definitions:
import { z } from 'zod'
import { HarnessPackMetaSchema, HcpPolicyFileSchema } from '@harnesscontextprotocol/sdk'
z.toJSONSchema(HarnessPackMetaSchema)
z.toJSONSchema(HcpPolicyFileSchema)