Skip to main content
Glama
ysnr-dev

fhir-mcp-server

by ysnr-dev

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/tokengrant_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 を参照してください。

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ysnr-dev/fhir-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server