fhir-mcp-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fhir-mcp-serverfind patients with hypertension"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 buildRelated MCP server: FHIRfly MCP Server
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-mcpfhir-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-mcpClaude 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.jsClaude 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": "..."
}
}
}
}Web版(リモート HTTP MCP / スマホ Claude アプリ向け)
Claude Desktop / Code は stdio でローカル起動しますが、スマホの Claude アプリは
ローカルプロセスを起動できず、公開 HTTPS に常駐するリモート MCP サーバー
(カスタムコネクタ)+ OAuth にしか接続できません。そのための HTTP エントリポイント
dist/http.js を用意しています(stdio 版 dist/index.js はそのまま併存)。
トランスポート: MCP Streamable HTTP(
/mcpに POST/GET/DELETE)認可: 外部 IdP(Auth0 等)へ委譲する OAuth。
/.well-known/oauth-*メタデータと authorize/token/register の proxy を自動提供し、/mcpは Bearer トークンで保護このフェーズでは OAuth は「接続の入口」を守るだけ。認証ユーザー単位の FHIR アクセス制御(SMART on FHIR
user/*/patient/*相当)は本番データ移行時に対応予定。 FHIR への接続は従来通り固定の SMART Backend Services クレデンシャルを使います (デモ・評価データ前提)。
起動
npm run build
PUBLIC_URL=https://your-host \
OAUTH_ISSUER_URL=https://YOUR_TENANT.auth0.com/ \
OAUTH_AUTHORIZATION_URL=https://YOUR_TENANT.auth0.com/authorize \
OAUTH_TOKEN_URL=https://YOUR_TENANT.auth0.com/oauth/token \
OAUTH_JWKS_URL=https://YOUR_TENANT.auth0.com/.well-known/jwks.json \
OAUTH_AUDIENCE=https://your-host/api \
FHIR_BASE_URL=http://localhost:3000 \
node dist/http.jsdocker compose で常駐起動する場合(.env に上記を書いておく):
docker compose up fhir-mcp-http # http://localhost:8080/mcp で待受環境変数はローカルでは .env(サンプル: .env.example)にまとめ、
Node 20+ の --env-file で読み込めます:
npm run build && node --env-file=.env dist/http.js外部 IdP(Auth0)の設定
詳細手順は docs/auth0-setup.md を参照。要点:
API を作成し Identifier を
OAUTH_AUDIENCEに設定。テナントの Default Audience をその Identifier に設定(これをしないと Auth0 が JWT ではなく opaque トークンを発行し検証に失敗する — MCP × Auth0 の典型的な落とし穴)。
Dynamic Client Registration を有効化し、ログイン接続を domain level に昇格 (Claude アプリがクライアント自己登録するため)。
OAUTH_REGISTRATION_URLも設定。.well-known/openid-configurationの値をOAUTH_ISSUER_URL等に写す。 IdP は Google / Cognito 等にも差し替え可能。
スマホの前に、M2M トークンで /mcp の Bearer 検証が通ることを確認できます
(手順は上記ドキュメント参照)。
Cloud Run へのデプロイ(想定)
gcloud run deploy fhir-mcp-server \
--source . --command node,dist/http.js \
--set-env-vars PUBLIC_URL=https://SERVICE_URL,OAUTH_ISSUER_URL=...,OAUTH_AUDIENCE=...,FHIR_BASE_URL=...PORT は Cloud Run が注入します(HTTP_PORT 未設定時のフォールバックとして利用)。
scale-to-zero でデモのコストを最小化できます。
Render へのデプロイ(Blueprint / Docker)
render.yaml(Blueprint)を同梱しています。既存 Dockerfile を使い、起動コマンドを
http 版に上書きする構成です。
リポジトリを Render に接続し、Blueprint から
render.yamlを読み込む。sync: falseの環境変数(OAUTH_*/FHIR_*/PUBLIC_URL)を Render ダッシュボードで設定。初回デプロイで
https://<service>.onrender.comが発行されるので、それをPUBLIC_URL(メタデータ用)に設定して再デプロイ。IdP 側の Allowed Callback にもこの URL を登録。スマホ Claude アプリのカスタムコネクタに
https://<service>.onrender.com/mcpを登録。
注意点(Free プラン):
15分無アクセスでスリープし、次アクセスでコールドスタート(数十秒)。初回接続が 遅延/タイムアウトすることがある。安定させたい場合は
render.yamlのplanをstarterに変更(常時起動)。セッションはメモリ保持のため、インスタンス再起動で切断される(低トラフィックのデモは問題なし)。
PORTは Render が注入(HTTP_PORT未設定時のフォールバックで対応済み)。
スマホ Claude アプリへの登録
Claude アプリの「カスタムコネクタ」に PUBLIC_URL(= https://SERVICE_URL/mcp)を登録し、
OAuth ログインを済ませると、get_capabilities / search_fhir 等が実機で使えます。
設定(環境変数)
変数 | 既定 | 説明 |
|
| 接続先 FHIR サーバー |
| なし | SMART Backend Services のクレデンシャル。両方未設定なら無認証モード(Authorization ヘッダーを送らない。fhir-server の |
|
|
|
|
| 検索 |
Web版(HTTP)の追加設定
変数 | 既定 | 説明 |
|
| HTTP 待受ポート( |
| (必須) | このサーバーの公開 URL。OAuth メタデータ・リソース識別子に使用 |
| (必須) | 外部 IdP の issuer |
| (必須) | IdP の authorization エンドポイント |
| (必須) | IdP の token エンドポイント |
| (必須) | アクセストークン検証用の JWKS |
| (必須) | アクセストークンに期待する |
| なし | IdP の Dynamic Client Registration エンドポイント(任意) |
認証(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 スコープを付与ツール一覧
参照系(常時登録)
ツール | 対応エンドポイント | 説明 |
|
| 対応リソース・検索パラメータ・オペレーションの要約。使い方の自己発見の起点 |
|
| 検索。チェーン検索・ |
|
| 単一リソース取得 |
|
| 患者コンパートメント一括取得( |
|
| インスタンス/タイプ/システムレベルの履歴 |
|
| 保存せずにリソースを検証 |
書き込み系(FHIR_MCP_ALLOW_WRITES=true のときのみ登録)
ツール | 対応エンドポイント | 説明 |
|
| 作成( |
|
| 全置換更新( |
|
| 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/http.ts エントリポイント(Streamable HTTP transport + OAuth)
├── src/auth.ts 外部 IdP へ委譲する OAuth プロバイダ・JWT 検証
├── 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 を参照してください。
Available Tools
6 toolsget_capabilitiesGet FHIR server capabilitiesARead-only
Fetch the FHIR server's CapabilityStatement (GET /metadata) and return a compact summary: supported resource types, interactions, search parameters, and operations. Call this first to discover what the server supports.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, and description adds that it returns a compact summary of resource types, interactions, search parameters, and operations. No contradictions. Slightly enhanced beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with action ('Fetch'), no wasted words. Perfectly structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, annotations, and no output schema, the description sufficiently explains the return value (compact summary of capabilities). Complete enough for a simple read-only discovery tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, so no need for parameter explanation. Schema coverage is 100%. Baseline score of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it fetches the CapabilityStatement and returns a compact summary of capabilities. Specifies verb 'Fetch' and resource 'FHIR server's CapabilityStatement'. Differentiates from sibling tools like search_fhir, read_fhir etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Call this first to discover what the server supports', providing clear usage context. Lacks explicit when-not or alternative tools but is adequate for a discovery tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_historyGet resource historyARead-only
Fetch version history. With resourceType and id: history of one resource (GET /{type}/{id}/_history). With only resourceType: history across that type. With neither: system-wide history.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Logical id (requires resourceType) | |
| count | No | Entries per page (default 20, capped at 50) | |
| since | No | Only versions created after this instant (ISO 8601) | |
| resourceType | No | FHIR resource type (omit for system-level history) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds implementation details (endpoint patterns) beyond the readOnlyHint annotation, but does not explain what the history response contains (e.g., version entries, ordering) or pagination behavior beyond the count parameter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, front-loaded with the primary purpose, no redundancy or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Description is mostly complete for a read operation with readOnlyHint, but lacks details about the return format (no output schema) and does not mention that the response is typically a Bundle of history entries, which would aid an agent in processing the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptive parameter descriptions, but the tool description adds meaningful context by explaining the three usage modes and how parameters relate (e.g., id requires resourceType), which goes beyond the schema's individual field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it fetches version history and specifies three distinct modes based on parameter combinations (with id+resourceType, only resourceType, neither). This distinguishes it from siblings like search_fhir and read_fhir, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides explicit context for when to use each combination of parameters, but does not indicate when NOT to use the tool or mention alternative tools for similar tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
patient_everythingFetch a patient's full recordARead-only
Fetch all resources in a patient's compartment (GET /Patient/{id}/$everything): conditions, observations, encounters, medications, etc. Use types to limit resource types and since to limit to recently-updated resources — both are recommended to keep responses manageable.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Results per page (default 20, capped at 50) | |
| since | No | Only resources updated after this instant (ISO 8601, e.g. 2026-01-01T00:00:00Z) | |
| types | No | Restrict to these resource types, e.g. ["Observation", "Condition"] | |
| patientId | Yes | Logical id of the Patient |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description adds the behavioral context that it fetches a large bundle of resources, but does not detail pagination or performance implications. Since annotations cover the safety profile, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence defines purpose and endpoint; the second gives actionable parameter guidance. It is front-loaded and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool that returns a large bundle of resources, the description covers the key points: what is returned, optional filters, and the endpoint. Without an output schema, it could mention pagination or response format, but it is sufficient for a read-only operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so baseline is 3. The description adds value by explaining that `types` and `since` are recommended for limiting response size, providing context beyond the schema descriptions. This justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Fetch all resources in a patient's compartment' with specific examples (conditions, observations, etc.) and the FHIR endpoint. It distinguishes from sibling tools like read_fhir (single resource) and search_fhir (query-based).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description recommends using `types` and `since` to keep responses manageable, providing explicit guidance for efficient use. It implies this is for comprehensive patient data retrieval but does not explicitly contrast with siblings for when to use alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_fhirRead a FHIR resourceARead-only
Read a single resource by type and id (GET /{resourceType}/{id}).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Logical id of the resource | |
| resourceType | Yes | FHIR resource type, e.g. Patient |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description adds the HTTP method and URL pattern (GET /{resourceType}/{id}), providing additional behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that efficiently conveys the tool's purpose without any wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (read by type and ID), the description is complete. It covers the purpose, HTTP method, and URL pattern. Output schema is not needed for such a tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters having descriptions. The description reiterates 'by type and id' but does not add new meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Read a single resource by type and id', with a specific verb and resource. It distinguishes from sibling tools like search_fhir and patient_everything which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (to read a single resource) by specifying 'Read a single resource by type and id'. It does not explicitly list alternatives but is clear in context of siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_fhirSearch FHIR resourcesARead-only
Search resources of a given type (GET /{resourceType}?...). Search parameters are passed through to the server as-is, so chained parameters, _has, _include, _revinclude, _sort, _total etc. all work. To keep responses small, prefer _elements (comma-separated field list) or _summary=true, and page with _count plus the returned hasNextPage flag (use params like _count/_offset or the server's paging links).
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Results per page (default 20, capped at 50) | |
| params | No | Search parameters as key-value pairs, e.g. {"name": "山田", "_elements": "id,name,birthDate"}. Repeat-style OR values can be comma-separated per FHIR search rules. | |
| resourceType | Yes | FHIR resource type to search, e.g. Patient, Observation, Condition |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, so the tool is safe for reads. The description adds valuable behavioral context: HTTP GET method, parameter passthrough, pagination behavior, and response size control. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The first sentence states the core action and HTTP method, the second provides crucial usage tips. Information is front-loaded and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description explains the pagination response (hasNextPage flag). For a search tool with moderate complexity, it covers essential aspects: parameters, pagination, response size. Could mention more about return format but is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all 3 parameters with descriptions. The description adds extra meaning: params can include FHIR chaining, _include, _revinclude, and mentions _elements, _summary, _count which are not in schema but are related. Adds value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches resources of a given type via GET, and the title 'Search FHIR resources' reinforces this. It distinguishes from siblings like read_fhir (single resource retrieval) and patient_everything (specific patient bundle).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use and how: pass parameters as-is, use _elements/_summary for small responses, paginate with _count and hasNextPage flag. It doesn't explicitly state when not to use but siblings imply alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_fhirValidate a FHIR resourceARead-only
Validate a resource against the server's profiles without saving it (POST /{resourceType}/$validate). Use this before create_fhir/update_fhir to catch structural or terminology errors early. The resource JSON must include resourceType.
| Name | Required | Description | Default |
|---|---|---|---|
| resource | Yes | The FHIR resource to validate (JSON object including resourceType) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description confirms the operation is read-only (no save), aligning with readOnlyHint annotation. It adds behavioral context about the endpoint and required structure (resourceType), surpassing annotation detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with purpose and endpoint. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks description of the return value (e.g., OperationOutcome). While sufficient given no output schema, adding expected response type would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, schema already defines the param. Description adds critical constraint that resource must include resourceType, which is not in schema description, enhancing clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool validates a FHIR resource against server profiles without saving, using a specific HTTP method and endpoint. It distinguishes from sibling tools like search or read by focusing on validation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises using this tool before create_fhir or update_fhir to catch errors early, providing clear context for when to use it over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
v0.1.0- First observed
get_capabilities - First observed
get_history - First observed
patient_everything - First observed
read_fhir - First observed
search_fhir - First observed
validate_fhir
TDQS
Each tool targets a distinct FHIR operation: server metadata, searching, reading, patient compartment, history, and validation. No overlaps are apparent.
Most tool names follow a verb_noun pattern (e.g., get_capabilities, search_fhir), except patient_everything which uses a noun_verb form. The inconsistency is minor and does not hinder understanding.
Six tools is appropriate for a FHIR MCP server covering essential interactions: discovery, search, read, patient compartment, history, and validation. The scope is well-balanced.
The toolset lacks create, update, and delete operations, which are core to resource lifecycle management. The validate_fhir tool even references create_fhir/update_fhir as prerequisites, but they are missing.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
- mcpOAuthcom.medplum
Securely access and manage FHIR healthcare data stored in Medplum.
Hosted MCP server for the Healthie EHR & telehealth API: patients, appointments, charting, tasks.
Hosted MCP server for Cliniko — patients, appointments, availability, and invoices for AI agents.
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceEnables seamless integration with FHIR APIs for healthcare applications, allowing users to search, retrieve, create, update, and analyze clinical information through natural language interactions. Supports SMART-on-FHIR authentication and works with various healthcare systems like EPIC and HAPI FHIR servers.-

FHIRfly MCP Serverofficial
AlicenseNot gradedqualityBmaintenanceMCP server for connecting Claude Desktop to FHIRfly healthcare reference data APIs, enabling lookup of drugs, providers, clinical codes, and more.209MIT- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to securely interact with FHIR R4 servers for clinical decision support workflows, including PlanDefinition execution, FHIR resource management, terminology services, and Questionnaire/StructureMap transformation via Matchbox.1-
- FlicenseNot gradedqualityDmaintenanceProvides access to Medplum FHIR healthcare data, enabling Claude and other MCP clients to read, search, and query FHIR resources from one or more Medplum environments.16-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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