Skip to content
Skip to content
HCP
Quickstart

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.

.npmrc
@harnesscontextprotocol:registry=https://npm.pkg.github.com
bun add @harnesscontextprotocol/sdk

Runtimes 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

runtime.ts
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.

#ResponsibilityFail-closed rule
1Load surface.json, policy.json, HARNESS.md from a pack directoryReject the pack if lint fails
2Lint on install: Policy covers every command and trigger; Skill present; wrap has named commands or pass_throughSee Lint rules
3Authorise each exec against five capability axes for a PrincipalDeny with a reason; never default-allow
4Gate writes with confirm: trueRefuse before any adapter runs
5Mint Binding through your hub for user / local / mothership modesNo ambient environment fallback
6Execute the Adapter: spawn the wrap bin with a rendered argv, or call in-processUnknown bin denied in sandbox
7Sandbox by default: bin allow-list, cwd jail, no inherited credentialsnative-local only by explicit opt-in
8Audit writes with Principal + tenant (+ project) + Binding + pack + verb + operationNone
9Report availability per command: installed · activated · connected · executableEvery 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