---
title: "Adopt in a host"
description: "One command gives a coding agent the HCP Skill, the `hcpx` binary and one MCP tool, and an in-process loop gets one typed tool per command."
canonical: https://harnesscontextprotocol.io/docs/hosts
---

# Adopt in a host

> One command gives a coding agent the HCP Skill, the `hcpx` binary and one MCP tool, and an in-process loop gets one typed tool per command.

A host is an agent product such as an IDE assistant, a coding agent or a
TypeScript tool loop, and adopting HCP takes about as much work as adding an MCP
server. For a supported host one command is the whole integration: it writes one
Skill that teaches the CLI and one tool, `hcp`, that runs it, both generated
from the activated packs, and a pack activated later changes the Skill's catalog
without adding a tool. Pick your agent below, or embed the runtime if you build
your own loop.

## Set up in one command

```bash
hcpx activate transit ledger
hcpx adopt claude --write        # or: codex, cursor, opencode, grok, mcp, agent
```

<HostSetup />

To inspect what adopt would write, run any target with `--json` and without
`--write` (`hcpx adopt cursor --json`), or run `hcpx generate --json`. What a
host gets depends on whether its agent has a terminal.

| Host | What it gets | Adding a pack later |
|------|--------------|---------------------|
| [Coding agent](/docs/hosts/coding-agents) with a terminal (Claude Code, Cursor, Codex, OpenCode, Grok Bot) | The agent plugin: one Skill and the `hcpx` binary, plus the one-tool MCP export | Changes the catalog the Skill points at; no new tools |
| [MCP-only client](/docs/hosts/mcp) | The same plugin exposed as one MCP tool, `hcp` | Same; `tools/list` stays `[hcp]` |
| In-process loop ([AI SDK](/docs/hosts/ai-sdk)) | `HarnessAgent`: one typed tool per executable command, named `<pack_id>__<verb_key>` | Adds that pack's executable commands as tools |

Both shapes come from one generator, under the normative rules in
[Projections](/docs/specification/projections), and run through the same
runtime, the open reference or a company's own, which holds Binding, grants and
the sandbox.

```text
activated packs ──► generateHarnessSurfaces() ──┬── .hcp/plugin.json         one bash wrap (`hcpx`)
                                                ├── .hcp/surface.json        catalog
                                                ├── Cursor                    Skill + .cursor/mcp.json
                                                ├── OpenCode                  one tool `hcp`
                                                ├── Grok Bot / Grok Build     terminal → hcpx · one MCP tool
                                                └── AI SDK                    HarnessAgent tool map (in-process)
```

## The agent plugin

Every coding agent adopts HCP through the plugin, and its three faces reach the
same runtime.

