WebMCP control room

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.

harshkamdar67.github.io/airlock-relay/app
The Relay console showing a blocked session, a rate limit on Anthropic, and the prompt to hand to a browser agent
7 typed toolsSession, events, routes, proposal, execution, and replay exposed through WebMCP with schemas and annotations.
Human approval, enforcedNo approve tool exists. Approval issues a token bound to the proposal revision, and any edit revokes it.
Real runtimesAirlock sessions today, plain Claude Code through hooks, and any agent through a small ingest contract.

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.

1The agent reads

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.

Agent
2The agent proposes

prepare_handoff writes a proposal into the page. Cooldown routes, routes without room, and metered routes it was not allowed are refused with alternatives.

Agent
3You decide

Change the target, add a note, then approve or reject. Approval is bound to the exact revision you saw.

You
4The agent executes

execute_handoff resumes the session on the approved route from its checkpoint, or is refused if you edited after approving. Retries are safe.

Agent

The 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.

ToolKindWhat it does
get_sessionreadTask, active model and provider, blocked or running and why, context against the window, checkpoint.
get_eventsreadThe router's event log: requests, 429s, cooldowns, failover attempts, handoff activity.
get_routesreadEvery route with provider, tier, context window, fit, plan headroom, readiness, and metered flag.
prepare_handoffwriteCreates a proposal. Refuses cooldown routes, routes without room, and metered routes unless allowed. Never switches anything.
get_handoffreadStatus, revision, target, every change the human made, and the approval token once approved.
execute_handoffwriteResumes on the approved route. Fails before approval and when the proposal changed after approval. Idempotent.
get_replayreadThe 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.

RuntimeWhere facts come fromBlock signalResume
AirlockThe 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 CodeClaude Code hooks post to the bridge.The StopFailure hook.claude --resume <id> --model <alias>
Any agentYour runtime posts small JSON state and events.An event with a failure set.Whatever your runtime supports.

Set it up in two minutes →