RxRelay
Enables Twilio-based voice and SMS communication, including inbound TeXML voice handling and outbound coordination calls and patient notifications.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@RxRelayGet the proof receipt for case RX-1001"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
RxRelay
A voice agent that has to prove it helped.
Consent-first voice coordination for prescription access.
A case can close only when consent ∧ action ∧ counterpart outcome ∧ patient update are on the record — not when an LLM says “done.”
Website · Judge demo · Pitch deck · PPTX · Quickstart · Proof gate · Paper
✅ Product completeness (v0.2)
Everything judges need for demo + evaluation is shipped and tested.
Surface | Status |
Consent + deterministic 4/4 proof gate | Works (tested) |
Pharmacy→clinic→ready→SMS proof path | Works (sandbox E2E; voice + dashboard) |
Inbound TeXML voice ( | Works (isolated blast radius) |
PAVO demand routing + safe-stop | Works; verified turns upgrade speech+DTMF + strong model |
Signed hash-chained proof receipts | Works ( |
Counterpart attestation (pharmacy/clinic) | Works ( |
Human ops queue + resume + timeout scan | Works |
Live SSE proof stream | Works ( |
MCP tools (8) | Works |
Marketing site + 13-slide HTML/PPTX deck | Shipped |
Outbound SMS + coordination call adapters | Works — sandbox always; live carrier path is intentionally fail-closed until OTP allowlist + |
Related MCP server: BRAINS MCP Server
📖 Table of contents
Demo number (live inbound): +1 (802) 676-8127 · full judge script: docs/JUDGE_DEMO.md
⚡ Why this exists
A prescription can be clinically approved and still be unreachable. Something stalls — prior auth, stock, a missing form — and the patient becomes the switchboard:
call pharmacy → call clinic → call insurer → repeat context → still no trustworthy answer.
Voice agents are an obvious fit for that loop. The failure mode is subtler:
An agent that says “I’ve taken care of it” and an agent that actually coordinated something look identical at the transcript layer.
In medication access, that gap is the whole risk.
RxRelay closes the gap by refusing to close a case it cannot substantiate.
Generic voice agent | RxRelay |
“I’ll take care of it.” | “Here is the evidence I can prove.” |
One inference path for every turn | PAVO-style routing across ASR and reasoning |
Conversation ends ⇒ task done | Case stays open until the proof gate is satisfied |
Treats every request as automatable | Hard-stops clinical advice, Rx changes, emergency cues, controlled-inventory questions |
Failed API call still narrates success | Failed provider call records no action evidence |
🔐 The proof gate
This is the core idea, and it is deliberately boring: an LLM never decides that a case is resolved. A pure function over recorded state does.
// src/store.mjs — the close gate is not generative
function resolutionProof(caseRecord) {
const checks = [
{ id: "consent", label: "Explicit consent recorded", passed: caseRecord.evidence.consentRecorded },
{ id: "action", label: "Permitted coordination action completed", passed: caseRecord.evidence.permittedActionCompleted },
{ id: "outcome", label: "Counterpart outcome recorded", passed: caseRecord.evidence.counterpartOutcomeRecorded },
{ id: "notification", label: "Patient notification sent", passed: caseRecord.evidence.patientNotificationSent },
];
return { checks, ready: checks.every((check) => check.passed) };
} consent ∧ permitted action ∧ counterpart outcome ∧ patient update
─────── ──────────────── ────────────────── ──────────────
recorded provider-accepted pharmacy/clinic fact consented SMS
(or sandbox)
│
▼
Resolution verified
(every other state stays open)Property | How it is enforced |
No action before consent |
|
No fabricated completions | Evidence flags are set by state transitions, never by model output |
Failure is visible | A rejected provider call leaves |
Partial progress stays open | Clinic submission ≠ resolved Rx; pharmacy confirmation is still required |
There is a dedicated honesty test — a provider that throws must not manufacture action evidence:
test("failed outbound coordination cannot create a false action proof", async () => {
const failingTelephony = { placeCoordinationCall: async () => { throw new Error("Provider unavailable"); } };
const store = new CaseStore({ telephony: failingTelephony });
await assert.rejects(() => store.beginCoordination("RX-1048"), /Provider unavailable/);
assert.equal(store.get("RX-1048").evidence.permittedActionCompleted, false);
});🖥️ Screenshots
Proof board | Architecture | PAVO routing |
Deterministic close gate | End-to-end system topology | Demand-conditioned pipelines |
Problem framing | Live demo flow | Safety contract |
Full narrative deck: HTML · PPTX (npm run deck)
🏗 Architecture
Two processes. One shared case file. The public tunnel only ever touches the TeXML voice gateway — never the dashboard or MCP surface.
Caller (consented)
│
▼
┌──────────────────────────────────────────┐
│ Cloudflare quick tunnel │
│ (scripts/live-inbound.mjs) │
└────────────────────┬─────────────────────┘
│ TeXML only
▼
┌──────────────────────────────────────────┐ ┌──────────────────────────────────────────┐
│ voice-server.mjs :3001 │ │ server.mjs :3000 │
│ /voice /voice/turn /health │ │ proof board · /api/cases · /mcp │
│ token-gated · no dashboard · no MCP │ │ webhook seam · demo lab │
└────────────────────┬─────────────────────┘ └────────────────────┬─────────────────────┘
│ │
└──────────────────┬─────────────────────────────┘
▼
┌─────────────────────────┐
│ shared CaseStore │
│ persist → data/cases.json
└───────────┬─────────────┘
│
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
pavo.mjs inference.mjs telephony.mjs
demand-conditioned OpenAI Responses sandbox | fail-closed
routing + local fallback live adapterDeep dive: docs/ARCHITECTURE.md · full diagram: docs/ARCHITECTURE_DIAGRAM.md · pitch architecture slide in assets/architecture.png.
🚀 Quickstart
git clone https://github.com/vnmoorthy/rxrelay.git
cd rxrelay
cp .env.example .env
npm test # 27 tests · node:test · no install step
npm run deck # rebuild PPTX → deck/output/… ; HTML at deck/pitch.html
npm run dev # http://localhost:3000There is nothing to npm install. The sandbox demo has zero runtime dependencies — Node 20+ provides the HTTP server, test runner, --env-file-if-exists, and fetch.
Default mode is TELEPHONY_PROVIDER=demo with ALLOW_LIVE_TELEPHONY=false, so the entire flow runs without dialing or texting a real person.
Pitch deck
Live HTML: vnmoorthy.github.io/rxrelay/deck/pitch.html
Local HTML:
deck/pitch.html(fullscreen · ← → ·Nnotes)PPTX:
npm run deck→deck/output/RxRelay_Hackathon_Pitch.pptx
Demo in 100 seconds
Open RX-1048 (consent already recorded).
Call pharmacy → sandbox coordination action.
Record blocker → prior authorization needed.
Record clinic step → follow-up submitted.
Confirm readiness → pharmacy outcome + consented sandbox SMS.
Watch the close gate turn green only at 4/4.
Try an uncertain / unsafe turn in the PAVO lab — upgrade the pipeline or safe-stop; never invent completion.
Full script (dashboard sandbox): docs/DEMO.md · judge live call: docs/JUDGE_DEMO.md (+18026768127)
📞 Live inbound voice
voice-server.mjs is a deliberately isolated TeXML gateway. It shares cases with the dashboard through data/cases.json.
npm run dev # proof board on :3000
npm run live:inbound # voice :3001 → public tunnel → point claimed numberlive:inbound tries Cloudflare quick tunnel first, then falls back to Serveo (ssh -R … serveo.net) when Cloudflare returns 429/1015. Override with VOICE_TUNNEL=serveo or reuse an existing URL via TUNNEL_PUBLIC_URL=https://….
Then call the claimed number and say:
I consent to a pharmacy status follow-up and text updates.
Inbound voice ≠ outbound messaging. Live SMS/calls stay disabled until ALLOW_LIVE_TELEPHONY=true and LIVE_ALLOWED_RECIPIENTS contains OTP-verified numbers. The live adapter refuses completion without a provider-issued action id.
OTP helpers:
npm run verify -- +1XXXXXXXXXX
npm run confirm -- +1XXXXXXXXXX 123456Details: docs/A1MOBILE_LIVE_SETUP.md
Optional LiveKit + OpenAI Realtime (post-hackathon)
Tonight's demo stays on TeXML. ChatGPT Realtime needs media streaming (WebRTC/WebSocket), not TeXML <Gather> turn-taking. The a1 PAVO gateway (hack.a1mobile.com/gw/v1) exposes chat models only (sol / terra / luna) — /realtime returns 404 — so Realtime needs a direct OPENAI_API_KEY, plus LiveKit Cloud, plus switching the claimed number from webhook → SIP using creds from GET /api/numbers/me.
Twilio is a different carrier and is not on the a1mobile claimed DID without leaving hackathon rails. Photon Spectrum (@photon-ai/voice-ts) is a real product (messaging + voice over Photon's gRPC plane) but needs a Photon VOICE_TOKEN and does not answer +18026768127 faster than TeXML tonight.
Scaffold (fails closed until keys exist; does not remove TeXML):
npm run voice:realtime # checks LIVEKIT_* + OPENAI_API_KEY + A1_SIP_*🔬 PAVO: route the pipeline, not just the model
Grounded in PAVO: Pipeline-Aware Voice Orchestration with Demand-Conditioned Inference Routing.
A better LLM cannot repair a misheard authorization number.
When a turn is uncertain or carries a critical entity, RxRelay upgrades transcription and reasoning together.
Route | Triggered by | Pipeline |
Fast | greetings, simple confirmations | fast ASR → compact reasoning |
Balanced | routine status coordination | reliable ASR → tool-aware reasoning |
Verified | noise, low ASR confidence, names/numbers/dates, prior auth, contradiction | high-accuracy ASR → structured verifier |
Safe stop | clinical advice, emergency cues, Rx changes, controlled inventory, identity data | no autonomous action → human handoff |
Safe stop is checked first. The router is a readable pure function in src/pavo.mjs.
Research: paper · pavo-bench
🛡 Safety contract
RxRelay does not:
give medical advice or interpret symptoms
prescribe, change, refill, or transfer a prescription
determine insurance coverage or eligibility
disclose controlled-medication inventory
contact anyone without explicit, scope-limited consent
Urgent medical cues are a handoff, not an automation opportunity. Voice consent requires both a consent phrase and a scope term (pharmacy / status / coordinate / text / update).
Live mode is a configuration decision, never a code-path accident.
🔌 MCP tools
POST /mcp exposes JSON-RPC tools that share the same consent + proof gate as the UI:
Tool | Purpose |
| Create a consent-gated coordination case |
| Record explicit patient consent |
| Start a non-clinical pharmacy status call |
| Record |
| Issue a single-use pharmacy/clinic/insurer attestation link |
| Export a signed hash-chained proof receipt |
| Return status + deterministic resolution proof |
| List cases held for human review |
No tool can bypass the proof gate.
🥊 How it compares
RxRelay | Typical voice agent demo | Human switchboard | |
Completion claim | Deterministic proof gate | Conversational “done” | Memory / sticky notes |
Uncertain audio | Upgrade ASR and reasoning (PAVO) | Hope the LLM repairs it | Ask the patient to repeat |
Clinical / emergency language | Safe stop → human | Often continues | Escalates unevenly |
Failed provider call | No action evidence recorded | Often narrates success | Unknown |
Outbound contact | OTP allowlist + consent | Frequently unconstrained | Manual |
Public blast radius | Voice-only process | Full app exposed | N/A |
🏆 Built for the a1mobile Voice AI Hackathon 2026
Criterion | Evidence |
Idea & creativity | Moves voice agents from talking → evidence-backed access coordination |
Real-world value | Removes patient-as-switchboard work in prescription access |
Technical execution | Case state machine, PAVO routing, TeXML gateway, counterpart portal, signed receipts, human ops, SSE, MCP (8), proof gate, CI + 27 tests |
Voice UX | Voice-first consent, confirmation on uncertain critical details, explicit safe stops |
Works live | Sandbox E2E today; real inbound TeXML path; live outbound fails closed until provider accepts + returns an id |
🧠 Related work
Research
PAVO Bench — pipeline-aware voice inference routing + paper
Systems by the same author
Groundtruth — refuse “done” without evidence (same philosophy, coding agents)
Lifeline — evidence-gated voice safety patterns
MCP Observatory — tool timeline / replay ideas in the case trail
Also: Verdict · Cohort · AlphaSignal · LaunchDay
📁 Repository map
src/pavo.mjs PAVO-inspired demand-conditioned routing (pure function)
src/inference.mjs Guarded OpenAI-compatible client + local fallback
src/dialogue.mjs Phone turn shaping, ASR repairs, TeXML Say helpers
src/voice-lexicon.mjs Consent / intent paraphrase expansion
src/voice-training/ Mined lexicon + few-shot exemplars for Maya
src/store.mjs Consent-gated case state machine + proof gate
src/persist.mjs Shared local JSON store for dashboard + voice
src/telephony.mjs Sandbox adapter + fail-closed live provider adapter
src/receipt.mjs Signed hash-chained proof receipts
src/counterpart.mjs Magic-link attestation tokens
src/bus.mjs Case event bus for live SSE
server.mjs HTTP API, webhook seam, MCP endpoint, proof board
voice-server.mjs Token-protected TeXML inbound gateway
scripts/ live:inbound · point · verify · confirm
public/ Proof-board dashboard
site/ Marketing site → GitHub Pages
assets/ Social preview + pitch visuals for the README
docs/ Architecture, live setup, DEMO, JUDGE_DEMO
deck/ 13-slide HTML + PPTX (`npm run deck`)
test/ node:test suite (27) — routing, consent, proof honesty🤝 Contributing
See CONTRIBUTING.md and the CODE_OF_CONDUCT.md.
npm run check
npm testSecurity reports: SECURITY.md — especially anything that could fabricate proof or skip consent.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityCmaintenanceEnables multi-agent communication workflows with consensus arbitration, peer messaging, and operator-mediated collaboration through authenticated MCP tools.Last updated1
- Alicense-qualityBmaintenanceProvides MCP tools for lead qualification, enabling evidence gathering from CRM, scoring, and knowledge base with role-based access and deterministic decision gating.Last updatedAGPL 3.0
- AlicenseBqualityBmaintenanceEnables MCP-compatible agents to make safe, consented phone calls using Twilio and Deepgram.Last updated4Apache 2.0
- AlicenseAqualityDmaintenanceEnables HIPAA-aware healthcare workflow automation including patient intake, clinical summaries, compliance checking, and appointment scheduling via MCP tools.Last updated4971Business Source 1.1
Related MCP Connectors
Remote MCP for MCP consent scope receipt, structured receipts, audit logs, and reviewer-ready eviden
Phone, SMS & email for AI agents — one remote MCP endpoint, OAuth login, zero install.
A paid remote MCP for Skybridge, built to return verdicts, receipts, usage logs, and audit-ready JSO
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/vnmoorthy/rxrelay'
If you have feedback or need assistance with the MCP directory API, please join our Discord server