Inspiration

People who need to step away unexpectedly, a scheduled procedure, a custody handoff, a hospital stay with no warning, have always faced the same bad choice: hand someone full access and hope they use good judgment, or go dark and let everything queue up until they're back. Password managers solve access, not judgment. Auto-replies solve nothing, they just defer. What was missing was a way to hand off exactly the part of a decision someone is comfortable handing off, nothing more, with everything outside that boundary going to a person they trust instead of an inbox nobody's watching. WebMCP made a genuine version of that possible: a tool surface that changes based on who is looking and what state things are in, computed live in the browser rather than fixed on a server, is what lets the boundary actually get enforced instead of just described in a policy nobody reads.

What it does

Relay lets someone prepare a delegate agent before they become unreachable, one that keeps answering the people who depend on them, inside limits they set in advance, escalating anything outside those limits to a person they trust. The absence doesn't have to be the same shape twice. A contractor covering client work during a scheduled procedure. Two co-parents who need logistics handled without every message pulling one of them out of their day. Someone who ends up in the hospital with no warning and no time to write instructions for anyone. A support lead pulled into a family emergency mid-shift. Relay works the same way whether the absence was planned six weeks out or started an hour ago. A person prepares a delegate agent in advance: an interview-style briefing agent asks about their specific situation and drafts a full configuration for them to review, rather than making them author policy from scratch. When the person goes unreachable, the delegate starts answering the people and agents who depend on them, inside a boundary of autonomy the principal defined, escalating anything outside that boundary to a named human, and producing a complete accounting of what happened.

How we built it

Relay registers seven WebMCP tools through document.modelContext.registerTool, but which tools are visible depends on who's looking and what state the relay is in: the principal sees five configuration tools while their relay is still in draft, a recipient sees nothing until the relay goes active and then sees exactly one tool (ask_delegate) scoped to their own access token, and everyone can request a record of what happened, filtered to what they're allowed to see. That conditional, per-visitor tool surface, not just per-server but per-session, is something a hosted MCP server can't express, and it's the core of why this is a WebMCP-native product rather than a chatbot with extra steps. Underneath that, the delegate's reasoning loop uses Claude to classify every incoming request into a tier (autonomous, flagged, refused) and propose a reply, then a deterministic check runs after the model and before any action is taken.

Challenges we ran into

The interesting part of building this turned out not to be the AI, it was the governance. Anyone can wire a chatbot to answer messages while someone's away. The harder problem is making sure it never quietly does more than it was authorized to do. If a request's dollar value exceeds an autonomous ceiling, it has to be forced to flagged regardless of what the model said. If nothing matches, it has to fall through to a configured default and never default to autonomous. The model proposes. The code disposes. Getting that rule to actually hold, every time, took more iteration than the AI side of the build did.

The other hard challenge was the permission surface itself, described above, getting the tool set to genuinely change per visitor and per state rather than just claiming to.

Late in the build, rehearsing the actual demo flow surfaced a genuine problem: the briefing interview was losing its own memory mid-conversation, because session state lived in server memory with no guarantee two requests land on the same instance. We caught it by testing the exact path a judge would take, not by reading the code, and moved session state into the database before it ever reached a recording.

Accomplishments we're proud of

The deterministic override actually holds under a live test, not just in theory: a request the model classified one way gets forced to a different tier the moment it crosses a rule the principal set, and the reply shown updates to match, so the tier badge and the words never contradict each other. The tool surface is genuinely live, not simulated, confirmed by calling document.modelContext.getTools() directly in an actual WebMCP-enabled browser and watching the exact same page return a different tool list depending on who's asking. And we found and fixed the session-memory bug above before it ever showed up in a recording, by actually rehearsing the demo end to end instead of assuming the happy path would hold.

What we learned

For a product where an agent has a multi-turn conversation, the failure modes that matter show up in an actual multi-turn conversation, not in a single request, and the only way to catch them is to actually run the conversation end to end rather than trust that a single successful test proves the whole path works.

What's next

There's no principal login yet, a relay's own URL currently acts as the access credential the way a recipient's token does, which is fine for a single-user demo but not for a multi-tenant product. Principal authentication is the next piece. Beyond that, more activation conditions (calendar-based, not just missed check-ins) and letting an approver resolve a flagged request directly through their own agent, not just by clicking Approve, are the two directions we'd take this next.

Built With

Share this project:

Updates

Submission history