mcpField
O
openfda-mcp-server

openfda-mcp-server

リモート
github.com/cyanheadsヘルスケア42 日前に更新
リポジトリ

openfda-mcp-server について

openfda-mcp-server は、医薬品、食品、医療機器、リコールに関する openFDA の公開データを MCP クライアントに提供します。フィールド集計や、ステージングした結果への読み取り専用 SQL にも対応し、STDIO と Streamable HTTP を利用できます。

主な機能

  1. 01有害事象、リコール、供給不足の検索
  2. 02医薬品ラベル、承認、NDC の照会
  3. 03医療機器承認とたばこ報告の検索
  4. 04フィールド値の集計とスキーマ確認
  5. 05結果のステージングと読み取り専用 SQL

活用シーン

  1. 01医薬品のラベル、有害事象、リコールの確認
  2. 02医薬品の供給不足や FDA 承認の調査
  3. 03食品・機器・医薬品の有害事象の検索
  4. 04ステージング済み検索結果への SQL 実行

MCP 対応

検索、照会、集計、ステージング結果の分析を行う 15 個の MCP ツールで、openFDA データに接続します。STDIO と Streamable HTTP に対応します。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://openfda.caseyjhand.com/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

パッケージ
npm@cyanheads/openfda-mcp-server0.9.1

ツール

14
パラメーター型必須説明
skipnumberいいえページネーションでスキップするレコード数(デフォルトは 0)。openFDA のページネーション上限は 25000 件です。それを超える値を指定すると pagination_limit_reached エラーが返されます。
sortstringいいえ並べ替え式です。フィールドパスの後に :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)を指定するとクエリエラーになります。このカテゴリに対応するフィールドを使用してください。
limitnumberいいえ返されるレコードの最大数(1~1000、デフォルトは 10)。シリアライズされたレコードのサイズは openFDA のエンドポイント間で最大 3 桁異なるため、ページには 24000 バイトのシリアライズ予算も適用されます。予算を超えるページでは、要求数より少ないレコードが返され、切り捨てられた件数が page_omitted に報告されます。レコードが一致した場合、サイズにかかわらず少なくとも 1 件が返されます。page_bytes はそのサイズを報告し、page_largest_fields は最大のフィールドを示します。これらのフィールドは投影によって除外できます。医薬品の報告は群を抜いて大きく、医薬品/事象の報告は平均で数十キロバイトですが、食品/事象の報告は数百バイトです。
stagebooleanいいえ一致した結果セットを DataCanvas にステージングして SQL 分析を行います。ステージングされた列の一覧には openfda_dataframe_describe を、SQL の実行には openfda_dataframe_query を使用します。デフォルトは false で、1 回の上流リクエストにつき 1 ページを返します。true の場合は、サイズ上限に達するまでレコードもキャンバステーブルに取り込みます(取り込まれた件数は staged_rows で報告)。ステージングは上限付きの一部データに対するレコード単位の SQL に適しています。一致した全件の分布を集計するには、openfda_count_values を使ってサーバー側で 1 回のリクエストで集計してください。CANVAS_PROVIDER_TYPE=duckdb が必要です。
fieldsarrayいいえ各返却レコードに保持するドット区切りのレコードパス。例:["receivedate", "patient.drug.medicinalproduct"]。返却レコード内の任意のキーのパスを指定でき、検索可能なフィールドは openfda_describe_fields で確認できます。インラインのバイト予算を測定する前に、各レコードは指定パスと識別キー(safetyreportid、report_number、mdr_report_key)に投影されます。これは両方のレスポンス形式で同じです。配列を通るパスは各要素に適用されます。レコードが大きい場合に使用してください。page_bytes が予算を超えると、サイズ超過レコードの最大フィールドが示されます。返却レコードに存在しないパスは通知に記載されます。省略するとレコード全体が返されます。パスに使用できるのは英字、数字、アンダースコア、ドットのみです。それ以外はリクエスト前に拒否されます。stage=true の場合、投影されるのはインラインページのみで、ステージングテーブルの列はそのまま保持されます。
searchstringいいえopenFDA の検索クエリ。例:patient.drug.medicinalproduct:"aspirin"、patient.reaction.reactionmeddrapt:"nausea" AND serious:"1"。省略すると最新のレコードを参照します。二重引用符、丸括弧、範囲指定の角括弧は対応させ、クエリ末尾をバックスラッシュにしないでください。満たさない場合、リクエスト前に拒否されます。
categoryenumはい製品カテゴリ。カテゴリごとにレスポンスのフィールドスキーマが異なります。drug | food | device
canvas_idstringいいえこのツールまたは別の openFDA 検索ツール(openfda_search_* または openfda_lookup_ndc)で stage=true を指定した以前の呼び出しから返された Canvas ID。指定すると、この検索結果がそのキャンバスにステージングされます(stage=true と同じ効果)。結果セットを蓄積してテーブル間で結合できます。省略すると、新しいキャンバスにステージングされます。

詳細

@cyanheads/openfda-mcp-server

openFDA を通じて、医薬品、食品、医療機器、リコールに関する FDA データを検索できます。STDIO または Streamable HTTP に対応しています。

15 個のツール

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

公開ホストサーバー: https://openfda.caseyjhand.com/mcp


概要

openFDA の公開 API から、医薬品、食品、医療機器、リコールに関する FDA データを取得できます。有害事象、リコール、医薬品の承認、医療機器の承認を検索できるほか、NDC コードや医薬品ラベルを調べたり、任意のエンドポイントのフィールド件数を集計したりできます。

ツール
ツール説明
openfda_drug_profile1つの医薬品名から、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_fieldsopenFDA エンドポイントで検索可能なフィールドパスを、カテゴリー別にまとめて返します
openfda_get_drug_labelFDA の医薬品ラベル(添付文書/SPL 文書)を検索します
openfda_search_drug_approvalsDrugs@FDA データベースで NDA/ANDA 申請の承認を検索します
openfda_search_device_clearancesFDA の医療機器市販前届出を検索します:510(k) クリアランスおよび PMA 承認
openfda_lookup_ndcNDC(National Drug Code)Directory で医薬品を検索します
openfda_dataframe_describeDataCanvas にステージングされたテーブルと列のスキーマを一覧表示します
openfda_dataframe_queryDataCanvas にステージングされた結果セットに対して、読み取り専用の SQL を実行します
openfda_dataframe_dropDataCanvas にステージングされたテーブルを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_KEYopen.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_TYPEDataCanvas のステージングと 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_PORTHTTP サーバーのポートです。3010
MCP_SESSION_MODEHTTP セッションモードです。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_ENABLEDOpenTelemetry を有効にします。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.tscreateApp() エントリーポイント:ツールの登録、サービスのセットアップ、ミラー更新の配線。
src/configZod によるサーバー固有の環境変数の解析と検証。
src/mcp-server/tools/definitionsツール定義(*.tool.ts)、全15個。
src/mcp-server/tools共有ツールヘルパー:エンドポイントごとのフィールドカタログ、入力スキーマとガード、フォーマッター、SPL テーブルのレンダリング。
src/services/openfdaopenFDA API クライアント(リトライ、レート制限、エラーの正規化)、インラインページ予算、fields レコード投影、Canvas ステージング。
src/services/openfda/mirrorオプトインのローカル一括ミラー:データセットレジストリ、ダンプ読み取り、取り込み処理、ミラーとライブクエリの切り替え、更新スケジュール。
src/services/canvasステージングと SQL 用の DataCanvas アクセサー。
scripts/openfda-mirror.tsmirror:* スクリプトから実行するミラーのライフサイクル 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 ファイルを参照してください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。