Skip to content
Skip to content
HCP

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/sdk

Hcp 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>

OptionTypeDefaultNotes
runtimeHcpRuntimeDriver | 'local' | 'proprietary-stub''local'Pass your own driver to embed
packDirsstring[]noneRequired for 'local'
packsLoadedHcpPack[]noneRequired for 'proprietary-stub'
sandboxbooleantrue
nativeLocalbooleanfalsenative-local only when sandbox: false && nativeLocal: true
grantsHcpGrant[]permissiveGrants()
principalHcpPrincipal{ id: 'local-principal', kind: 'human' }
tenant_idstring'local-tenant'
project_idstring | nullnullRequired for land brain
allowBinsstring[]pack binsSandbox allow-list additions

Methods

MethodReturnsBehaviour
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)voidReplaces the authz grants
sandboxModeHcpSandboxMode'sandbox' | 'native-local'
authzHcpAuthzContextPrincipal, 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, and HCP_SANDBOX set 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

ExportPurpose
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) => HcpAuthzDecision

defaultAuthorize 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

ExportPurpose
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.