.md

Schemas

Seven JSON Schemas, each live at its $id, for validating surface.json, policy.json, the envelopes, grants, availability and hcp.eval.json.

On this page

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.

surface.json#

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#

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#

JSON
{
  "$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#

JSON
{
  "$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#

JSON
{
  "$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#

JSON
{
  "$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.

JSON
{
  "$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:

TypeScript
import { z } from 'zod'
import { HarnessPackMetaSchema, HcpPolicyFileSchema } from '@harnesscontextprotocol/sdk'

z.toJSONSchema(HarnessPackMetaSchema)
z.toJSONSchema(HcpPolicyFileSchema)