mcpField
T
tebra

tebra

本地服务
github.com/jamesrosing健康医疗16 周前更新

关于 tebra

tebra-mcp-server 将 Tebra 诊所管理账户连接到兼容 MCP 的 AI Agent,提供 SOAP 业务操作及可选的 FHIR 临床数据访问,适用于使用 Tebra 的诊所。需要有效 API 凭据,临床结果可能包含受保护的健康信息。

主要功能

  1. 01管理患者记录和预约
  2. 02处理就诊、费用和付款
  3. 03访问保险与授权信息
  4. 04上传和删除患者文档
  5. 05配置后读取 FHIR 临床数据
  6. 06验证连接并查看 API 限流

适用场景

  1. 01在诊所工作流程中搜索患者记录
  2. 02安排或修改预约
  3. 03创建就诊记录并推进账单状态
  4. 04启用 FHIR 后查看患者用药或检验结果

MCP 相关

向 MCP 客户端开放 Tebra SOAP 操作,以及单独配置后可用的 FHIR R4 临床数据工具。服务需要 Tebra 凭据;FHIR 工具还需要额外的 FHIR 凭据。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"com-jamesrosingmd-tebra": {
"command": "npx",
"args": [
"-y",
"tebra-mcp-server"
],
"env": {
"TEBRA_SOAP_USER": "<TEBRA_SOAP_USER>",
"TEBRA_SOAP_PASSWORD": "<TEBRA_SOAP_PASSWORD>",
"TEBRA_CUSTOMER_KEY": "<TEBRA_CUSTOMER_KEY>"
}
}
}
}
启动命令npx -y tebra-mcp-server
需要配置的环境变量
TEBRA_SOAP_USERTebra SOAP API username
TEBRA_SOAP_PASSWORD密钥Tebra SOAP API password
TEBRA_CUSTOMER_KEY密钥Tebra customer key (per-practice identifier)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmtebra-mcp-server0.2.5

工具

33

收录的工具列表 · 更新于 2 周前

参数类型必填说明
mrnstring否病历号
querystring否按全名搜索(向后兼容的 fullName 别名)
genderenum否按性别筛选Male | Female | Other | Unknown
fullNamestring否按全名搜索
isActiveboolean否按启用/停用状态筛选
lastNamestring否按姓氏筛选
firstNamestring否按名字筛选
externalIdstring否外部系统 ID
dateOfBirthstring否出生日期(YYYY-MM-DD)
practiceNamestring否诊所名称筛选
toCreatedDatestring否创建日期范围结束(YYYY-MM-DD)
toDateOfBirthstring否出生日期范围结束(YYYY-MM-DD)
fromCreatedDatestring否创建日期范围开始(YYYY-MM-DD)
fromDateOfBirthstring否出生日期范围开始(YYYY-MM-DD)
toLastModifiedDatestring否修改日期范围结束(YYYY-MM-DD)
fromLastModifiedDatestring否修改日期范围开始(YYYY-MM-DD)
insuranceCompanyNamestring否保险公司名称筛选
referringProviderNamestring否转诊医生姓名筛选

详细介绍

tebra-mcp-server

npm version License: MIT

