Your coding agent got stuck at 2 AM. A browser agent and you fix it together.
Airlock Relay turns a blocked coding-agent session into a page that two parties operate at once. The agent reads the runtime through seven typed WebMCP tools and proposes a handoff to another model. You edit the proposal, approve it with one click, and the agent resumes the work from its checkpoint. Nothing is inferred from the DOM and nothing switches without you.
Works in the ChatGPT desktop browser and in Chrome 149+ with WebMCP enabled. The console runs a demo seeded from a real Airlock router export; connect the local bridge for your own session.

How a handoff happens
Both parties act on one shared object. The page records who did what, in order, and the agent can read that timeline back.
get_session, get_events, and get_routes tell it what broke, what is on cooldown, which routes fit the context, and what spends metered usage.
Agentprepare_handoff writes a proposal into the page. Cooldown routes, routes without room, and metered routes it was not allowed are refused with alternatives.
AgentChange the target, add a note, then approve or reject. Approval is bound to the exact revision you saw.
Youexecute_handoff resumes the session on the approved route from its checkpoint, or is refused if you edited after approving. Retries are safe.
AgentThe console
Dark-first, one accent, four actor tints. The status and the four numbers that decide the next action sit top-left; everything else is progressive disclosure.




What the agent can do
Every tool has a JSON Schema, a use-case description, and annotations. Reads carry readOnlyHint; the event log carries untrustedContentHint. Results are bounded and errors are structured so the agent can self-correct.
| Tool | Kind | What it does |
|---|---|---|
get_session | read | Task, active model and provider, blocked or running and why, context against the window, checkpoint. |
get_events | read | The router's event log: requests, 429s, cooldowns, failover attempts, handoff activity. |
get_routes | read | Every route with provider, tier, context window, fit, plan headroom, readiness, and metered flag. |
prepare_handoff | write | Creates a proposal. Refuses cooldown routes, routes without room, and metered routes unless allowed. Never switches anything. |
get_handoff | read | Status, revision, target, every change the human made, and the approval token once approved. |
execute_handoff | write | Resumes on the approved route. Fails before approval and when the proposal changed after approval. Idempotent. |
get_replay | read | The attributed timeline: runtime, agent, and human actions in order. |
Works with
The page, the tools, the approval model, and the replay are identical for every runtime. Only the adapter changes.
| Runtime | Where facts come from | Block signal | Resume |
|---|---|---|---|
| Airlock | The router's loopback diagnostics and model list, polled by the bridge. | Router cooldown lists and chain-exhausted events. | airlock hybrid <route> --resume <id> |
| Plain Claude Code | Claude Code hooks post to the bridge. | The StopFailure hook. | claude --resume <id> --model <alias> |
| Any agent | Your runtime posts small JSON state and events. | An event with a failure set. | Whatever your runtime supports. |