# MCP over HTTP or over stdio

Use stdio when the server runs on the same machine as the client and needs local access: no port, no token, one process per client. Use streamable HTTP when the server is remote, shared or paid: it has a URL, a key per caller and can stream partial results. Holon serves both, and every published agent is an MCP server on https.

## The difference in one line each

**Stdio**: the client starts the server as a child process and writes JSON-RPC messages to its standard input, reading answers from its standard output. Nothing listens on a port.

**Streamable HTTP**: the server is a web service at a URL. The client posts messages to it, and the server can answer with a single response or stream events back while it works.

Both carry the same protocol, described in [what is the Model Context Protocol](/guides/what-is-model-context-protocol). The choice is about where the server runs and who may reach it.

## When stdio fits

Stdio is the right default when the server exists to give the assistant access to this machine: your files, your repository, a local database, a command line tool. Three properties make it pleasant.

There is no authentication to arrange. The process inherits your user's access, and secrets come from environment variables in the client's configuration. There is no key to rotate, and no token that could leak to a third party.

There is no network surface. Nobody can reach the server but the client that started it, because there is nothing to reach.

The lifecycle is simple. The client starts the process when it connects, and kills it when it stops. Each client gets its own instance, so there is no shared state to reason about and no concurrency between users.

The limits follow from the same properties. One user per process, no sharing between machines, and updates mean shipping a new binary or package to every person using it. A server that holds a database connection pool or costs money per call is badly served by a model where every client runs its own copy.

## When streamable HTTP fits

HTTP is the right default as soon as the server is somebody else's. A single deployment serves everyone, you update it by deploying, and each caller presents a token that identifies them. That is also what makes metering possible: the server knows who is calling before it does any work.

Streaming matters for long calls. A run that takes thirty seconds can send progress while it works instead of holding a silent connection, which keeps clients and proxies from treating it as dead.

The costs are the ones every web service has: TLS, a public name, a health check and a restart policy. For a paid agent those are not optional, and [deploying an MCP server](/guides/deploy-an-mcp-server) covers what Holon requires of the address.

## How Holon serves both

Holon appears on both sides of the protocol, so both transports show up in different places.

**The gateway as a server, over HTTP.** The hosted gateway exposes the six Holon tools at `/mcp`, over streamable HTTP. This is what you connect an assistant to:

```sh
claude mcp add --transport http holon https://api.useholon.com/mcp \
  --header "Authorization: Bearer hlk_a_your_agent_key"
```

**The gateway as a server, over stdio.** The command line version runs the same tools as a local process against a local state file, for development on the prototype:

```sh
holon mcp --mandate demo/sandbox
```

**Agents, always over HTTP.** A published agent is an MCP server on its author's own host, reached at an https URL. The gateway connects to it, calls one named tool, and reads the result. Holon refuses an endpoint that is not https, one that carries credentials, or one that resolves to a private address, and it never follows redirects.

## What changes for keys

Over stdio there is no key. The mandate is chosen when the process starts, with `--mandate`, and the running server acts under it. Whoever can start the process decides what it may spend.

Over HTTP the key is the mandate. An agent key (`hlk_a_…`) is tied to exactly one mandate and travels as an `Authorization: Bearer` header on every request. It cannot be widened from the client side, it can be revoked from the console at any time, and every resource it touches is scoped to it: it sees its own receipts, approvals and budget, and gets a 404 for anyone else's. A human key (`hlk_h_…`) is a different principal, expires after 30 days, and is the only one that may decide on an approval.

Put another way: over stdio the boundary is your machine, over HTTP the boundary is the key.

## What changes for approvals

A call above your threshold is held. How you are asked depends on the client, not on the transport alone.

If the client supports elicitation, a form can appear in it, showing the agent, the worst case and the input, and you answer there. On the hosted gateway that form is only sent to agent keys marked as attended, because a form is meaningless when no human is watching the client. The starter key is attended, since it is meant for a desktop or terminal assistant; keys you create later are not unless you ask.

Otherwise the call stays pending and you decide elsewhere: in the console with your human key, or with `holon approve <id>` on the local prototype. The agent then re-submits the same call with the approval, which is bound to the mandate, the agent version, the input hash and the cap, so it cannot be reused for anything else. The full picture is in [approve AI agent spending](/guides/approve-ai-agent-spending).

## A rule of thumb

Local access, one user, no money: stdio. Remote, shared, metered or paid: streamable HTTP. If you are writing an agent to publish, the decision is made for you.

## Questions

### Is HTTP slower than stdio?

It adds a network round trip and TLS. For a call that takes a second or more, the difference is noise. For a tool called hundreds of times against local files, stdio wins.

### Can one server offer both transports?

Yes, and many do: the same tool handlers behind two entry points. The Holon CLI serves stdio locally, and the hosted gateway serves the same tools over HTTP.

### Which transport do I need to publish an agent?

Streamable HTTP on https. A stdio server runs on the caller's machine, and Holon calls agents over the network.

Updated 2026-09-23.
