SDK
The TypeScript reference SDK: Hcp facade, runtime drivers, loaders and lints, grants, availability, generation, host adoption, and HarnessAgent.
Package: @harnesscontextprotocol/sdk. TypeScript, ESM, Zod schemas. It is the
reference implementation of the Specification; the spec
governs where they differ.
bun add @harnesscontextprotocol/sdkHcp facade
import { Hcp } from '@harnesscontextprotocol/sdk'
const hcp = await Hcp.create({
packDirs: ['./packs/transit', './packs/ledger'],
sandbox: true,
grants: [{ capability: 'verb.exec.read' }],
principal: { id: 'u_1', kind: 'human' },
tenant_id: 't_1',
project_id: null,
})
await hcp.activate(['transit'])
const res = await hcp.exec('transit', 'plan', { from: 'Zurich', to: 'Bern' })Hcp.create(opts): Promise<Hcp>
| Option | Type | Default | Notes |
|---|---|---|---|
runtime | HcpRuntimeDriver | 'local' | 'proprietary-stub' | 'local' | Pass your own driver to embed |
packDirs | string[] | none | Required for 'local' |
packs | LoadedHcpPack[] | none | Required for 'proprietary-stub' |
sandbox | boolean | true | |
nativeLocal | boolean | false | native-local only when sandbox: false && nativeLocal: true |
grants | HcpGrant[] | permissiveGrants() | |
principal | HcpPrincipal | { id: 'local-principal', kind: 'human' } | |
tenant_id | string | 'local-tenant' | |
project_id | string | null | null | Required for land brain |
allowBins | string[] | pack bins | Sandbox allow-list additions |
Methods
| Method | Returns | Behaviour |
|---|---|---|
activate(ids) | Promise<void> | Throws cannot activate unknown pack: <id> |
activatedPacks() | string[] | |
connect(id) | Promise<void> | Throws if not activated or the driver's connect fails |
exec(id, verb, args?) | Promise<HcpExecResult> | Returns ok: false for unactivated packs; delegates to the driver |
listVerbs(id) | Promise<string[]> | |
skill(id) | Promise<string> | HARNESS.md text or '' |
listPacks() | Promise<LoadedHcpPack[]> | |
setGrants(grants) | void | Replaces the authz grants |
sandboxMode | HcpSandboxMode | 'sandbox' | 'native-local' |
authz | HcpAuthzContext | Principal, tenant, project, grants |
Runtime drivers
type HcpRuntimeDriver = {
name: string
listPacks(): Promise<LoadedHcpPack[]>
getPack(pack_id: string): Promise<LoadedHcpPack | null>
connect?(pack_id: string, authz: HcpAuthzContext): Promise<{ ok: boolean; error?: string }>
exec(args: {
pack_id: string; verb_key: string; args?: Record<string, unknown>
authz: HcpAuthzContext; sandbox: HcpSandboxMode
}): Promise<HcpExecResult>
}createReferenceLocalRuntime({ packDirs, allowBins? })runs wrap and composite adapters with a process allow-list, a cwd jail, andHCP_SANDBOXset in the child. It implements the pipeline in §6.3.createProprietaryStubRuntime({ packs, grants, principal })runs the same authorization pipeline with a stubbed adapter step. It is the starting point for a hosted runtime. See Build runtimes.
type HcpExecResult = {
ok: boolean; pack_id: string; verb_key: string
result?: unknown; error?: string; stdout?: string; stderr?: string
}Loading and linting
| Export | Purpose |
|---|---|
loadPackFromDir(dir) | Reads the three files, parses hcp meta, returns LoadedHcpPack |
lintLoadedPack(pack) | Runs lintHarnessPack + lintHcpPolicy; returns HarnessPackLintIssue[] |
lintHarnessPack({...}) | Manifest-level lints (presence, meta, wrap, plane, openapi, sense_only) |
lintHcpPolicy({...}) | Coverage lints (missing/extra verbs and stimuli, surface_id match) |
parseHarnessPackMeta(raw) | Zod parse of the hcp block |
parseHcpPolicyFile(raw) | Zod parse of policy.json |
getVerbPolicy(file, key), getStimulusPolicy(file, ref) | Lookups |
applyHarnessPackMeta(meta) | Runtime projection (bin, cwd, env) from meta |
wrapAgentEnvFromMeta(meta, env?) | Merged child environment |
type LoadedHcpPack = {
pack_id: string; dir: string
manifest: HcpPackManifest; policy: HcpPolicyFile
harness_md: string; harness_present: boolean
adapter_kind: HarnessAdapterKind; binding?: HarnessBinding; wrap?: HarnessWrapTarget
verb_keys: string[]
}Schemas
Zod schemas, exported for validation and for generating JSON Schema:
HarnessPackMetaSchema, HarnessBindingSchema, HarnessAdapterKindSchema,
HarnessWrapTargetSchema, HarnessPassThroughSchema, HarnessOpenApiRefSchema,
HcpPolicyFileSchema, HcpPolicyEntrySchema, HcpPolicyOperationSchema,
HcpPrivacyLandSchema.
Constants: HCP_PROTOCOL_ID = 'hcp', HCP_VERSION = 1. See
Schemas.
Grants
const HCP_CAPABILITIES = ['pack.install', 'pack.connect', 'verb.exec.read', 'verb.exec.write', 'sense.enable'] as const
type HcpGrant = { capability: HcpCapability; pack_id?: string; verb_keys?: string[] }
type HcpPrincipal = { id: string; kind: 'human' | 'service' | 'agent' | 'mothership' }
type HcpAuthzContext = { principal: HcpPrincipal; tenant_id: string; project_id: string | null; grants: HcpGrant[] }
type HcpAuthorize = (ctx: HcpAuthzContext, req: HcpExecRequest) => HcpAuthzDecisiondefaultAuthorize implements §9.4 and §9.5:
land brain requires project_id; the capability is chosen from the Policy
operation; grant matching narrows by pack_id then verb_keys.
permissiveGrants() returns one unscoped grant per capability.
Availability
buildPackAvailability({ pack, installed, activated, connected, grants, source_available })
returns HcpPackAvailability with per-command executable and a reason
(not installed, not activated, missing <capability>). Used by
hcp availability.
Generation and adoption
| Export | Purpose |
|---|---|
generateHarnessSurfaces(hcp, opts?) | Prompt block, tools, skills, per-host configs from activated packs |
hcpToolName(pack_id, verb_key) | hcp__<pack>__<verb> |
adoptOpenCode(surfaces, cwd, { write, pluginEntry }) | Writes opencode.json + plugin wiring |
adoptCursor(surfaces, cwd, { write }) | Writes .cursor/ rules and skills |
buildHcpContextBundle(hcp, opts?) | Stable prefix + leads + hcp__read_skill tool. See Context optimization |
hcpToToolLoopAgent(hcp, opts) | AI SDK tool set from an Hcp |
Host intake
For hosts that consume a generated surface manifest rather than embedding the
runtime: loadSurfaceManifest(cwd), loadHostIntake(cwd, opts?),
resolveSurfaceTool(manifest, toolName), execVerbViaCli(tool, args, opts)
(shells to hcp exec and parses JSON; non-json cli output on failure).
HarnessAgent
import { HarnessAgent } from '@harnesscontextprotocol/sdk'
const agent = await HarnessAgent.create({
runtime: 'ai-sdk', model, packDirs: ['./packs/transit'],
grants: [{ capability: 'verb.exec.read' }],
})
for await (const ev of agent.run('Plan Zurich → Bern at 9')) { … }See AI SDK for options, events, and approval flow.
Store helpers
resolveHcpHome(env?), ensureHcpHome(), ensureBootstrapPack(dir, layout),
installPackFromDir(src, layout), uninstallPack(id, layout),
listInstalledPackDirs(layout), readCliState(layout), writeCliState(state, layout),
installPackSkill(pack, layout). These back the CLI.
Deprecated aliases
Systems* policy schema names and parseSystemsSurfacePolicyFile /
lintSystemsSurfacePolicy remain exported and map to their Hcp* equivalents.