---
title: "MCP export"
description: "A host that can only add an MCP server gets one tool, `hcp`, that runs `hcpx` commands in process while the pack stays the unit you install."
canonical: https://harnesscontextprotocol.io/docs/hosts/mcp
---

# MCP export

> A host that can only add an MCP server gets one tool, `hcp`, that runs `hcpx` commands in process while the pack stays the unit you install.

For a host that can only add an MCP server, the reference export is one tool
named `hcp` that wraps the CLI, instead of one tool per command. Search, install,
Skill, availability and exec all go through it, so the host takes new packs
without a config change, which a host given one tool per command never could.
Run `hcpx adopt mcp --write` and point the host at `hcpx mcp`.

## How a call runs

The tool's argument is the same argv you would type after `hcpx`. The server is
no shell, so it rejects pipes, substitution and chaining, and it runs each call
inside its own process the way `hcpx` runs it in a terminal: one runtime load
and no new CLI process. Every call still goes through Policy, Binding and the
sandbox, and the access commands refuse the agent there as they do in its
shell.

```text
Host (MCP only)
   │  tools/list → [hcp]
   │  tools/call { args: "exec transit plan -- from=A to=B" }
   ▼
hcpx mcp  (stdio)  →  run that argv in this process  (no shell, no new process)
   ▼
exec transit plan --json -- from=A to=B
   ▼
runtime (§6.3)  →  spawns the pack's CLI
```

## Run it

```bash
bun add -g @harnesscontextprotocol/cli   # GitHub Packages preview: /docs/quickstart#install-the-cli
hcpx adopt mcp --write
hcpx mcp                                  # stdio server
```

Adopt writes `.hcp/mcp.json`:

```json
{
  "mcpServers": {
    "hcp": {
      "command": "hcpx",
      "args": ["mcp"],
      "env": { "HCP_HOME": "~/.hcp" }
    }
  }
}
```

`command` is [the name that starts the CLI on your machine](/docs/quickstart#one-binary-two-names).
Point the host at that command, then call the one tool named `hcp`:

| `args` (string) | `argv` (array) | What happens |
|-----------------|----------------|----------------|
| `search transit` | `["search","transit"]` | Catalog search |
| `skill transit` | `["skill","transit"]` | Skill text |
| `availability transit` | `["availability","transit"]` | Four-flag availability |
| `exec transit plan -- from=A to=B` | `["exec","transit","plan","--","from=A","to=B"]` | Execute through the runtime |
| `install npm:@scope/pack` | `["install","npm:@scope/pack"]` | Install a pack package |

Prefer `argv` when the host can pass an array, and use `args`, the bash-like
form, when it only sends a string. Neither is a shell, and both reject
metacharacters.

For reading, `resources/list` exposes `hcp://catalog`, `hcp://help` and
`hcp://skill/<pack_id>` for installed packs, with no extra tools. Actions still
go through the single `hcp` tool, and writes still need `confirm=true` when
Policy says so, so MCP gives the model no way around the gate.

## What the export does not do

Installing the MCP server installs no pack, because `hcpx install` still copies
the three files. When the host can load HCP directly, native adopt
([coding agents](/docs/hosts/coding-agents)) is the better path, for the reasons
in [Adopt in a host](/docs/hosts#why-mcp-is-not-the-install-path). The normative
rules are in
[§12.5](/docs/specification/projections#125-export-to-other-protocols).

## Related

- [Agent plugin](/docs/hosts#the-agent-plugin)
- [CLI](/docs/reference/cli)
- [Catalog](/docs/packs/share#catalog)

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