Inspiration
When my mother died, I learned how much of my sister's life lived in one person's memory: the people she trusts, the routines that keep her steady, the warning signs only family knew to watch for. My sister wants to make her own decisions, and she should. But the world isn't built for that.
People with cognitive disabilities experience violent crime at the highest rate of any disability group the Bureau of Justice Statistics measures: 83.3 per 1,000 people in 2017–2019, against 12.3 per 1,000 for people without disabilities. Much of the harm comes from someone the person knows: an online "friend" who needs bus money, a neighbor who keeps borrowing a debit card, a stranger at the door who says he's from the power company.
Most safety technology answers this with surveillance: someone else watches, someone else decides. I wanted to test the opposite idea. Could a voice assistant help a person think it through for themselves, in plain adult language, and bring in someone they trust only when they say yes?
What it does
SafeGuide is a voice-first companion built as a real MCP server, with a simulated Alexa+ client that talks to it over Streamable HTTP.
A person says or types what's happening ("Alex needs $200 for a bus ticket to come see me"), pastes a suspicious text, or uploads a screenshot. SafeGuide returns a clear card: green, yellow, or red; what it noticed; one to three things to do; and an offer to reach a trusted person. Everything is spoken aloud as well as shown.
It remembers people across conversations. "This is the second time Alex asked you for money. Alex only talks to you online." Patterns that look harmless one message at a time become visible over a week.
It never gives a false all-clear. Green means only that no scam or pressure sign was spotted, and it always says what to do if something feels wrong.
Danger comes first. Weapons, someone trying to get in, being followed, fire or gas, a health emergency, crisis or self-harm, and someone hurting them are checked before anything else. Answers are short and action-first: "Stay inside and lock the door if you can. Call 911 now." Crisis responses include 988.
Nothing happens without consent. To contact Maria, SafeGuide shows the exact message and waits for a human Yes or No through MCP elicitation. No timeout ever decides for the person, and the AI can't approve on their behalf.
It checks messages the person can't easily read aloud. Screenshot upload (read by Claude vision) and a paste box work on any phone or computer. SafeGuide is also built to appear in Android’s Share menu once installed (implemented and unit-tested; not yet verified on a physical Android device).
It lets people practice. Short role-plays ("someone at the door says they need to come in") with kind, adult feedback.
Ten MCP tools: check_situation, get_safety_checklist, remember_person, get_person_history, notify_trusted_contact, get_my_people, practice_scenario, raise_concern, plus two app-only tools for card buttons (acknowledge_safety, respond_contact_confirmation).
Five MCP App interfaces (risk, checklist, person, confirmation, practice) are served by the server as ui:// resources, so any MCP Apps host renders SafeGuide's own accessible cards. That's the same extension Alexa+ supports for visual responses on devices with screens.
How I built it
How I worked: I'm a solo builder. I developed SafeGuide in Replit, using Replit Agent to write and test code from detailed specs, and used Claude to plan the architecture, write those specs, review the code, and stress-test the safety rules. Every safety rule, consent decision, and test threshold was mine to set and verify.
MCP: official MCP SDK version 2 packages (
server,client,node,express), negotiating protocol 2025-11-25 over Streamable HTTP, verified by automated tests.MCP Apps:
@modelcontextprotocol/ext-appson spec 2026-01-26. The client is a compliant host using the officialAppBridge, rendering each card in an opaque-origin sandboxed iframe with a restrictive content security policy. Card buttons call tools back through the host, never directly.Elicitation for consent:
notify_trusted_contactsendselicitation/createwith the exact message. For hosts without elicitation, a one-useconfirmation_idbound to the session and the exact content is required for the second call.Agent Skill:
skills/safeguide/SKILL.mdin the open Agent Skills format teaches any agent how to use the server: when to check, how to speak, when to confirm, what never to do. Both the client's agent loop and the server'ssafety_companionprompt load the same skill text, and a test asserts they match.Safety engine: deterministic, normalized rules (case, punctuation, repeated letters, misspellings, word variants) for immediate danger, health emergencies, crisis, abuse, scams, and pressure, plus memory-based escalation from stored history.
AI: Claude Sonnet reads screenshots and can optionally reword a custom result. A bounded Claude Haiku reviewer acts as a raise-only safety net. Neither can lower a rule-based red.
Dignity Filter: a standalone, dependency-free library with its own tests and MIT license. It removes pet names and child-directed praise, reframes "you can't" as "it's safer to," screens sentence length and readability, and falls back to reviewed text when a sentence fails.
Stack: TypeScript, Express 5, React, PostgreSQL, pnpm monorepo. Voice input is recorded in the browser and transcribed server-side; replies are read aloud with adjustable pace.
Demo safety for judges: every visitor gets a private, persistent copy of the fictional data, a confirmed "Reset demo," two fictional personas (Jordan and Keisha), and a "Try your own" panel. Per-IP rate limits, a daily AI cap, and a kill switch keep rule checks running if AI is paused.
Challenges I ran into
A miss that sounded like an all-clear. Late in the build I typed "i see someone weird with a knife" and SafeGuide answered that it didn't find a warning sign. Patching that phrase would have fixed one sentence and left a hundred like it. Instead I rebuilt the safety layer around one principle: a miss must never sound like an all-clear.
Green wording changed so it never claims safety.
Danger categories now run first, on normalized text.
Feeling words ("weird," "scared," "following me") always trigger at least a safety check.
A 180-message evaluation set, written in the voice of real users (short, misspelled, no punctuation), enforces hard rules: 100% of urgent messages must reach red, and no harmless message ("im cutting veggies with a knife") may.
Speed versus AI. Alexa+'s MCP Toolkit requires responses within 500 milliseconds, and an LLM call inside a tool can't reliably meet that. So I moved AI out of the tools entirely. Tools return reviewed, rule-based results immediately: 4.32 ms median, 93.59 ms slowest over real Streamable HTTP with PostgreSQL in local benchmarks. AI then works as a safety net beside the tools: after every result, the client checks whether the person described danger the rules missed, and if so calls raise_concern, which can only raise a level.
Consent can't be a prompt. Telling a model "don't contact anyone without permission" works most of the time. For this audience, most of the time isn't enough. I made consent part of the protocol: exact-message elicitation, a human Yes or No, one-use confirmation IDs tied to the session and wording, and no path where the model can confirm for the person.
A public demo that judges can't break. With a public demo token, every judge would share one fictional Jordan, and the "second time Alex asked" moment would change with every visit. Per-visitor private copies, a confirmed reset, and rate limits keep the demo identical for every judge.
Honest limits. In live tests, the Haiku safety reviewer timed out more often than I'd like. I designed around that rather than hiding it: rules and a local audit run on every turn, urgent responses never wait for AI, and the README says plainly that the AI reviewer is a backstop, not a guarantee.
Accomplishments that I'm proud of
- 110 of 110 urgent test messages reach red, with no harmless message flagged red and only 4% of harmless messages flagged yellow, across 180 messages written the way the target users type.
- 9,792 generated robustness checks (5,481 distinct texts across punctuation, apostrophes, repeated letters, and word order) run with AI disabled.
- Real MCP end to end: protocol 2025-11-25, Streamable HTTP, MCP Apps with the official
AppBridge, elicitation, resources, a prompt, and an Agent Skill the app actually runs on. A developer view shows the live JSON-RPC traffic, so judges can see it isn't a mock. - Memory that protects people. Cross-session person history turns "Alex needs bus money" from a one-off into a recognizable pattern.
- Dignity as engineering, not tone. The Dignity Filter is a tested, reusable library, published as open source so any assistant serving people with disabilities can use it.
- Fast without cutting corners on safety: every text tool well under 500 milliseconds, with urgent guidance never waiting on AI.
- 112 automated tests passing across the server, client, and Dignity Filter.
What I learned
-AI makes solo building possible. It doesn’t make it easy. AI development let one person build what would once have taken a team. But deciding what “safe” means for this audience, catching the knife miss, and checking every claim against the code still took real time, energy, and human judgment.
- Rules for safety, AI for understanding. Deterministic rules give the guarantees: red can't be argued down, and every answer is reproducible and testable. AI adds what rules can't: reading a screenshot, noticing danger phrased in a way no rule expected. The key design choice is the direction: AI may only raise concern.
- The most dangerous output is a confident "you're fine." Wording matters as much as detection. Changing what green says reduced risk as much as adding new rules.
- Write test cases in your users' voice. My early tests were tidy sentences. Real messages look like "theres a man with a knife outside." The evaluation set got better when it stopped sounding like me.
- Consent belongs in the protocol. MCP elicitation turned "ask before contacting someone" from a hope into a guarantee.
- Dignity is a feature users notice. "It's safer to wait" and "you can't do that" carry the same safety advice. Only one keeps people coming back.
What's next for SafeGuide
- Real Alexa+. The server already follows the Alexa+ MCP Toolkit's requirements: Streamable HTTP, spec 2025-11-25, MCP Apps for screens, and sub-500 ms responses. When the toolkit opens beyond select partners, the next steps are OAuth 2.1 with PKCE, add-on listing assets, and testing in Amazon's Alexa+ web simulator.
- Co-design with adults with intellectual disabilities and their families, starting with a small pilot, before any claim about real-world outcomes.
- Real trusted-contact delivery (SMS and push) with the same exact-message consent.
- More languages and reading levels, chosen by the person.
- Part of a family of tools. Add more scenarios and options for individuals to upload their specific needs/use case. SafeGuide is one of three I'm building for the same families, alongside SibHaven (caregiver source of truth integrated with Ring) and Home Coach (daily routines on Fire TV). Each stands alone; together they cover the moment, the night, and the routine.
Try it either select and option or speak/type it in: "Alex asked me for $200 for a bus ticket," then "i see someone weird with a knife," then "My coworker invited me to lunch." Open Developer traffic to watch the real MCP calls.
Built With
- claude
- express.js
- mcp
- node.js
- openai
- pnpm
- postgresql
- react
- replit
- typescript
Log in or sign up for Devpost to join the conversation.