---
title: "Pack"
description: "What the three files of a pack hold, what never goes in them, where packs live, and the gold packs to copy when you start a new one."
canonical: https://harnesscontextprotocol.io/docs/concepts/pack
---

# Pack

> What the three files of a pack hold, what never goes in them, where packs live, and the gold packs to copy when you start a new one.

A Harness Pack is what a runtime installs: one directory, one id and three
files that declare a capability's commands, rules and teaching. The pack
declares and the runtime executes, so a pack holds nothing that depends on who
runs it and moves unchanged between runtimes. Start by copying the
[gold pack](#gold-packs) closest to your capability and changing its id, bin,
commands and Binding mode.

## Layout

```text
packs/<id>/
  surface.json    manifest — id, adapter, Binding mode, named commands, optional triggers
  policy.json     rules — one row per command and per trigger
  HARNESS.md      Skill — one screen of teaching
```

The layout is flat, though a runtime may nest directories for its own
operations without the pack knowing. The three names are exact and
case-sensitive, and install fails when one is missing or when Policy does not
cover every command and trigger. `surface.json` is the manifest's legacy
filename, kept for wire stability, and has nothing to do with UI surfaces.

| File | Piece | You fill |
|------|-------|----------|
| `surface.json` | [Manifest](/docs/packs/manifest) | Identity (`id`), how it runs (`kind`, `cliBin`, `wrap`), the credentials it needs (`binding.mode`), the `verbs` map of named commands with their CLI forms, and triggers only for an upstream system that pushes, so most packs have none |
| `policy.json` | [Policy](/docs/concepts/policy) | For every command and trigger: `operation` (`read` \| `write`), `privacy.land`, and `confirm` on writes that must not auto-fire |
| `HARNESS.md` | [Skill](/docs/concepts/skill) | Lead, hot-path table, examples, anti-patterns |

### Optional fields

Add these to the manifest only when the capability needs them.

| Field | When |
|-------|------|
| `stimulusTriggers[]` | The upstream system pushes real events |
| `binding.family` | Related packs should share one login |
| `wrap.agent_env` | The wrapped bin needs environment defaults it already understands |
| `plane: "control"` | Admin or operator CLI, which makes it a second pack |
| `transports: [... "mcp"]` | A runtime will export MCP tools from this pack |
| `pass_through` | Bootstrap only; promote to named commands |
| `openapi` | `kind: openapi` |
| `skill_url` | A hosted copy of the Skill |

### What stays out

- Secrets, a `secrets/` directory or a `.env` file. The pack names a Binding
  mode and the runtime's hub mints the credential.
- User allow-lists, roles, tenant ids and connector types, which belong to
  runtime grants and Principal scope.
- A server, since a pack describes an existing CLI or API.
- A whole binary. A pack names 5 to 12 commands, and `allowedSubcommands`
  pass-through is a bootstrap to promote.
- UI widget catalogs or inbox chrome. A UI host invokes commands from outside.
- A `families/` directory, since family is a manifest field.
- Extra Markdown for scale. A capability scales by adding packs, never by
  growing one.

### Where packs live

| Location | Purpose |
|----------|---------|
| Your repository, `packs/<id>/` | Source of record; one living repo per `pack_id` |
| `$HCP_HOME/packs/<id>/` | Installed copy in the runtime store |
| `$HCP_HOME/skills/<id>/SKILL.md` | Skill copy written on activate |

### Gold packs

| Pack | Class | Location |
|------|-------|----------|
| `transit` | Public read | `hcp/examples/packs/transit` |
| `ledger` | Gated write | `hcp/examples/packs/ledger` |
| `echo` | Composite, sandbox-safe | `hcp/examples/packs/echo` |
| `hcp-cli` | The bootstrap pack (composite, `local` Binding) | `hcp/packs/hcp-cli` |

## Identity

A pack's identity is its manifest `id`, which is also `pack_id` on the wire and
`surface_id` in the Policy file, and lint checks that all three agree. One
`pack_id` maps to one maintained repository. A command is identified by
`pack_id` + `verb_key`, a pair that stays stable across the CLI face, the JSON
face, the Skill, the host tool catalog and any MCP export.

## Planes

| `plane` | Meaning | Binding |
|---------|---------|---------|
| `runtime` (default) | End-user capability | `public` · `user` · `local` |
| `control` | Admin, fleet, operator | `mothership`, in a second pack |

A runtime never silently activates a control-plane pack on an end-user
Principal, and a domain CLI with both an admin face and a user face is two
packs.

## Versioning

An HCP/1.x pack declares protocol affinity `hcp: 1` in its metadata and leaves
content versioning to its repository. A manifest `version` field with registry
resolution is on the [roadmap](/docs/community/roadmap).

## Example

The gold public-read pack, in full:

<Tabs items={['surface.json', 'policy.json', 'HARNESS.md']}>
<Tab value="surface.json">

```json
{
  "id": "transit",
  "name": "Transit",
  "kind": "wrap",
  "cliBin": "transit",
  "plane": "runtime",
  "transports": ["cli", "json_exec"],
  "binding": { "mode": "public", "hub": "public" },
  "wrap": { "bin": "../../bins/transit.mjs", "argv_template": ["{{verb}}"] },
  "verbs": {
    "find":   { "description": "Resolve a place.",                       "cli": ["transit", "find", "{{query}}"] },
    "plan":   { "description": "Time-first options between two places.", "cli": ["transit", "plan", "{{from}}", "{{to}}"] },
    "show":   { "description": "Expand one option.",                     "cli": ["transit", "show", "{{optionId}}"] },
    "status": { "description": "Live observation.",                      "cli": ["transit", "status"] },
    "follow": { "description": "Follow a run.",                          "cli": ["transit", "follow", "{{runId}}"] }
  }
}
```

</Tab>
<Tab value="policy.json">

```json
{
  "surface_id": "transit",
  "version": 1,
  "verbs": {
    "find":   { "operation": "read", "privacy": { "land": "personal" } },
    "plan":   { "operation": "read", "privacy": { "land": "personal" } },
    "show":   { "operation": "read", "privacy": { "land": "personal" } },
    "status": { "operation": "read", "privacy": { "land": "personal" } },
    "follow": { "operation": "read", "privacy": { "land": "personal" } }
  },
  "stimuli": {}
}
```

</Tab>
<Tab value="HARNESS.md">

```md
# HCP — Transit

Public five-command wrap sample. No login. No secrets. Copy this shape for
discover / plan / show / status / follow.

## Hot path

| Command | CLI |
|---------|-----|
| `find` | `transit find "Central" --json` |
| `plan` | `transit plan "A" "B" --json` |
| `show` | `transit show opt-1 --json` |
| `status` | `transit status --json` |
| `follow` | `transit follow run-1 --json` |

## Anti-patterns

- One mega-command `run`
- Polling `plan` in a tight loop
- Host-absolute paths in this Skill
```

</Tab>
</Tabs>

## Related

- [Build packs](/docs/packs): the authoring path
- [Specification: Pack model](/docs/specification/pack-model)

## Sitemap

- [Documentation](https://harnesscontextprotocol.io/docs)
- [Packs](https://harnesscontextprotocol.io/packs)
- [Glossary](https://harnesscontextprotocol.io/docs/reference/glossary)
- [llms.txt](https://harnesscontextprotocol.io/llms.txt)
- [llms-full.txt](https://harnesscontextprotocol.io/llms-full.txt)
- [OpenAPI](https://harnesscontextprotocol.io/openapi.json)
- [MCP](https://harnesscontextprotocol.io/mcp)
