Household Recall Watch について
Household Recall Watchは、米国とEUの公開データで家庭用品のリコールや医薬品不足を調べる、セルフホスト可能なMCPサーバーと音声対応ウェブインターフェースです。個別検索とローカルの監視リストを組み合わせ、公式情報のリンクと日付を返します。LLMを使わないスクリプトモードでも動作します。
主な機能
- 01米国の商品、食品、医薬品リコールを検索
- 02EUの商品警告と医薬品不足を検索
- 03家庭用品の監視リストを管理
- 04監視対象の新たなリコールを確認
- 05出典リンク、日付、危険性、対処法を表示
- 06LLM不要のスクリプトモード付き音声UI
活用シーン
- 01家庭用品のリコール有無を確認する
- 02食品リコールや医薬品警告を調べる
- 03家庭用品を登録して定期的に確認する
- 04リコール情報を確認し公式通知を開く
MCP 対応
リコール検索と家庭用品の監視リスト管理を行う8つのツールを提供します。音声エージェントはStreamable HTTPで接続でき、stdioのエントリーポイントも含まれています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Recall Radar —「自宅にリコール対象品はある?」に答える MCP サーバーと音声フロントエンド
音声アシスタントが政府の公開リコールデータをもとに家庭の安全に関する質問に答えられる、セルフホスト可能なModel Context Protocolサーバーです。
- 米国の製品リコール(CPSC)と家庭用医療機器のリコール(FDA)、
- 米国の食品リコール(FDA)、
- 米国の医薬品リコール(FDA)とEUの医薬品不足(European Medicines Agency)、
- EUの危険製品に関する警告(EU Safety Gate、旧RAPEX)、
- アシスタントが事前に確認する家庭用品ウォッチリスト:「夏以降、私の持ち物にリコール対象品はありましたか?」
回答には、音声での返答に使う短いspoken文と、各項目の情報源URLと日付を含む構造化された詳細情報が含まれます。実行にAPIキーもアカウントもLLMも必要ありません。
Amazon Developer HackathonのAlexa+部門向けに開発されました。MCP仕様 2025-11-25、Streamable HTTP、ステートレス、@modelcontextprotocol/sdk 1.30.1。
これは実際のMCPサーバーを利用したシミュレーションのスマートディスプレイ体験です。Alexa+デバイスには接続されていません。審査員向け実行ガイド、検証記録、問題点の記録をご覧ください。
医療または安全に関する助言ではありません。 リコールや供給不足のデータは不完全、または古い場合があります。必ずリンク先の通知を確認し、行動を起こす前に薬剤師、医師、またはメーカーに相談してください。処方薬の服用を自己判断で中止しないでください。
実行する(1 つのコマンド)
Node 20 以降が必要です。1 つのプロセスで、MCP サーバーを /mcp、音声 UI を /、エージェントを
POST /api/ask で提供します:
npm ci && npm start
# recall-radar MCP server: http://127.0.0.1:3000/mcp (health: /healthz, ...)
# Recall Radar voice UI: http://127.0.0.1:3000/ (agent: POST /api/ask, model: Scripted mode, no LLM)
評価方法。
- キーなし、スクリプトモード。
npm startを実行し、http://127.0.0.1:3000/ を開きます。バッジには スクリプトモード、 LLM なし と表示されます。固定のフレーズとツールの対応付けがモデルの代わりになりますが、MCP の呼び出しとリコールデータは実際のもので、最新の状態です。候補チップを試すか、URL から操作してください:http://127.0.0.1:3000/?q=Watch%20my%20crib%20mattress&q=Has%20anything%20in%20my%20house%20been%20recalled%3F - モデルを使用する場合。 リポジトリの外部で
OPENAI_API_KEYを設定し、npm startを実行します。バッジには選択したモデル(デフォルトはgpt-6-luna)が表示されます。この方法は、2026-10-02 にそのモデルで実際に実行しました。他のモデルは試していません(EVIDENCE.md)。
Docker を使用する場合:
docker build -t recall-radar-mcp . && docker run --rm -p 3000:3000 recall-radar-mcp
docker run --rm -p 3000:3000 -e OPENAI_API_KEY recall-radar-mcp # with a model
| env | default | meaning |
|---|---|---|
PORT | 3000 | HTTP ポート |
HOST | 127.0.0.1(Docker では 0.0.0.0) | バインドアドレス |
WATCHLIST_PATH | ./data/watchlist.json | 家庭のウォッチリストの保存先。CPSC から最後に正常に取得した応答は、同じ場所に cpsc-cache.json として保存されます |
ALLOWED_ORIGINS | (なし) | localhost 以外で許可する追加のブラウザー Origin(カンマ区切り、すべてを許可する場合は *) |
MODEL_PROVIDER | OPENAI_API_KEY が設定されている場合は openai、それ以外は scripted | openai、ollama、または scripted |
OPENAI_API_KEY | (なし) | OpenAI キー。ログへの記録やブラウザーへの送信は行われません |
OPENAI_MODEL | gpt-6-luna | 関数呼び出しに対応する任意の Chat Completions モデル |
OPENAI_REASONING_EFFORT | none | reasoning_effort として送信されます。GPT-6 モデルは none を指定しないと、Chat Completions で関数ツールを拒否します。このフィールドを拒否するモデルでは omit を設定してください |
OPENAI_BASE_URL | https://api.openai.com/v1 | OpenAI 互換ゲートウェイ用 |
OLLAMA_URL / OLLAMA_MODEL | http://127.0.0.1:11434 / llama3.1 | Ollama の OpenAI 互換エンドポイント(/v1/chat/completions) |
MCP_URL | このプロセス自身の /mcp | エージェントの接続先を、別の Recall Radar MCP サーバーに設定します |
エンドポイント:POST /mcp(MCP Streamable HTTP、ステートレス:セッション ID なし、GET ストリームなし)、GET /healthz、
GET /(UI)、POST /api/ask({"q": "...", "history": [...]})、GET /api/config、GET /api/watchlist。
stdio エントリも含まれています:npm run start:stdio。
stdio エントリは、MCP Registry に
io.github.MGrin/household-recall-watch(server.json)として登録されています。パッケージは GitHub リリースに添付される MCPB バンドルです。npm run pack:mcpb で再ビルドすると、server.json に記載する必要がある SHA-256 が出力されます。バンドルのウォッチリストは ~/.recall-radar/watchlist.json に保存されます。
公開処理は .github/workflows/publish-mcp.yml です。v* タグ(または gh workflow run publish-mcp.yml --ref vX.Y.Z)で実行すると、リリースバンドルと server.json の整合性を確認し、GitHub OIDC を使用して公開します。ワークフローの実行前に、バンドルを GitHub リリースに添付してください。
マシンが HTTP プロキシ経由でしかインターネットに接続できない場合、Node 組み込みの fetch は、NODE_USE_ENV_PROXY=1(Node 24 以降)を設定しない限り HTTPS_PROXY を無視します。これは OpenAI の呼び出しにも適用されます。
音声フロントエンド(スマートディスプレイのシミュレーション)
このトラックでは「ウェブアプリで Alexa+ の体験をシミュレーション」できるようになっています。これは Recall Radar という名称で、サードパーティの商標は使用していません。
- プッシュ・トゥ・トーク:マイクボタン(またはスペースバー)を押したまま話します。ブラウザーの Web Speech API(
SpeechRecognition)を使用します。この API がない場合はマイクが無効になり、テキストボックスで同じ操作ができます。マイクの動作は、実機での確認が必要です。 - 音声での応答:
speechSynthesisを使い、ミュート切り替え機能もあります。下端に沿ったライトバーに、聞き取り中、思考中、発話中の状態が表示されます。スピーカー出力は、実機での確認が必要です。 - ツールの実行記録:エージェントが呼び出した各 MCP ツールについて、引数と所要時間をチップで表示します。回答が MCP サーバーから得られたことを確認できます。
- リコールカード:情報源、日付、タイトル、危険性、対処法、該当したウォッチリスト項目、公式通知へのリンクを表示します。
- 家庭内ウォッチリストパネル(+ボックスまたは音声で追加、×で削除。どちらもエージェント経由で処理)と、文字起こしを表示します。
- 読み込み時に質問するには
?q=...を指定します。スクリプト付きのデモには?q=a&q=bのように繰り返し指定し、無音でキャプチャするにはmute=1を追加します。
エージェント(src/agent/)
agent.ts は実際の MCP クライアントです(SDK の Client と StreamableHTTPClientTransport を使用)。質問ごとに /mcp に接続してツールを一覧表示し、モデルの関数形式に変換して、最大 6 モデルステップのツール呼び出しループを実行します。ツールの結果は、そのツールの structuredContent としてモデルに返されます。
ModelAdapter(types.ts)は 1 つのメソッドで、メッセージとツールを受け取り、テキストまたはツール呼び出しを返します。
| アダプター | 状態 |
|---|---|
openai(openai.ts) | SDK を使わず、通常の fetch でツール対応の OpenAI Chat Completions を呼び出します。3 ステップのツールループを含め、記録された形式のレスポンスを使ったユニットテストを実施済みです。2026-10-02 に gpt-6-luna でライブ API を使って実行しました(EVIDENCE.md)。 |
ollama | Ollama の OpenAI 互換エンドポイントを指定した同じクラスです。未テスト:ビルドマシンに Ollama がインストールされていませんでした。 |
scripted(scripted.ts) | 決定論的です。いくつかの言い回しを 1 回のツール呼び出しに対応付け、ツール自身の spoken 文(最初の項目のみ)を応答として返します。テストと API キー不要のデモで使用します。 |
システムプロンプト(prompt.ts)では、音声優先の回答(危険性、公式の対処法、今すべきことを 2~3 文で説明)、すべての主張をツールの結果に基づかせること、公式の対処法の文面を超えた医療アドバイスを禁止することを定めています。
試してみる
MCP Inspector(LLM キー不要):
npx @modelcontextprotocol/inspector
Inspector の UI でトランスポートに Streamable HTTP を選び、URL に http://127.0.0.1:3000/mcp を入力して[Connect]をクリックします。続いて Tools → List Tools を選び、任意のツールを呼び出します。
ターミナルから、同梱の SDK クライアントを使う場合:
npm run call # list tools
npm run call -- search_product_recalls '{"query":"stroller","limit":3}'
npm run call -- watchlist_add '{"name":"crib mattress","kind":"product"}'
npm run call -- check_my_household '{}'
ツール
8 つのツールがあります。search_eu_product_recalls は v0.2.0 で追加されたため、デモ動画の収録時にはまだなく、動画では 7 つのツールが紹介されています。
| tool | 回答する質問 | 情報源 |
|---|---|---|
search_product_recalls | 「ベビーカー/スペースヒーター/ベビーベッドはリコールされていますか?」 | CPSC、openFDA device |
search_food_recalls | 「ピーナッツバターはリコールされていますか?」「リステリア菌によるリコールはありますか?」 | openFDA food |
search_medicine_alerts | 「インスリンはリコールまたは不足していますか?」(region: us、eu、all) | openFDA drug、EMA shortages |
watchlist_add | 「Graco のベビーカーを監視してください。」(kind: product、food、medicine、any) | ローカルファイル |
watchlist_list | 「何を監視していますか?」 | ローカルファイル |
watchlist_remove | 「ベビーカーの監視を停止してください。」 | ローカルファイル |
search_eu_product_recalls (v0.2.0) | 「USB 充電器は EU でリコールされましたか?」製品名、ブランド、モデル、またはバーコードで検索します(デフォルト:過去 28 日間、最新の週次レポートを最大 12 件) | EU Safety Gate |
check_my_household | 「家にあるものでリコールされたものはありますか?」(デフォルト:過去 180 日間) | CPSC、openFDA、EMA。品目の種類別(Safety Gate を除く) |
各ツールは zod 入力スキーマと outputSchema を宣言します。結果は structuredContent(SDK による検証済み)とテキストで返されます。各リコールは次の形式に正規化されます。
{ source, id, title, hazard, remedy, date /* YYYY-MM-DD */, products[], url, summary /* one spoken sentence */ }
上流サービスのいずれかが停止しても、ほかのサービスは引き続き回答し、結果に警告が表示されます。質問に関するすべての情報源が停止している場合、ツールは適切な MCP ツールエラー(isError: true)を返します。
CPSC の API では、同じ URL に対して何日も、一貫して一部の URL は応答し、ほかは 503 エラーを返すことがありました(2026-10-02~10-04 に確認)。そのため、CPSC の読み取りでは、まず対象期間の URL を試し、次に商品フィルターを外した同じ期間の URL を試します。それでも失敗した場合は、最大 3 件のより古い開始日(その月の 1 日、前月の 1 日、障害発生中に応答したいくつかの日付)を試し、ここで対象期間内の行に絞り込みます。20 秒以内に最大 6 件のリクエストを行います。より古い URL から回答が得られた場合、結果の notes にその URL を示します。正常な CPSC の応答はすべて、ウォッチリストの隣にあるファイル(cpsc-cache.json。最新 8 件の URL と各取得時刻)にも保存されます。すべてのライブリクエストが失敗した場合は、保存済みデータのうち、対象期間内に該当する最新のコピーの行を返します。各要約の末尾には「CPSC データの保存済みコピー(取得日:)から。CPSC にライブ接続できませんでした」と記載され、警告には取得時刻が示されます。保存済みコピーがない場合は、CPSC を利用不可として報告します。ほかの情報を捏造することはありません。
すべての上流リクエストには 10 秒のタイムアウトが設定されています(Safety Gate は 20 秒)。EMA は繰り返しのダウンロードをレート制限するため、ファイルはメモリ内に 1 時間キャッシュされます。Safety Gate は毎週金曜日に週次レポートを 1 件公開します。各レポートは約 200~300 KB で、配信には 3~6 秒かかります(2026-10-02)。検索では最大 12 件のレポートを一度に 4 件ずつ読み込み、インデックスは 1 時間、公開済みの各レポートはプロセス終了までキャッシュされます。キャッシュのない状態での 4 週間分の検索には約 5 秒かかりました。再検索はキャッシュから回答します。対象期間に 12 件を超えるレポートがある場合、回答の since は実際に読み込んだ最も古いレポートを示します。
データソースと利用条件
| ソース | エンドポイント | 利用条件 |
|---|---|---|
| 米国消費者製品安全委員会 | saferproducts.gov/RestWebServices/Recall | 米国政府の著作物、パブリックドメイン |
| openFDA の執行措置レポート(食品、医薬品、医療機器) | api.fda.gov/{food,drug,device}/enforcement.json | open.fda.gov/license に記載のとおり、パブリックドメイン/CC0。openFDA 独自の免責事項:医療に関する判断には依拠しないでください。キーなしの利用にはレート制限があります(利用規約)。 |
| 欧州医薬品庁、医薬品不足カタログ | ema.europa.eu/en/documents/report/shortages-output-json-report_en.json | EMA を出典として明記すれば再利用できます(法的通知)。EMA の各項目には EMA の URL が含まれます |
| 欧州委員会、EU Safety Gate 週次レポート | ec.europa.eu/safety-gate-alerts/api/download/weeklyReport/{list,detail}/xml/… | アラートの意味を歪めず、欧州委員会が指定する正確な文言で出典を明記すれば再利用が許可されます(免責事項、「Reuse of alerts」、現行版 2026-06-11)。各回答には、この文言が attribution と本文に含まれます。各項目は公式アラートにリンクします |
openFDA にはリコールごとのウェブページがないため、FDA 項目の url には、そのリコールだけを返す openFDA API クエリ(search=recall_number:"…")が設定されています。
Safety Gate の帰属表示(原文どおり):「"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"」。欧州委員会は、アラートに記載されたブランドが、所有者の許可なく経済事業者によって使用されている可能性があることも明記しています。
既存コードの適用
src/sources/ema.ts は、同じ作者による ema-medicines-watch Apify Actor の独自の以前のコードを適用しています。EMA の dd/mm/yyyy 日付パーサー、{meta, data[]} 形式のチェック、切り詰められたファイルを検出するガードが含まれます。
src/sources/safetygate.ts は、同じ作者による eu-recall-watchlist Apify Actor のコードを適用しています。Safety Gate XML パーサーの設定、CDATA の処理、連結された measures フィールド、原文どおりの帰属表示が含まれます。
それ以外はすべて、このエントリーのために作成されました。
開発
npm run build # tsc -> dist/
npm test # vitest, against recorded fixtures in test/fixtures (no network)
LIVE=1 npm test # also runs test/live.test.ts against the real APIs
test/agent.test.ts は、スクリプト化されたアダプターを使用し、HTTP 経由で実際の MCP サーバーに対してエージェントループを実行します(上流サービスはフィクスチャにモック)。さらに、/api/* ルートと静的 UI もテストします。test/openai.test.ts は、モックされた Chat Completions エンドポイントに対して OpenAI アダプターを単独で実行するほか、複数ステップのエージェントループ内でも実行します。
エンドツーエンドテストでは、HTTP サーバーを起動し、SDK の Client を使用して
StreamableHTTPClientTransport 経由で接続します。プロトコル 2025-11-25 がネゴシエートされることを確認し、ツールの一覧を取得してすべてのツールを呼び出します。上流の fetch はフィクスチャにルーティングされます。
ライセンス
MIT、© 2026 Nikita Grishin Limited。LICENSE を参照してください。摩擦ログ:FRICTION.md。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。