Implement a runtime
Build the thing that loads packs, enforces grants, mints Binding, sandboxes adapters, and reports availability, with the reference SDK or from scratch.
A runtime is whatever drives the agent and takes responsibility for packs. In HCP the harness is the runtime: there is no separate server to host. This page shows the fastest route with the reference TypeScript SDK, then what a runtime in any language must do to conform.
With the reference SDK
Install
The SDK publishes to GitHub Packages as @harnesscontextprotocol/sdk.
@harnesscontextprotocol:registry=https://npm.pkg.github.combun add @harnesscontextprotocol/sdkRuntimes that only need to parse and lint packs, with no agent loop, can import
@harnesscontextprotocol/sdk/pack, which carries no AI SDK dependency.
Create a runtime over pack directories
import { Hcp } from '@harnesscontextprotocol/sdk'
const hcp = await Hcp.create({
packDirs: ['./packs/transit', './packs/ledger'],
sandbox: true, // default posture
allowBins: ['transit', 'ledger'], // wrap bins the sandbox may spawn
principal: { id: 'user_42', kind: 'human' },
tenant_id: 'acme',
project_id: null, // required only for land: brain
grants: [
{ capability: 'verb.exec.read', pack_id: 'transit' },
{ capability: 'verb.exec.read', pack_id: 'ledger' },
{ capability: 'verb.exec.write', pack_id: 'ledger', verb_keys: ['transfer'] },
{ capability: 'pack.connect', pack_id: 'ledger' },
],
})Nothing is implicit. If you omit grants, the SDK uses permissiveGrants(), which
is fine for a local demo and wrong for anything multi-tenant.
Activate, connect, exec
await hcp.activate(['transit', 'ledger'])
await hcp.connect('ledger') // Binding mint; skipped for public packs
const read = await hcp.exec('transit', 'plan', { from: 'A', to: 'B' })
// { ok: true, pack_id: 'transit', verb_key: 'plan', result: {…} }
const denied = await hcp.exec('ledger', 'transfer', { amount: 10 })
// { ok: false, error: 'confirm required' }
const ok = await hcp.exec('ledger', 'transfer', { amount: 10, confirm: true })
// { ok: true, … }Every result is an envelope: { ok, pack_id, verb_key, result?, error? }. A
denial is a value, not an exception, so agents can branch on it.
Report availability
import { buildPackAvailability } from '@harnesscontextprotocol/sdk'
for (const pack of await hcp.listPacks()) {
const report = buildPackAvailability({
pack,
installed: true,
activated: hcp.activatedPacks().includes(pack.pack_id),
connected: false,
grants: hcp.authz.grants,
})
// report.verbs[i] → { verb_key, operation, land, executable, reason? }
}An agent should read availability before it plans, so it does not discover a denial mid-run.
Plug in your own driver
The SDK's Hcp class is a thin front over an HcpRuntimeDriver. Implement that
interface to back packs with your own catalog, credential hub, and RBAC.
import type { HcpRuntimeDriver } from '@harnesscontextprotocol/sdk'
const driver: HcpRuntimeDriver = {
id: 'acme-runtime',
kind: 'proprietary',
listPacks: () => catalog.all(),
getPack: (id) => catalog.get(id),
connect: (pack_id, authz) => hub.mint(pack_id, authz),
exec: async ({ pack_id, verb_key, args, authz, sandbox }) => {
// grant → confirm → mint → adapter → sandbox → audit
},
}
const hcp = await Hcp.create({ runtime: driver, grants })createProprietaryStubRuntime ships as an in-memory example of this shape, so
multi-runtime behaviour is testable without a vendor stack.
From scratch, in any language
A conforming runtime does these nine things. Each is specified in Runtimes and tested by the conformance vectors.
| # | Responsibility | Fail-closed rule |
|---|---|---|
| 1 | Load surface.json, policy.json, HARNESS.md from a pack directory | Reject the pack if lint fails |
| 2 | Lint on install: Policy covers every command and trigger; Skill present; wrap has named commands or pass_through | See Lint rules |
| 3 | Authorise each exec against five capability axes for a Principal | Deny with a reason; never default-allow |
| 4 | Gate writes with confirm: true | Refuse before any adapter runs |
| 5 | Mint Binding through your hub for user / local / mothership modes | No ambient environment fallback |
| 6 | Execute the Adapter: spawn the wrap bin with a rendered argv, or call in-process | Unknown bin denied in sandbox |
| 7 | Sandbox by default: bin allow-list, cwd jail, no inherited credentials | native-local only by explicit opt-in |
| 8 | Audit writes with Principal + tenant (+ project) + Binding + pack + verb + operation | None |
| 9 | Report availability per command: installed · activated · connected · executable | Every false carries a reason |
Optionally, a runtime routes Sense: it accepts declared triggers under the
sense.enable grant and records them in a sink. How it delivers them is its own
business.
What you do not have to build
- A public network "HCP server". Remote transport is a runtime choice; the protocol defines no server role.
- A registry. Local directory install is enough for HCP/1.x.
- Publication of your ACL tables, catalog schema, or credential hub internals.
Harnesses see only
activate·connect·exec· Skill.
Next
- Runtimes: the full responsibility model
- Authorization: Principals, lands, grants
- Sandbox
- Runtime conformance