用于 Tebra(前身为 Kareo)诊所管理的 MCP 服务。它将现有的 Tebra 账户连接到 Claude 和其他兼容 MCP 的 AI Agent,提供 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 会与诊所单独签署自己的 BAA,与 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 时进行一次重试。支持两种客户端身份验证方式:SMART Backend Services private_key_jwt(在 appSphere 中注册为“Confidential (URL for JWKS)”的 Backend App——服务使用 RS384 对客户端断言进行签名,其中 iss=sub=客户端 ID、aud=令牌 URL、exp 为 5 分钟后,且包含唯一的 jti;断言通过 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获取诊所元数据(名称、税务 ID、账单信息)
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 要求第二个搜索参数的三个资源(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 中的限流阈值保持一致。当工具的调用频率超过允许的上限时,客户端会短暂休眠,直到满足间隔要求后再发送请求——调用只会延迟,不会被丢弃。

操作调用之间的最小间隔
GetPatient250 ms
GetPractices、GetProviders、GetServiceLocations、GetProcedureCodes、GetEncounterDetails、GetAppointment,所有 Create* / Update* / Delete*500 ms
GetPatients、GetAppointments、GetAppointmentReasons、GetCharges、GetPayments、GetTransactions、GetExternalVendors、UpdatePatient1000 ms
GetAllPatients、GetThrottles5000 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 已签署《业务伙伴协议》的 Claude 方案。完整政策请参阅 PRIVACY.md。

桌面扩展(.mcpb)

manifest.json 会将服务打包为供 Claude Desktop 使用的 MCP Bundle,其中每项凭据都声明为敏感的 user_config(存储在操作系统钥匙串中),FHIR 私钥则声明为 file 输入。使用以下命令构建 Bundle:

npm run pack:mcpb   # builds, prunes dev dependencies, writes tebra-mcp-server.mcpb

src/__tests__/manifest.test.ts 会将 manifest 固定为与 package.json 和工具注册表一致,因此,如果向服务添加了工具却未在 manifest 中添加条目,测试套件就会失败。

在 Claude Desktop 中安装后,FHIR 私钥必须使用桌面应用可读取的绝对路径(例如 C:\Users\you\keys\fhir.pem 这样的 Windows 路径,而不是相对于某个项目的路径)。如果密钥无法读取,13 个 FHIR 工具会被禁用,并在 stderr 中显示消息;34 个 SOAP 工具不会因此停止运行。安装表单中留空的可选字段可以正常处理:Claude Desktop 会将它们原样作为 ${user_config.<key>} 占位符传入,服务会将其视为未设置。

API 参考

此服务封装了两个 Tebra API:

SOAP API v2.1(34 个工具)

  • 端点:https://webservice.kareo.com/services/soap/2.1/KareoServices.svc
  • 身份验证:RequestHeader,包含 CustomerKey、Password、User(WSDL 序列顺序很重要)
  • 请求正文按 WSDL(?xsd=xsd0/xsd7)中的成员顺序生成——WCF 会静默丢弃顺序错误的成员
  • 所有请求都包含带指数退避的重试(尝试 3 次,间隔 1s、2s、4s)

FHIR R4 API(13 个工具)

  • 端点:https://fhir.prd.cloud.tebra.com/fhir-request(注意其中的连字符——可通过 TEBRA_FHIR_BASE_URL 配置)
  • 身份验证:通过 OAuth2 客户端凭据流程访问 https://fhir.prd.cloud.tebra.com/smartauth/oauth/token
  • 缓存令牌,并在令牌过期前自动刷新;遇到 401 时重试一次
  • 自动跟进 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

回归测试套件锁定了 3 项 Tebra 线格式不变量(SOAPAction 契约片段、RequestHeader 顺序、空 Fields/已填充 Filter),并覆盖每个请求构建器各自的 WSDL 成员顺序——这些问题的失败表现都是静默返回空结果,而不是报错,因此测试是唯一能快速反馈的途径。

路线图

  • 针对 0.4.0 写入数据结构,在沙盒诊所运行实时冒烟测试套件(数据结构源自 WSDL 并由单元测试锁定;剩下的步骤是生产环境验证)
  • 为大型列表工具添加客户端分页(limit/offset + has_more),与 tebra_get_all_patients 保持一致
  • 使用 .strict() schema 进行 Zod 运行时验证,让拼写错误的参数明确报错,而不是被丢弃
  • 从 Server.setRequestHandler 迁移到 SDK 的 McpServer/registerTool API,并添加 outputSchema/structuredContent
  • 面向 Agent 的评估集(10 个只读且可验证的问题),用于发现错误但看似合理的数据——这是单元测试无法检测的故障类型

更新日志

0.6.0 (2026-09-19)

满足 Connectors Directory 上架要求。线格式没有变化。

  • 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):添加 manifest.json(MCPB 0.2),其中每项凭据都通过敏感 user_config 配置;新增 PRIVACY.md、npm run pack:mcpb,以及在版本标签上打包 bundle 的 CI 工作流。
  • fix(fhir):FHIR 密钥路径无法读取时,启动不再退出;未展开的 Claude Desktop ${user_config.*} 占位符会被视为未设置(2026-09-19 实时验证:这两种情况都会导致桌面扩展显示“Server disconnected”并停止运行,且没有可见原因)。
  • docs:在 README、软件包说明和 skill 中说明本项目独立于 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 工具已禁用”启动消息和环境变量文档注释现在会说明 private_key_jwt 路由;package-lock.json 已重新同步至软件包版本(#17)。
0.5.0 (2026-09-04)
  • 功能(FHIR 身份验证):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 fixture 验证,从未访问在线令牌端点。
0.4.3 (2026-08-04)
  • 修复(外部 ID):在 tebra_create_patient 和 tebra_update_patient_external_id 中,对超过 25 个字符的 ID 采用失败关闭策略——Tebra 的外部 ID 存储会在 25 个字符处静默截断(通过截断值上的 UNIQUE KEY 冲突在线验证),这会导致之后所有使用完整值的查找失败。ID 在每个供应商范围内也必须唯一。(此保护措施刚好未赶上 0.4.2 压缩包。)
0.4.2 (2026-08-04)

写入路径现已通过生产环境验证:针对真实诊所反复运行实时写入冒烟测试,确认了 CreatePatient、CreateAppointment、CreateDocument,以及外部 ID 批量操作和供应商范围内查找的端到端流程(就诊写入操作仍需选择加入验证)。测试发现了另外四项线路层面的事实,现已全部修复:

  • 必需成员(CreatePatient 出错并提示 “Expecting element 'Practice'” 后进行的 minOccurs 审计):PatientCreate/PatientUpdate 要求 Practice;AppointmentCreate 要求 PracticeId;AppointmentUpdate 要求 PatientId+ServiceLocationId;DocumentCreateRequest 要求 PracticeId。
  • 外部 ID 按供应商区分,在每个供应商范围内唯一,并会在 25 个字符处静默截断——现在较长 ID 的写入会失败关闭(截断会导致之后所有查找失败)。
  • DocumentDate 实际上是 xs:dateTime——仅日期格式的输入会规范化为 ISO 午夜时间;美国格式的字符串会导致反序列化器出错(Filter 日期成员为 xs:string,仍可接受这两种格式)。
  • UpdatePatientsExternalID 响应中的 ItemsUpdated 回显为空,即使操作成功也是如此——应改为通过 tebra_get_patient 中供应商范围内的 ExternalID 查找来验证。

详情:

  • 修复(create/update_patient):Practice 是 PatientCreate 和 PatientUpdate 的必需成员——现在始终会传出;如果未提供 practiceName/practiceId,则会通过 GetPractices 自动解析账户的首个诊所(并缓存)。tebra_update_patient 新增可选的 practiceName/practiceId 参数。
  • 修复(create_appointment):PracticeId 为必需项——未提供时会自动解析。
  • 修复(update_appointment):PatientId 和 ServiceLocationId 为必需项——未提供时会通过 GetAppointment 自动补全,因此仅更新状态或重新安排时间仍可正常工作。
  • 修复(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 名称。现在信封会声明这两个命名空间,且这两个工具会输出带 kar7: 前缀的成员。
  • fix(get_appointment_reasons):WSDL 要求提供 PracticeId(省略时会报错)。如果未提供,处理程序现在会通过 GetPractices 自动解析该账户的首个诊所 ID,并缓存结果。
  • fix(search_patients):服务端将 ToDateOfBirth 视为不包含边界——搜索精确的 dateOfBirth 时,现在会发送 [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 时,令牌服务端会指出客户端注册时使用的范围——客户端现在会自动使用该范围重试一次(不同注册可能使用 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 现在会按 WSDL 序列顺序将筛选条件放入 <kar:Filter>,并使用空的 <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 顺序重新排列(顺序错误的成员会被静默丢弃——出生日期、性别、电子邮件和地址都未能持久化),并使用正确的名称(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 现在会封装包含真实枚举值的 EncounterUpdateStatus(Draft/Submitted/Approved/Rejected/Unpayable——“Review” 是 UI 标签,不是 API 状态);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 会触发一次自动令牌刷新并重试;起止日期范围现在会生成两个重复的 date 参数(此前会进行百分号编码并合并成一个格式错误的值);现在会自动跟进 Bundle 分页(link[rel=next],最多 10 页,并标记截断情况);为必需的第二个搜索参数设置了默认值(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)
  • 杂项:移除了打包附带的项目专用集成模板(src/integrations/epic-notes-integration.ts、src/integrations/fal-integration.ts)及所有相关引用(README 的“集成服务”部分、工作流示例标签、贡献者文档)。这些模板是供外部下游项目复制粘贴的连接器模块——服务从未导入它们,它们也不属于服务的运行时——因此不应包含在已发布的软件包中。没有新增或移除任何 MCP 工具;45 个工具的范围保持不变,编译后的 tarball 不再包含 dist/integrations/。
0.3.1 (2026-07-07)
  • 修复(get_charges):现在发送的 <kar:Fields/> 为空。0.3.0 中显式设置的列开关触发了 Tebra 的投影反转问题——无论筛选条件是否匹配,每次调用都会返回一个空的 <ChargeData/> 占位符(没有任何实际字段,也没有故障)。空的 Fields 会返回完整记录,其中包括 PrimaryInsurance* 理赔裁定列(付款、合同调整及原因、二次调整及原因、裁定日期);这些正是显式开关原本要显示的字段。
  • 响应解析器(已导出的 parseChargeBlocks)会丢弃空占位块——之前,无匹配结果的响应会被计为一笔虚构的全空收费记录。
  • status 筛选器文档现列出实时观察到的枚举值:Pending、Completed、Error - Rejection、Voided、Ready。至少有些账户没有 Denied 状态——拒赔会显示为 Error - Rejection。
  • 已通过生产环境的 Tebra 进行实时验证:一次为期 12 个月、分 14 个时间窗口的拉取返回了 293 笔包含已填充财务数据的实际收费记录;已确认服务端 Status 筛选正常工作。
0.3.0 (2026-07-06)
  • 修复(get_charges):筛选条件已从 <kar:Fields> 移至 <kar:Filter>,并按照 WSDL(xsd0)中的顺序输出——放在 Fields 中时,WCF 会静默跳过这些条件,因此 GetCharges 会返回整个软件包历史记录中未经筛选的数据。现在 patientId 会抛出异常(ChargeFilter 没有患者 ID 成员;请使用 patientName)。
  • 注意:Tebra 会在服务端强制要求 GetCharges 的入账日期窗口不超过 60 天。
0.2.6 (2026-07-06)
  • 修复(get_appointment_detail):GetAppointment 不接受列表端点使用的 Fields/Filter 请求结构。根据实时 WSDL(KareoServices.svc?xsd=xsd0),GetAppointmentReq = RequestBase + <Appointment>{ AppointmentId: xs:long }</Appointment>(小写 “d”)。旧请求信封每次调用都会出错,报错为 'EndElement' 'request' … Expecting element 'Appointment',因此 tebra_get_appointment_detail 无法用于实时 Tebra。
  • 响应采用 WSDL 的 AppointmentCreate 结构——患者信息嵌套在 <PatientSummary> 下(团体参与者位于 <PatientSummaries> 下),使用 ISO 格式的 StartTime/EndTime、AppointmentStatus 和字母枚举形式的 AppointmentType。该工具的输出现映射这些实际字段(患者姓名和出生日期、预约模式、原因 ID、重复信息、团体参与者、审计时间戳),而不是虚构的 AppointmentData 字段集。
  • 已通过实时验证:成功返回了一条真实预约的完整详情。给贡献者的经验:Tebra 的单条记录操作可能与对应的列表操作采用完全不同的 WSDL 契约——不要想当然地套用 Fields/Filter 模式,请先阅读 ?xsd=xsd0。
0.2.5 (2026-04-28)
  • 修复(soap):现在每个 GET 请求正文都会在 <kar:Fields> 后添加同级的 <kar:Filter />。Tebra 的 WSDL 将 Filter 标记为 minOccurs="0",但其服务端 GetFilteredX(...) 方法会在不进行空值检查的情况下解引用 filter 参数,当参数缺失时就会抛出 NullReferenceException。已修复的工具:practices、providers、service-locations、procedure-codes、transactions、payments、charges、encounters、patients(搜索和按 ID 获取)、bulk-patients、appointments。没有 0.2.5 时,每次 GET 调用都会因服务端 NullRef 而失败。
  • 新增回归测试,断言 <kar:Filter /> 按照 WSDL 要求的顺序输出(Fields 在前,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):现在 SOAPAction HTTP 标头包含 Kareo 调度器要求的 KareoServices/ WCF 合约段。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)会放在请求正文内,这是 Tebra 的 WSDL 预期的位置,而不是放在 SOAP 信封标头中。
0.2.1 (2026-04-26)
  • 已在 MCP Registry 中以 com.jamesrosingmd/tebra 发布(已验证域名命名空间)。
0.2.0
  • 首次公开发布。

请立即从 0.2.4 或更早版本升级。 所有先前版本都至少存在上述三个线格式错误之一,只有 0.2.5 能够端到端满足 Tebra 的全部三项 WSDL/运行时要求。

许可证

MIT License

Copyright (c) 2026 James H. Rosing, MD, FACS

特此免费授权任何获得本软件及相关文档文件(以下简称“软件”)副本的人不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,并允许向其提供本软件的人也这样做,但须遵守以下条件:

上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。

本软件按“原样”提供,不附带任何明示或默示的保证,包括但不限于对适销性、特定用途适用性和不侵权的默示保证。在任何情况下,作者或版权持有人均不对因本软件或本软件的使用或其他处理而产生的任何索赔、损害或其他责任承担责任,无论是在合同、侵权或其他诉讼中。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。