fhir-mcp-server
FHIR R4 サーバー(JP-Core 準拠の fhir-server や HAPI FHIR 等)に接続する MCP(Model Context Protocol)サーバーです。Claude Desktop / Claude Code などの MCP クライアントから、FHIR データを自然言語で検索・参照・(オプトインで)書き込みできます。
- fhir-server とはリポジトリ分離(接点は HTTP + Bearer トークンのみ)
- SMART Backend Services(OAuth2
client_credentials+system/*スコープ)のクライアントとして動作 FHIR_BASE_URLとクレデンシャルの差し替えで任意の FHIR R4 サーバーに接続可能
セットアップ
Node.js 20+ が必要です。
npm install
npm run build
Docker / docker compose で動かす
Node.js をホストに入れずに動かす場合は Docker イメージを使います。MCP の stdio サーバーなので常駐(up)は不要で、クライアントが必要なときに docker compose run で起動します。
docker compose build
動作確認(手動で JSON-RPC を流す代わりに、後述のクライアント登録をしてもよい):
docker compose run --rm -T fhir-mcp
- 既定の接続先は
http://host.docker.internal:3000(= ホストのlocalhost:3000)。fhir-server をホストで直接動かしていても、docker compose(ポート 3000 公開)で動かしていてもそのままつながります - 接続先やクレデンシャルは環境変数で上書きできます:
FHIR_BASE_URL=... FHIR_CLIENT_ID=... docker compose run --rm -T fhir-mcp - fhir-server(Rails)側は HostAuthorization で
host.docker.internalを許可している必要があります(development.rb のconfig.hosts << "host.docker.internal")
Docker 経由で Claude Code に登録する場合:
claude mcp add fhir -- docker compose -f /path/to/fhir-mcp-server/compose.yaml run --rm -T fhir-mcp
Claude Desktop の場合:
{
"mcpServers": {
"fhir": {
"command": "docker",
"args": [
"compose", "-f", "/path/to/fhir-mcp-server/compose.yaml",
"run", "--rm", "-T", "fhir-mcp"
]
}
}
}
Claude クライアントへの接続
Claude Code
claude mcp add fhir -- node /path/to/fhir-mcp-server/dist/index.js
環境変数を渡す場合:
claude mcp add fhir \
-e FHIR_BASE_URL=http://localhost:3000 \
-e FHIR_CLIENT_ID=... \
-e FHIR_CLIENT_SECRET=... \
-- node /path/to/fhir-mcp-server/dist/index.js
Claude Desktop(claude_desktop_config.json)
{
"mcpServers": {
"fhir": {
"command": "node",
"args": ["/path/to/fhir-mcp-server/dist/index.js"],
"env": {
"FHIR_BASE_URL": "http://localhost:3000",
"FHIR_CLIENT_ID": "...",
"FHIR_CLIENT_SECRET": "..."
}
}
}
}
設定(環境変数)
| 変数 | 既定 | 説明 |
|---|---|---|
FHIR_BASE_URL |
http://localhost:3000 |
接続先 FHIR サーバー |
FHIR_CLIENT_ID / FHIR_CLIENT_SECRET |
なし | SMART Backend Services のクレデンシャル。両方未設定なら無認証モード(Authorization ヘッダーを送らない。fhir-server の FHIR_AUTH_ENABLED=false 環境向け) |
FHIR_MCP_ALLOW_WRITES |
false |
true のときだけ書き込みツール(create/update/patch)を登録 |
FHIR_MCP_MAX_COUNT |
50 |
検索 _count の上限 |
認証(SMART Backend Services)
FHIR_CLIENT_ID / FHIR_CLIENT_SECRET を設定すると、POST {FHIR_BASE_URL}/oauth/token に grant_type=client_credentials でアクセストークンを取得します。
- トークンは
expires_inの 90% 経過で先回り再取得 - API が 401 を返した場合は 1 回だけトークンを再取得してリトライ
- トークン・シークレットはログに出力しません
fhir-server 側のクライアント登録例:
bin/rails "fhir:register_client[fhir-mcp-server,system/*.read]"
# 書き込みも許可する場合は system/*.write スコープを付与
ツール一覧
参照系(常時登録)
| ツール | 対応エンドポイント | 説明 |
|---|---|---|
get_capabilities |
GET /metadata |
対応リソース・検索パラメータ・オペレーションの要約。使い方の自己発見の起点 |
search_fhir |
GET /{type}?... |
検索。チェーン検索・_has・_include 等は params でそのまま透過 |
read_fhir |
GET /{type}/{id} |
単一リソース取得 |
patient_everything |
GET /Patient/{id}/$everything |
患者コンパートメント一括取得(_type/_since 対応) |
get_history |
GET [/{type}[/{id}]]/_history |
インスタンス/タイプ/システムレベルの履歴 |
validate_fhir |
POST /{type}/$validate |
保存せずにリソースを検証 |
書き込み系(FHIR_MCP_ALLOW_WRITES=true のときのみ登録)
| ツール | 対応エンドポイント | 説明 |
|---|---|---|
create_fhir |
POST /{type} |
作成(If-None-Exist による条件付き作成対応) |
update_fhir |
PUT /{type}/{id} |
全置換更新(If-Match による楽観ロック対応) |
patch_fhir |
PATCH /{type}/{id} |
JSON Patch(RFC 6902)による部分更新 |
delete はツールとして提供しません(AI からの破壊的操作は初期スコープ外)。
トークン消費を抑えるコツ
検索結果の Bundle はそのまま返さず、{ total, returned, hasNextPage, resources } に整形して返します。それでも大きい場合は件数を切り詰め、絞り込みのガイダンスを付けます。以下を活用してください:
_elements=id,name,birthDate— 必要なフィールドだけ取得_summary=true— サマリー要素のみ取得_count— ページサイズを絞る(既定 20)patient_everythingではtypes/sinceで範囲を限定
開発
npm run dev # tsx で直接実行
npm test # unit テスト(fetch モック)
npm run lint # biome
npm run build # tsc → dist/
integration テスト
実サーバー相手の e2e は FHIR_INTEGRATION_BASE_URL を設定したときだけ実行されます:
# fhir-server を docker compose 等で起動しておく
FHIR_INTEGRATION_BASE_URL=http://localhost:3000 npm test
# 認証ありモードを試す場合
FHIR_INTEGRATION_BASE_URL=http://localhost:3000 \
FHIR_INTEGRATION_CLIENT_ID=... \
FHIR_INTEGRATION_CLIENT_SECRET=... \
npm test
アーキテクチャ
MCP クライアント(Claude 等)
│ stdio
▼
fhir-mcp-server
├── src/index.ts エントリポイント(stdio transport)
├── src/server.ts McpServer 構築・ツール登録
├── src/config.ts 環境変数の読み込み・検証
├── src/fhir-client.ts FHIR REST 呼び出し(fhir+json、OperationOutcome 整形、401 リトライ)
├── src/token-manager.ts SMART トークン管理(先回り更新)
├── src/format.ts Bundle / CapabilityStatement の要約整形
└── src/tools/*.ts ツール実装(薄い層)
│ HTTP(S) + Authorization: Bearer
▼
FHIR R4 サーバー(fhir-server / HAPI など)
設計の背景・rationale は docs/DESIGN.md を参照してください。