
Household Recall Watch
io.github.MGrinv0.2.0Updated Oct 2, 2026
Household recall checks over public CPSC, openFDA, EMA and EU Safety Gate data. No API key.
Overview
Lets an assistant search public US and EU product, food and medicine recall data and keep a household watchlist of items to check for recalls.
- What it does
- Provides eight tools over public government recall sources: CPSC and openFDA device recalls, openFDA food recalls, openFDA drug and EMA medicine shortage alerts, and EU Safety Gate dangerous-product alerts. A local household watchlist can be added to, listed and removed, and check_my_household checks watched items against the recall sources. Each result is normalised with source, title, hazard, remedy, date, product list, official notice link and a short spoken sentence.
- When to use it
- Useful when someone wants an assistant to answer questions like whether a stroller, food or medicine has been recalled, or to proactively check a personal list of household items against recent recall notices. It is aimed at household safety questions rather than general product research.
- Requirements
- Runs as a local process; Node 20 or newer, or Docker. No API keys or accounts are needed for the recall data. An OpenAI-compatible key or a local Ollama endpoint is optional and only needed for the model-backed agent path; the scripted mode works without one. Internet access is required to reach the government recall sources.
Installation
In SourceWeft
- Open Household Recall Watch in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
Recall Radar — an MCP server and voice front end for "has anything in my house been recalled?"
A self-hosted Model Context Protocol server that lets a voice assistant answer household safety questions from public government recall data:
- US product recalls (CPSC) and home medical-device recalls (FDA),
- US food recalls (FDA),
- US medicine recalls (FDA) and EU medicine shortages (European Medicines Agency),
- EU dangerous-product alerts (EU Safety Gate, formerly RAPEX),
- and a household watchlist the assistant checks proactively: "has anything I own been recalled since the summer?"
Every answer carries a short spoken sentence for the voice reply, plus structured detail with the
source URL and date of every item. No API keys, no accounts, no LLM needed to run it.
Built for the Amazon Developer Hackathon, Alexa+ track. MCP spec 2025-11-25, Streamable HTTP,
stateless, @modelcontextprotocol/sdk 1.30.1.
This is a simulated smart-display experience backed by a real MCP server; it has not been connected to an Alexa+ device. See the judge-run guide, the verification record and the friction log.
Not medical or safety advice. Recall and shortage data can be incomplete or late. Always check the linked notice, and ask a pharmacist, doctor or the manufacturer before acting. Never stop a prescribed medicine on your own.
Run it (one command)
Node 20 or newer. One process serves the MCP server at /mcp, the voice UI at / and the agent at
POST /api/ask:
Judge path.
- No key, scripted mode.
npm start, open http://127.0.0.1:3000/. The badge reads Scripted mode, no LLM: a fixed phrase-to-tool mapping stands in for the model, but the MCP calls and the recall data are real and live. Try the suggestion chips, or drive it from the URL:http://127.0.0.1:3000/?q=Watch%20my%20crib%20mattress&q=Has%20anything%20in%20my%20house%20been%20recalled%3F - With a model. Set
OPENAI_API_KEYoutside the repository and runnpm start. The badge identifies the selected model (gpt-6-lunaby default). This path was run live on 2026-10-02 with that model; other models were not exercised (EVIDENCE.md).
Or Docker:
Endpoints: POST /mcp (MCP Streamable HTTP, stateless: no session id, no GET stream), GET /healthz,
GET / (the UI), POST /api/ask ({"q": "...", "history": [...]}), GET /api/config, GET /api/watchlist.
A stdio entry is also included: npm run start:stdio.
The stdio entry is listed in the MCP Registry as
io.github.MGrin/household-recall-watch (server.json). Its package is an MCPB bundle
attached to the GitHub release; npm run pack:mcpb rebuilds it and prints the SHA-256 that
server.json must carry. The bundle keeps its watchlist at ~/.recall-radar/watchlist.json.
Publishing is .github/workflows/publish-mcp.yml: on a v* tag (or gh workflow run publish-mcp.yml --ref vX.Y.Z) it checks the release bundle against server.json, then publishes with GitHub OIDC.
Attach the bundle to the GitHub release before the workflow runs.
If your machine reaches the internet only through an HTTP proxy, Node's built-in fetch ignores
HTTPS_PROXY unless you set NODE_USE_ENV_PROXY=1 (Node 24+). That applies to the OpenAI calls too.
The voice front end (a simulated smart display)
The track allows "a simulated Alexa+ experience in a web app"; this is ours, named Recall Radar and using no third-party marks.
- Push to talk: hold the mic button (or the space bar) and speak; it uses the browser's Web Speech
API (
SpeechRecognition). Where that is missing the mic is disabled and the text box does the same job. Microphone behavior still needs a real-device check. - Spoken reply through
speechSynthesis, with a mute toggle; a light bar along the bottom edge shows listening, thinking and speaking. Speaker output still needs a real-device check. - Tool trace: a chip for every MCP tool the agent called, with its argument and latency, so a viewer can see the answer came from the MCP server.
- Recall cards: source, date, title, hazard, remedy, the watchlist item it matched, and a link to the official notice.
- Household watchlist panel (add with the + box or by voice, remove with ×; both go through the agent), and a transcript.
?q=...asks on load; repeat it (?q=a&q=b) for a scripted walkthrough, and addmute=1for silent capture.
The agent (src/agent/)
agent.ts is a real MCP client (SDK Client + StreamableHTTPClientTransport): per question it
connects to /mcp, lists the tools, maps them to the model's function format and runs the tool-call
loop, capped at 6 model steps. Tool results go back to the model as the tool's structuredContent.
A ModelAdapter (types.ts) is one method: messages + tools in, text or tool calls out.
The system prompt (prompt.ts) keeps answers voice-first (two or three sentences: hazard, official
remedy, what to do now), grounds every claim in a tool result, and forbids medical advice beyond the
official remedy text.
Try it
MCP Inspector (no LLM key needed):
In the Inspector UI choose transport Streamable HTTP, URL http://127.0.0.1:3000/mcp, Connect,
then Tools → List Tools and call any tool.
From the terminal, with the bundled SDK client:
Tools
Eight tools. search_eu_product_recalls was added in v0.2.0, after the demo video was recorded; the
video shows and says seven.
Each tool declares a zod input schema and an outputSchema; results come back as structuredContent
(validated by the SDK) and as text. Each recall is normalised to:
If one upstream is down, the others still answer and the result lists a warning; if every source for
a question is down, the tool returns a clean MCP tool error (isError: true). Every upstream request
has a 10-second timeout (20 seconds for Safety Gate). The EMA file is cached for an hour in memory,
because EMA rate-limits repeated downloads. Safety Gate publishes one weekly report every Friday, each
about 200-300 KB and 3-6 seconds to serve (2026-10-02): a search reads at most 12 reports, four at a
time, caches the index for an hour and each published report for the life of the process. A cold
four-week search took about 5 seconds; a repeat answers from the cache. When the window holds more
than 12 reports, since in the answer is the oldest report actually read.
Data sources and terms
openFDA has no per-recall web page, so an FDA item's url is the openFDA API query that returns exactly
that recall (search=recall_number:"…").
The Safety Gate attribution, verbatim: "Alerts from the Rapid Alert System for dangerous non-food products, published free of charge on the Safety Gate website (https://ec.europa.eu/safety-gate-alerts) © European Union, 2005 – 2026". The Commission also notes that brands in the alerts may have been used by the economic operators without the owner's permission.
Pre-existing code adapted
src/sources/ema.ts adapts our own earlier code from the ema-medicines-watch Apify Actor (same
author): the EMA dd/mm/yyyy date parser, the {meta, data[]} shape check and the truncated-file guard.
src/sources/safetygate.ts adapts the eu-recall-watchlist Apify Actor (same author): the Safety Gate
XML parser settings, CDATA handling, the run-together measures field and the verbatim attribution.
Everything else was written for this entry.
Development
test/agent.test.ts runs the agent loop with the scripted adapter against the real MCP server over HTTP
(upstreams mocked to fixtures), plus the /api/* routes and the static UI. test/openai.test.ts runs the
OpenAI adapter against a mocked Chat Completions endpoint, alone and inside a multi-step agent loop.
The end-to-end test starts the HTTP server, connects with the SDK Client over
StreamableHTTPClientTransport, checks that protocol 2025-11-25 is negotiated, lists the tools and
calls every one, with upstream fetch routed to fixtures.
Licence
MIT, © 2026 Nikita Grishin Limited. See LICENSE. Friction log: FRICTION.md.
Source: README.md at commit fbaff1d
Tools
0Version history
1- v0.2.0LatestOct 2, 2026

