Skip to main content
Glama
clinical-mcp

clinical-mcp

by sarathi-aiml

clinical-mcp

臨床ワークフローのためのMCPサーバー:合成FHIR R4患者記録の検索と要約、PubMedからの文献取得、フリーテキストの匿名化を、Claude(または任意のMCPクライアント)からすべて行えます。

リファレンス品質のMCPサーバーとして構築されています:完全な仕様面(ツール、リソース、プロンプト — ほとんどの公開サーバーはツールのみ)を実装し、ワイヤープロトコルを検証するテストスイートを同梱し、stdioまたは認証付きストリーミングHTTPで動作します。

すべての患者データは合成データであり、Syntheaによって生成されています。このプロジェクトには実際のPHIは一切存在しません。

Architecture

[Claude / MCP client]
        |  stdio  or  streamable-http (+ bearer auth)
        v
[clinical-mcp  (MCPServer)]
   |-- tools ------ search_patients, get_patient_summary, get_observations,
   |                search_pubmed, get_pubmed_abstract, deidentify_text
   |-- resources -- fhir://patients            (roster)
   |                fhir://patients/{id}       (full record, URI template)
   |-- prompts ---- clinical_summary, literature_review
   |
   +-- FhirStore ----------- in-memory index over Synthea FHIR R4 bundles
   +-- PubMedClient -------- NCBI E-utilities, rate-limited (3/s, 10/s w/ key)
   +-- deidentify() -------- HIPAA Safe Harbor regex redaction

Quick start

pip install clinical-mcp

Claude Desktop / Claude Codeの設定(mcpServersエントリ):

{
  "clinical": {
    "command": "clinical-mcp",
    "env": { "CLINICAL_MCP_DATA_DIR": "/path/to/fhir/bundles" }
  }
}

ソースから:

git clone https://github.com/sarathi-aiml/clinical-mcp
cd clinical-mcp
pip install -e ".[dev]"
clinical-mcp                       # stdio, serves the bundled 10-patient sample
pytest                             # 33 tests, no network needed

次に、Claudeに次のような質問をします:

"50歳以上の高血圧の女性患者を検索し、最初の患者を要約し、彼女の薬剤リストに関連する最新のPubMed論文を3件取得してください。"

Tools

Tool

What it does

search_patients

名前、性別、年齢範囲、または診断された状態で名簿をフィルタリング

get_patient_summary

人口統計 + 状態、薬剤、アレルギー、予防接種

get_observations

検査とバイタル、FHIRカテゴリ、名前、日付でフィルタリング可能

search_pubmed

NCBI E-utilitiesによるPubMed検索([MeSH]などのフィールドタグをサポート)

get_pubmed_abstract

PMIDの完全な要約、セクションラベルを保持

deidentify_text

セーフハーバー匿名化:名前、日付、SSN/MRN、電話、メール、郵便番号、89歳以上の年齢

リソースは同じデータをアドレス可能な形で公開します(fhir://patients/{id})。これにより、クライアントはツールの往復なしに完全な患者記録をコンテキストとして添付できます。プロンプトは、私が最もよく使う2つのワークフロー(チャート要約と患者に基づく文献レビュー)を再利用可能なテンプレートとしてエンコードします。

HTTP transport with auth

CLINICAL_MCP_API_KEY=$(openssl rand -hex 32) clinical-mcp --transport http --port 8000

すべてのリクエストはAuthorization: Bearer <key>を保持する必要があります。サーバーはHTTPで認証なしの起動を拒否します。stdio(デフォルト)はキーを必要としません — トランスポートが信頼境界です。

Data

リポジトリにはdata/sample/の下に10件のトリミングされた合成患者が含まれています。より大きなコーパスが必要な場合:

python scripts/fetch_data.py --out data/full            # ~1,100 patients
CLINICAL_MCP_DATA_DIR=data/full clinical-mcp

--trimは、サーバーが実際に読み取るリソースタイプ(Patient、Condition、MedicationRequest、Observation、AllergyIntolerance、Encounter、Immunization、Procedure、DiagnosticReport、CarePlan)にバンドルを絞り込み、高ボリュームのタイプに上限を設定します。

De-identification: scope and limits

deidentify_textは正規表現ベースのセーフハーバースクリーニングです。構造化された臨床テキストに現れる識別子形式を捕捉し、さらにストアに読み込まれたすべての患者名を匿名化します。これは認定された匿名化パイプラインではありません — 敬称のないフリーテキストの名前、スペルミス、まれなコンテキストの識別子はすり抜けます。実際のPHIには、訓練されたNERパス(例:Philter、または人間によるレビューを伴うLLMパス)を上に重ねる必要があります。このツールは決定的な最初のフィルターであり、カテゴリごとのカウントにより監査が容易になります。

What breaks at 500K documents a week

このサーバーは意図的にその役割に合わせてサイズ設定されています — 合成コーパス上のリファレンス実装です。本番負荷で最初に失敗する点と、それぞれのアップグレードパスは次のとおりです:

  1. インメモリストア。 起動時にすべてがRAMに読み込まれます。約1万人の患者は快適ですが、約10万人は快適ではなく、起動時間は線形に増加します。最初の修正:同じFhirStoreインターフェースの背後に、名前、生年月日、状態コードのインデックスを持つSQLite/DuckDB。本当の修正:ストアを実際のFHIRエンドポイント(HAPI、またはクラウドFHIR API)に向け、ツールをFHIR検索パラメータの薄い変換レイヤーにします。

  2. バンドルごとに1人の患者。 ローダーはSyntheaのレイアウトを前提としています。混合バンドルでは、ファイルレベルのグループ化ではなく、参照解決(subject.reference)が必要です。

  3. PubMedのレート制限。 3リクエスト/秒(キー付きで10)は対話的には問題ありませんが、バッチでは役に立ちません。大量処理では、クエリハッシュをキーにしたTTL付きのローカルキャッシュと、記事ごとの呼び出しではなくバッチefetch(リクエストあたり最大200 PMID)が必要です。

  4. 正規表現による匿名化の再現率。 週50万ドキュメントでは、再現率99%でも数千の識別子が漏れます。カウント出力はまさにこの測定のために設計されています:サンプリング、監査、測定された再現率でゲートをかけ、その後パイプラインにNERモデルを配置します。

  5. シングルプロセスHTTP。 1つのプロセスでuvicornの下のストリーミングHTTPは、チームには対応できますが、フリートには対応できません。水平スケーリングには、ロードバランサーの背後にあるステートレスセッション(ストアは読み取り専用なので、これはほぼ無料です)と、ゲートウェイでのクライアントごとのレート制限が必要です。

Development

pip install -e ".[dev]"
pytest              # protocol-level + unit tests, PubMed mocked
ruff check .

Docker:

docker build -t clinical-mcp .
docker run --rm -i clinical-mcp                                   # stdio
docker run --rm -p 8000:8000 -e CLINICAL_MCP_API_KEY=secret \
  clinical-mcp --transport http --host 0.0.0.0

License

MIT

Related MCP Connectors