Inspiration
Roughly one to two in a hundred people live with OCD. An intrusive urge shows up — did I lock the door, are my hands clean — and the anxious brain insists you act on it right now, exactly when you can't argue back. The gold-standard treatment, Exposure and Response Prevention (ERP), is almost paradoxical: you get better by not acting on the urge, over and over, until the alarm quiets on its own.
The hard part is that the loop hits when no therapist is in the room. But something else usually is: a voice assistant. People already talk to Alexa+ when they're alone, hands busy, mid-spiral. I wanted to turn that into an objective reality anchor — something that grounds you in facts you set when you were calm, instead of feeding the compulsion with reassurance.
What it does
RealityAnchor is an MCP add-on for Alexa+ (and any MCP-capable agent) for OCD and cognitive loops. You talk to Alexa+ the way you already do; when a loop starts, it calls RealityAnchor's tools and does one of three things:
- Pauses the compulsion (human-in-the-loop). For a checking/doubt urge, it reads back your own calm-state anchor, names the thinking trap (intolerance of uncertainty), and instead of reassuring you it starts a timed ERP delay — you urge-surf, then commit. Reassurance on demand is the compulsion; delaying it is the therapy.
- Auto-resolves from an anchor. For a contamination urge where the facts already settle it ("my hands feel dirty but they're clean"), a matching anchor closes the loop with no delay and no intervention needed.
- Says act now. For a genuine safety signal — I smell gas — it recognizes real evidence and tells you plainly: this is not the loop, act now. Knowing when not to intervene is what makes the rest trustworthy.
Three MCP tools do the work:
get_baseline_rules— reads the user's pre-committed calm-state anchors back to them, in their own words.evaluate_cognitive_distortion— classifies the trigger against CBT distortions, rates risk, and flags genuine safety signals.trigger_erp_delay— starts a human-in-the-loop ERP delay with a resume callback.
Alongside the voice path, a visual grounding view (/mcp-view) renders each tool call as a live trace and builds the flow — the same context Alexa+ would show in the Alexa app.
How we built it
One Next.js (App Router) deploy hosts everything:
- A self-hosted MCP server over Streamable HTTP (MCP spec 2025-11-25) at
/api/mcp, built on@modelcontextprotocol/sdk'sWebStandardStreamableHTTPServerTransport. It's stateless — a fresh server per request — so it scales as a plain serverless route. - The analysis is generated by Claude on Amazon Bedrock (
@anthropic-ai/bedrock-sdk), with the first-party Anthropic API and a deterministic keyword heuristic as fallbacks, resolved in that order. - A BYOK flow lets anyone paste their own Bedrock key in the app's settings — stored only in the browser, sent per request, never persisted server-side — and threaded all the way through the in-app agent's loopback MCP call via a request header.
- The grounding UI is React Flow (
@xyflow/react) + Zustand, with an in-app "Alexa+ simulator" (/api/agent) that is itself a real MCP client connecting back to my own server, so the traces you see are genuine tool calls, not mock-ups. - For the external-client demo, any MCP client — Claude Code, Claude Desktop, the MCP Inspector, Gemini, Cursor — connects to the same URL and drives the tools with no glue code.
Challenges we ran into
- Locked-down MCP clients. A company-managed Claude Desktop blocked adding custom connectors, so I proved the external integration with Claude Code in the terminal (and the MCP Inspector as a policy-proof fallback) — both connect to the exact same Streamable HTTP endpoint.
- Stateless server, two surfaces. Because the MCP server holds no session and has no push channel to the browser, external tool calls (terminal) and the visual grounding view are deliberately separate surfaces; I was careful not to imply one drives the other, and I route the UI through its own agent/context path.
- Threading BYOK through a loopback agent. Getting a browser-pasted Bedrock key to drive every model path — including the in-app agent's own MCP round-trip — meant forwarding credentials through an MCP client transport header without ever writing them to the server.
- Making the reply honest. The agentic loop emits only the final terminal message as the spoken reply, so the chat bubble is the real answer rather than intermediate "let me check" asides.
Accomplishments that we're proud of
- A genuine MCP add-on: an outside agent discovers the server and calls the tools over Streamable HTTP with zero custom integration — exactly what the Alexa+ track asks for.
- The three-outcome spine, including the case most tools get wrong: recognizing a real safety signal and telling the user to act, not wait.
- ERP done right — a human-in-the-loop delay with a real resume callback, modeling the actual therapy instead of hand-waving "you've got this."
- BYOK on Bedrock, so a judge can run the whole thing on their own key and see real model output, with a heuristic fallback that keeps the demo working offline.
What we learned
- The practical details of MCP over Streamable HTTP — stateless transports, loopback clients, and how different MCP clients (Claude Code, Inspector, Desktop, Gemini, Cursor) each expect to be configured.
- Wiring Claude on Amazon Bedrock through the Mantle client, including BYOK precedence and graceful degradation to a heuristic.
- The clinical principle underneath the product: reassurance on demand is itself the compulsion, which flips the usual assistant instinct — the most helpful move is often to not answer and to hand control back to the user.
- Designing for a voice-first experience with a visual fallback, where the same tool context has to read well out loud and render as a diagram.
What's next for RealityAnchor
- Per-user anchor persistence and a proper onboarding to capture calm-state rules.
- A production Alexa+ skill deployment and real-device testing on an Echo.
- A richer, clinician-reviewed distortion and safety-signal library.
- An optional shared-session bridge (shared in-memory session + SSE) so an external agent's tool calls can update the visual grounding view live.
- Analytics for the user on their own ERP reps over time — the delays they held, the loops that passed on their own.
Built With
- ai-agents
- alexa+
- amazon-bedrock
- amazon-web-services
- json-rpc
- mcp
- model-context-protocol
- next.js
- react
- server-sent-events
- streamable-http
- tailwindcess
- typescript
- zustand
Log in or sign up for Devpost to join the conversation.