---
title: "Adapter"
description: "When to use wrap, composite, openapi or sense_only, the fields and safety rules of a wrap, and how a pack grows from pass-through to composite."
canonical: https://harnesscontextprotocol.io/docs/concepts/adapter
---

# Adapter

> When to use wrap, composite, openapi or sense_only, the fields and safety rules of a wrap, and how a pack grows from pass-through to composite.

An Adapter is how a command runs, and it sits beneath the pack's identity. A
pack can move from a wrap over a demo bin to the real CLI and then to
composite while its id, commands, Policy, Skill, host projection and grants
stay the same, which is why commands deserve good names from the start.

| Kind | Meaning | Reach for it when |
|------|---------|-------------------|
| `wrap` | Spawn an existing CLI with a rendered argv | The capability already exists as a binary. This is the default |
| `composite` | Call in-process (HTTP/SDK) | You own the SDK, or spawn cost matters |
| `openapi` | Commands bootstrapped from an OpenAPI document | You want a large surface quickly and will review the Policy it infers |
| `sense_only` | Emit triggers; no user commands | The pack observes and never acts |

## Wrap

Most packs start as a wrap, which leaves the wrapped tool unchanged.

```text
verb_key ──► argv from cli[] / argv_template (no shell interpolation)
         ──► spawn allow-listed wrap.bin … --json
         ──► parse stdout · non-zero exit → { ok: false, error }
```

```json title="surface.json (fragment)"
"kind": "wrap",
"wrap": {
  "bin": "../../bins/ledger.mjs",
  "argv_template": ["{{verb}}"],
  "agent_env": { "LEDGER_OUTPUT": "json" }
}
```

| Field | Meaning |
|-------|---------|
| `bin` | The executable. Relative paths resolve against the pack directory |
| `argv_template` | Fallback argv when a command has no `cli[]`. `{{verb}}` expands to the command tail |
| `agent_env` | Environment defaults the bin already understands. Pack-owned; runtimes never special-case bin ids |

Arguments are templated into an argv and never into a shell string. The bin
must be on the sandbox allow-list, and an unknown bin is denied, never looked
up on `PATH`. The minted Binding reaches the bin as the env or files it already
reads, and tokens never appear in Skill logs. A wrap declares named commands or
an explicit `pass_through` bootstrap (HCP/1.1), and lint fails when it declares
neither.

### Pass-through is a bootstrap

```json
"pass_through": { "allowedSubcommands": ["status", "list"], "maxArgv": 6 }
```

Pass-through gets a binary under Policy in an hour. Then promote the hot path to
named commands with Policy rows and drop the allow-list. A mega-command `run`
does not conform.

## Composite

When the SDK is yours, calling in-process saves serialising across a process
boundary. The `hcp-cli` bootstrap pack is composite, and so are most
linked-channel packs once they settle, usually in steps:

```text
pass_through ──► named 5–12 commands + policy.json ──► composite for hot paths
```

## OpenAPI

An `openapi` pack points at a document and lets tooling propose commands, with
`GET` as `read` and mutating methods as `write`. Review the inferred Policy as a
draft and still name the commands; HCP/1 requires no full codegen UI.

```json
"kind": "openapi",
"openapi": { "url": "https://api.example.com/openapi.json" }
```

## Sense-only

A `sense_only` pack declares no user commands and at least one stimulus, and
lint fails without a trigger ref. It fits pure ingress such as a webhook source
or an event feed. Add `connect` or `setup.*` only when the upstream source
needs a registration call, never bash to "install a webhook".

## Related

- [Wrap a CLI](/docs/packs/wrap-a-cli)
- [Sandbox](/docs/runtimes/sandbox): allow-lists and the cwd jail
- [Specification: Manifest](/docs/specification/manifest): adapter fields

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