Skip to main content

The path a request takes

Three things worth noticing: The CLI dials out. The WebSocket to the edge is an outbound connection from your machine. Nothing inbound is opened, no port is forwarded, and your router and firewall don’t need to know anything about this. Your server sees an ordinary local request. The CLI forwards each one to 127.0.0.1 (or myapp.test, or wherever you pointed it) exactly as it arrived, with the Host header rewritten to your local target. Self-signed certificates are accepted deliberately, because Herd and Valet use them. The timeline is a copy, not a checkpoint. The edge forwards each chunk of the response the instant it arrives and hands a copy to the inspector afterwards. Forward first, inspect second — always in that order.

Why “never buffer” matters

MCP streams over Server-Sent Events. A proxy that waits for a complete response body before passing it on turns every streaming response into a hang: the agent sits there receiving nothing until the server finishes, which for a long-running tool call may be minutes. So the edge streams. Its regression test fires a reference server one byte at a time and asserts the SSE frame terminators survive. The production TLS layer disables response buffering for the same reason. The practical consequence for you: a slow tool call looks slow, not broken, and partial output reaches the agent as it’s produced.

The parts

A single static Rust binary. Holds the WebSocket to the edge, multiplexes many concurrent agent requests over it, forwards each to your local server, and reconnects with jittered backoff when the network blips. It also runs the handshake probe locally for heymcp probe.
Terminates TLS, resolves the hostname to your tunnel, applies path policy and any bearer requirement, and streams the exchange both ways. It also parses MCP frames as they pass, which is where the timeline comes from.Every failure at the edge answers with a real HTTP status code and a JSON-RPC error object, because agents are not browsers and an HTML error page is an unretryable, confusing failure inside a client. See Troubleshooting.
The web app at app.heymcp.dev. Receives events over a websocket as they happen, folds request/response pairs into single rows, and keeps history for as long as your plan’s retention window allows.

What happens when something goes wrong