tebra について
tebra-mcp-serverは、Tebraの診療管理アカウントをMCP対応AIエージェントに接続し、SOAPによる業務操作と任意のFHIR臨床データを提供します。Tebraを利用する医療機関向けで、有効なAPI認証情報が必要です。臨床データには保護対象の医療情報が含まれる場合があります。
主な機能
- 01患者記録と予約の管理
- 02診療記録、請求、支払いの処理
- 03保険情報と認可情報へのアクセス
- 04患者文書のアップロードと削除
- 05設定時のFHIR臨床データ参照
- 06接続確認とAPIスロットルの参照
活用シーン
- 01医療機関の業務で患者記録を検索
- 02予約の作成または変更
- 03診療記録を作成し請求ステータスを進行
- 04FHIRを有効にして患者の薬剤や検査結果を確認
MCP 対応
TebraのSOAP操作と、別途設定した場合のFHIR R4臨床データツールをMCPクライアントに公開します。Tebraの認証情報が必要で、FHIRツールには追加のFHIR認証情報が必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y tebra-mcp-serverTEBRA_SOAP_USERTebra SOAP API usernameTEBRA_SOAP_PASSWORDシークレットTebra SOAP API passwordTEBRA_CUSTOMER_KEYシークレットTebra customer key (per-practice identifier)ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
33掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| mrn | string | いいえ | 医療記録番号 |
| query | string | いいえ | フルネームで検索(後方互換性のための fullName の別名) |
| gender | enum | いいえ | 性別でフィルタリングMale | Female | Other | Unknown |
| fullName | string | いいえ | フルネームで検索 |
| isActive | boolean | いいえ | 有効/無効のステータスで絞り込みます |
| lastName | string | いいえ | 姓で絞り込みます |
| firstName | string | いいえ | 名で絞り込みます |
| externalId | string | いいえ | 外部システム ID |
| dateOfBirth | string | いいえ | 正確な生年月日(YYYY-MM-DD) |
| practiceName | string | いいえ | 診療所名のフィルター |
| toCreatedDate | string | いいえ | 作成日の範囲の終了(YYYY-MM-DD) |
| toDateOfBirth | string | いいえ | 生年月日の範囲の終了(YYYY-MM-DD) |
| fromCreatedDate | string | いいえ | 作成日の範囲の開始(YYYY-MM-DD) |
| fromDateOfBirth | string | いいえ | 生年月日の範囲の開始(YYYY-MM-DD) |
| toLastModifiedDate | string | いいえ | 更新日の範囲の終了(YYYY-MM-DD) |
| fromLastModifiedDate | string | いいえ | 更新日の範囲の開始(YYYY-MM-DD) |
| insuranceCompanyName | string | いいえ | 保険会社名のフィルター |
| referringProviderName | string | いいえ | 紹介医名のフィルター |
詳細
tebra-mcp-server
Tebra(旧 Kareo)の診療所管理向け MCP サーバーです。既存の Tebra アカウントを Claude やその他の MCP 対応 AI エージェントに接続し、患者、診療、予約、請求、文書、保険、臨床データを扱う 34 個の SOAP ツールと 13 個の FHIR 臨床ツールを公開します。すべてのリクエストボディは、稼働中の Tebra WSDL コントラクトから生成されます(メンバー名とシーケンス順は KareoServices.svc?xsd=xsd0/xsd7 と照合済み)。また、ワイヤーフォーマットを固定する回帰テストスイートも備えています。有効な Tebra API 認証情報がなければ、データには一切アクセスできません。
これは独立したオープンソースプロジェクトです。Tebra Technologies, Inc. とは提携、推奨、支援関係にありません。「Tebra」と「Kareo」は各所有者の商標であり、ここではこのサーバーが接続する API を特定する目的でのみ使用しています。ツールの結果には保護対象の医療情報が含まれます。これを Claude に送信するには、Anthropic が業務委託契約(BAA)を締結している Claude プランが必要です。一般向け Claude プランは対象外です。また、対象プランであることの確認は、サーバーを運用する診療所の責任です。
ホスティング版を利用できます
認証情報、ホスティング、更新を自分で管理したくない場合は、DOCK をご利用ください。これは本サーバーのマネージド版で、診療所ごとの認証情報の暗号化、監査ログ、下書きを優先する書き込みアクション、ワークフローライブラリを備えています。創設診療所は、永久に適用される料金を確保できます。フロントデスクは月額 49 ドル(Zenoti)、請求デスクは月額 99 ドル(Tebra。DOCK は Anthropic とは別に、診療所と独自の BAA を締結します)、診療所全体は月額 129 ドル(両方)です。https://dockhq.vercel.app
クイックスタート
npx tebra-mcp-server
前提条件
- Node.js 18+
- Tebra SOAP API 認証情報(Tebra PM 管理画面の Settings > API で生成)
- (任意)臨床データへのアクセスに使用する Tebra FHIR API 認証情報
環境変数
SOAP API(必須)
| 変数 | 必須 | 説明 |
|---|---|---|
TEBRA_SOAP_USER | はい | SOAP API ユーザー(メールアドレス) |
TEBRA_SOAP_PASSWORD | はい | SOAP API パスワード |
TEBRA_CUSTOMER_KEY | はい | Tebra PM 管理画面の顧客キー |
TEBRA_SOAP_ENDPOINT | いいえ | SOAP エンドポイントの上書き(テスト用) |
FHIR API(任意 — 臨床データツールを13個有効にします)
| 変数 | 必須 | 説明 |
|---|---|---|
TEBRA_FHIR_CLIENT_ID | FHIR の場合 | Tebra appSphere の登録で取得した OAuth2 クライアント ID |
TEBRA_FHIR_PRIVATE_KEY_PATH | FHIR の場合(JWKS 登録) | SMART Backend Services private_key_jwt 用の PEM(PKCS#8)秘密鍵のパスです。公開鍵部分は Tebra に登録した JWKS です。シークレットより優先されます |
TEBRA_FHIR_KID | 鍵のパスを指定する場合 | 公開済み JWKS にある公開鍵の kid です(鍵のパスを設定する場合は必須です) |
TEBRA_FHIR_CLIENT_SECRET | FHIR の場合(シークレット登録) | OAuth2 クライアントシークレット — 鍵のパスが設定されていない場合にのみ使用されるフォールバックです |
TEBRA_FHIR_BASE_URL | いいえ | FHIR R4 ベース URL(デフォルトは https://fhir.prd.cloud.tebra.com/fhir-request) |
TEBRA_FHIR_TOKEN_URL | いいえ | OAuth2 トークンエンドポイント(デフォルトは Tebra 本番環境) |
TEBRA_FHIR_SCOPE | いいえ | OAuth2 スコープ(デフォルトは system/*.read です。appSphere の登録内容に合わせてください) |
FHIR 認証情報は Tebra appSphere を通じて取得します。サーバーは OAuth2 クライアントクレデンシャルフローを使用し、トークンを自動的にキャッシュして有効期限の60秒前に更新し、401 の場合は1回だけ再試行します。クライアント認証方式として、SMART Backend Services private_key_jwt(appSphere Backend App を「Confidential (URL for JWKS)」として登録します。サーバーは iss と sub にクライアント ID、aud にトークン URL、5分間の exp、一意の jti を設定した RS384 クライアントアサーションに署名し、client_assertion として client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer とともに送信します。秘密鍵はディスクから一度だけ読み込まれ、送信されることはありません)と、従来の client_secret フローをサポートしています。前者には鍵のパスを、後者にはシークレットを設定してください。注:トークンが発行される前に、診療所とバックエンドサービスのクライアントの両方を Tebra Customer Care に有効化してもらう必要があります。401 は「認証情報が正しくない」ではなく「まだ有効化されていない」ことを示している場合があります。
インストール
Claude Code
プロジェクトルートの .mcp.json に追加します。
{
"mcpServers": {
"tebra": {
"command": "npx",
"args": ["-y", "tebra-mcp-server"],
"env": {
"TEBRA_SOAP_USER": "[email protected]",
"TEBRA_SOAP_PASSWORD": "your-password",
"TEBRA_CUSTOMER_KEY": "your-customer-key",
"TEBRA_FHIR_CLIENT_ID": "optional-fhir-client-id",
"TEBRA_FHIR_CLIENT_SECRET": "optional-fhir-client-secret"
}
}
}
}
Claude Desktop
claude_desktop_config.json に追加します。
{
"mcpServers": {
"tebra": {
"command": "npx",
"args": ["-y", "tebra-mcp-server"],
"env": {
"TEBRA_SOAP_USER": "[email protected]",
"TEBRA_SOAP_PASSWORD": "your-password",
"TEBRA_CUSTOMER_KEY": "your-customer-key"
}
}
}
}
Cursor / VS Code
MCP 設定に追加します。
{
"mcpServers": {
"tebra": {
"command": "npx",
"args": ["-y", "tebra-mcp-server"],
"env": {
"TEBRA_SOAP_USER": "[email protected]",
"TEBRA_SOAP_PASSWORD": "your-password",
"TEBRA_CUSTOMER_KEY": "your-customer-key"
}
}
}
}
利用可能なツール(合計47個)
患者管理
| ツール | 説明 |
|---|---|
tebra_search_patients | 名前、生年月日の範囲、保険、診療所などで患者を検索します(サーバー側のフィルター16種類) |
tebra_get_patient | ケース、保険契約、承認情報を含む患者の完全な記録を取得します(Tebra ID または外部 ID を指定) |
tebra_create_patient | 基本情報、保険、保証人を登録して新しい患者を登録します |
tebra_update_patient | 患者の基本情報と連絡先を更新します |
tebra_get_all_patients | ページネーションを使用して患者を一括取得します(同期処理用) |
予約
| ツール | 説明 |
|---|---|
tebra_get_appointments | 日付範囲、リソース(医療提供者)、患者、ステータス、場所で予約を検索します |
tebra_get_appointment_detail | 繰り返し情報、グループデータ、リソースを含む予約の詳細を取得します |
tebra_create_appointment | 予約を作成します(医療提供者、場所、開始時刻と所要時間または終了時刻) |
tebra_update_appointment | 既存の予約を更新または再予約します |
tebra_update_appointment_status | ステータスのみを変更します(Confirmed、CheckedIn、NoShow、Cancelled、...) |
tebra_delete_appointment | 予約を完全に削除します |
tebra_get_appointment_reasons | 診療所で設定されている予約の種類や理由を一覧表示します |
tebra_create_appointment_reason | 新しい予約の種類や理由を作成します |
診療と請求
| ツール | 説明 |
|---|---|
tebra_get_encounter | ステータス、プロバイダー、サービス明細 ID を含む診療の詳細を取得します |
tebra_create_encounter | 明細ごとの診断と処置を含む診療(スーパービル)を作成します |
tebra_update_encounter_status | ワークフローの遷移:Draft -> Submitted -> Approved / Rejected / Unpayable |
tebra_get_charges | 18 個のフィルター(日付、患者名、プロバイダー、ステータス)を使って請求項目を検索します |
tebra_get_payments | 転記日、支払者、バッチ、照会番号で支払い記録を検索します |
tebra_create_payment | 患者アカウントに支払いを計上します |
保険と承認
| ツール | 説明 |
|---|---|
tebra_get_patient_authorizations | ステータス、残りの受診回数、CPT コードを含むすべての承認を取得します |
tebra_check_insurance_eligibility | 登録済みの保険データから資格を確認します |
医療機関の設定
| ツール | 説明 |
|---|---|
tebra_get_providers | ID、専門分野、NPI 番号を含むすべてのプロバイダーを一覧表示します |
tebra_get_service_locations | 住所と連絡先情報を含む医療機関の所在地を一覧表示します |
tebra_get_practices | 医療機関のメタデータ(名称、納税者番号、請求情報)を取得します |
tebra_get_procedure_codes | 説明と既定料金を含む処置コードのカタログを取得します |
ドキュメント
| ツール | 説明 |
|---|---|
tebra_create_document | 患者のカルテにドキュメント(PDF、画像)をアップロードします |
tebra_delete_document | 患者のカルテからドキュメントを削除します |
財務分析
| ツール | 説明 |
|---|---|
tebra_get_transactions | 財務レポート用の詳細な取引データを取得します |
外部ベンダーとシステム
| ツール | 説明 |
|---|---|
tebra_validate_connection | ヘルスチェック。SOAP の認証情報と接続を検証します |
tebra_get_throttles | 現在の API レート制限状況と残りのクォータを取得します |
tebra_register_external_vendor | ID の紐付け用に外部ベンダーを登録します |
tebra_get_external_vendors | 登録済みの外部ベンダーを一覧表示します |
tebra_update_patient_external_id | 外部システム ID を Tebra の患者に紐付けます |
tebra_set_primary_patient_case | 既存の患者ケースをプライマリに設定します(ケース ID を指定) |
FHIR 臨床データ(FHIR 認証情報が必要)
これらのツールは、Tebra FHIR R4 API を介して臨床データにアクセスします。別途 FHIR 認証情報が必要です(上記の環境変数を参照)。FHIR 認証情報が設定されていない場合、これらのツールは登録されません。
FHIR の患者 ID は SOAP の患者 ID とは異なる識別子体系です。tebra_fhir_search_patients を使用して解決してください。すべての FHIR 検索では Bundle のページネーションが自動的に処理されます(最大 10 ページ)。また、Tebra が 2 つ目の検索パラメーターを必要とする 3 つのリソース(MedicationRequest の intent、CarePlan の category、CareTeam の status)には適切な既定値が設定されているため、結果が空のまま返されることはありません。
| ツール | 説明 |
|---|---|
tebra_fhir_search_patients | 名前、生年月日、識別子で FHIR 患者 ID を検索します |
tebra_fhir_get_allergies | 患者のアレルギーおよび不耐性の一覧 |
tebra_fhir_get_medications | 現在および過去の服薬一覧 |
tebra_fhir_get_conditions | 問題リスト/現在の状態 |
tebra_fhir_get_vitals | 最近のバイタルサイン(血圧、心拍数、体温、体重、BMI) |
tebra_fhir_get_lab_results | 検査結果と観察値 |
tebra_fhir_get_immunizations | 予防接種記録 |
tebra_fhir_get_procedures | 実施された処置 |
tebra_fhir_get_care_plans | 現在のケアプラン |
tebra_fhir_get_care_team | ケアチームのメンバーと役割 |
tebra_fhir_get_diagnostic_reports | 診断レポート(放射線診断、病理診断) |
tebra_fhir_get_documents | 臨床ドキュメント(CDA、記録) |
tebra_fhir_get_devices | 埋め込み型デバイス(UDI データ) |
レート制限
SOAP クライアントは、Tebra API Technical Guide のスロットリングしきい値に合わせて、アクションごとに呼び出し間の最小間隔を適用します。ツールが許容される制限を超える頻度で呼び出された場合、リクエストを送信する前に、間隔を満たすために必要な時間だけクライアントがスリープします。呼び出しは遅延されますが、破棄されることはありません。
| アクション | 呼び出し間の最小間隔 |
|---|---|
GetPatient | 250 ms |
GetPractices、GetProviders、GetServiceLocations、GetProcedureCodes、GetEncounterDetails、GetAppointment、すべての Create* / Update* / Delete* | 500 ms |
GetPatients、GetAppointments、GetAppointmentReasons、GetCharges、GetPayments、GetTransactions、GetExternalVendors、UpdatePatient | 1000 ms |
GetAllPatients、GetThrottles | 5000 ms |
クライアント側のスロットリングに加え、すべての SOAP 呼び出しは、エラーを通知する前に最大 3 回、指数バックオフ(1s、2s、4s)で再試行されます。tebra_get_throttles を使用すると、Tebra のサーバー側レート制限カウンターをリアルタイムで照会できます。
ワークフローの例
予約フロー
1. tebra_get_providers -- Get provider IDs
2. tebra_get_service_locations -- Get location IDs
3. tebra_get_appointment_reasons -- Get reason/type IDs
4. tebra_create_appointment -- Create with provider, location, reason IDs
5. tebra_get_appointment_detail -- Verify creation
診療承認フロー
1. tebra_create_encounter -- Create superbill (status: Draft)
2. tebra_update_encounter_status -- Move to Submitted (shows as "Review" in Tebra's UI)
3. tebra_update_encounter_status -- Move to Approved (triggers billing)
OR
3. tebra_update_encounter_status -- Reject back to Draft
受付チェックインフロー
1. tebra_get_appointments -- Today's schedule (resourceName = provider)
2. tebra_update_appointment_status -- CheckedIn on arrival
3. tebra_update_appointment_status -- CheckedOut at departure
支払い計上フロー
1. tebra_search_patients -- Find patient
2. tebra_get_charges -- Find outstanding charges
3. tebra_create_payment -- Post payment to patient account
4. tebra_get_payments -- Verify payment posted
患者のオンボーディング
1. tebra_search_patients -- Check for existing patient
2. tebra_create_patient -- Create if not found
3. tebra_update_patient_external_id -- Link Supabase client ID
4. tebra_create_appointment -- Schedule first visit
診療記録作成のための臨床コンテキスト
1. tebra_get_appointments -- Get today's schedule
2. tebra_get_appointment_detail -- Get appointment context
3. tebra_get_patient -- Full patient demographics
4. tebra_get_patient_authorizations -- Check auth status
5. tebra_fhir_get_allergies -- Allergies
6. tebra_fhir_get_medications -- Current medications
7. tebra_fhir_get_conditions -- Problem list
8. tebra_fhir_get_vitals -- Recent vitals
ツールの依存関係チェーン
一部のツールでは、ほかのツールから取得した ID が必要です。主な依存関係は次のとおりです。
tebra_create_appointment
requires: patientId (from tebra_search_patients or tebra_create_patient)
requires: providerId (from tebra_get_providers)
requires: locationId (from tebra_get_service_locations)
optional: reasonId (from tebra_get_appointment_reasons)
tebra_create_encounter
requires: patientId (from tebra_search_patients)
requires: providerId (from tebra_get_providers)
recommended: practiceName/practiceId (from tebra_get_practices)
optional: authorization number (from tebra_get_patient_authorizations)
tebra_create_payment
requires: patientId (from tebra_search_patients)
tebra_update_encounter_status
requires: encounterId (from tebra_create_encounter or tebra_get_encounter)
tebra_create_document
requires: patientId (from tebra_search_patients)
tebra_update_patient_external_id
requires: patientId (from tebra_search_patients or tebra_create_patient)
recommended: externalVendorId (from tebra_get_external_vendors)
tebra_set_primary_patient_case
requires: patientCaseId (from tebra_get_patient — cases[].caseId)
All clinical tebra_fhir_get_* tools
require: FHIR patientId (from tebra_fhir_search_patients — NOT the SOAP patient ID)
プライバシーポリシー
このサーバーはローカルで実行され、お客様自身の認証情報を使用して Tebra の API とのみ通信します。バックエンドやテレメトリはなく、ディスクへの書き込みも行いません。認証情報と患者識別子は、デバッグログおよびエラーメッセージから削除されます。また、レコードを返すすべてのツールには、必要最小限の項目を選択するための fields 引数があります。ツールの結果には保護対象医療情報が含まれるため、これを Claude に送信するには、Anthropic が業務提携契約(Business Associate Agreement)を締結している Claude プランが必要です。ポリシー全文は PRIVACY.md をご覧ください。
デスクトップ拡張機能(.mcpb)
manifest.json は、サーバーを Claude Desktop 用の MCP Bundle としてパッケージ化します。すべての認証情報は機密性の高い user_config(OS のキーチェーンに保存)として宣言され、FHIR 秘密鍵は file 入力として宣言されます。次のコマンドでバンドルをビルドします。
npm run pack:mcpb # builds, prunes dev dependencies, writes tebra-mcp-server.mcpb
src/__tests__/manifest.test.ts は、マニフェストを package.json およびツールレジストリに固定します。そのため、マニフェストエントリを追加せずにサーバーへツールを追加すると、テストスイートは失敗します。
Claude Desktop にインストールする場合、FHIR 秘密鍵にはデスクトップアプリから読み取り可能な絶対パスを指定する必要があります(プロジェクトからの相対パスではなく、C:\Users\you\keys\fhir.pem のような Windows パスを指定します)。鍵を読み取れない場合、stderr にメッセージが表示され、13 個の FHIR ツールが無効になりますが、34 個の SOAP ツールは停止しません。インストールフォームで空欄のままにした任意のフィールドも許容されます。Claude Desktop はそれらを文字列の ${user_config.<key>} プレースホルダーとして渡し、サーバーは未設定として扱います。
API リファレンス
このサーバーは、2 つの Tebra API をラップします。
SOAP API v2.1(34 個のツール)
- エンドポイント:
https://webservice.kareo.com/services/soap/2.1/KareoServices.svc - 認証:CustomerKey、Password、User を含む RequestHeader(WSDL のシーケンス順が重要)
- リクエストボディは WSDL(
?xsd=xsd0/xsd7)のメンバー順に生成されます。順序が異なると WCF はエラーを返さずにメンバーを破棄します - すべてのリクエストで、指数バックオフによる再試行を行います(1s、2s、4s の間隔で 3 回試行)
FHIR R4 API(13 個のツール)
- エンドポイント:
https://fhir.prd.cloud.tebra.com/fhir-request(ハイフンに注意。TEBRA_FHIR_BASE_URLで設定可能) - 認証:
https://fhir.prd.cloud.tebra.com/smartauth/oauth/tokenに対する OAuth2 クライアント認証情報フロー - トークンをキャッシュし、有効期限前に自動更新し、401 時は 1 回再試行
- Bundle のページネーションを自動的にたどります(検索ごとに最大 10 ページ)
開発
git clone https://github.com/jamesrosing/tebra-mcp-server.git
cd tebra-mcp-server
npm install
npm run dev # tsx — runs src/index.ts directly without a build step
npm run build # tsc — compiles to dist/
npm test # node:test via tsx — 37 regression tests covering wire-format invariants
npm start # node dist/index.js — runs the compiled output
回帰テストスイートでは、Tebra のワイヤーフォーマットに関する 3 つの不変条件(SOAPAction のコントラクトセグメント、RequestHeader の順序、空の Fields/値が設定された Filter)に加え、すべてのリクエストビルダーについてツールごとの WSDL メンバー順序を固定しています。これらすべてに共通する失敗時の挙動はエラーではなく、結果がひっそりと空になることです。そのため、テストだけが迅速なフィードバック手段です。
ロードマップ
- サンドボックスの診療所を使った、0.4.0 の書き込み形式に対するライブスモークテストスイート(形式は WSDL から導出され、単体テストで固定済みです。残る作業は本番環境での検証です)
- 大規模な一覧取得ツールへのクライアント側ページネーション(
limit/offset+has_more)。tebra_get_all_patientsと同様の方式です .strict()スキーマによる Zod の実行時検証。誤記された引数が黙って破棄されず、明確に失敗するようにしますServer.setRequestHandlerから SDK のMcpServer/registerToolAPI への移行。outputSchema/structuredContentを追加します- エージェント向けの評価セット(検証可能な読み取り専用の質問 10 件)。もっともらしいものの誤ったデータを検出します。これは単体テストでは検出できない種類の失敗です
変更履歴
0.6.0 (2026-09-19)
コネクタディレクトリへの対応。ワイヤーフォーマットに変更はありません。
- feat(annotations): すべてのツールに
titleと MCP アノテーション(readOnlyHint、destructiveHint、idempotentHint、openWorldHint)を追加しました。これらは動詞から導出され、tool-annotations.test.tsで固定されています。 - feat(redact): SOAP デバッグログから PHI と認証情報を除去し、リクエスト内の患者識別子をスローされるエラーメッセージ(SOAP フォールト、FHIR エラー、
tebra_get_patientの引数エラー)から除去します。合成レコードを使ってテストし、識別子が残らないことを確認しています。 - feat(fields): レコードを返すツールで、必要最小限の項目を選択するための
fields(配列内のドット区切りパス)を使用できます。tebra_get_all_patientsは名簿用の投影をデフォルトで使用し、tebra_get_patientは指定されない限り保険証券番号と団体番号を省略します。 - refactor(fhir): ハンドラーは、起動時に一度解決される
FhirConfigを受け取ります。また、OAuth トークンキャッシュはクライアントごとに分けられます。 - feat(mcpb): すべての認証情報に機密性の高い
user_configを設定したmanifest.json(MCPB 0.2)、PRIVACY.md、npm run pack:mcpb、およびバージョンタグでバンドルをパックする CI ワークフローを追加しました。 - fix(fhir): FHIR キーパスを読み取れなくても起動時に終了しなくなりました。また、展開されていない Claude Desktop の
${user_config.*}プレースホルダーは未設定として扱われます(2026-09-19 の実機検証では、どちらも目に見える原因がないままデスクトップ拡張機能を「Server disconnected」の状態にしていました)。 - docs: README、パッケージの説明、スキルに、Tebra からの独立性と BAA の要件を明記しました。
server.jsonではTEBRA_SOAP_USERをシークレットとして指定しています。
0.5.1 (2026-09-06)
- fix(retry safety):
tebra_create_payment(およびその他すべての Create* アクション)は、タイムアウト、送信後の接続リセット、HTTP 5xx の後に再送されなくなりました。これらの失敗では、Tebra 側で書き込みが確定したものの応答だけが失われた可能性があり、Tebra の SOAP API には冪等性キーがありません。そのため、自動再試行により患者のアカウントへ二重に支払いが登録されるおそれがあります(#13)。Create* アクションが再試行するのは、Tebra が処理を実行できる前に発生したと確実に判断できる失敗(429 によるスロットリング、接続拒否/名前解決失敗)だけです。それ以外の失敗では、再送信前に確認する読み取りツールを示すAmbiguousOutcomeErrorをスローします。読み取りアクションでは、従来どおり最大 3 回の再試行を行います。 - 起動時の「FHIR tools disabled」というメッセージと環境変数のドキュメントコメントで、
private_key_jwt方式を明記しました。また、package-lock.jsonをパッケージのバージョンと同期しました(#17)。
0.5.0 (2026-09-04)
- feat(FHIR auth):SMART Backend Services の
private_key_jwtクライアント認証に対応しました。TEBRA_FHIR_PRIVATE_KEY_PATHとTEBRA_FHIR_KIDを設定すると、トークンリクエストではシークレットの代わりに RS384 クライアントアサーション(iss=sub=クライアント ID、aud=トークン URL、exp=5 分、リクエストごとに一意のjti)が送信されます。これは、JWKS URL を登録した appSphere Backend App が必要とする形式です。キーのパスが設定されていない場合は、引き続きclient_secretがフォールバックとして使用されます。シークレットを使用する既存のインストールには変更ありません。FhirConfig.clientSecretはオプションになり、新たにFhirConfig.privateKeyが追加されました。オフラインでテスト済みです。アサーションは公開済みの JWKS フィクスチャに対して検証され、実際のトークンエンドポイントには接続しません。
0.4.3 (2026-08-04)
- fix(external IDs):
tebra_create_patientとtebra_update_patient_external_idで、25 文字を超える ID をフェイルクローズするようにしました。Tebra の外部 ID ストレージは、25 文字を超える ID を通知なしに切り詰めます(切り詰め後の値との UNIQUE KEY 衝突により実環境で確認済み)。これにより、完全な値を使った以降の検索がすべて失敗します。また、ID はベンダーごとに一意です。(このガードは 0.4.2 の tarball への反映に間に合いませんでした。)
0.4.2 (2026-08-04)
書き込みパスが本番環境で検証されました:実際の診療所でライブ書き込みスモークテストを繰り返し、CreatePatient、CreateAppointment、CreateDocument、および外部 ID の一括処理とベンダースコープの検索がエンドツーエンドで動作することを確認しました(encounter の書き込み操作は、検証のため引き続きオプトイン方式です)。テストの実行で判明した追加のワイヤー仕様 4 件を、すべてここで修正しました。
- 必須メンバー(CreatePatient で「Expecting element 'Practice'」エラーが発生した後の
minOccurs監査):PatientCreate/PatientUpdate にはPractice、AppointmentCreate にはPracticeId、AppointmentUpdate にはPatientIdとServiceLocationId、DocumentCreateRequest にはPracticeIdが必要です。 - 外部 ID はベンダースコープで、ベンダーごとに一意であり、25 文字を超えると通知なしに切り詰められます — 25 文字を超える ID の書き込みは、フェイルクローズするようになりました(切り詰めによって以降の検索がすべて失敗します)。
DocumentDateは真のxs:dateTimeです — 日付のみの入力は ISO 形式の午前 0 時に正規化されます。米国形式の文字列を渡すとデシリアライザーでエラーになります(xs:stringである Filter の日付メンバーは、引き続きどちらの形式も受け付けます)。UpdatePatientsExternalIDのレスポンスでは、成功時でもItemsUpdatedのエコーが空で返されます — 代わりに、tebra_get_patientのベンダースコープExternalID検索で確認してください。
詳細:
- fix(create/update_patient):
Practiceは PatientCreate と PatientUpdate の必須メンバーです — 常に出力されるようになりました。practiceName/practiceId が省略された場合は、GetPractices を使ってアカウントの最初の診療所を自動解決します(キャッシュ済み)。tebra_update_patientにオプションの practiceName/practiceId 引数を追加しました。 - fix(create_appointment):
PracticeIdは必須です — 省略された場合は自動解決します。 - fix(update_appointment):
PatientIdとServiceLocationIdは必須です — 省略された場合は GetAppointment から自動取得するため、ステータスのみ、または予約変更のみの更新も引き続き動作します。 - fix(create_document):
PracticeIdは必須です — 省略された場合は自動解決します。 - 必須メンバーが不足している場合、ビルダーは明確なメッセージを出してフェイルクローズします。回帰テストを 3 件追加しました(合計 39 件)。
0.4.1 (2026-08-04)
0.4.0 のリクエスト形式を本番環境で検証しました。読み取り専用のスモークテスト一式(24 項目:すべての SOAP 読み取りツールと FHIR パイプライン)が、実際の Tebra の診療所に対してすべて合格するようになりました。本番環境でのみ判明した問題を修正しました。
- fix(xsd7 namespace):GetServiceLocations と GetProcedureCodes で「Expecting element 'Fields'」という障害が発生していました。xsd7 の targetNamespace には末尾のスラッシュがありません(
…/api/schemasと xsd0 の…/api/schemas/)。そのため、Fields/Filter メンバーは異なる XML 名になります。エンベロープで両方の名前空間を宣言し、この 2 つのツールでkar7:プレフィックス付きのメンバーを出力するようになりました。 - fix(get_appointment_reasons):WSDL では
PracticeIdが必須です(省略すると障害が発生)。ハンドラーは、指定されていない場合に GetPractices を使ってアカウントの最初の診療所 ID を自動解決するようになりました(キャッシュあり)。 - fix(search_patients):サーバー側では
ToDateOfBirthは排他的です。dateOfBirthを完全一致で検索するときは、何も見つからない幅 0 の範囲ではなく、[DOB, DOB+1) を送信するようになりました。 - fix(rate limiting):エンドポイントのウィンドウごとに安全マージンを +250ms 追加しました。間隔をちょうど空けても、Tebra のサーバー側で 429 が発生します。また、スロットリングエラー(HTTP-200 の ErrorResponse ブロック内で報告されるもの)を再試行可能として分類するようになりました。
- fix(get_encounter):GetEncounterDetails が EncounterStatus を 1 始まりの数値コードで返すため、ラベルに変換するようになりました(3=Approved。同じ受診の請求行と照合して本番環境で検証済みです)。
- fix(FHIR auth):
invalid_scopeの場合、トークンサーバーはクライアントの登録スコープを通知します。クライアントは、そのスコープを使って自動的に 1 回再試行するようになりました(登録内容はsystem/*.readとpatient/*.readの間で異なります)。
0.4.0 (2026-08-03)
WSDL 契約を全範囲にわたって監査しました。すべてのリクエストビルダーを実際の WSDL(KareoServices.svc?xsd=xsd0/xsd7)から再導出したところ、0.3.0 で GetCharges のために修正した Fields/Filter の配置ミスがほかのすべてのリスト GET にも影響していたこと、さらに、ほとんどの書き込み操作で誤ったラッパー要素やメンバー名が使われていたことが判明しました。いずれの場合も障害は表面化せず(フィルターが適用されない、フィールドが破棄される、またはサーバー側で障害が発生する)長期間見過ごされていました。修正後のリクエスト形式を固定する回帰テストを 26 件追加しました。
- 修正(一覧 GET): patients、appointments、payments、transactions、providers、service-locations、procedure-codes、bulk-patients、encounter-details では、条件が
<kar:Filter>(WSDL のシーケンス順)に設定され、<kar:Fields/>が空になりました。以前はフィルター引数がすべて暗黙に無視され、すべての呼び出しでフィルター未適用の結果が返されていました。WSDL にフィルターメンバーがない引数は、ガイダンスを表示して安全側に失敗するようになりました(patients.mrn、appointments.providerId→resourceNameを使用、payments.patientId)。 - 修正(get_patient / authorizations / eligibility):
GetPatientReqには Fields メンバーがまったくありません。ID はFilter(SinglePatientFilter)に設定されるようになり、患者を個別に検索できるようになりました。tebra_get_patientではexternalId/externalVendorIdによる検索も可能になりました。 - 修正(レスポンスパーサー): 実際の WSDL メンバー名を全体で使用するようになりました。ネストされたケース/保険ポリシー/承認データ(
PatientCaseData→PatientInsurancePolicyData→PatientInsurancePolicyAuthorizationData、AuthorizedNumberOfVisits)、MedicalRecordNumber、NationalProviderIdentifier、一括ページング用のPatientBatchDataとnextStartKey、ThrottleDetail、ExternalVendorData、EncounterDetailsDataが対象です。以前の名前では何も一致せず、保険/承認/ケースのデータは常に空として解析されていました。一覧パーサーでは、Tebra が返す実体のない空のプレースホルダー行をすべて除外するようになりました。 - 修正(書き込み):
create/update_patientのメンバーを WSDL のシーケンス順に並べ替え(順序が異なるメンバーは暗黙に破棄され、DOB、性別、メールアドレス、住所が一度も保存されていませんでした)、正しい名前(SocialSecurityNumber、PatientExternalID、MedicalRecordNumber)を使用し、保険をCases → Policiesの下にネストするようになりました。create/update_appointmentはフラットなAppointmentCreate/Update形式(StartTime/EndTime、PatientSummary、ProviderId)に書き換えられました。delete_appointmentはAppointmentでラップするようになりました。create_encounterはEncounterCreate(サービスラインごとのDiagnosisCode1–4、RenderingProvider、Practice)に書き換えられました。update_encounter_statusは実際の列挙値(Draft/Submitted/Approved/Rejected/Unpayable。「Review」は UI 上のラベルであり、API のステータスではありません)を使い、EncounterUpdateStatusでラップするようになりました。create_paymentはPaymentCreateのネストされたグループを使用するようになりました。create_documentはメンバー順にDocumentToCreateでラップするようになりました。delete_documentはDocumentId(大文字と小文字を区別)を送信するようになりました。外部 ID ツールはExternalVendor/Updates→UpdateBatchのバッチ形式を使用するようになりました。create_appointment_reasonはメンバー順になり、色は整数になりました。validate_connectionは、認証情報としてGetCustomerIdFromKeyRequestが実際に要求する値を送信するようになりました。 - 変更:
tebra_update_patient_case→tebra_set_primary_patient_case— 基盤となる操作(UpdatePrimaryPatientCase)はPatientCaseIdを指定してケースをプライマリに昇格させるだけで、名前や支払者シナリオの編集は受け付けません。以前のツール名も引き続きルーティングされます。 - 新規:
tebra_update_appointment_status—UpdateAppointmentStatusを使った対象を絞ったステータス変更(CheckedIn/NoShow/Cancelled など)に対応しました。完全な更新より低コストです。 - 修正(FHIR): デフォルトのベース URL を
https://fhir.prd.cloud.tebra.com/fhir-requestに修正しました(ハイフンを使用。以前の/fhir/requestパスではすべての呼び出しで HTTP 200 と空の本文が返されることを、2026-08-03 に実環境で確認済みです)。本文が空の 200 レスポンスでは、設定に関する説明的なエラーが発生するようになりました。401 ではトークンの自動更新と再試行を 1 回行います。開始日と終了日の範囲は、dateパラメーターを 2 つ繰り返して出力するようになりました(以前はパーセントエンコードされ、1 つの不正な値になっていました)。Bundle のページネーションを自動で処理するようになりました(link[rel=next]、最大 10 ページ、切り詰めが発生した場合はその旨を表示)。必須の 2 つ目の検索パラメーターをデフォルトで設定するようになりました(MedicationRequest intent=order、CarePlan category=assess-plan、CareTeam status=active)。これらがないと、Tebra は通知なしに空の Bundle を返します。 - 新規:
tebra_fhir_search_patients— 名前/生年月日/識別子で FHIR Patient を検索します。FHIR の患者 ID は SOAP ID とは別の識別子空間に属しており、以前はサーバー内で解決する手段がありませんでした。 - 修正(コア):
extractTag/extractAllTagsはタグ名の境界を必須とするようになりました(PatientがPatientDataに一致しなくなりました)。サーバーのバージョンはpackage.jsonから読み取るようになりました(以前は0.2.5にハードコードされていました)。サーバー名をtebra-mcp-serverに修正しました。レート制限テーブルのキーにCreatePayment/UpdateAppointmentStatusを追加しました。
0.3.2 (2026-07-15)
- chore:プロジェクト固有の統合テンプレート(
src/integrations/epic-notes-integration.ts、src/integrations/fal-integration.ts)と、それらへのすべての参照(README の「Integration Services」セクション、ワークフロー例のラベル、コントリビューター向けドキュメント)を削除しました。これらは外部の下流プロジェクト向けのコピー&ペースト用コネクターモジュールであり、サーバーからインポートされることも実行時に使われることもなかったため、公開パッケージに含めるべきではありませんでした。MCP ツールの追加・削除はなく、45 個のツール構成に変更はありません。コンパイル済みの tarball にdist/integrations/は含まれなくなりました。
0.3.1 (2026-07-07)
- fix(get_charges):
<kar:Fields/>を空のまま送信するようになりました。0.3.0 の明示的な列切り替えは Tebra の射影反転の癖を引き起こし、フィルターに一致する項目に関係なく、すべての呼び出しで実フィールドが 0 個の空の<ChargeData/>プレースホルダーが 1 つだけ返されていました(fault はありませんでした)。Fields を空にすると、完全なレコードが返されます。明示的な切り替えで表示しようとしていたPrimaryInsurance*の査定列(支払い、契約調整と理由、二次調整と理由、査定日)も含まれます。 - 応答パーサー(
parseChargeBlocks、エクスポート済み)が空のプレースホルダーブロックを除外するようになりました。一致なしの応答が、以前はすべて空の偽の請求 1 件としてカウントされていました。 statusフィルターの説明に、実際の運用環境で確認された列挙値を追加しました:Pending、Completed、Error - Rejection、Voided、Ready。一部のアカウントにはDeniedステータスがありません。却下はError - Rejectionとして表示されます。- 本番環境の Tebra で実動確認済み:12 か月分を 14 ウィンドウで取得した結果、金額情報が設定された実際の請求 293 件が返されました。サーバー側の
Statusフィルタリングが機能することも確認しました。
0.3.0 (2026-07-06)
- fix(get_charges):フィルター条件を
<kar:Fields>から<kar:Filter>に移し、WSDL(xsd0)の順序で出力するようになりました。Fields 内では WCF によって暗黙に無視されていたため、GetCharges はパッケージの全履歴を対象にフィルターなしのデータを返していました。patientIdはエラーをスローするようになりました(ChargeFilter に患者 ID メンバーはありません。patientNameを使用してください)。 - 注:Tebra は GetCharges のサーバー側で、投稿日を 60 日以内に制限しています。
0.2.6 (2026-07-06)
- fix(get_appointment_detail):
GetAppointmentは、一覧取得エンドポイントで使われるFields/Filterのリクエスト形式を受け付けません。実際の WSDL(KareoServices.svc?xsd=xsd0)によると、GetAppointmentReq = RequestBase + <Appointment>{ AppointmentId: xs:long }</Appointment>(小文字の「d」)です。古いエンベロープはすべての呼び出しで'EndElement' 'request' … Expecting element 'Appointment'という fault を返していたため、tebra_get_appointment_detailは実際の Tebra に対して動作していませんでした。 - 応答は WSDL の
AppointmentCreate形式です。患者は<PatientSummary>の下にネストされ(グループ参加者は<PatientSummaries>)、StartTime/EndTimeは ISO 形式、AppointmentStatusがあり、AppointmentTypeは列挙型の文字値です。このツールの出力は、架空のAppointmentDataフィールドセットではなく、実際のフィールド(患者名と生年月日、予約モード、理由 ID、繰り返し設定、グループ参加者、監査タイムスタンプ)をマッピングするようになりました。 - 実際の環境で確認済み:実際の予約の詳細をすべて取得できました。コントリビューター向けの教訓:Tebra の単一レコード操作は、一覧取得に対応する操作とはまったく異なる WSDL コントラクトを持つ場合があります。Fields/Filter の形式を前提とする前に、
?xsd=xsd0を確認してください。
0.2.5 (2026-04-28)
- fix(soap):すべての GET リクエスト本文で、
<kar:Fields>の後に兄弟要素<kar:Filter />を含めるようになりました。Tebra の WSDL ではFilterはminOccurs="0"とされていますが、サーバー側のGetFilteredX(...)メソッドは null チェックなしでフィルターパラメーターを参照するため、存在しない場合はNullReferenceExceptionが発生します。修正したツール:practices、providers、service-locations、procedure-codes、transactions、payments、charges、encounters、patients(検索および ID 指定による取得)、bulk-patients、appointments。0.2.5 がない場合、すべての GET 呼び出しがサーバー側の NullRef で失敗します。 - WSDL で必要な順序(Fields の後に Filter)で
<kar:Filter />が出力されることを検証する回帰テストを追加しました。
0.2.4 (2026-04-28)
- fix(soap):
<RequestHeader>の子要素が、WSDL で必須とされる順序(CustomerKey → Password → User)でシリアライズされるようになりました。以前のCustomerKey → User → Passwordの順序では、有効な認証情報を使用していても認証に失敗し、その失敗が通知されませんでした。Tebra のカスタマーケアから書面で確認済みです。
0.2.3 (2026-04-28)
- fix(soap):
SOAPActionHTTP ヘッダーに、Kareo のディスパッチャーが要求する WCF コントラクトセグメントKareoServices/が含まれるようになりました。バージョン 0.2.2 以前では${SOAP_NAMESPACE}${operation}が送信され、ディスパッチャーに HTTP 500(ContractFilter mismatch at the EndpointDispatcher)で拒否されていました。RFC 3902 §3.2 に従い、ヘッダー値も明示的に引用符で囲むようになりました。 - ヘッダー値が正確であることを検証する回帰テストを追加しました(
npm test)。
0.2.2 (2026-04-27)
- fix(soap):
RequestHeader(User/Password/CustomerKey)が、SOAP エンベロープヘッダーではなく、Tebra の WSDL が指定するリクエストボディ内に配置されるようになりました。
0.2.1 (2026-04-26)
- MCP Registry に
com.jamesrosingmd/tebra(ドメイン認証済みの名前空間)として公開しました。
0.2.0
- 初回の一般公開リリースです。
0.2.4 以前からは、至急アップグレードしてください。 以前のすべてのリリースには、上記の 3 つのワイヤーフォーマットの不具合のうち少なくとも 1 つがありました。Tebra の WSDL/ランタイム要件をエンドツーエンドですべて満たすのは 0.2.5 のみです。
ライセンス
MIT License
Copyright (c) 2026 James H. Rosing, MD, FACS
本ソフトウェアおよび関連ドキュメントファイル(以下「本ソフトウェア」)の複製を入手するすべての人に対し、使用、複製、変更、結合、公開、配布、サブライセンス、および/または販売する権利を含め、本ソフトウェアを制限なく取り扱うことを無償で許可します。また、本ソフトウェアを提供する人に対しても、同様の権利を許可します。ただし、以下の条件に従うものとします。
上記の著作権表示および本許諾表示は、本ソフトウェアのすべての複製または実質的な部分に含めるものとします。
本ソフトウェアは「現状のまま」提供され、商品性、特定目的への適合性、および権利侵害がないことの保証を含む、明示または黙示を問わず、いかなる種類の保証もありません。作者または著作権者は、契約、不法行為、その他のいずれの理由による場合も、本ソフトウェア、本ソフトウェアの使用、またはその他の取引に起因または関連して生じるいかなる請求、損害、その他の責任についても責任を負いません。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。