fhirHydrant について
fhirHydrantは、SMART Backend Servicesを通じてR4以降のFHIR APIに接続する、MCPクライアント向けNode.jsサーバーです。メタデータに応じた操作を設定でき、レスポンスの整形やFHIRPathフィルタリング、用語検索に対応します。
主な機能
- 01SMART Backend Services認証
- 02メタデータに応じた検索と読み取り
- 03設定可能な操作とBundle送信
- 04コンパクトな応答とFHIRPathフィルタリング
- 05安全なページネーションと監査イベント
- 06LOINC・SNOMED CT検索
活用シーン
- 01臨床FHIR APIのリソース検索・読み取り
- 02必要に応じたリソースの作成・更新・削除
- 03大きなFHIR Bundleの次ページ取得
- 04臨床用語コードの検索
MCP 対応
MCPクライアントに、FHIRリソースの検索・読み取り・任意のCRUD、名前付き操作、ページネーション、用語検索のツールを提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y fhirhydrantMCP_TRANSPORTRun the installed package over MCP stdio.FHIR_AUTHシークレットFHIR authentication mode. Use none only for an unauthenticated FHIR endpoint.FHIR_SERVER_URLFull base URL of the FHIR API, such as https://fhir.example.org/fhir/R4.FHIR_TOKEN_URLシークレットSMART Backend Services token endpoint. Required when FHIR_AUTH=smart unless it can be derived from FHIR_BASE_URL.FHIR_CLIENT_IDSMART Backend Services client ID. Required when FHIR_AUTH=smart.FHIR_ACTIVE_KEYシークレットBase64-encoded PKCS#8 private signing key. Required when FHIR_AUTH=smart.FHIR_JWKS_URLExternally reachable JWKS URL for the signing key. Recommended for SMART authentication over stdio.FHIR_VERSIONFHIR release used for FHIRPath and response shaping.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
28掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | はい | FHIR Bundle のリンク link[rel=next].url 値から取得したページネーション URL |
| fhirpath | string | いいえ | FHIR 応答に対してローカルで評価される FHIRPath 式 — _elements または _summary が利用できない、または不十分な場合に、クライアント側の射影に使用します |
| responseMode | enum | いいえ | 応答形式:compact または fullcompact | full |
| maxResults | number | いいえ | compact 結果の目標件数 — このしきい値に達すると、サーバーは追加ページの取得を停止します |
| prefetch | boolean | いいえ | false に設定すると、サーバー側のページ統合が無効になります |
詳細
fhirHydrant:FHIR MCP サーバー
R4 以降の FHIR API 向けに、最新の完全に設定可能なオープンソースの Node.js Model Context Protocol(MCP)サーバーです。署名済み JWT クライアント認証情報を使用する SMART on FHIR v2 Backend Services を介して、MCP 対応の LLM AI クライアントを臨床データに接続します。
fhirHydrant は、FHIR リソース、名前付き操作、用語検索、ページネーションを MCP ツールに変換します。デフォルトのリソースと操作は出発点です。リソース、操作、検索コントロール、指示、メッセージは、ソースを変更せずに設定ファイルで拡張、縮小、置き換えできます。
- JWKS ホスティング、鍵のローテーション、トークンの更新、動的スコープに対応する SMART Backend Services 認証
- 検索、直接読み取り、vread、履歴、および任意のメタデータ制御付き CRUD に対応する設定可能なリソースツール
- 臨床データ、用語、IPS、患者照合、検証、カスタムワークフロー向けの設定ファイル駆動の名前付き操作
- CapabilityStatement に対応したツール、検索コントロール、操作のゲート制御、実行時のスコープチェック
- トークン効率化機能:コンパクトな応答、FHIRPath フィルタリング、バイト数制限、
_countによる調整、サイズ超過時の Bundle 再試行 - 任意の用語ツール、PHI を最小限に抑えた監査イベント(デフォルトではリソースの内容を含みません)、stdio または Streamable HTTP トランスポート
注記: MCP ツール呼び出しで返される FHIR データには PHI が含まれる場合があります。 MCP クライアントの会話履歴の保存方法とログの動作が、コンプライアンス要件に適合していることを確認してください。
目次
- クイックスタート
- ツール
- メタデータとスコープのゲート制御
- トークン効率化と応答の調整
- 監査イベント
- SMART Backend 認証と鍵
- 環境変数
- FHIR バージョンのサポート
- ツールとメッセージのカスタマイズ
- トランスポート
- デプロイ例
- 開発
クイックスタート
要件
- Node.js >= 24
- サポート対象の FHIR サーバー
- SMART 認証(デフォルト)の場合:SMART Backend Services クライアント登録、および公開鍵を JWKS 経由で利用できる RSA-2048 または EC P-384 秘密鍵
認証なしの公開 FHIR テストサーバーに接続する場合は、FHIR_AUTH=none を設定し、クライアントと鍵は不要です(認証なしアクセスを参照)。
stdio トランスポートでは通常、外部でホストされた JWKS URL が必要です。組み込みの /jwks エンドポイントは、SMART 認証を使用して fhirHydrant を HTTP 経由で実行する場合にのみ利用できます。
インストール
# install globally
npm install -g fhirhydrant
# or run without installing
npx fhirhydrant
ソースから実行する場合:
git clone https://github.com/faulkj/fhirhydrant.git
cd fhirhydrant
npm install
npm run build
MCP クライアントの設定
デスクトップ MCP クライアントでは、通常、stdio が最もシンプルなトランスポートです。
{
"mcpServers": {
"fhirhydrant": {
"command": "npx",
"args": ["-y", "fhirhydrant"],
"env": {
"MCP_TRANSPORT": "stdio",
"FHIR_BASE_URL": "https://fhir.example.org",
"FHIR_CLIENT_ID": "your-client-id",
"FHIR_ACTIVE_KEY": "LS0tLS1CRUdJTi...base64-of-your-pem...",
"FHIR_JWKS_URL": "https://example.org/.well-known/jwks.json"
}
}
}
}
FHIR_ACTIVE_KEY は、base64 エンコードされた PKCS#8 秘密鍵(RSA または EC P-384)です。kid は起動時に、短縮した JWK サムプリントから自動的に導出され、コンソールに記録されます。
認証なしアクセス
fhirHydrant を認証なしの公開 FHIR エンドポイント(オープンサンドボックスでのテストに便利です)に接続するには、FHIR_AUTH=none を設定します。クライアント ID や署名鍵は不要で、トークンは要求されず、リクエストは Authorization ヘッダーなしで送信されます。
{
"mcpServers": {
"fhirhydrant": {
"command": "npx",
"args": ["-y", "fhirhydrant"],
"env": {
"MCP_TRANSPORT": "stdio",
"FHIR_AUTH": "none",
"FHIR_SERVER_URL": "https://hapi.fhir.org/baseR4"
}
}
}
}
ツール
fhirHydrant は、設定と実行時の機能チェックに基づいてツールを登録します。
正確な一覧は、config/resources/ フォルダー、付与された SMART スコープ、
/metadata、書き込み設定、操作設定、用語設定によって異なります。
| ツールまたはファミリー | 利用可能になる条件 | 目的 |
|---|---|---|
| リソースツール | リソースが設定され、メタデータ/スコープで許可されている | FHIR リソースの検索、直接読み取り、vread、履歴の取得、および必要に応じた CRUD |
system_history | サーバーがシステムレベルの history インタラクションを通知し、スコープで許可されている | すべてのリソースタイプにわたるシステムレベルの変更履歴を取得します |
capabilities | 常に登録されます | CapabilityStatement の概要、登録済みツール、スキップされたツール、検索パラメーター、操作、メタデータに関する注記を確認します |
paginate | 常に登録されます | サーバーから返された next URL を使用して、FHIR Bundle の次のページを取得します |
operate | 1 つ以上の名前付き操作がゲート条件を通過した場合 | 臨床データ、用語、IPS、照合、検証、またはカスタムワークフロー向けに、設定済みの FHIR 名前付き操作を実行します |
bundle | FHIR_BUNDLE_CAPABILITIES が設定されている | FHIR のバッチまたはトランザクション Bundle を送信します。書き込みには追加の明示的な許可が必要です |
terminology_lookup | FHIR_TERMINOLOGY_BASE_URL が設定されている | 1 つの LOINC または SNOMED CT コードを検索します |
code_search | FHIR_TERMINOLOGY_BASE_URL が設定されている | テキストで LOINC または SNOMED CT コードを検索します |
リソースツール
リソースツールは config/resources/
フォルダーから生成されます。リソースごとに JSON ファイル(例:patient.json)が 1 つあり、起動時にスキャンされます。
同梱の設定は、一般的な臨床、管理、投薬、医療従事者、組織、文書リソースを網羅しています。リソースを追加するにはファイルを追加し、削除するにはファイルを削除します。ソースの変更は不要です。
各リソースツールは、設定済みの検索パラメーター、_id を使った任意の直接読み取り、さらにコンパクトモードで固定されていない場合は responseMode に対応しています。
直接読み取りは、空でない引数が _id のみの場合に限って行われます。_id と他のパラメーターが指定された場合は検索として処理され、呼び出し元の意図が暗黙のうちに破棄されることはありません。
リソースツールは、デフォルトでは検索/読み取り専用です。メタデータで制御される CRUD 操作を有効にするには、FHIR_WRITE_CAPABILITIES を設定します。
FHIR_WRITE_CAPABILITIES=create,update,patch,delete
| アクション | 必須パラメーター | FHIR 呼び出し |
|---|---|---|
vread | _id、_vid | GET /ResourceType/{id}/_history/{vid} |
history | _id(インスタンス)または指定なし(タイプ) | GET /ResourceType/{id}/_history または GET /ResourceType/_history |
create | body | POST /ResourceType |
update | _id、body | PUT /ResourceType/{id} |
patch | _id、body | JSON Patch を使用した PATCH /ResourceType/{id} |
delete | _id | DELETE /ResourceType/{id} |
vread は、リソースが supportsDirectRead に対応し、サーバーが vread インタラクションを通知している場合に利用できます。history は、サーバーが history-instance または history-type を通知している場合に利用できます。どちらも SMART の r 権限が必要です。任意の _since および _at パラメーターで履歴結果を絞り込めます。
履歴レスポンスは Bundle であり、コンパクトモード、FHIRPath、統合処理に対応しています。
書き込みボディは FHIR 呼び出しの前に検証されます。body.resourceType はツールのリソースと一致する必要があり、更新時に body.id が存在する場合は _id と一致する必要があります。また、patch には JSON Patch 配列が必要です。スコープは有効な機能に基づいて決定されます。読み取り/検索には system/Patient.rs、作成/読み取り/検索には system/Patient.crs、完全な書き込みサポートには system/Patient.cruds が使用されます。
SMART v2 には patch 専用の文字がないため、patch は u に対応します。
コアツール
capabilities は、キャッシュされた CapabilityStatement の概要、登録済みおよびスキップされたツール、検索パラメーター、操作、メタデータの注記を返します。
paginate は、FHIR オリジンおよび許可されたパスプレフィックスに照らして検証された、サーバー返却の next URL を使用して Bundle のページを取得します。コンパクトモードが有効で、取得したページに続きがある場合、paginate は複数の上流ページを自動的にまとめ、1つのコンパクトなレスポンスとして返します(リソース検索ツールと同じ動作です)。まとめ処理を無効にして1ページだけ取得するには、prefetch=false を指定します。
名前付き操作
operate ツールは、config/operations.json の FHIR 名前付き操作を実行します。提供されている操作カタログは、臨床データの集約、検証、ドキュメント検索、用語操作、IPS 生成、患者照合に対応しています。ソースを変更せずに、操作カタログを拡張、縮小、置換、または無効化できます。
用語ツール
有効にするには FHIR_TERMINOLOGY_BASE_URL を設定します。
| ツール | 説明 |
|---|---|
terminology_lookup | 1つの LOINC または SNOMED CT コードを検索します |
code_search | ページングに対応し、テキストフィルターでコードを検索します |
これらのツールは、設定された用語サーバーを直接呼び出します。臨床用 FHIR サーバーの認証情報は使用しません。選択した FHIR リリースに適合する用語エンドポイントを使用してください。たとえば、https://tx.fhir.org/r4 です。
Bundle の実行
bundle を有効にするには、FHIR_BUNDLE_CAPABILITIES=batch(または batch,transaction)を設定します。このツールは FHIR の batch または transaction Bundle を送信し、標準レスポンスパイプラインを通じてサーバーのレスポンスを返します。
安全モデル:
- 読み取り専用の batch Bundle(すべてのエントリーが GET)は、
FHIR_BUNDLE_CAPABILITIES=batchのみで実行できます。 - 書き込みエントリー(POST、PUT、PATCH、DELETE)には、さらに
FHIR_BUNDLE_WRITES_ENABLED=trueと、FHIR_WRITE_CAPABILITIESに対応するアクションが必要です。 - Transaction Bundle には、明示的に
FHIR_BUNDLE_CAPABILITIES=transactionを設定する必要があります。 - 各エントリーは、設定済みのリソース、SMART スコープ、メタデータのインタラクションに照らして事前検証されます。エントリーが1つでも失敗すると、送信前に Bundle 全体が拒否されます。
V1 での除外項目: 条件付きリクエスト、システムレベルの _history、絶対 URL、Bundle エントリー内の $operation URL はサポートされません。
Bundle 内の履歴: vread(Resource/id/_history/vid)、インスタンス履歴(Resource/id/_history)、型履歴(Resource/_history)のエントリーは、サーバーが対応するインタラクションを提示し、スコープが許可している場合、Bundle 内で使用できます。これらは読み取りエントリーとして扱われます。
メタデータとスコープによる制御
FHIR_METADATA_MODE=off を設定しない限り、fhirHydrant は起動時に FHIR サーバーの CapabilityStatement を取得します。strict モードでは、次のように動作します。
/metadataにリソースタイプが存在する場合にのみ、リソースツールが登録されます_count、_sort、_summary、_elements、_include、_revincludeなどのサーバー側検索制御は、提示されている場合にのみ公開されます- サーバーが提示していない検索パラメーターはブロックされます
- 書き込みアクションには、
FHIR_WRITE_CAPABILITIESと一致する CapabilityStatement のインタラクションの両方が必要です - 名前付き操作には、対象のリソースタイプが存在し、付与された SMART スコープがそのリソースを許可し、操作自体がリソースの CapabilityStatement エントリーに提示されている必要があります
warn モードでは、提示されていないパラメーターも警告付きで許可されますが、存在しないリソースタイプは引き続きスキップされます。SMART スコープも実行時に確認されるため、スキーマにツールが存在していても、付与されたトークンスコープによってブロックされる場合があります。
トークンの節約とレスポンスの整形
FHIR のレスポンスは、多くの場合、MCP クライアントが必要とする量を大幅に上回ります。fhirHydrant は取得後にレスポンスを整形し、FHIR サーバーが対応機能を提示している場合はサーバー側の制御を利用してトークンを節約します。
| 機能 | 動作 |
|---|---|
_count のデフォルト値/上限 | デフォルトでは _count を挿入しません(ページサイズはサーバーが決定します)。FHIR_DEFAULT_COUNT を設定すると値を挿入し、FHIR_MAX_COUNT を設定すると呼び出し側が明示した値に上限を設けます(0 = 上限なし) |
| ページの統合 | コンパクトモードが有効な場合、サーバーは複数の上流ページを順次取得し、それぞれをただちにコンパクト化して、統合した 1 つの Bundle を返します。maxResults、prefetch、および FHIR_PREFETCH_* 環境変数で制御します |
| バイト数の上限 | FHIR_MAX_RESPONSE_BYTES は、モデルに返すすべての JSON レスポンスのサイズを制限します。上限を超える Bundle は透過的に分割されます |
| 自動再試行 | サイズ超過した検索 Bundle は、まずローカルでの分割を試し、その後、フォールバックとして _count を小さくして再試行します |
| FHIRPath | fhirpath は返された FHIR JSON をローカルでフィルタリングし、一致したノードを配列として返します |
| コンパクトモード | responseMode=compact は、一般的な FHIR のエンベロープノイズを取り除き、データ型を簡略化します |
| フルモード | responseMode=full は、未加工の FHIR JSON を返します |
| コンパクトモードの固定 | FHIR_RESPONSE_MODE=compact-locked は、ツールスキーマから responseMode を非表示にします |
| ネイティブ成果物 | JSON 以外のレスポンス(ドキュメント、画像、DICOM、RTF、HTML、XML、CSV、NDJSON、ZIP、オクテットストリーム)と JSON FHIR Binary は、メタデータエンベロープと 1 つの MCP 埋め込みテキスト/blob リソースに正規化されます。FHIR_MAX_ARTIFACT_MB(JSON の上限とは別)で上限が設定され、分割されず、FHIRPath/コンパクト化/ページ統合も適用されません。JSON 専用の整形引数は無視され、その旨が注記されます |
コンパクト出力は AI 向けの JSON であり、正規の FHIR ではありません。meta、ナラティブ、拡張、CodeableConcept、Reference、Quantity、CodeableReference などの新しいデータ型といった FHIR のノイズや一般的なデータ型を削除または簡略化します。
FHIRPath はローカルで実行され、FHIR サーバーに式が送信されることはありません。評価に失敗した場合、未加工のレスポンスは返されず、エラーが返されます。
構造化レスポンスエンベロープ
すべての FHIR データツール(リソースツール、paginate、operate、bundle、system_history)は、各ツールの outputSchema で提示され、structuredContent として返される単一の構造化エンベロープを返します(テキストコンテンツも同じエンベロープをシリアル化したものです)。エンベロープには FHIR ペイロード(data)と、レスポンスモード、hasMore/continuation によるページネーションのシグナル、Bundle およびページ統合の統計情報、人が読める形式の notes などのメタデータが含まれます。フィールドの全一覧は各ツールの outputSchema に記載されています。
可能な場合、サイズ超過したレスポンスは分割されます(data は保持され、continuation から取得できます)。分割できない場合、エンベロープは status: "truncated" としてマークされ、data は省略されます。切り詰められたレスポンスは、一部のみの成功結果であり、エラーではありません。機能ツールと用語ツールは、この FHIR エンベロープとは異なる独自の構造を返します。
ページの統合
検索(リソースツールまたは paginate)でコンパクトモードが有効な場合、サーバーは複数の上流 FHIR ページを順次取得し、それぞれをただちにコンパクト化して、統合した 1 つのコンパクト Bundle を返します。これにより、複数回の「次のページ」呼び出しを 1 回に減らせます。
maxResultsは目標値を設定します。このしきい値を超えるとサーバーは取得を停止します(ページ全体が追加されるため、わずかに超える場合があります)prefetch=falseは、その呼び出しでのページ統合を無効にします_countは引き続き、上流の FHIR ページサイズを制御します- ページ数、エントリー数、バイト数、時間に設定可能な上限に達すると、ページ統合は停止します
continuation.urlはサーバーが停止した位置を示します。続行するには、responseMode=compactを指定してpaginateを呼び出してください(残りがある場合はhasMoreが示します)- FHIRPath でフィルタリングするリクエストは単一ページのままで、ページ統合されません
responseMode=fullは常に上流の単一ページを返します
監査イベント
FHIR_AUDIT_SINK に console、file、http の任意の組み合わせを設定します。
http シンクは、各監査イベントを外部のコレクター、SIEM、または FHIR 監査リポジトリ(FHIR サーバー自体ではありません)に POST します。送信先には FHIR_AUDIT_HTTP_URL を設定し、FHIR_AUDIT_HTTP_FORMAT には raw(汎用コレクター(Splunk HEC や Datadog など)向けの、内部の PHI を最小限に抑えた監査 JSON)または fhir-auditevent(ATNA 形式や FHIR ネイティブの監査リポジトリに適した、最小限の FHIR R4 AuditEvent リソース)のいずれかを設定します。fhir-auditevent へのマッピングは意図的に簡易化されており、ATNA/BALP の完全な準拠プロファイルではありません。任意の FHIR_AUDIT_HTTP_AUTH 値は、Authorization ヘッダーとしてそのまま送信されます。送信は応答を待たずに行われ、タイムアウトは 5 秒です。通信エラーはログに記録されますが、ツールの応答には影響しません。
監査イベントには、タイムスタンプ、ツール、該当する場合はリソースタイプ、操作、ステータス、所要時間、応答サイズ、ページネーションの概要、リクエスト ID、任意のプロキシ認証済みユーザーが含まれます。デフォルトでは FHIR リソースの内容は含まれません。
認証プロキシの背後で実行する場合は、FHIR_AUDIT_USER_HEADER に、そのプロキシが挿入する信頼できる ID ヘッダーを設定します。
一般的なヘッダー:Azure EasyAuth の X-MS-CLIENT-PRINCIPAL-NAME、OAuth2 Proxy の
X-Auth-Request-Email、Cloudflare Access の
Cf-Access-Authenticated-User-Email。
プロキシがそのヘッダーの受信時の値を削除または上書きする場合にのみ、この設定を使用してください。そうでない場合、クライアントが任意の監査ユーザーを偽装できます。
SMART Backend 認証とキー
fhirHydrant は SMART Backend Services を使用します。これは、クライアント認証情報と署名済み JWT アサーションを組み合わせた方式です。これはバックエンドからの FHIR アクセスであり、ブラウザーを使った SMART のスタンドアロン起動ではありません。MCP の経路には、対話型のリダイレクト/ログインフローはありません。
FHIR_ACTIVE_KEY には、未加工の PKCS#8 署名キー(RSA、RS384 で署名、または EC P-384、ES384 で署名)を指定します。HTTP モードで FHIR_JWKS_URL が未設定の場合、組み込みの /jwks エンドポイントは、アクティブキーに加えて、退役済みのキーがあればその公開鍵も公開します。各キーの kid は、RFC 7638 JWK Thumbprint の切り詰め値(公開 JWK の正規化されたメンバーの SHA-256 から得られる base64url 文字列の先頭 12 文字)によって自動的に導出され、起動時にログへ記録されます。
キーのローテーション手順:
- 新しいキー(RSA-2048 または EC P-384)を生成します。
- 新しい PEM を
FHIR_RETIRED_KEYSに追加し、JWKS に両方のキーが含まれるよう再デプロイします。 - 起動時にログへ記録された新しい kid を認証サーバーに登録します。
- 新しい PEM を
FHIR_ACTIVE_KEYに移し、古い PEM をFHIR_RETIRED_KEYSに移します。再デプロイします。 - 認証サーバーのキャッシュが期限切れになった後、古いキーを
FHIR_RETIRED_KEYSから削除します。
外部 JWKS を使用する場合は、FHIR_ACTIVE_KEY を切り替える前に新しい公開鍵を公開してください。
環境変数
完全なサンプルについては .env.example を参照してください。
必須
| 変数 | 説明 |
|---|---|
FHIR_BASE_URL | FHIR サーバー URL とトークン URL の導出に使用するベース URL。FHIR_SERVER_URL(および SMART 認証の場合は FHIR_TOKEN_URL)が設定されている場合は任意です |
FHIR_CLIENT_ID | SMART Backend Services のクライアント ID(FHIR_AUTH=none の場合は不要) |
FHIR_ACTIVE_KEY | Base64 エンコードされた PKCS#8 PEM 署名キー。RSA または EC P-384(FHIR_AUTH=none の場合は不要) |
任意
| 変数 | デフォルト | 説明 |
|---|---|---|
FHIR_AUTH | smart | smart(SMART Backend Services)または none(認証なし。公開テストエンドポイント向け) |
FHIR_RETIRED_KEYS | 未設定 | JWKS ローテーション用の、Base64 エンコードされた PEM のカンマ区切りリスト |
FHIR_VERSION | R4 | 有効な R4 以降の FHIR リリース。派生 URL、FHIRPath モデル、コンパクトモデルのメタデータを制御します |
FHIR_SERVER_URL | <base>/api/FHIR/<FHIR_VERSION> | 明示的に指定する FHIR API URL のオーバーライド |
FHIR_TOKEN_URL | <base>/oauth2/token | 明示的に指定するトークンエンドポイントのオーバーライド |
FHIR_JWKS_URL | 未設定 | 外部 JWKS URL。HTTP モードで省略すると、組み込みの /jwks が有効になります |
MCP_TRANSPORT | http | http または stdio |
PORT | 5000 | HTTP リスナーのポート |
BIND_HOST | 0.0.0.0(または --dev フラグ指定時は 127.0.0.1) | HTTP のバインドアドレス |
ALLOWED_HOSTS | 未設定 | DNS リバインディング保護用のホスト名のカンマ区切りリスト |
FHIR_METADATA_MODE | strict | /metadata 検証のモード。strict、warn、off |
FHIR_DEFAULT_COUNT | 0 | 許可されている場合に検索へ追加するデフォルトの _count。0 = サーバーに任せます |
FHIR_MAX_COUNT | 0 | 呼び出し元が明示的に指定した _count 値の上限。0 = 上限なし |
FHIR_MAX_RESPONSE_BYTES | 262144 | モデル向け JSON レスポンスのバイト数上限。サイズ超過した Bundle は分割されます |
FHIR_MAX_ARTIFACT_MB | 16 | ネイティブ/バイナリアーティファクトの本文に適用される、独立したバイト数上限(MiB)。JSON の上限とは別に適用されます(Base64 転送では約 +33%) |
FHIR_REQUEST_TIMEOUT_MS | 30000 | FHIR リクエストを送信する際の、試行ごとのタイムアウト |
MCP_JSON_LIMIT | 4mb | MCP リクエスト本文の最大許容サイズ(Express の JSON リミット文字列)。大きな書き込み/Bundle ペイロードが拒否される場合は引き上げてください |
MCP_AUTHZ | none | 認可プロバイダー:none または entra。呼び出し元ごとにツールへのアクセスを制御します(HTTP のみ。Authorization: Bearer が必要) |
MCP_ROLE_PREFIX | FhirHydrant | 付与されるロール値のプレフィックス(例:FhirHydrant.Patient.Read) |
MCP_ENTRA_TENANT_ID | 未設定 | Entra テナント GUID(ドメインエイリアスではありません)。MCP_AUTHZ=entra の場合に必須です |
MCP_ENTRA_AUDIENCE | 未設定 | v2 アクセストークンの aud に指定する API アプリケーション(クライアント)ID。MCP_AUTHZ=entra の場合に必須です |
FHIR_RESPONSE_MODE | 未設定 | compact、full、compact-locked。未設定の場合、検索のデフォルトはコンパクト、直接読み取りのデフォルトはフルです |
FHIR_WRITE_CAPABILITIES | 未設定 | 書き込みアクションのカンマ区切りリスト:create、update、patch、delete |
FHIR_VALIDATE_WRITES | local | off、local(クライアント側の構造チェック)、または server(ローカルチェックに加えて、create/update の前にサーバーの $validate で事前検証) |
FHIR_WRITE_DRY_RUN | false | true に設定すると、FHIR サーバーに書き込みを実行せずに検証し、ログに記録します |
FHIR_BUNDLE_CAPABILITIES | 未設定 | Bundle タイプのカンマ区切りリスト:batch、transaction。bundle ツールを有効にします |
FHIR_BUNDLE_WRITES_ENABLED | false | true に設定すると、Bundle 内の書き込みエントリを許可します(FHIR_WRITE_CAPABILITIES も必要です) |
FHIR_OPERATIONS | 未設定 | 操作キーのカンマ区切りリスト。none を指定すると、カタログのすべての操作が無効になります。デフォルトのカタログ:everything、lastn、validate、docref、expand、lookup、translate、summary、match |
FHIR_TERMINOLOGY_BASE_URL | 未設定 | 用語ツールを有効にします(例:https://tx.fhir.org/r4) |
FHIR_PAGINATION_PATHS | 未設定 | ページネーションリンクで許可する追加のパスプレフィックス(例:FHIRProxy) |
FHIR_PREFETCH_MAX_PAGES | 5 | 統合されたコンパクト検索で先行取得する、上流ページの最大数 |
FHIR_PREFETCH_MAX_ENTRIES | 5000 | 停止するまでに蓄積する上流エントリの最大数 |
FHIR_PREFETCH_MAX_BYTES | 2097152 | 停止するまでに取得する生データの最大バイト数 |
FHIR_PREFETCH_TIMEOUT_MS | 25000 | 統合ループに割り当てる実行時間 |
FHIR_AUDIT_SINK | 未設定 | console、file、http の任意の組み合わせ |
FHIR_AUDIT_FILE | ./audit.jsonl | file 監査シンクが有効な場合に使用する JSONL ファイル |
FHIR_AUDIT_HTTP_URL | 未設定 | http 監査シンクの送信先 URL。http が有効な場合に必須です |
FHIR_AUDIT_HTTP_FORMAT | raw | raw(内部 AuditEvent JSON)または fhir-auditevent(FHIR R4 AuditEvent) |
FHIR_AUDIT_HTTP_AUTH | 未設定 | http シンクがそのまま送信する Authorization ヘッダー値 |
FHIR_AUDIT_USER_HEADER | 未設定 | プロキシで認証されたユーザーヘッダー。監査イベントにコピーされます |
LOG_LEVEL | info | ログの詳細度:error、warn、info、debug |
明示的な FHIR_SERVER_URL と FHIR_TOKEN_URL の値は、導出された URL より常に優先されます。 |
FHIR バージョンのサポート
FHIR_VERSION を設定して、有効にする R4 以降の FHIR リリースを選択します。この設定は、導出される FHIR API URL、FHIRPath モデルコンテキスト、および簡潔なレスポンスモデルのメタデータを制御します。一部のリリースでは、最も近い互換性のある FHIRPath モデルが使用される場合があります。用語サービスには、選択した FHIR リリースに一致するエンドポイントを使用してください。明示的に設定された FHIR または用語サービスの URL が別のバージョンを参照しているように見える場合は、起動ログにヒントが表示されます。
ツールとメッセージのカスタマイズ
config/ 以下はすべて、ソースを変更せずにカスタマイズできます。
設定は部分的なオーバーレイとして解決されます。各ファイルについて、カレントディレクトリにある ./config/<file>(存在する場合)がパッケージに含まれるデフォルトを上書きし、指定しなかった項目は組み込みのデフォルトにフォールバックします。そのため、npm インストールはすぐに使用でき、カスタマイズするには、変更したいファイルだけを含む ./config フォルダーをサーバーの起動場所と同じ場所に配置します。
オーバーレイには 2 つの適用単位があります。
- ファイル単位(
resources/*.json、operations.json、search-controls.json、core-tools.json、instructions/*):用意したファイルは、パッケージに含まれるファイル全体を置き換えます。新しいリソースファイル(例:./config/resources/myresource.json)を追加すると、ツールが追加されます。オーバーレイでは上書きと追加ができますが、パッケージに含まれるリソースを削除することはできません。厳密に最小限のカタログを配布するには、パッケージに含まれるconfig/resources/ファイルを削除してください(compose の例を参照)。 - キー単位(
messages/*.json):ローカルファイルは、含まれる個々のキーのみを上書きします。それ以外のすべてのキーは、パッケージに含まれるデフォルトにフォールバックします。そのため、ファイル全体をコピーせずに、単一の説明やメッセージを調整できます。不明なキー、空の値、不正な JSON がある場合は、誤記を検出できるよう、起動時に即座にエラーになります。
messages/*.json ファイルはプロセス起動時に一度だけ読み込まれます。変更を反映するには、サーバーを再起動する必要があります(また、ツールのスキーマや説明の場合は、クライアントの再接続も必要です)。リソース、検索コントロール、オペレーションの開発時のホットリロードについては、以下で説明します。
| ファイル | 用途 |
|---|---|
resources/*.json | FHIR リソースのツール(リソースごとに 1 ファイル):検索パラメーター、直接読み取りの動作、requireOneOf のルール |
operations.json | operate 用の名前付きオペレーションカタログ(オペレーションごとの説明と注記) |
search-controls.json | _count、_sort、_summary、_elements、_include、_revinclude、_lastUpdated、fhirpath、responseMode、maxResults、prefetch の説明 |
messages/output-schema.json | すべてのツールの outputSchema フィールドの説明(キー単位のオーバーレイ) |
messages/input-schema.json | 生成されるリソース入力パラメーター(_id、_vid、_since、_at、action、body)と、operate ツールのタイトルおよびパラメーターの説明(キー単位のオーバーレイ) |
instructions/manifest.json | 組み合わせる説明フラグメントの順序付きリスト。それぞれに任意で when ゲート(terminology、writes、operations、bundle)を指定できます。このファイルを編集することで、カスタムビルドのセクションを並べ替えたり、追加または削除したりできます。 |
instructions/*.md | マニフェストが参照する説明フラグメント。ゲート付きセクションは、対応する機能が有効な場合にのみ含まれます。{{OPERATIONS_LIST}} トークンは、最新のオペレーションカタログに置き換えられます。 |
messages/*.json | ユーザー向けのメッセージ、エラー、レスポンスの注記(キー単位のオーバーレイ。core、write、operations、terminology、bundle、artifact の各ドメインに分割) |
core-tools.json | 組み込みツールの説明とパラメーターのヒント |
リソース定義スキーマ
config/resources/ 内の各ファイルには、単一のリソース定義オブジェクトが含まれます。ファイルはファイル名の順に読み込まれます。ファイル名には慣例として、小文字のリソース名を使用します(例:patient.json)。各オブジェクトには次のフィールドがあります。
| フィールド | 型 | 説明 |
|---|---|---|
resource | string | FHIR リソースタイプ |
toolName | string | MCP ツール名。一意である必要があります |
description | string | ツールの説明 |
supportsDirectRead | boolean | _id による GET /ResourceType/{id} を有効にします |
searchParams | Record<string,string> | FHIR 検索パラメーターとその説明 |
requireOneOf | (string | string[])[] | 検索には少なくとも1つの選択肢が必要です。文字列は単一の必須パラメーターを表します。ネストされた配列は、すべてのパラメーターが必須となるパラメーターセットを表します。["patient"] は patient を受け付け、[["given","family"],["identifier"]] は given と family の組み合わせ、または identifier を受け付けます |
searchParams の値は説明であり、完全な FHIR 機能モデルではありません。サーバー固有の検索動作が適用される場合があります。
ホットリロード
開発環境(NODE_ENV が production ではない場合)では、config/resources/ フォルダー、search-controls.json、operations.json が監視されます。無効な JSON がある場合は、最後に有効だったスナップショットが維持されます。実質的な変更を伴う再読み込みは、トランザクションとして適用されます。導出された SMART スコープが変わる場合、新しい定義とツール登録を確定する前に新しいトークンを取得するため、取得に失敗しても実行中のカタログは変更されません。ツールの追加・削除や、操作スキーマおよびパラメーター名スキーマの変更は再起動なしで即時に再登録されます。意味的に変更のない保存では更新は行われません。本番環境では起動時に一度だけ設定を読み込みますが、実行時の /metadata の変更(capabilities(refresh=true) によるもの)や、トークン更新時のバックエンドの SMART スコープの変更があれば、どのモードでも利用可能なツールが再評価されます。
避けられない制約が1つあります。ツール一覧とスキーマはホットリロードされますが、サーバーの instructions は MCP の initialize 時に一度だけ送信され、既存の接続では置き換えられません。変更された指示テキストを受け取るには、クライアントが再接続して再初期化する必要があります。
トランスポート
Stdio
MCP_TRANSPORT=stdio を設定します。標準出力は MCP プロトコル専用です。ログは標準エラー出力にリダイレクトされます。stdio のデプロイでは、外部の FHIR_JWKS_URL を使用してください。
Streamable HTTP
HTTP トランスポートはステートレスで、次の場所に MCP を公開します。
POST http://localhost:5000/mcp
Accept: application/json, text/event-stream
Content-Type: application/json
MCP クライアントの設定:
{
"mcpServers": {
"fhirhydrant": {
"url": "http://localhost:5000/mcp"
}
}
}
GET /health は、PHI を含まない準備状況のスナップショットを返します。
{
"status": "ok",
"mcp": true,
"metadata": true,
"tools": 23,
"auth": true,
"tokenExpiresIn": 287
}
認可が有効な場合、authz はアクティブなプロバイダーを示します。また、登録されたツール数は呼び出し元によって異なるため、tools は省略されます。
HTTP を localhost の外部に公開する場合は、TLS とユーザー認証にリバースプロキシを使用してください。パブリックインターフェイスにバインドする場合は、ALLOWED_HOSTS を設定してください。
呼び出し元ごとの認可(Entra、任意)
デフォルト(MCP_AUTHZ=none)では、すべての呼び出し元が/metadataとバックエンドのSMARTスコープによってのみ制限されるすべてのツールを利用できます。MCP_AUTHZ=entraを設定すると、呼び出し元ごとの認可レイヤーを任意で追加できます。各/mcpリクエストには、Microsoft Entraが発行したAuthorization: Bearer <token>を含める必要があり、呼び出し元のアプリロールによって、そのリクエストで利用できるツールが決まります。これはMCPレイヤーでの認可に限られ、FHIRサーバー自体の認可に置き換わることはありません。また、バックエンドのSMARTトークンと設定ですでに許可されている範囲を狭めることしかできません。
APIアプリの登録では、マニフェストのrequestedAccessTokenVersionを2に設定する必要があります。プロバイダーはテナント固有のv2発行者を検証し、MCP_ENTRA_AUDIENCEにはAPIアプリのクライアントIDを指定する必要があります。
呼び出し元が必要なロールを持たないツールは、登録自体が行われません。tools/listに表示されず、単にブロックされるわけではありません。ヘルパーツール(capabilities、paginate、terminology_lookup、code_search)は認可の対象外です。
アプリロールの値(デフォルトのFhirHydrantプレフィックスの場合):
| ロール | 許可される操作 |
|---|---|
FhirHydrant.<Resource>.Read | 対象リソースの検索、読み取り、vread、履歴 |
FhirHydrant.<Resource>.Write | 読み取り操作に加え、作成、更新、パッチ、削除(FHIR_WRITE_CAPABILITIESの設定に従う) |
FhirHydrant.Operation.<key> | operateツールによる、指定されたオペレーション(例:FhirHydrant.Operation.everything) |
FhirHydrant.Bundle | bundleツール |
FhirHydrant.SystemHistory.Read | システム全体のsystem_historyツール |
FhirHydrant.Admin | 上記すべて。ただし、バックエンドのSMARTスコープ、/metadata、書き込み/バンドル/オペレーションの設定による制限は引き続き適用されます |
HTTPトランスポートが必要です。MCP_AUTHZ=entraとMCP_TRANSPORT=stdioを併用すると、起動時に失敗します。Bearerトークンがない場合、または無効な場合は401が返されます。
認可プロバイダーの追加
同梱されているプロバイダーはEntraのみですが、認可レイヤーは特定のプロバイダーに依存しない設計です。これはソースコードの拡張であり、実行時プラグインではありません。npmパッケージにはbin/server.jsのみが含まれ(プロバイダーはバンドル済み)、プロバイダーを追加するにはリポジトリをフォークまたはクローンして再ビルドする必要があります。
共有パイプラインはプロバイダーに依存しません。プロバイダーが行うのは、Authorizationヘッダーを{ subject, roles }に変換することだけです。ロールの語彙(.Read/.Write/Operation.<key>/Bundle/SystemHistory.Read/Admin)とMCP_ROLE_PREFIXの処理は、すべてのプロバイダーについてdecideAuthzが適用します。
プロバイダー(例:auth0)の追加に必要な変更は2つだけです。
ts/mcp/authz/auth0.tsを作成し、AuthzProviderをエクスポートします。validate(authorization)を実装して{ subject, roles }を返すようにします(拒否する場合は例外をスローします)。必要に応じて、プロバイダー環境変数の不足を即座に検出するvalidateConfig()も実装します。プロバイダー固有の環境変数はすべてこのモジュール内に保持し、Configにフィールドを追加しないでください。ts/mcp/authz/registry.tsに次のエントリーを1つ追加します。auth0: () => import("./auth0.ts").then((m) => m.auth0Provider)。
これだけです。AuthzMode型、MCP_AUTHZパーサー、およびエラーメッセージはすべてレジストリのキーから自動的に導出されるため、完全な型安全性を保ったままMCP_AUTHZ=auth0を使用できます。他のファイルを変更する必要はありません。
デプロイ例
examples/ディレクトリには、Docker Compose、リバースプロキシ(Caddy)、Azure Container Apps、Azure App Service、Kubernetes向けの単独で動作するデプロイ例があります。それぞれに、npmからインストールするDockerfileと、さまざまな設定ファイルを上書きする方法を示すconfig/オーバーレイが含まれています。
開発
# dev server
npm run dev
# type-check
npm run check
# build and run
npm run build
npm start
ビルドの出力先はbin/server.jsです。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。