openfda-mcp-server について
openfda-mcp-server は、医薬品、食品、医療機器、リコールに関する openFDA の公開データを MCP クライアントに提供します。フィールド集計や、ステージングした結果への読み取り専用 SQL にも対応し、STDIO と Streamable HTTP を利用できます。
主な機能
- 01有害事象、リコール、供給不足の検索
- 02医薬品ラベル、承認、NDC の照会
- 03医療機器承認とたばこ報告の検索
- 04フィールド値の集計とスキーマ確認
- 05結果のステージングと読み取り専用 SQL
活用シーン
- 01医薬品のラベル、有害事象、リコールの確認
- 02医薬品の供給不足や FDA 承認の調査
- 03食品・機器・医薬品の有害事象の検索
- 04ステージング済み検索結果への SQL 実行
MCP 対応
検索、照会、集計、ステージング結果の分析を行う 15 個の MCP ツールで、openFDA データに接続します。STDIO と Streamable HTTP に対応します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://openfda.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-openfda https://openfda.caseyjhand.com/mcp{"mcpServers":{"cyanheads-openfda":{"type":"http","url":"https://openfda.caseyjhand.com/mcp"}}}Cursor で開く{"servers":{"cyanheads-openfda":{"type":"http","url":"https://openfda.caseyjhand.com/mcp"}}}VS Code で開く{"mcpServers":{"cyanheads-openfda":{"type":"http","url":"https://openfda.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-openfda":{"serverUrl":"https://openfda.caseyjhand.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
14| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| skip | number | いいえ | ページネーションでスキップするレコード数(デフォルトは 0)。openFDA のページネーション上限は 25000 件です。それを超える値を指定すると pagination_limit_reached エラーが返されます。 |
| sort | string | いいえ | 並べ替え式です。フィールドパスの後に :asc または :desc を任意で付けます(大文字・小文字は問いません。:ascending と :descending も使用でき、方向はすべて asc または desc として送信されます)。複数のフィールドはカンマで区切ります。フィールドパスに使用できるのは英字、数字、アンダースコア、ピリオドのみです。それ以外の文字や方向はリクエスト前に拒否されます。並べ替え可能な日付フィールドはカテゴリごとに異なります:drug → receivedate:desc(または receiptdate)、food → date_created:desc(または date_started)、device → date_received:desc(または date_of_event)。別カテゴリのフィールド(例:food または device で receivedate)を指定するとクエリエラーになります。このカテゴリに対応するフィールドを使用してください。 |
| limit | number | いいえ | 返されるレコードの最大数(1~1000、デフォルトは 10)。シリアライズされたレコードのサイズは openFDA のエンドポイント間で最大 3 桁異なるため、ページには 24000 バイトのシリアライズ予算も適用されます。予算を超えるページでは、要求数より少ないレコードが返され、切り捨てられた件数が page_omitted に報告されます。レコードが一致した場合、サイズにかかわらず少なくとも 1 件が返されます。page_bytes はそのサイズを報告し、page_largest_fields は最大のフィールドを示します。これらのフィールドは投影によって除外できます。医薬品の報告は群を抜いて大きく、医薬品/事象の報告は平均で数十キロバイトですが、食品/事象の報告は数百バイトです。 |
| stage | boolean | いいえ | 一致した結果セットを DataCanvas にステージングして SQL 分析を行います。ステージングされた列の一覧には openfda_dataframe_describe を、SQL の実行には openfda_dataframe_query を使用します。デフォルトは false で、1 回の上流リクエストにつき 1 ページを返します。true の場合は、サイズ上限に達するまでレコードもキャンバステーブルに取り込みます(取り込まれた件数は staged_rows で報告)。ステージングは上限付きの一部データに対するレコード単位の SQL に適しています。一致した全件の分布を集計するには、openfda_count_values を使ってサーバー側で 1 回のリクエストで集計してください。CANVAS_PROVIDER_TYPE=duckdb が必要です。 |
| fields | array | いいえ | 各返却レコードに保持するドット区切りのレコードパス。例:["receivedate", "patient.drug.medicinalproduct"]。返却レコード内の任意のキーのパスを指定でき、検索可能なフィールドは openfda_describe_fields で確認できます。インラインのバイト予算を測定する前に、各レコードは指定パスと識別キー(safetyreportid、report_number、mdr_report_key)に投影されます。これは両方のレスポンス形式で同じです。配列を通るパスは各要素に適用されます。レコードが大きい場合に使用してください。page_bytes が予算を超えると、サイズ超過レコードの最大フィールドが示されます。返却レコードに存在しないパスは通知に記載されます。省略するとレコード全体が返されます。パスに使用できるのは英字、数字、アンダースコア、ドットのみです。それ以外はリクエスト前に拒否されます。stage=true の場合、投影されるのはインラインページのみで、ステージングテーブルの列はそのまま保持されます。 |
| search | string | いいえ | openFDA の検索クエリ。例:patient.drug.medicinalproduct:"aspirin"、patient.reaction.reactionmeddrapt:"nausea" AND serious:"1"。省略すると最新のレコードを参照します。二重引用符、丸括弧、範囲指定の角括弧は対応させ、クエリ末尾をバックスラッシュにしないでください。満たさない場合、リクエスト前に拒否されます。 |
| category | enum | はい | 製品カテゴリ。カテゴリごとにレスポンスのフィールドスキーマが異なります。drug | food | device |
| canvas_id | string | いいえ | このツールまたは別の openFDA 検索ツール(openfda_search_* または openfda_lookup_ndc)で stage=true を指定した以前の呼び出しから返された Canvas ID。指定すると、この検索結果がそのキャンバスにステージングされます(stage=true と同じ効果)。結果セットを蓄積してテーブル間で結合できます。省略すると、新しいキャンバスにステージングされます。 |
詳細
@cyanheads/openfda-mcp-server
openFDA を通じて、医薬品、食品、医療機器、リコールに関する FDA データを検索できます。STDIO または Streamable HTTP に対応しています。
公開ホストサーバー: https://openfda.caseyjhand.com/mcp
概要
openFDA の公開 API から、医薬品、食品、医療機器、リコールに関する FDA データを取得できます。有害事象、リコール、医薬品の承認、医療機器の承認を検索できるほか、NDC コードや医薬品ラベルを調べたり、任意のエンドポイントのフィールド件数を集計したりできます。
ツール
| ツール | 説明 |
|---|---|
openfda_drug_profile | 1つの医薬品名から、FDA の統合プロファイルを取得します:識別情報、ラベル、有害事象、リコール、承認、供給不足 |
openfda_search_adverse_events | 医薬品、食品、医療機器に関する有害事象報告を検索します |
openfda_search_animal_events | 動物用医薬品および医療機器に関する有害事象報告を検索します |
openfda_search_drug_shortages | ステータス、入手可能性、治療カテゴリー、製造業者で FDA の医薬品供給不足記録を検索します |
openfda_search_tobacco_reports | たばこ製品、電子たばこ、ベイピングデバイスに関する問題報告を検索します |
openfda_search_recalls | 医薬品、食品、医療機器に関する取締報告およびリコール措置を検索します |
openfda_count_values | 任意の openFDA エンドポイントの任意のフィールドについて、値を集計し、一意の値を数えます |
openfda_describe_fields | openFDA エンドポイントで検索可能なフィールドパスを、カテゴリー別にまとめて返します |
openfda_get_drug_label | FDA の医薬品ラベル(添付文書/SPL 文書)を検索します |
openfda_search_drug_approvals | Drugs@FDA データベースで NDA/ANDA 申請の承認を検索します |
openfda_search_device_clearances | FDA の医療機器市販前届出を検索します:510(k) クリアランスおよび PMA 承認 |
openfda_lookup_ndc | NDC(National Drug Code)Directory で医薬品を検索します |
openfda_dataframe_describe | DataCanvas にステージングされたテーブルと列のスキーマを一覧表示します |
openfda_dataframe_query | DataCanvas にステージングされた結果セットに対して、読み取り専用の SQL を実行します |
openfda_dataframe_drop | DataCanvas にステージングされたテーブルを1つ削除します(オプトイン方式、デフォルトでは無効) |
機能リファレンス
openfda_drug_profile ツール
- 1つの
drug名(ブランド名またはジェネリック名)を1回だけ照合して識別情報(一般名、NDC、RxCUI、SPL set ID)を特定します。リコール、承認、供給不足の検索キーにはmeta.fanOutKeyを使用します。これは、入力された名前が特定されたジェネリック医薬品の成分である場合はその入力名、それ以外の場合はそのジェネリック名です。meta.resolvedVia(label、ndc、none)は情報源を示し、単一成分の製品が配合剤より優先されます - リコールと承認では、openFDA が標準化していない記録(
product_description、products.active_ingredients.name)も検索します。recalls_totalは最新の5件のリコールとともに一致件数を示します label、adverse_events、recalls、approval、shortageの各セクションはベストエフォートで取得され、見つからない場合はnull(または空のrecalls)を返します。degraded[]には、サブクエリが上流で失敗したセクションが示されるため、一覧にあるセクションは「存在しない」のではなく「不明」です- 認証、設定、キャンセルに関するエラーは、セクションの機能低下として処理されず、呼び出し全体が失敗します
openfda_search_adverse_events ツール
category(drug、food、device)でエンドポイントとレコードのスキーマを選択します。1ページあたり最大1000件のレコードを取得できます- ソート可能な日付フィールドはカテゴリーによって異なります:
receivedate(drug)、date_created(food)、date_received(device)。別のカテゴリーのフィールドを指定すると、query_errorになります - テキスト出力では、医薬品の投与経路、反応の転帰、患者の年齢層のコードを生の値とともにデコードして表示します(
via oral (048)、fatal (5)、elderly (6))。構造化出力ではコードをそのまま保持します
openfda_search_animal_events ツール
- 動物に関する報告を対象とする任意の
search。例:animal.species、drug.active_ingredients.name、reaction.veddra_term_name、serious_ae。1ページあたり最大1000件のレコードを取得できます - すべてのレコードでブランド名と製造業者名は
MSKにマスキングされるため、有効成分で検索してください。drug.manufacturer.registration_numberを指定すると、1つの承認に絞り込めます - レコードには動物の種、品種、年齢、体重、医薬品と投与経路、VeDDRA の反応用語、転帰が含まれます
openfda_search_drug_shortages ツール
status(Current/To Be Discontinued/Resolved)、therapeutic_category、generic_name、またはcompany_nameを対象に、任意でsearchを指定できます。1ページあたり最大1000件です- 各レコードの
openfdaブロックには、openfda_get_drug_labelまたはopenfda_lookup_ndcへの連鎖に使用できるbrand_name、product_ndc、rxcuiが含まれます
openfda_search_tobacco_reports ツール
tobacco_products、reported_health_problems、reported_product_problems、またはnonuser_affectedを対象に、任意でsearchを指定できます。1ページあたり最大1000件です- レポートには問題の配列に加え、
number_tobacco_products、number_health_problems、number_product_problemsの各件数が含まれます
openfda_search_recalls ツール
category(drug、food、device)とendpointを指定します。enforcement(デフォルト。すべてのカテゴリーで使用可能)またはrecall(デバイスのみ。ほかのカテゴリーではrecall_endpoint_non_deviceとして失敗します)を選択できます。1ページあたり最大1000件です- Enforcement レコードには
recall_number、classification(Class I/II/III)、statusが含まれます。デバイスの recall レコードには代わりにproduct_res_numberとrecall_statusが含まれ、危険度分類はありません
openfda_count_values ツール
- 20種類の openFDA エンドポイントのいずれかを示す
endpoint、countフィールド式、および任意のsearchを指定します。件数順に並べた上位用語を最大1000件(デフォルトは100件)返します。日付フィールドでは、区別されたYYYYMMDD日付ごとに1つの用語を返し、同じ方法で並べます truncatedは、limitを超える区別された用語があることを示します。ただし、最大の1000用語の場合は、完全性を確認できない旨の通知が表示されます(日付の件数は openFDA がすべての日付を送信するため、どのlimitでも正確です)。openFDA が集計できない式はnot_aggregatableとして失敗します(openfda_describe_fieldsからcountAs形式を取得してください)- 一括ミラーが有効な場合でも、常にライブ API に対して実行されます
openfda_describe_fields ツール
endpoint:openfda_count_valuesが受け付けるものと同じ20種類のエンドポイント- フィールドパスはカテゴリー別に分類され、それぞれに
type、説明、countAs(検証済みの件数式。フィールドを集計できない場合はnull)が付属します。また、引用符、AND/OR、.exact、日付範囲に関するqueryTipsも含まれます
openfda_get_drug_label ツール
- ラベルフィールド(
openfda.brand_name、openfda.generic_name、openfda.manufacturer_name、set_id)を対象とするsearchが必須です。limitのデフォルトは5、最大は1000です - 24,000バイトのインライン予算を超えるページでは、ラベル本文の代わりに
kind: "outline"(セクション名とサイズを大きい順に表示)が返されます。sections: [...]を指定して再度呼び出すと、これらのセクションと識別メタデータ(openfda、set_id、id、effective_time、version)が返されます。予算を超える場合でも全体が返されます *_tableセクションはテキスト出力では Markdown テーブルとして表示されます。構造化された結果では、未加工の SPL マークアップが保持されます
openfda_search_drug_approvals ツール
openfda.brand_name、sponsor_name(大文字で保存されるため、小文字の引用値では一致しません)、submissions.submission_type、またはsubmissions.review_priorityを対象に、任意でsearchを指定できます。1ページあたり最大1000件です- レコードには
application_number、sponsor_name、products[]、および申請に関する完全なsubmissions[]履歴が含まれます
openfda_search_device_clearances ツール
pathway(510kまたはpma。1回の呼び出しにつきいずれか1つ)と、applicant、product_code、advisory_committee_description、またはopenfda.device_nameを対象とする任意のsearchを指定します。1ページあたり最大1000件です- 510(k) レコードには
k_number、device_name、decision_dateが含まれます。PMA レコードにはpma_number、trade_name、supplement_numberが含まれます
openfda_lookup_ndc ツール
product_ndc、brand_name、generic_name、openfda.manufacturer_name、またはactive_ingredients.nameを対象とするsearchが必須です。1ページあたり最大1000件です- レコードには
product_ndc、labeler_name、dosage_form、route、marketing_category、active_ingredients[]、packaging[]が含まれます
openfda_dataframe_describe tool
- ステージング済み検索の
canvas_idを指定すると、各テーブルのname、kind、ステージング済みの全row_count、および DuckDB の型と NULL 許容性を含む列を一覧表示します CANVAS_PROVIDER_TYPE=noneの場合はcanvas_disabled、canvas_idの期限が切れているか存在したことがない場合はcanvas_not_foundとして失敗します
openfda_dataframe_query tool
canvas_idと読み取り専用のSELECTを 1 つ指定します。DDL、DML、COPY、ファイル読み取り関数は拒否されます。スカラー値はテキストとして保存され(計算にはCASTを使用)、ネストされた openFDA ブロックは JSON 列として保存されます- 行数はキャンバスの行数上限までです。
truncated: trueは、ORDER BYとLIMIT/OFFSETを使って次のページに進む必要があることを示します。失敗の種類はcanvas_disabled、canvas_not_found、missing_table、invalid_queryです
openfda_dataframe_drop tool
- デフォルトでは無効です。呼び出し可能にするには
OPENFDA_DATAFRAME_DROP_ENABLED=trueを設定します。設定しない場合、ランディングページでは無効として表示され、tools/listには含まれません canvas_idとopenfda_dataframe_describeで取得したtable名を指定します。そのテーブルまたはビューのみを削除してremaining_tablesを返し、キャンバスと他のテーブルはそのまま残します- 失敗の種類は
canvas_disabled、canvas_not_found、missing_table(すでに削除済み、期限切れ、または入力ミス)です
機能
@cyanheads/mcp-ts-core を基盤としており、stdio および Streamable HTTP トランスポート、切り替え可能な認証(none/jwt/oauth)、切り替え可能なストレージ(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1)、オプションの OpenTelemetry トレースを備えた構造化ログを提供します。
openFDA 固有の機能:
- 20 個すべての openFDA エンドポイントを 1 つのクライアントで利用でき、429 および 5xx では再試行します。API キーは不要です(1 日あたり 1K リクエスト)。無料の
OPENFDA_API_KEYを設定すると、1 日あたり 120K リクエストまで引き上げられます - クエリはドット区切りのパスに対する
field:valueを AND/OR で結合します(句の間の URL 形式の+は空白として扱われます)。openfda_describe_fieldsでパスを一覧表示でき、不正なクエリはリクエスト前にmalformed_searchとして失敗します - ページング:
limitは最大 1000、skipは openFDA の上限である 25,000 件までです(上限を超えるとpagination_limit_reached)。各ページは 24,000 バイトの上限内に収められます openfda_search_*ツールまたはopenfda_lookup_ndcのfieldsを指定すると、各レコードを指定したドット区切りのパスに絞り込めるため、大きなレコードもインラインに収まります- DataCanvas へのステージング(デフォルトで有効。
CANVAS_PROVIDER_TYPE=noneで無効化)に対応し、stage: trueまたはcanvas_idを指定できます。また、オプションのローカル一括ミラー(OPENFDA_MIRROR_ENABLED=true)を使うと、API の利用枠を消費せずに完全一致のキー検索に応答します
エージェントに適した出力:
- 開示された上限情報:
page_omitted、page_bytes、page_largest_fields、projected_fields、ラベルoutline、staged_rowsによって、切り捨てられた内容がすべて報告されます - 型付きエラー:呼び出し元はメッセージを解析する代わりに、
error.data.reason(rate_limited、query_error、not_aggregatableなど)に基づいて処理を分岐できます - 不明と不在の区別:
openfda_drug_profileは FDA レコードがないセクションにnullを返し、失敗したセクションをdegraded[]に一覧表示します - 空の結果に対するガイダンス:一致する検索結果がない場合、
openfda_describe_fieldsと、より広い検索語を案内します
はじめに
インストールせずに、ホストされたインスタンスに接続します:
claude mcp add --transport http openfda-mcp-server https://openfda.caseyjhand.com/mcp
または、ローカルで実行します:
claude mcp add openfda-mcp-server -- npx -y @cyanheads/openfda-mcp-server
その他のクライアントでは、MCP 設定ファイルに以下を追加します:
{
"mcpServers": {
"openfda-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/openfda-mcp-server"]
}
}
}
API キーは不要です。無料の openFDA API キー を OPENFDA_API_KEY として設定すると、1 日あたりの上限が 1K から 120K リクエストに引き上げられます。Docker またはソースからのビルドについては、サーバーの実行を参照してください。
設定
| 変数 | 説明 | デフォルト |
|---|---|---|
OPENFDA_API_KEY | open.fda.gov から取得できる無料の API キーです。1 日あたりの上限が 1K リクエストから 120K リクエストに増えます。 | なし |
OPENFDA_BASE_URL | プロキシまたはモック用の API ベース URL の上書き値です。 | https://api.fda.gov |
OPENFDA_MIRROR_ENABLED | 完全一致のキー検索に対して、ローカルの一括ミラーを使用して応答します。 | false |
OPENFDA_MIRROR_PATH | ミラー対象のデータセットごとに 1 つの SQLite ファイルを格納するディレクトリです。 | ./data/openfda-mirror |
OPENFDA_MIRROR_REFRESH_CRON | プロセス内ミラー更新用の Cron 式です(HTTP トランスポートのみ)。 | なし |
OPENFDA_MIRROR_FALLBACK_LIVE | ミラーが未準備、レコードが見つからない、またはミラーでエラーが発生した場合に、ライブ API にフォールバックします。 | true |
OPENFDA_MIRROR_REFRESH_TIMEOUT_MS | 更新を中止するまでの実時間の上限(ミリ秒)です。 | 21600000(6h) |
OPENFDA_MIRROR_BASE_URL | 一括ダウンロードのマニフェスト(download.json)を提供するホストです。 | https://api.fda.gov |
CANVAS_PROVIDER_TYPE | DataCanvas のステージングと SQL を設定します。none にすると無効になります。データフレームツールは引き続き一覧に表示され、canvas_disabled を返します。 | duckdb |
OPENFDA_DATAFRAME_DROP_ENABLED | ステージングされたテーブルを削除する openfda_dataframe_drop を有効にします。CANVAS_PROVIDER_TYPE=duckdb が必要です。 | false |
MCP_TRANSPORT_TYPE | トランスポートです。stdio または http を指定します。 | stdio |
MCP_HTTP_PORT | HTTP サーバーのポートです。 | 3010 |
MCP_SESSION_MODE | HTTP セッションモードです。stateless、stateful、または auto を指定します。 | stateless |
MCP_AUTH_MODE | 認証方式です。none、jwt、または oauth を指定します。 | none |
MCP_LOG_LEVEL | ログレベルです(debug、info、warning、error など)。 | info |
LOGS_DIR | ログファイル用のディレクトリです(Node.js のみ)。 | <app-root>/logs |
STORAGE_PROVIDER_TYPE | ストレージバックエンドです。in-memory、filesystem、supabase、cloudflare-kv/r2/d1 を指定します。 | in-memory |
OTEL_ENABLED | OpenTelemetry を有効にします。 | false |
省略可能な上書き設定の一覧については、.env.example を参照してください。
Claude Desktop の MCPB バンドルでは、プラットフォーム固有の DuckDB バインディングが含まれないため、DataCanvas は無効になっています。ステージングと SQL には npm または Docker を使用してください。
ローカルの一括ミラー
OPENFDA_MIRROR_ENABLED=true にすると、サーバーは 4 つの openFDA 一括ダンプ(drug/label、drug/ndc、drug/enforcement、drug/drugsfda)のローカル SQLite コピーを保持します。ローカルで応答するのは完全一致検索のみです。id、set_id、product_id、product_ndc、recall_number、event_id、application_number のいずれかを対象とする、単一の引用符付き field:"value" 条件で、count や sort がなく、skip が 0 で、該当レコードが 1 件の場合に限ります。それ以外はすべて API に送られます。
初回のデータ取得は個別に実行され、起動時には実行されません。
bun run mirror:init # all four datasets
bun run mirror:init drug/enforcement # one dataset
bun run mirror:status # sync state per dataset
bun run mirror:verify # integrity check + row counts
bun run mirror:refresh # re-harvest datasets whose dump has advanced
更新ではダンプ全体を再読み込みします。HTTP トランスポートでプロセス内更新を実行するには、OPENFDA_MIRROR_REFRESH_CRON を設定してください。stdio の場合は、ホストから bun run mirror:refresh を実行してください。ミラーからの応答に含まれる meta.lastUpdated は、提供されたダンプのタイムスタンプです。ライブ API のタイムスタンプとは異なる場合があります。
Node では、任意のピア依存関係である better-sqlite3 をインストールしてください(Bun では組み込みの bun:sqlite を使用します)。OPENFDA_MIRROR_REFRESH_CRON には、任意のピア依存関係である node-cron も必要です。これがない場合、サーバーは起動時に失敗します。
サーバーの実行
ローカル開発
Bun v1.4.0 以降(または Node.js v24 以降)が必要です。
-
クローンとインストール:
git clone https://github.com/cyanheads/openfda-mcp-server.git cd openfda-mcp-server && bun install cp .env.example .env # optionally set OPENFDA_API_KEY and the mirror or canvas options -
ビルドと実行:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
チェックとテストの実行:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/openfda-mcp-server:latest
イメージは、HTTP トランスポート、ステートレスセッションモード、および /var/log/openfda-mcp-server へのログ出力をデフォルトで使用します。MCP クライアントから stdio 経由で実行するには、"command": "docker" と "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/openfda-mcp-server:latest"] を使用します。ローカルでビルドするには、docker build -t openfda-mcp-server . を実行します。OpenTelemetry のピア依存関係はデフォルトでインストールされます。これらを省略するには、--build-arg OTEL_ENABLED=false を指定してビルドします。コンテナーの置き換え後もミラーの取り込みデータを保持するには、/usr/src/app/data/openfda-mirror にボリュームをマウントしてください。
プロジェクト構成
| ディレクトリ | 目的 |
|---|---|
src/index.ts | createApp() エントリーポイント:ツールの登録、サービスのセットアップ、ミラー更新の配線。 |
src/config | Zod によるサーバー固有の環境変数の解析と検証。 |
src/mcp-server/tools/definitions | ツール定義(*.tool.ts)、全15個。 |
src/mcp-server/tools | 共有ツールヘルパー:エンドポイントごとのフィールドカタログ、入力スキーマとガード、フォーマッター、SPL テーブルのレンダリング。 |
src/services/openfda | openFDA API クライアント(リトライ、レート制限、エラーの正規化)、インラインページ予算、fields レコード投影、Canvas ステージング。 |
src/services/openfda/mirror | オプトインのローカル一括ミラー:データセットレジストリ、ダンプ読み取り、取り込み処理、ミラーとライブクエリの切り替え、更新スケジュール。 |
src/services/canvas | ステージングと SQL 用の DataCanvas アクセサー。 |
scripts/openfda-mirror.ts | mirror:* スクリプトから実行するミラーのライフサイクル CLI。 |
tests/ | src/ の構成に対応する単体テストと統合テスト。 |
開発ガイド
開発ガイドラインとアーキテクチャ上のルールについては、CLAUDE.md を参照してください。概要は次のとおりです。
- ハンドラーは例外をスローし、フレームワークが捕捉します。ツールのロジックで
try/catchは使用しません。 - リクエストスコープのログには
ctx.logを使用します。 - 新しいツールは
src/mcp-server/tools/definitions/index.tsのバレルに登録します。 - 外部 API 呼び出しをラップします。生データを検証し、ドメイン型に正規化してから、出力スキーマを返します。openFDA が返していないフィールドを捏造してはいけません。
データの帰属
データは、米国食品医薬品局のサービスである openFDA から取得しています。openFDA ライセンスの下で、データは CC0 1.0 に基づきパブリックドメインに提供されています。ただし、例外が1つあります。GMDN® の医療機器分類コンテンツ(Term Code、Term Name、Term Definition)は The GMDN Agency からライセンス供与されており、これを再配布したり AI のトレーニングに使用したりするには、同 Agency から別途ライセンスを取得する必要があります。
このため、ローカルミラーの対象は医薬品データセットのみです。device/classification とその他すべての医療機器エンドポイントは対象外であり、取り込み処理では、GMDN を含むフィールドを持つレコードはディスクに書き込まず、拒否します。
FDA はこのプロジェクトを推奨していません。医療に関する判断に openFDA を頼らないでください。
コントリビューション
イシューを歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
ライセンス
このプロジェクトは Apache 2.0 ライセンスの下でライセンスされています。詳細は LICENSE ファイルを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。