| Face | What it is |
|------|------------|
| Skill | One `SKILL.md` that teaches lint, install, and exec |
| Bash | One binary, `hcpx`, also installed as `hcp` ([two names](/docs/quickstart#one-binary-two-names)) |
| MCP | One tool named `hcp` (served by `hcpx mcp`) that runs the same commands |

```bash
bun add -g @harnesscontextprotocol/cli
bun add @harnesscontextprotocol/plugin
hcpx adopt agent --write
```

During the preview both packages are on GitHub Packages, where
`@harnesscontextprotocol/plugin` is restricted, and
[Install the CLI](/docs/quickstart#install-the-cli) shows the `.npmrc`.

```json title=".hcp/plugin.json"
{
  "id": "hcp",
  "wrap": { "bin": "hcpx", "kind": "bash" },
  "skill": ".hcp/skills/hcp/SKILL.md",
  "mcp": { "command": "hcpx", "args": ["mcp"], "tool": "hcp" },
  "home": "/home/you/.hcp",
  "activated": ["transit", "ledger"]
}
```

`mcp.command` and `wrap.bin` are `hcpx`, and adopt writes `hcp` instead only for
an older install that answers to no other name. The host targets (`claude`,
`codex`, `cursor`, `opencode`, `grok`, `mcp`) write this same plugin into the
paths each host reads, listed in [Coding agents](/docs/hosts/coding-agents).

## Embed the runtime in your own loop

If you build your own agent loop, `HarnessAgent` wraps the runtime as a
tool-loop agent with grant-filtered tools, progressive Skill disclosure and
approval on write commands.

```ts
import { Hcp, HarnessAgent } from '@harnesscontextprotocol/sdk'

const hcp = await Hcp.create({ packDirs: ['./packs/transit'], sandbox: true })
await hcp.activate(['transit'])

const agent = await HarnessAgent.create({
  hcp,
  harness: 'my-product-v1',
  runtime: 'ai-sdk',
  model,
  context: { skillLeadChars: 480 },
})

const run = await agent.send('Plan a route from A to B')
await run.wait()
```

Each executable command becomes one tool named `<pack_id>__<verb_key>`, with
dots turned into underscores (`transit__plan`), and long results are compacted
between steps ([Context optimization](/docs/hosts#context-optimization)).
[AI SDK](/docs/hosts/ai-sdk) has the options, approvals and events.

## Adding native support to a new host

A host with no adopt target can attach the plugin by hand: put the Skill where
the host reads Skills and `hcpx` on its `PATH`, or register MCP as
`{ "command": "hcpx", "args": ["mcp"] }`. Native intake takes little more work.
A host that meets the
[host checklist](/docs/specification/conformance#144-host-conformance):

1. Presents packs in one of the two shapes: the `hcpx` binary plus its Skill,
   for hosts whose agent has a terminal, or one tool per executable command
   named `hcpToolName(pack_id, verb_key)`, for in-process loops. Both come from
   `generateHarnessSurfaces()` or the catalog at `.hcp/surface.json`.
2. Executes through the runtime (`hcpx exec <pack> <verb>` on the CLI face,
   `Hcp.exec()` in-process) and never spawns the wrap binary itself.
3. Exposes the Skill (the copied `SKILL.md`) progressively, lead first and full
   text on demand.
4. Surfaces write commands as approvals and passes `confirm: true` only after
   the user has agreed.
5. Reads availability before offering a tool, so the agent never sees a command
   it cannot run.
6. Never embeds credentials, adds a second policy for the same command, or
   hand-registers tools that bypass the pack.

A host may also subscribe to Sense for chrome, such as an inbox badge or a
"credential stale" banner, through the runtime's sink, but it never owns mint.
New `hcpx adopt <host>` targets go through the
[RFC process](/docs/community/governance#rfc-process).

## Why MCP is not the install path

| | Adding an MCP server | Adopting HCP |
|--|----------------------|--------------|
| Setup | A config fragment per server | `hcpx install`, `hcpx activate`, then `hcpx adopt` once |
| `tools/list` | N tools per server | `[hcp]`, or the `hcpx` binary |
| Credentials | The server holds them | The runtime mints them; the pack names a mode |
| Writes | Tool annotations hint at side effects | Policy `confirm` is enforced before exec |

MCP-only hosts use the [single-tool export](/docs/hosts/mcp), `hcpx mcp`. It
runs every call through the runtime but installs no pack, because it only
forwards to a runtime that already has packs installed and activated. Native
adopt also keeps Policy, Binding, Sense and Skill visible to the host, so it can
show approvals and teaching correctly.

## Context optimization

Ten activated packs with ten commands and a one-screen Skill each are more text
than an agent should see every turn, so the generated context loads them in
layers.

```text
┌──────────────────────────────────────────────┐
│ STABLE PREFIX (cache-friendly, rarely changes)│
│  · doctrine: activate packs, never hand-wire  │
│  · pack / command index (executable only)     │
│  · Skill leads (~480 chars each)              │
│  · "call hcp__read_skill for full teaching"   │
├──────────────────────────────────────────────┤
│ TOOLS                                         │
│  · hcp__read_skill                            │
│  · <pack>__<verb> … grant-filtered            │
│  · write commands: needsApproval              │
├──────────────────────────────────────────────┤
│ CONVERSATION (compacted by prepareStep)       │
└──────────────────────────────────────────────┘
```

The prefix holds only what changes with the activated set, the pack index and
the Skill leads, so prompt caches stay warm across turns; your own
`instructions` follow it. Each lead is the first `skillLeadChars` characters of
the pack's `HARNESS.md` (default 480) and often the only part the agent sees
before it acts, which is why the [Skill file guide](/docs/concepts/skill#skill-file)
insists it stand alone. The always-present `hcp__read_skill` tool returns the
full Skill for a `pack_id` (the hot-path table, examples and anti-patterns),
which is progressive disclosure in the Agent Skills sense with no per-pack code
in the host.

Only commands that are `executable` for the current grants become tools
(`executableOnly: true` by default), so the agent never wastes steps on tools it
would be denied. Every `operation: write` command carries `needsApproval: true`,
which the host renders while the runtime still enforces `confirm`. Between
tool-loop steps, `prepareStep` shortens old tool outputs such as long `list`
results and verbose `doctor` reports, keeps `hcp__read_skill` results intact,
and can narrow `activeTools` to the packs the conversation is using.

```ts
type ContextOptimizationOptions = {
  skillLeadChars?: number        // default 480
  // further knobs: compaction thresholds, activeTools narrowing
}
```

The whole bundle comes from `buildHcpContextBundle(hcp, options)`, which is also
what `hcpx generate` inspects and `hcpx adopt` writes for Cursor and OpenCode. A
hand-rolled context kit drifts from the packs, so regenerate it instead.

```bash
hcpx generate --json
```

## 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)
