tebra-mcp-server
This server connects a Tebra (Kareo) practice management account to MCP-compatible AI agents, exposing 47 tools for managing patient, appointment, billing, clinical, and practice data.
Patient Management: search, create, update, and bulk-fetch patients; retrieve full records with insurance, cases, and authorizations.
Appointments: search, create, update, delete, and get appointment details; manage appointment statuses and reasons.
Encounters & Billing: create and retrieve encounters (superbills), update encounter workflow statuses, search charges, and post/retrieve payments.
Insurance & Authorizations: view patient authorizations and check insurance eligibility from on-file data.
Practice Configuration: list providers, service locations, practices, and procedure codes.
Documents: upload and delete patient documents (PDF, images).
Financial Analysis: retrieve granular transaction data for reporting.
External Vendor & System Tools: validate connection, check rate limits, register external vendors, link external IDs, and set primary patient cases.
FHIR Clinical Data (13 tools): search FHIR patients and retrieve allergies, medications, conditions, vitals, lab results, immunizations, procedures, care plans, care team, diagnostic reports, clinical documents, and devices.
Click on "Deploy 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., "@tebra-mcp-serversearch for patient John Smith"
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.
tebra-mcp-server
MCP server for Tebra (formerly Kareo) practice management. Connects your existing Tebra account to Claude and other MCP-compatible AI agents, exposing 34 SOAP tools and 13 FHIR clinical tools for patients, encounters, appointments, billing, documents, insurance, and clinical data. Every request body is generated from the live Tebra WSDL contract (member names and sequence order verified against KareoServices.svc?xsd=xsd0/xsd7), with a regression suite locking the wire format in place. No data is accessible without valid Tebra API credentials.
This is an independent open-source project. It is not affiliated with, endorsed by, or supported by Tebra Technologies, Inc.; "Tebra" and "Kareo" are trademarks of their owner, used here only to identify the API this server talks to. Tool results contain protected health information: sending them to Claude requires a Claude plan under which Anthropic signs a Business Associate Agreement (BAA). Consumer Claude plans are not covered, and confirming coverage is the responsibility of the practice operating the server.
Hosted version available
Do not want to manage credentials, hosting, and updates yourself? DOCK is the managed version of this server: encrypted per-practice auth, audit logs, draft-first write actions, and a workflow library. Founding practices lock lifetime pricing: Front Desk $49/mo (Zenoti), Billing Desk $99/mo (Tebra; DOCK signs its own BAA with the practice, separate from Anthropic's), Full Practice $129/mo (both). https://dockhq.vercel.app
Quick Start
npx tebra-mcp-serverRelated MCP server: MediLinkAI
Prerequisites
Node.js 18+
Tebra SOAP API credentials (generated in Tebra PM admin under Settings > API)
(Optional) Tebra FHIR API credentials for clinical data access
Environment Variables
SOAP API (required)
Variable | Required | Description |
| Yes | SOAP API user (email) |
| Yes | SOAP API password |
| Yes | Customer key from Tebra PM admin |
| No | Override SOAP endpoint (for testing) |
FHIR API (optional -- enables 13 clinical data tools)
Variable | Required | Description |
| For FHIR | OAuth2 client ID from Tebra appSphere registration |
| For FHIR (JWKS registrations) | Path to the PEM (PKCS#8) private key for SMART Backend Services |
| With the key path | The |
| For FHIR (secret registrations) | OAuth2 client secret — the fallback used only when no key path is set |
| No | FHIR R4 base URL (defaults to |
| No | OAuth2 token endpoint (defaults to Tebra production) |
| No | OAuth2 scope (defaults to |
FHIR credentials are obtained through Tebra appSphere. The server uses the OAuth2 client credentials flow with automatic token caching, refresh 60s before expiry, and a one-shot retry on 401. Two client authentications are supported: SMART Backend Services private_key_jwt (an appSphere Backend App registered as "Confidential (URL for JWKS)" — the server signs an RS384 client assertion with iss=sub=client id, aud=token URL, a 5-minute exp and a unique jti, sent as client_assertion with client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer; the private key is read from disk once and never transmitted) and the legacy client_secret flow. Set the key path for the former, the secret for the latter. Note: both the practice and the backend-service client must be activated by Tebra Customer Care before tokens are issued — a 401 can mean "not yet activated" rather than "bad credentials".
Installation
Claude Code
Add to .mcp.json in your project root:
{
"mcpServers": {
"tebra": {
"command": "npx",
"args": ["-y", "tebra-mcp-server"],
"env": {
"TEBRA_SOAP_USER": "user@practice.com",
"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
Add to your claude_desktop_config.json:
{
"mcpServers": {
"tebra": {
"command": "npx",
"args": ["-y", "tebra-mcp-server"],
"env": {
"TEBRA_SOAP_USER": "user@practice.com",
"TEBRA_SOAP_PASSWORD": "your-password",
"TEBRA_CUSTOMER_KEY": "your-customer-key"
}
}
}
}Cursor / VS Code
Add to your MCP settings:
{
"mcpServers": {
"tebra": {
"command": "npx",
"args": ["-y", "tebra-mcp-server"],
"env": {
"TEBRA_SOAP_USER": "user@practice.com",
"TEBRA_SOAP_PASSWORD": "your-password",
"TEBRA_CUSTOMER_KEY": "your-customer-key"
}
}
}
}Available Tools (47 total)
Patient Management
Tool | Description |
| Search patients by name, DOB range, insurance, practice, and more (16 server-side filters) |
| Get full patient record (by Tebra ID or external ID) with cases, insurance policies, and authorizations |
| Register a new patient with demographics, insurance, and guarantor |
| Update patient demographics and contact info |
| Bulk patient retrieval with pagination (for sync operations) |
Appointments
Tool | Description |
| Search appointments by date range, resource (provider), patient, status, location |
| Get full appointment detail including recurrence, group data, and resources |
| Create an appointment (provider, location, start time + duration/end) |
| Update or reschedule an existing appointment |
| Change only the status (Confirmed, CheckedIn, NoShow, Cancelled, ...) |
| Permanently delete an appointment |
| List configured appointment types/reasons for the practice |
| Create a new appointment type/reason |
Encounters & Billing
Tool | Description |
| Get encounter details with status, providers, and service line IDs |
| Create an encounter (superbill) with per-line diagnoses and procedures |
| Workflow transitions: Draft -> Submitted -> Approved / Rejected / Unpayable |
| Search charges with 18 filters (dates, patient name, provider, status) |
| Search payment records by post date, payer, batch, reference number |
| Post a payment to a patient account |
Insurance & Authorizations
Tool | Description |
| Get all authorizations with status, remaining visits, and CPT codes |
| Check eligibility from on-file insurance data |
Practice Configuration
Tool | Description |
| List all providers with IDs, specialties, and NPI numbers |
| List practice locations with addresses and contact info |
| Get practice metadata (name, tax ID, billing info) |
| Get procedure code catalog with descriptions and default fees |
Documents
Tool | Description |
| Upload a document (PDF, image) to a patient's chart |
| Remove a document from a patient's chart |
Financial Analysis
Tool | Description |
| Get granular transaction data for financial reporting |
External Vendor & System
Tool | Description |
| Health check -- verifies SOAP credentials and connectivity |
| Get current API rate limit status and remaining quota |
| Register an external vendor for ID linking |
| List registered external vendors |
| Link an external system ID to a Tebra patient |
| Promote an existing patient case to primary (by case ID) |
FHIR Clinical Data (requires FHIR credentials)
These tools access clinical data via the Tebra FHIR R4 API. They require separate FHIR credentials (see Environment Variables above). If FHIR credentials are not configured, these tools will not be registered.
FHIR patient IDs are a different identifier space from SOAP patient IDs — use tebra_fhir_search_patients to resolve them. All FHIR searches follow Bundle pagination automatically (up to 10 pages), and the three resources where Tebra requires a second search parameter (MedicationRequest intent, CarePlan category, CareTeam status) get sensible defaults so they don't silently return empty.
Tool | Description |
| Find FHIR patient IDs by name, birthdate, or identifier |
| Patient allergy and intolerance list |
| Active and historical medication list |
| Problem list / active conditions |
| Recent vital signs (BP, HR, temp, weight, BMI) |
| Lab results and observation values |
| Vaccination records |
| Procedures performed |
| Active care plans |
| Care team members and roles |
| Diagnostic reports (radiology, pathology) |
| Clinical documents (CDA, notes) |
| Implantable devices (UDI data) |
Rate Limits
The SOAP client enforces a minimum interval between calls per action, mirroring the throttling thresholds in the Tebra API Technical Guide. When a tool is called more frequently than its limit allows, the client sleeps just long enough to satisfy the interval before sending the request — calls are delayed, never dropped.
Action | Min interval between calls |
| 250 ms |
| 500 ms |
| 1000 ms |
| 5000 ms |
On top of client-side throttling, every SOAP call retries up to 3 times with exponential backoff (1s, 2s, 4s) before surfacing an error. Use tebra_get_throttles to query Tebra's server-side rate limit counters in real time.
Example Workflows
Scheduling Flow
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 creationEncounter Approval Flow
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 DraftFront-Desk Check-In Flow
1. tebra_get_appointments -- Today's schedule (resourceName = provider)
2. tebra_update_appointment_status -- CheckedIn on arrival
3. tebra_update_appointment_status -- CheckedOut at departurePayment Posting Flow
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 postedPatient Onboarding
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 visitClinical Context for Note Creation
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 vitalsTool Dependency Chains
Some tools require IDs obtained from other tools. Key dependencies:
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)Privacy Policy
This server runs locally and talks only to Tebra's API with your own credentials. It has no backend, no telemetry, and writes nothing to disk. Credentials and patient identifiers are scrubbed from the debug log and from error messages, and every record-returning tool takes a fields argument for minimum-necessary selection. Tool results contain protected health information, so sending them to Claude requires a Claude plan under which Anthropic signs a Business Associate Agreement. The full policy is in PRIVACY.md.
Desktop Extension (.mcpb)
manifest.json packages the server as an MCP Bundle for Claude Desktop, with every credential declared as sensitive user_config (stored in the OS keychain) and the FHIR private key as a file input. Build the bundle with:
npm run pack:mcpb # builds, prunes dev dependencies, writes tebra-mcp-server.mcpbsrc/__tests__/manifest.test.ts pins the manifest to package.json and to the tool registry, so a tool added to the server without a manifest entry fails the suite.
When installed in Claude Desktop, the FHIR private key must be an absolute path the desktop app can read (a Windows path such as C:\Users\you\keys\fhir.pem, not a path relative to some project). An unreadable key disables the 13 FHIR tools with a message on stderr; it does not stop the 34 SOAP tools. Optional fields left blank in the install form are tolerated: Claude Desktop passes them through as the literal ${user_config.<key>} placeholder, which the server treats as unset.
API Reference
The server wraps two Tebra APIs:
SOAP API v2.1 (34 tools)
Endpoint:
https://webservice.kareo.com/services/soap/2.1/KareoServices.svcAuth: RequestHeader with CustomerKey, Password, User (WSDL sequence order matters)
Request bodies generated in WSDL (
?xsd=xsd0/xsd7) member order — WCF silently drops out-of-order membersAll requests include retry with exponential backoff (3 attempts at 1s, 2s, 4s)
FHIR R4 API (13 tools)
Endpoint:
https://fhir.prd.cloud.tebra.com/fhir-request(note the hyphen — configurable viaTEBRA_FHIR_BASE_URL)Auth: OAuth2 client credentials flow against
https://fhir.prd.cloud.tebra.com/smartauth/oauth/tokenToken caching with automatic refresh before expiry and one-shot 401 retry
Bundle pagination followed automatically (up to 10 pages per search)
Development
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 outputThe regression suite pins the three Tebra wire-format invariants (SOAPAction contract segment, RequestHeader order, empty-Fields/populated-Filter) plus per-tool WSDL member order for every request builder — the failure mode for all of these is a silent empty result, not an error, so the tests are the only fast feedback loop.
Roadmap
Live smoke-test suite for the 0.4.0 write shapes against a sandbox practice (shapes are WSDL-derived and unit-pinned; production verification is the remaining step)
Client-side pagination (
limit/offset+has_more) on the large list tools, mirroringtebra_get_all_patientsZod runtime validation with
.strict()schemas so misspelled arguments fail loudly instead of being droppedMigration from
Server.setRequestHandlerto the SDK'sMcpServer/registerToolAPI, addingoutputSchema/structuredContentAgent-facing evaluation set (10 read-only, verifiable questions) to catch wrong-but-plausible data — the failure class unit tests cannot see
Changelog
0.6.0 (2026-09-19)
Connectors Directory readiness. No wire-format changes.
feat(annotations): every tool carries a
titleand MCP annotations (readOnlyHint,destructiveHint,idempotentHint,openWorldHint) derived from its verb, pinned bytool-annotations.test.ts.feat(redact): PHI and credentials are scrubbed from the SOAP debug log, and patient identifiers from the request are scrubbed out of thrown error messages (SOAP faults, FHIR errors, and
tebra_get_patientargument errors). Tested against synthetic records so no identifier survives.feat(fields): record-returning tools accept
fieldsfor minimum-necessary selection (dotted paths through arrays).tebra_get_all_patientsdefaults to a roster projection;tebra_get_patientomits insurance policy and group numbers unless named.refactor(fhir): handlers take a
FhirConfigresolved once at startup, and the OAuth token cache is keyed per client.feat(mcpb):
manifest.json(MCPB 0.2) with sensitiveuser_configfor every credential,PRIVACY.md,npm run pack:mcpb, and a CI workflow that packs the bundle on version tags.fix(fhir): startup no longer exits when the FHIR key path is unreadable, and unexpanded Claude Desktop
${user_config.*}placeholders count as unset (verified live 2026-09-19: both took the desktop extension down as "Server disconnected" with no visible cause).docs: independence from Tebra and the BAA requirement stated in the README, package descriptions, and skill;
server.jsonnow marksTEBRA_SOAP_USERsecret.
0.5.1 (2026-09-06)
fix(retry safety):
tebra_create_payment(and every other Create* action) is no longer re-sent after a timeout, a reset after send, or an HTTP 5xx. Those failures are ambiguous — Tebra may have committed the write with only the response lost — and Tebra's SOAP API has no idempotency key, so the automatic retry could post a second payment to a patient's account (#13). Create* actions now retry only on failures that provably happened before Tebra could act (429 throttle, connection refused/unresolved); anything else throwsAmbiguousOutcomeErrornaming the read tool to verify with before resubmitting. Read actions keep the full 3-attempt retry.The "FHIR tools disabled" startup message and env-var doc comments now name the
private_key_jwtroute;package-lock.jsonresynced to the package version (#17).
0.5.0 (2026-09-04)
feat(FHIR auth): SMART Backend Services
private_key_jwtclient authentication. WithTEBRA_FHIR_PRIVATE_KEY_PATH+TEBRA_FHIR_KIDset, the token request carries an RS384 client assertion (iss=sub=client id,aud=token URL,exp=5 min, uniquejtiper request) instead of a secret — the shape an appSphere Backend App registered with a JWKS URL requires.client_secretremains the fallback when no key path is set; an existing secret install is unchanged.FhirConfig.clientSecretis now optional andFhirConfig.privateKeyis new. Tested offline: the assertion is verified against a published JWKS fixture, never a live token endpoint.
0.4.3 (2026-08-04)
fix(external IDs): fail closed on IDs over 25 characters in
tebra_create_patientandtebra_update_patient_external_id— Tebra's external-ID storage silently truncates at 25 chars (verified live via a UNIQUE KEY collision on the truncated value), which breaks every later lookup by the full value. IDs are also unique per vendor. (This guard just missed the 0.4.2 tarball.)
0.4.2 (2026-08-04)
The write path is now production-verified: iterating a live write-smoke harness against a real practice confirmed CreatePatient, CreateAppointment, CreateDocument, and the external-ID batch + vendor-scoped lookup end-to-end (encounter write ops remain opt-in to verify). The runs surfaced four additional wire facts, all fixed here:
Required members (
minOccursaudit after CreatePatient faulted "Expecting element 'Practice'"): PatientCreate/PatientUpdate requirePractice; AppointmentCreate requiresPracticeId; AppointmentUpdate requiresPatientId+ServiceLocationId; DocumentCreateRequest requiresPracticeId.External IDs are vendor-scoped, unique per vendor, and silently truncated at 25 characters — writes with longer IDs now fail closed (truncation breaks every later lookup).
DocumentDateis a truexs:dateTime— date-only input is normalized to ISO midnight; US-format strings fault the deserializer (Filter date members, beingxs:string, still accept either).The
UpdatePatientsExternalIDresponse returns an emptyItemsUpdatedecho even on success — verify via the vendor-scopedExternalIDlookup ontebra_get_patientinstead.
Details:
fix(create/update_patient):
Practiceis a required member of PatientCreate AND PatientUpdate — now always emitted; when practiceName/practiceId are omitted, the account's first practice is auto-resolved via GetPractices (cached).tebra_update_patientgains optional practiceName/practiceId args.fix(create_appointment):
PracticeIdis required — auto-resolved when omitted.fix(update_appointment):
PatientIdandServiceLocationIdare required — auto-hydrated from GetAppointment when omitted, so a status-only or reschedule-only update still works.fix(create_document):
PracticeIdis required — auto-resolved when omitted.Builders fail closed with clear messages if the required members are still missing; 3 new regression tests (39 total).
0.4.1 (2026-08-04)
Live production verification of the 0.4.0 shapes — a full read-only smoke pass (24 checks: every SOAP read tool plus the FHIR pipeline) now passes against a real Tebra practice. Fixes found only by going live:
fix(xsd7 namespace): GetServiceLocations and GetProcedureCodes faulted with "Expecting element 'Fields'" — xsd7's targetNamespace has NO trailing slash (
…/api/schemasvs xsd0's…/api/schemas/), so their Fields/Filter members are different XML names. The envelope now declares both namespaces and those two tools emitkar7:-prefixed members.fix(get_appointment_reasons):
PracticeIdis required by the WSDL (fault when omitted). The handler now auto-resolves the account's first practice ID via GetPractices (cached) when not supplied.fix(search_patients):
ToDateOfBirthis exclusive server-side — an exactdateOfBirthsearch now sends [DOB, DOB+1) instead of a zero-width range that matched nothing.fix(rate limiting): +250ms safety margin per endpoint window — an exact-interval gap still trips Tebra's server-side 429; throttle errors (reported inside HTTP-200 ErrorResponse blocks) are now classified retryable.
fix(get_encounter): GetEncounterDetails returns EncounterStatus as a 1-based numeric code; now mapped to labels (3=Approved, verified live against the same encounter's charge rows).
fix(FHIR auth): on
invalid_scope, the token server names the scope the client is registered with — the client now retries once with that scope automatically (registrations vary betweensystem/*.readandpatient/*.read).
0.4.0 (2026-08-03)
Full-surface WSDL contract audit. Every request builder was re-derived from the live WSDL (KareoServices.svc?xsd=xsd0/xsd7), which surfaced that the Fields/Filter misplacement fixed for GetCharges in 0.3.0 affected every other list GET, and that most write operations used wrong wrapper elements or member names. The failure mode in all cases is silent (unfiltered results, dropped fields, or server-side faults), which is why these survived so long. 26 new regression tests pin the corrected shapes.
fix(list GETs): patients, appointments, payments, transactions, providers, service-locations, procedure-codes, bulk-patients, and encounter-details now put criteria in
<kar:Filter>(WSDL sequence order) with an empty<kar:Fields/>— previously all of their filter args were silently ignored, and every call returned the unfiltered set. Args with no WSDL filter member now fail closed with guidance (patients.mrn,appointments.providerId→ useresourceName,payments.patientId).fix(get_patient / authorizations / eligibility):
GetPatientReqhas no Fields member at all — the ID now goes inFilter(SinglePatientFilter), so single-patient lookup works.tebra_get_patientalso gains lookup byexternalId/externalVendorId.fix(response parsers): real WSDL member names throughout — nested case/policy/authorization data (
PatientCaseData→PatientInsurancePolicyData→PatientInsurancePolicyAuthorizationData,AuthorizedNumberOfVisits),MedicalRecordNumber,NationalProviderIdentifier,PatientBatchData+nextStartKeyfor bulk paging,ThrottleDetail,ExternalVendorData,EncounterDetailsData. Previous names matched nothing, so insurance/auth/case data always parsed empty. All list parsers drop Tebra's phantom empty placeholder row.fix(writes):
create/update_patientmembers re-ordered to WSDL sequence (out-of-order members were silently dropped — DOB, gender, email, address never persisted) with correct names (SocialSecurityNumber,PatientExternalID,MedicalRecordNumber) and insurance nested underCases → Policies;create/update_appointmentrewritten to the flatAppointmentCreate/Updateshape (StartTime/EndTime,PatientSummary,ProviderId);delete_appointmentwrapsAppointment;create_encounterrewritten toEncounterCreate(per-service-lineDiagnosisCode1–4,RenderingProvider,Practice);update_encounter_statuswrapsEncounterUpdateStatuswith the real enum (Draft/Submitted/Approved/Rejected/Unpayable— "Review" is a UI label, not an API status);create_paymentuses thePaymentCreatenested groups;create_documentwrapsDocumentToCreatein member order;delete_documentsendsDocumentId(case-sensitive); external-ID tools useExternalVendor/Updates→UpdateBatchbatch shapes;create_appointment_reasonin member order with integer color;validate_connectionsends the credentialsGetCustomerIdFromKeyRequestactually expects.change:
tebra_update_patient_case→tebra_set_primary_patient_case— the underlying op (UpdatePrimaryPatientCase) only promotes a case to primary byPatientCaseId; it never accepted name/payer-scenario edits. Old tool name still routes.new:
tebra_update_appointment_status— targeted status changes (CheckedIn/NoShow/Cancelled...) viaUpdateAppointmentStatus, cheaper than a full update.fix(FHIR): default base URL corrected to
https://fhir.prd.cloud.tebra.com/fhir-request(hyphen — the old/fhir/requestpath returns HTTP 200 with an empty body for every call, verified live 2026-08-03); empty-200 responses now raise a descriptive configuration error; 401 triggers one automatic token refresh + retry; from/to date ranges emit two repeateddateparams (previously percent-encoded into one malformed value); Bundle pagination followed automatically (link[rel=next], up to 10 pages, truncation flagged); required second search params defaulted (MedicationRequest intent=order,CarePlan category=assess-plan,CareTeam status=active) — without them Tebra returns a silent empty bundle.new:
tebra_fhir_search_patients— FHIR Patient lookup by name/birthdate/identifier; FHIR patient IDs are a separate identifier space from SOAP IDs and previously had no in-server resolution path.fix(core):
extractTag/extractAllTagsrequire a tag-name boundary (Patientno longer matchesPatientData); server version is read from package.json (was hardcoded0.2.5); server name corrected totebra-mcp-server; rate-limit table keysCreatePayment/UpdateAppointmentStatus.
0.3.2 (2026-07-15)
chore: removed the bundled project-specific integration templates (
src/integrations/epic-notes-integration.ts,src/integrations/fal-integration.ts) and every reference to them (README "Integration Services" section, workflow-example labels, contributor docs). These were copy-paste connector modules for external downstream projects — never imported by the server and not part of its runtime — so they did not belong in the published package. No MCP tools were added or removed; the 45-tool surface is unchanged and the compiled tarball no longer shipsdist/integrations/.
0.3.1 (2026-07-07)
fix(get_charges):
<kar:Fields/>is now sent EMPTY. 0.3.0's explicit column toggles triggered Tebra's projection-inversion quirk — every call returned a single empty<ChargeData/>placeholder (zero real fields, no fault) regardless of filter matches. Empty Fields returns the full record, including thePrimaryInsurance*adjudication columns (payment, contract adjustment + reason, secondary adjustment + reason, adjudication date) the explicit toggles were meant to surface.Response parser (
parseChargeBlocks, exported) drops the empty placeholder block — a no-match response previously counted as one phantom all-empty charge.statusfilter documented with live-observed enum values:Pending,Completed,Error - Rejection,Voided,Ready. At least some accounts have NODeniedstatus — denials surface asError - Rejection.Verified live against production Tebra: a 12-month, 14-window pull returned 293 real charges with populated financials; server-side
Statusfiltering confirmed working.
0.3.0 (2026-07-06)
fix(get_charges): filter criteria moved out of
<kar:Fields>into<kar:Filter>, emitted in WSDL (xsd0) sequence order — inside Fields they were silently skipped by WCF, so GetCharges returned unfiltered data for the package's entire history.patientIdnow throws (ChargeFilter has no patient ID member; usepatientName).Note: Tebra enforces a server-side ≤60-day posting-date window on GetCharges.
0.2.6 (2026-07-06)
fix(get_appointment_detail):
GetAppointmentdoes NOT take theFields/Filterrequest shape the list endpoints use. Per the live WSDL (KareoServices.svc?xsd=xsd0),GetAppointmentReq = RequestBase + <Appointment>{ AppointmentId: xs:long }(lowercase "d"). The old envelope faulted on every call with'EndElement' 'request' … Expecting element 'Appointment', sotebra_get_appointment_detailnever worked against live Tebra.The response is the WSDL
AppointmentCreateshape — patient nested under<PatientSummary>(group attendees under<PatientSummaries>), ISOStartTime/EndTime,AppointmentStatus, enum-letterAppointmentType. The tool's output now maps these real fields (patient name + DOB, appointment mode, reason id, recurrence, group attendees, audit timestamps) instead of the fictionalAppointmentDatafield set.Verified live: full detail returned for a real appointment. Contributor lesson: single-record Tebra ops can have entirely different WSDL contracts from their list counterparts — read
?xsd=xsd0before assuming the Fields/Filter pattern.
0.2.5 (2026-04-28)
fix(soap): every GET request body now includes a sibling
<kar:Filter />after<kar:Fields>. Tebra's WSDL marksFilterasminOccurs="0", but their server-sideGetFilteredX(...)methods dereference the filter parameter without null-checking and throwNullReferenceExceptionwhen it's absent. Tools patched: practices, providers, service-locations, procedure-codes, transactions, payments, charges, encounters, patients (search + get-by-id), bulk-patients, appointments. Without 0.2.5, every GET call fails with a server-side NullRef.Added regression test asserting
<kar:Filter />is emitted in WSDL-required order (Fields before Filter).
0.2.4 (2026-04-28)
fix(soap):
<RequestHeader>children now serialize in WSDL-required order (CustomerKey → Password → User). The previousCustomerKey → User → Passwordorder caused silent authorization failures even with valid credentials. Confirmed in writing by Tebra customer care.
0.2.3 (2026-04-28)
fix(soap):
SOAPActionHTTP header now includes theKareoServices/WCF contract segment that Kareo's dispatcher requires. Versions 0.2.2 and earlier sent${SOAP_NAMESPACE}${operation}, which the dispatcher rejected with HTTP 500 (ContractFilter mismatch at the EndpointDispatcher). Header value is now also explicitly quoted per RFC 3902 §3.2.Added a regression test asserting the exact header value (
npm test).
0.2.2 (2026-04-27)
fix(soap):
RequestHeader(User/Password/CustomerKey) is now placed inside the request body where Tebra's WSDL expects it, rather than in the SOAP envelope header.
0.2.1 (2026-04-26)
Published to the MCP Registry under
com.jamesrosingmd/tebra(verified-domain namespace).
0.2.0
Initial public release.
Upgrade urgently from 0.2.4 or earlier. All prior releases hit at least one of the three wire-format bugs above, and only 0.2.5 satisfies all three of Tebra's WSDL/runtime requirements end-to-end.
License
MIT License
Copyright (c) 2026 James H. Rosing, MD, FACS
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Available Tools
34 toolstebra_check_insurance_eligibilityCheck Insurance EligibilityARead-only
Check insurance eligibility for a Tebra patient. Examines on-file insurance policies and authorization history. Note: this is an approximation based on on-file data, not a real-time payer eligibility check.
| Name | Required | Description | Default |
|---|---|---|---|
| patientId | Yes | Tebra patient ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds the caveat that this is an approximation based on on-file data and not a real-time check, which is beyond the readOnlyHint annotation. It doesn't contradict annotations and provides context about the reliability of the result.
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, front-loaded with the main action, and the caveat is succinctly stated. No 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?
For a single-parameter read-only tool with no output schema, the description covers the essential purpose and the approximation caveat. It could mention what the response contains, but that's minor given the simplicity.
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?
The input schema already describes patientId as 'Tebra patient ID' with 100% coverage. The description does not add additional parameter semantics beyond what the schema provides, so it's at baseline.
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 verb 'check' and the resource 'insurance eligibility' for a Tebra patient, and specifies it examines on-file policies and authorization history. It distinguishes from a real-time check, but does not explicitly name a sibling tool, so it's clear but not fully differentiated.
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 notes it's an approximation based on on-file data, not a real-time payer eligibility check, which implies when to use it (quick check) and when not (real-time need). However, it does not name an alternative tool or provide explicit 'when not to use' guidance, so it's only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_create_appointmentCreate AppointmentA
Create a new patient appointment in Tebra. Requires patient, provider, service location, start time, and either endDate or duration (minutes). Optionally set reason, mode (InOffice/Telehealth), status, and notes.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Optional appointment notes | |
| endDate | No | Appointment end date/time (ISO 8601); alternative to duration | |
| duration | No | Duration in minutes (used to compute end time when endDate is omitted) | |
| patientId | Yes | Tebra patient ID | |
| startDate | Yes | Appointment start date/time (ISO 8601, e.g. 2026-04-01T09:00:00) | |
| practiceId | No | Practice ID (required by Tebra; auto-resolved to the account's first practice if omitted) | |
| providerId | Yes | Tebra provider ID | |
| appointmentMode | No | Optional appointment mode | |
| appointmentName | No | Optional appointment display name | |
| appointmentStatus | No | Optional initial status (default 'Scheduled') | |
| serviceLocationId | Yes | Tebra service location ID | |
| appointmentReasonId | No | Optional Tebra appointment reason ID | |
| insurancePolicyAuthorizationId | No | Optional insurance authorization ID to link |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, so 'Create' is consistent and no contradiction exists. The description adds the useful 'either endDate or duration' constraint, but it does not disclose side effects, permission requirements, or what the response contains. With annotations covering basic safety, this is adequate but not rich.
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 filler: action first, required inputs second, optional inputs third. Every clause earns its place and the key creation constraint is front-loaded.
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 13-parameter tool with no output schema, the description covers the essential required fields, the critical endDate/duration constraint, and optional categories. It does not mention the return value, which an agent may need to know, but this is a minor gap since the schema and annotations already carry significant detail.
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 goes beyond the schema by explicitly stating that either endDate or duration is required—something the schema leaves ambiguous since both are optional—and it groups the optional fields (reason, mode, status, notes), which aids selection.
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 states a specific verb and resource: 'Create a new patient appointment in Tebra.' This clearly distinguishes it from siblings like update_appointment and delete_appointment by emphasizing 'new' and listing creation-specific required fields.
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 clearly implies use when creating an appointment and lists the necessary inputs, but it does not explicitly contrast with alternatives such as update_appointment or delete_appointment, nor does it provide when-not-to-use guidance. It conveys context but leaves exclusion logic unstated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_create_appointment_reasonCreate Appointment ReasonA
Create a new appointment reason in Tebra with name and default duration. Color is a Tebra color code number (not hex).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Appointment reason name | |
| color | No | Optional Tebra color code (integer) | |
| duration | Yes | Default duration in minutes | |
| practiceId | No | Optional practice ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and destructiveHint=false. The description adds a useful clarification about the color format, but does not disclose other behavioral aspects such as potential duplicate handling, output/return behavior, or authentication requirements. There is no contradiction with 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 two sentences with no filler. It front-loads the purpose and includes only the most important non-obvious parameter detail (color format). 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 simple creation tool with rich schema descriptions and annotations, the description covers what is needed. It lacks an explicit note about return values or unique constraints, but the verb 'Create' plus the schema and annotations give sufficient context for correct invocation.
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 extra meaning by clarifying that color is a Tebra color code number, not hex, which goes beyond the schema's 'Optional Tebra color code (integer)'. The other parameters are adequately described in the 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 states a specific action ('Create') and resource ('appointment reason') with the key fields involved. It clearly differentiates from sibling create tools like tebra_create_appointment and tebra_create_patient by naming the unique resource.
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 usage when a new appointment reason is needed, but it does not explicitly state when to use this tool over alternatives or mention related tools like tebra_get_appointment_reasons for checking existing reasons. No exclusions or prerequisites are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_create_documentCreate DocumentA
Upload a document to a patient record in Tebra via base64 content (PDF, JPG, PNG, TIFF — type inferred from the file extension). documentLabel must be a Tebra DocumentLabel enum value (CamelCase, no spaces), e.g.: MedicalReport, PatientAuthorizationOrReferral, PatientCorrespondence, PatientDemographics, PatientInsuranceCard, PatientDriversLicense, Superbill, ExplanationofBenefits, InsuranceCorrespondence, OperativeReport, ... Use 'Other' when unsure.
| Name | Required | Description | Default |
|---|---|---|---|
| fileName | Yes | File name with extension (e.g. lab_results.pdf) — the extension determines the file type | |
| patientId | Yes | Tebra patient ID | |
| practiceId | No | Practice ID (required by Tebra; auto-resolved to the account's first practice if omitted) | |
| description | No | Optional document description/notes | |
| fileContent | Yes | Base64-encoded file content | |
| documentName | No | Optional display name for the document (defaults to fileName) | |
| documentLabel | Yes | Document category label from the Tebra DocumentLabel enum (e.g. MedicalReport, PatientAuthorizationOrReferral, PatientCorrespondence, PatientDemographics, PatientInsuranceCard, PatientDriversLicense, Other). Spaces are stripped automatically. | |
| encounterDate | No | Optional document date to associate with (ISO 8601) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavioral detail beyond the annotations: file type is inferred from the extension, documentLabel must be a CamelCase enum value, spaces are stripped automatically, and 'Other' is a safe fallback. This is useful context on top of the readOnlyHint/idempotentHint/destructiveHint 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 purpose statement is front-loaded in one precise sentence, and the follow-up sentence provides high-value enum guidance. The list of examples is long but directly necessary for correct invocation, and no sentence is wasted.
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 an 8-parameter create operation with no output schema, the description plus schema cover everything needed to call the tool correctly: required parameters, accepted file types, base64 content format, label enum constraints, and practiceId auto-resolution behavior. No essential invocation detail is missing.
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?
The input schema already documents all eight parameters, so the baseline is 3. The description adds value by explaining documentLabel semantics (CamelCase, no spaces, enum examples, fallback to Other) and how fileName's extension determines the accepted file type, which goes beyond the schema 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?
The description uses a specific verb and resource: 'Upload a document to a patient record in Tebra' and specifies the mechanism (base64 content) and accepted file types (PDF, JPG, PNG, TIFF). This clearly differentiates it from the only close sibling (tebra_delete_document) and from patient/appointment creation tools.
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 intended use is clear: when a document needs to be attached to a Tebra patient record. It does not explicitly discuss alternatives or when not to use the tool, but no close alternative exists among the siblings, and the guidance to use 'Other' when unsure helps the agent choose an appropriate label.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_create_encounterCreate EncounterA
Create a new encounter (superbill) in Tebra with diagnoses and procedures. Each procedure becomes a service line carrying up to 4 ICD-10 diagnosis codes (from the encounter-level diagnoses array, or per-procedure diagnosisCodes). practiceName or practiceId is strongly recommended — Tebra requires the practice on most accounts. Returns the created encounter ID.
| Name | Required | Description | Default |
|---|---|---|---|
| caseId | No | Optional patient case ID to bill under | |
| diagnoses | Yes | Encounter-level diagnosis codes; the first 4 are applied to each service line | |
| patientId | Yes | Tebra patient ID | |
| practiceId | No | Practice ID (alternative to practiceName) | |
| procedures | Yes | Array of procedures; each becomes one service line | |
| providerId | Yes | Rendering provider ID | |
| serviceDate | Yes | Date of service (ISO 8601, e.g. 2026-03-25) | |
| practiceName | No | Practice name (strongly recommended; required by Tebra on most accounts) | |
| authorizationId | No | Optional authorization number to link | |
| encounterStatus | No | Initial encounter status (default 'Draft'; 'Approved' triggers billing) | |
| serviceLocationId | No | Optional service location ID | |
| placeOfServiceCode | No | Optional place of service code (e.g. 11 for office) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, so the safety profile is known. The description adds valuable behavioral context: each procedure becomes a service line with diagnosis mapping, the practice requirement on most accounts, and the return of the created encounter ID. It does not contradict 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 sentences with zero filler. The primary purpose is front-loaded, followed by the critical service-line behavior and the practice requirement, then the return value. Every sentence 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 12-parameter tool with no output schema, the description covers the essential behavior: creation, service-line structure, diagnosis mapping, and practice requirement. It doesn't explicitly mention error conditions or default status, but the schema covers the 'Draft' default and enum options. The description is adequate for an agent to invoke it correctly.
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 all parameters are documented. The description adds meaning beyond the schema by explaining how diagnoses and procedures interact (encounter-level diagnoses applied per service line, per-procedure override) and the strong recommendation for practice identification. This helps the agent understand the intent behind parameter combinations.
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 action: 'Create a new encounter (superbill) in Tebra with diagnoses and procedures.' It uses a specific verb and resource, and distinguishes itself from sibling tools like tebra_update_encounter_status or tebra_get_encounter by focusing on creation. The mention of 'superbill' adds domain specificity.
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 usage (when you need to create an encounter) but does not explicitly state when not to use it or mention alternatives. It gives parameter-level guidance (practiceName/practiceId strongly recommended) but lacks tool-selection context compared to sibling operations. No exclusions or alternative tool names are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_create_patientCreate PatientA
Create a new patient in Tebra with demographics, address, insurance, and guarantor information. The practice is required by Tebra; if practiceName/practiceId are omitted, the account's first practice is used automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| mrn | No | Optional medical record number | |
| ssn | No | Optional SSN | |
| city | No | Optional city | |
| No | Optional email address | ||
| state | No | Optional state (2-letter abbreviation) | |
| gender | No | Optional gender (Tebra GenderCode: Male, Female, Unknown) | |
| zipCode | No | Optional ZIP code | |
| address1 | No | Optional street address line 1 | |
| address2 | No | Optional street address line 2 | |
| lastName | Yes | Patient last name | |
| firstName | Yes | Patient first name | |
| guarantor | No | Optional guarantor information | |
| homePhone | No | Optional home phone number | |
| externalId | No | Optional external system ID | |
| practiceId | No | Practice ID (alternative to practiceName) | |
| dateOfBirth | Yes | Date of birth (ISO 8601, e.g. 1990-01-15) | |
| mobilePhone | No | Optional mobile phone number | |
| practiceName | No | Practice name (auto-resolved to the account's first practice if omitted) | |
| referralSource | No | Optional referral source | |
| primaryInsurance | No | Optional primary insurance (created inside a default patient case) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false (mutation) and idempotentHint=false. The description adds a key behavioral detail: the practice is required but defaults to the account's first practice if practiceName/practiceId are omitted. This goes beyond annotations and helps the agent understand a non-obvious default. No contradiction with 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 sentences, each purposeful. The first states the core function, the second highlights the practice requirement/default. No filler, and the most critical usage note is front-loaded.
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?
The tool has 20 parameters and nested objects, and no output schema. The description does not mention what the tool returns (e.g., patient ID) or any post-creation behavior. Since there is no output schema, the description carries the burden of explaining the result, which it omits. This is a notable gap for a create 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 description coverage is 100%, so the schema already documents every parameter. The description adds no additional semantic detail beyond grouping parameters into categories; it does not clarify edge cases or relationships that the schema misses. 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 the verb 'Create' and the resource 'new patient in Tebra', and enumerates the major data categories (demographics, address, insurance, guarantor). This distinguishes it from siblings like tebra_update_patient and tebra_get_patient, which are obviously different operations.
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 this is for creating new patients but does not explicitly state when to use it instead of alternatives such as tebra_update_patient or tebra_search_patients. It gives no 'when-not-to-use' guidance, leaving the agent to infer from the tool name and sibling context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_create_paymentCreate PaymentA
Create a new patient payment in Tebra. Supports Cash, Check, CreditCard, ElectronicFundsTransfer, and Other payment methods. Optionally link to an appointment and practice. Not retried after a timeout or server error (Tebra has no idempotency key, so a re-send can double-charge); if the call fails with an unknown outcome, check tebra_get_payments before resubmitting. Supply referenceNumber so any duplicate is detectable.
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | Payment amount in dollars (e.g. 150.00) | |
| patientId | Yes | Tebra patient ID | |
| payerType | No | Optional payer type (defaults to 'Patient') | |
| batchNumber | No | Optional batch number | |
| paymentDate | No | Optional payment post date (ISO 8601, defaults to today server-side) | |
| practiceName | No | Optional practice name (recommended for multi-practice accounts) | |
| appointmentId | No | Optional appointment ID to link payment to | |
| paymentMethod | Yes | Payment method: Cash, Check, CreditCard, ElectronicFundsTransfer, or Other | |
| referenceNumber | No | Optional reference or check number |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate non-idempotent, non-read-only behavior, and the description enriches this substantially by explaining the double-charge risk and the lack of an idempotency key. It also advises checking tebra_get_payments before resubmission, adding operational context beyond the structured metadata.
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 compact and front-loaded with the core purpose, followed by essential caveats about retries and idempotency. Every sentence contributes value; there is 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?
Given the tool has 9 parameters and no output schema, the description covers the action, supported methods, failure handling, and duplicate mitigation. It doesn't describe the response format, which could be a minor gap for agents expecting to parse a created entity, but the critical operational details are well addressed.
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 all 9 parameters are already documented with descriptions. The description adds meaningful extra semantics, particularly around referenceNumber for duplicate detection and the optional linking to appointment/practice. This goes beyond the schema, providing practical guidance on how parameters relate to real-world usage.
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 states a clear, specific action: 'Create a new patient payment in Tebra' with a verb and resource, and explicitly lists the supported payment methods. It distinguishes itself from the sibling 'tebra_get_payments' by being the creation counterpart, making its purpose unambiguous.
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?
Provides explicit guidance on when to use the tool (creating a payment) and critical failure-handling instructions: not to retry after timeout/server error, and to check tebra_get_payments on unknown outcomes to avoid double-charging. It also recommends supplying referenceNumber for duplicate detection. It doesn't explicitly state when not to use it, but the context is clear for a creation operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_delete_appointmentDelete AppointmentADestructiveIdempotent
Delete an appointment from Tebra by appointment ID. This is irreversible — to keep history, prefer tebra_update_appointment_status with Cancelled.
| Name | Required | Description | Default |
|---|---|---|---|
| appointmentId | Yes | Tebra appointment ID to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide destructiveHint=true and idempotentHint=true. The description adds the stronger nuance 'irreversible' and the suggestion to use an alternative for history, which goes beyond the annotations. No contradiction.
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, front-loaded with the core action and the irreversible warning, followed by the alternative. Zero 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?
For a single-parameter delete with no output schema, the description covers the essential: action, irreversibility, and alternative. It does not detail error handling or return values, but those are minor given the tool's simplicity.
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%: appointmentId is described as 'Tebra appointment ID to delete', which is sufficient. The description adds no extra parameter details, but the schema already handles it. 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?
States a specific verb (delete) + resource (appointment) + identifier (appointment ID). Clearly distinguishes from tebra_update_appointment_status by naming the alternative and its purpose. No ambiguity.
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 when to use (permanent deletion) and when not to (when history is needed), and names the alternative tool (tebra_update_appointment_status with Cancelled). Provides a clear decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_delete_documentDelete DocumentADestructiveIdempotent
Delete a document from Tebra by document ID. This is irreversible.
| Name | Required | Description | Default |
|---|---|---|---|
| documentId | Yes | Tebra document ID to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, but the description adds the explicit consequence that deletion is irreversible, which is valuable cautionary context beyond the structured hint. It doesn't cover side effects or permissions, but the irreversibility warning is meaningful.
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 short sentences, zero filler, and the key warning ('This is irreversible') is front-loaded. The description is as compact as it can be while remaining informative.
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 single-parameter deletion tool with strong annotations (destructiveHint, idempotentHint), the description together with the schema is largely complete. It omits output/error behavior, but that is a minor gap for such a simple 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% and the schema already describes documentId as 'Tebra document ID to delete.' The description merely restates 'by document ID' and adds no format, validation, or sourcing details.
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?
States a specific action (delete), a specific resource (document), and the key by which the document is targeted (document ID). It is also clearly distinct from siblings like tebra_delete_appointment and tebra_create_document.
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?
Usage is implied: call this when a specific Tebra document must be removed. However, it gives no explicit when-not-to-use guidance or mention of alternatives, leaving tool selection mostly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_all_patientsGet All PatientsARead-only
Get all patients in bulk with pagination. Returns a page of patients and a continuation key for the next page. Use startKey from the previous response to get the next batch. By default each row is a roster entry (patientId, firstName, lastName, dateOfBirth, mrn, active); pass fields to request contact, insurance, or practice columns.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| isActive | No | Optional filter: true for active patients only, false for inactive only (applied client-side; the returned count reflects the filtered page) | |
| startKey | No | Continuation key from previous response (omit for first page) | |
| batchSize | No | Number of patients per page (default 200, max 1000) | |
| practiceId | No | Optional practice ID filter |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, and the description adds meaningful behavior: it returns a page plus a continuation key, requires startKey from the prior response, and documents the default roster entry field set. This goes beyond the annotations and helps the agent predict the response shape even without an output schema.
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 tight sentences front-load the core purpose, then explain pagination, and then describe the default field set and how to extend it. There is no filler, repetition, or content that belongs only in the schema.
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 bulk-read tool with full parameter documentation, readOnlyHint, and no output schema, this description is complete. It covers the return shape, pagination mechanism, default fields, and how to request additional fields, leaving no critical gap for an agent deciding to call it.
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 description coverage is 100%, so all five parameters are already documented with their own descriptions. The description reinforces startKey and fields usage but does not add significant new semantic detail beyond what the schema provides. 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 opens with 'Get all patients in bulk with pagination,' which gives a specific verb, resource, and scope. It clearly distinguishes this from sibling tools like tebra_get_patient and tebra_search_patients by emphasizing bulk retrieval of all patients rather than a single record or a filtered search.
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 gives clear operational context: use it for bulk patient retrieval, follow pagination with startKey, and pass fields for additional columns. It does not explicitly name alternatives or state when not to use it, but the bulk-vs-single distinction is strongly implied by the wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_appointment_detailGet Appointment DetailARead-only
Get full detail for a single appointment by ID, including recurrence rules, group data, and all resource slots.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| appointmentId | Yes | Tebra appointment ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description does not contradict this. It adds details about the response content (recurrence rules, group data, resource slots) but does not disclose additional behavioral traits such as authentication requirements, rate limits, or side effects. Since the annotations cover the read-only aspect, a 3 is appropriate for adding only marginal behavioral context.
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?
A single sentence that front-loads the verb and resource, then packs the key inclusion details. There is zero waste; every word 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?
For a read-only single-resource tool with two well-documented parameters and no output schema, the description fully covers what the agent needs to call it correctly: it specifies the identifier and the type of data returned. Nothing essential is missing.
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 description coverage is 100%: both parameters (appointmentId and fields) have descriptions in the schema. The tool description does not add extra parameter-level meaning beyond what the schema already provides, so the baseline of 3 applies. The fields parameter's PHI warning is already in the schema description, not the tool description.
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 uses a specific verb ('Get') with a clear resource ('full detail for a single appointment by ID') and enumerates the included content (recurrence rules, group data, resource slots), distinguishing it from sibling tools like tebra_get_appointments that list appointments. It is immediately clear what the tool does and how it differs from a list operation.
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 usage: this tool is for retrieving the full detail of a single appointment by ID, while tebra_get_appointments likely handles listing. It provides clear context for when to use it but does not explicitly name alternatives or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_appointment_reasonsGet Appointment ReasonsARead-only
Get all appointment reasons configured in the practice. Returns reason IDs, names, default durations, and color codes. Needed to create appointments with a reason.
| Name | Required | Description | Default |
|---|---|---|---|
| practiceId | No | Practice ID (defaults to the account's first practice) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful behavioral context by stating that it returns all reasons and listing what those returns contain, going beyond the schema without contradicting the 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 three short sentences with no filler. The core action is front-loaded, the return values are listed immediately after, and the practical dependency on appointments is stated last. Every sentence 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 read-only lookup with one optional parameter and no output schema, the description is complete: it tells the agent what the tool returns, why it is needed, and the only decision point (which practice). No critical information is missing for correct invocation.
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 the sole parameter practiceId already described as defaulting to the account's first practice. The description adds no new parameter-level meaning, so the baseline score of 3 is appropriate given that the schema handles semantic documentation.
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 identifies a specific resource (appointment reasons configured in the practice) and a specific action (Get all), then enumerates the returned fields (IDs, names, default durations, color codes). This fully distinguishes the tool from its siblings, such as create_appointment_reason and get_appointments, without ambiguity.
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 explicitly states that this tool is 'Needed to create appointments with a reason,' giving an agent a clear context for when to invoke it. It does not list alternatives or exclusions, but for a simple read-only lookup this is sufficient practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_appointmentsGet AppointmentsARead-only
Get appointments from Tebra within a date range. Filter by resource (provider name), patient, confirmation status, service location, reason, type, and more. To filter by provider, use resourceName with the provider full name (the WSDL has no provider ID filter).
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| endDate | Yes | End date (ISO 8601, e.g. 2026-03-31) | |
| patientId | No | Filter by Tebra patient ID | |
| startDate | Yes | Start date (ISO 8601, e.g. 2026-03-25) | |
| practiceName | No | Filter by practice name | |
| resourceName | No | Scheduler resource name to filter by — for provider filtering, pass the provider full name | |
| toCreatedDate | No | Created date range end (YYYY-MM-DD) | |
| appointmentType | No | Filter by type: U=Unknown, P=Patient, O=Other | |
| fromCreatedDate | No | Created date range start (YYYY-MM-DD) | |
| patientFullName | No | Filter by patient full name | |
| appointmentReason | No | Filter by appointment reason | |
| casePayerScenario | No | Patient case payer scenario filter | |
| confirmationStatus | No | Filter by confirmation status | |
| toLastModifiedDate | No | Modified date range end (YYYY-MM-DD) | |
| serviceLocationName | No | Filter by service location name | |
| fromLastModifiedDate | No | Modified date range start (YYYY-MM-DD) | |
| timeZoneOffsetFromGMT | No | Time zone offset from GMT for returned times (e.g. -8) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint and openWorldHint annotations already establish that this is a safe read operation. The description adds one useful behavioral nuance—the provider filtering workaround—but does not disclose other behavior such as result format, paging, or limits. This is acceptable but not rich.
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 no wasted words. The primary purpose and date-range scope come first, followed by the filter capabilities and the most important parameter nuance. Every sentence 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 read-only list tool with a fully self-documenting schema, the description is sufficient for correct invocation: it names the scope, the available filters, and the provider-filtering caveat. The lack of an output schema and any mention of response shape is a minor gap, but not critical given the strong schema and annotation coverage.
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 description coverage is 100%, so the schema already documents all 17 parameters. The description summarizes filter categories and restates the resourceName/provider guidance already present in the schema, but adds little new parameter-level meaning beyond that.
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 verb and resource: getting appointments from Tebra within a date range, with filtering options. It is easy to distinguish from a detail-fetch tool, though it does not explicitly name sibling tools like tebra_get_appointment_detail, so it stops short of full sibling differentiation.
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 gives clear usage context: use this to retrieve date-filtered appointment lists with multiple filter dimensions. It also provides a useful provider-filtering rule (use resourceName with provider full name because the WSDL has no provider ID filter). It does not explicitly state when not to use it or name alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_chargesGet ChargesARead-only
Get charges from Tebra with flexible filters: date range, patient name, provider, procedure/diagnosis codes, billing status, encounter status, and more. Returns charge details with payer, adjudication, adjustment reasons, amounts, and balances. Note: posting-date range is limited to 60 days server-side.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| status | No | Charge status filter. Observed values include 'Pending', 'Completed', 'Error - Rejection', 'Voided', 'Ready'. Note: 'Denied' is not a status Tebra uses; rejected claims carry 'Error - Rejection'. | |
| toDate | No | Service end date filter (ISO 8601) | |
| billedTo | No | Billed-to entity filter | |
| fromDate | No | Service start date filter (ISO 8601) | |
| batchNumber | No | Filter by batch number | |
| patientName | No | Patient full name to filter by (ChargeFilter has no patient ID member) | |
| diagnosisCode | No | Filter by ICD diagnosis code | |
| procedureCode | No | Filter by CPT procedure code | |
| toCreatedDate | No | Created date range end (YYYY-MM-DD) | |
| toPostingDate | No | Posting date range end (YYYY-MM-DD); max 60 days from fromPostingDate | |
| encounterStatus | No | Encounter status filter | |
| fromCreatedDate | No | Created date range start (YYYY-MM-DD) | |
| fromPostingDate | No | Posting date range start (YYYY-MM-DD); max 60 days from toPostingDate | |
| casePayerScenario | No | Case payer scenario filter | |
| toLastModifiedDate | No | Modified date range end (YYYY-MM-DD) | |
| fromLastModifiedDate | No | Modified date range start (YYYY-MM-DD) | |
| renderingProviderName | No | Rendering provider full name | |
| includeUnapprovedCharges | No | Include unapproved charges (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description does not need to restate safety. The description adds valuable behavioral context beyond the annotations, notably the server-side 60-day limit on posting-date ranges menus, and it explains what kind of charge details the result contains. No contradiction with annotations exists.
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 three sentences long, front-loads the core purpose in the first sentence, and gives a concise summary of outputs and a key limitation. There is no filler, repetition of schema properties, or unnecessary detail that would burden an agent selecting or invoking the tool.
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 read-only filtered-list tool with 19 optional parameters, the description covers the core inputs, the output shape, and an important server-side constraint. There is no output schema, but the description names the key returned groups (payer, adjudication, adjustment reasons, amounts, balances). Pagination and default field-set behavior are not described, but the annotations and schema already mitigate most gaps.
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 the schema already documents all 19 parameters with meaningful descriptions. The tool description mostly summarizes filter categories that the schema already names individually, adding little new parameter-level meaning; the 60-day caveat is also already present in the posting-date parameter 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?
The description clearly states a specific verb and resource: 'Get charges from Tebra', and lists both the available filter dimensions and the returned charge details. It is distinguishable from sibling tools like tebra_get_payments and tebra_get_transactions because it explicitly targets 'charges', though it does not name or contrast those alternatives.
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 tool's use is implied by the description: an agent can tell it is meant for retrieving charge records using various filterscombinations and seeing payer/adjudication details. However, there is no explicit guidance about when to choose this over related tools such as get_payments or get_transactions, and no stated exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_encounterGet EncounterARead-only
Get encounter details from Tebra by encounter ID, including patient, providers, status, service dates, place of service, and service line IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| encounterId | Yes | Tebra encounter ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, covering the safety profile. The description adds the list of returned fields, which provides context about the response content but not about any side effects or edge-case behaviors. It does not contradict the annotations and offers modest additional value.
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 states the purpose and key outputs without redundancy. Every word earns its place, making it highly efficient and easy to parse.
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 simple getter with two parameters and no output schema, the description is mostly complete. It lists several key fields but not exhaustively, and does not mention error behavior (e.g., 404 on missing ID). However, the fields parameter allows custom selection, mitigating the need for a full field list. The annotations cover safety, so the definition is adequate for an agent to call it correctly.
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 well-described: encounterId is simply a Tebra ID, and fields includes dotted-path guidance and a PHI warning. The description's mention of the default field set adds a small amount of context beyond the schema but does not significantly enhance parameter understanding.
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 uses a specific verb (Get), names the resource (encounter details), and lists the key returned fields (patient, providers, status, service dates, place of service, service line IDs). This clearly distinguishes it from sibling tools like get_charges or get_appointment_detail, which target different resources.
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 usage when you need encounter details by ID, but it does not explicitly mention alternatives or conditions for not using this tool. There is no guidance on choosing between this and related tools like tebra_get_appointment_detail, so the usage context is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_external_vendorsGet External VendorsARead-only
Get all registered external vendors in Tebra with their IDs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint and openWorldHint, covering the safety profile. The description adds that it returns the complete set of registered vendors with IDs, but it does not describe response shape, pagination, or potential scale. This is acceptable but not rich.
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?
A single front-loaded sentence with no wasted words. Every element—action, scope, qualification ('registered'), and output ('with their IDs')—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 zero-parameter, read-only list tool, this is nearly complete: annotations handle safety, and the description states scope and key return content. The main gap is the lack of an output schema and no mention of the exact list shape or pagination, but that is a minor omission for such a simple 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?
The tool has zero parameters and an empty schema, so there is little to document. The description's 'all registered' usefully reinforces that no filtering parameters exist and the result is the complete vendor collection, adding meaning beyond the empty 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 uses a specific verb ('Get') and a clear resource ('all registered external vendors in Tebra') while also indicating the key output ('with their IDs'). It is immediately distinguishable from sibling tools like tebra_register_external_vendor.
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 phrase 'all registered external vendors' gives clear context: this tool is for retrieving the full vendor list. It does not explicitly name alternative tools or exclusion conditions, but there is no competing list tool for external vendors among the siblings, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_patientGet PatientARead-only
Get a full patient record from Tebra by patient ID, or by external system ID (optionally scoped to an external vendor). Includes demographics, contact info, cases, insurance policies, and authorizations. Insurance policy and group numbers are omitted unless named in fields.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| patientId | No | Tebra patient ID (numeric) | |
| externalId | No | External system ID (alternative to patientId) | |
| externalVendorId | No | Optional external vendor ID to scope the externalId lookup |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true; the description adds a genuinely non-obvious data-visibility quirk: 'Insurance policy and group numbers are omitted unless named in fields'. This materially affects what the agent receives. It does not disclose error behavior or identifier-precedence semantics, but for a read-only fetch the disclosure is strong.
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 sentences, front-loaded with the action and identifier alternatives, then return contents, then the sensitive-data caveat. Every sentence earns its place with no filler or repetition of schema text.
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 read-only fetch with four well-documented parameters, the description covers return content categories and the fields caveat, and the annotations carry the safety profile. The main gap is the identifier requirement: required is empty and the description does not state that exactly one of patientId/externalId should be supplied or what happens if both are passed.
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 the baseline is 3; the description adds meaning by tying the fields parameter to the insurance/group-number omission behavior and by framing externalVendorId as optionally scoping the externalId lookup. It stops short of explaining precedence if both patientId and externalId are supplied, which the required:[] schema leaves ambiguous.
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?
States a specific verb and resource: 'Get a full patient record from Tebra' by patientId or externalId. The scope phrase 'full patient record' plus the listed contents (demographics, contact, cases, insurance, authorizations) distinguishes it from subset siblings like tebra_get_patient_authorizations and from search/bulk tools. Clear and actionable without needing to open the schema.
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 lookup methods ('by patient ID, or by external system ID') imply when the tool applies, but there is no explicit when-to-use vs alternatives such as tebra_search_patients (when no ID is known) or tebra_get_patient_authorizations (authorizations only). No exclusions or alternative routing are given, so usage context is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_patient_authorizationsGet Patient AuthorizationsARead-only
Get all insurance authorizations for a Tebra patient across all cases and policies. Returns auth number, approved/used/remaining visits, start/end dates, computed status (active/exhausted/expired/pending), payer contact info, and an expiring-soon warning.
| Name | Required | Description | Default |
|---|---|---|---|
| patientId | Yes | Tebra patient ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and open-world, and the description adds meaningful behavioral context beyond them: it returns computed status values (active/exhausted/expired/pending), payer contact info, and an expiring-soon warning. This helps set expectations without contradicting the 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 sentences with no filler. The first sentence front-loads the core action and scope; the second concisely enumerates the useful returned fields. Every clause 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?
With one simple parameter, no output schema, and read-only annotations, the description covers the key return aspects: auth number, visit counts, dates, computed status, payer contact info, and expiring-soon warning. It does not mention pagination or error behavior, but for a straightforward read-only lookup this is a minor gap.
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% and the single parameter, patientId, is already described as 'Tebra patient ID'. The description does not add further detail about the parameter, but none is needed given the schema's completeness.
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 verb ('Get') and resource ('insurance authorizations for a Tebra patient'), and adds scope ('across all cases and policies'). It does not explicitly distinguish itself from sibling tools like tebra_check_insurance_eligibility, so it stops short of a 5.
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 intended use is implied by the description: an agent should call this when it needs a patient's insurance authorizations and their status. However, there is no explicit guidance about when not to use it or which alternative tool to choose, such as eligibility checking.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_paymentsGet PaymentsBRead-only
Get payments from Tebra with optional post-date range, payer, batch, appointment, and reference-number filters. Returns payment details with amounts, methods, and payer info. Note: the Tebra WSDL has no patient ID filter for payments.
| Name | Required | Description | Default |
|---|---|---|---|
| amount | No | Optional exact amount filter | |
| payerName | No | Optional payer name filter | |
| payerType | No | Optional payer type filter (e.g. Patient, Insurance) | |
| paymentId | No | Optional payment ID lookup | |
| toPostDate | No | Optional end post date filter (ISO 8601) | |
| batchNumber | No | Optional batch number filter | |
| fromPostDate | No | Optional start post date filter (ISO 8601) | |
| practiceName | No | Optional practice name filter | |
| appointmentId | No | Optional appointment ID filter | |
| toCreatedDate | No | Optional end created date filter (ISO 8601) | |
| fromCreatedDate | No | Optional start created date filter (ISO 8601) | |
| referenceNumber | No | Optional reference/check number filter | |
| toLastModifiedDate | No | Optional end last-modified date filter (ISO 8601) | |
| fromLastModifiedDate | No | Optional start last-modified date filter (ISO 8601) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only nature is covered. The description adds the note about the Tebra WSDL lacking a patient ID filter, which is a useful external constraint. However, it does not describe return format, pagination, or how filters interact (AND/OR). With annotations covering 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 concise—two sentences plus a note—with no fluff. It front-loads the core action and filter categories. It could be slightly more structured, but it is efficient and readable. The note about the WSDL limitation is a valuable addition without excessive length.
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 with 14 optional parameters and no output schema, the description is incomplete. It does not explain whether it returns a single payment or a list, how filters combine, or any default behavior (e.g., date range default). It also does not mention response structure or error conditions. Given the complexity, more contextual detail is needed for an agent to call it correctly.
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 description coverage is 100%, so all 14 parameters have descriptions in the schema. The tool description summarizes some filters (post-date range, payer, batch, appointment, reference-number) but omits others like amount, paymentId, practiceName, and created/last-modified dates. Since the schema does the heavy lifting, the description adds minimal additional meaning beyond the schema, warranting a baseline 3.
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 verb 'Get' and the resource 'payments', and lists specific filters (post-date range, payer, batch, appointment, reference-number). It also adds a useful note about the missing patient ID filter. However, it does not explicitly differentiate from sibling tools like tebra_get_charges or tebra_get_transactions, though the resource is unambiguous.
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 no guidance on when to use this tool versus alternatives. It does not mention any exclusions or scenarios where another tool would be more appropriate. The only hint is the patient ID filter limitation, but it does not point to a substitute. An agent is left to infer usage from the name and filters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_practicesGet PracticesARead-only
Get all practices associated with the Tebra account. Returns practice IDs, names, NPI, tax ID, and contact info.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds scope ('all practices associated with the Tebra account') and return-field context, but does not discuss potential pagination, rate limits, or open-world caveats. This is acceptable but not rich.
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 one clean sentence that front-loads the action and scope, then lists the returned data fields. Every word contributes value and there is no redundant filler.
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 parameterless read-only list tool, this is complete: it states what is returned, the scope ('all practices associated with the Tebra account'), and the key output fields. No output schema exists, but the description fills that gap adequately.
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?
The input schema has zero parameters and 100% description coverage, so there is nothing for the description to explain. The baseline of 4 for parameterless tools applies, and the description appropriately focuses on outputs instead.
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 uses a specific verb and resource: 'Get all practices associated with the Tebra account.' It also enumerates the returned fields (practice IDs, names, NPI, tax ID, contact info), making the tool's purpose unmistakable and distinguishing it from sibling getters like providers or service locations.
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 clear usage: call this tool when you need the account's practice-level identifiers or contact information. It provides enough context for an agent to select it over other getters, and there are no competing practice-related siblings, though it does not explicitly state exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_procedure_codesGet Procedure CodesARead-only
Get procedure codes configured in the Tebra practice. Optionally filter by CPT code, active status, or customer-specific codes. Returns codes with official names, descriptions, and default units.
| Name | Required | Description | Default |
|---|---|---|---|
| active | No | Optional filter for active codes only | |
| searchTerm | No | Optional CPT/procedure code to filter by (e.g. 99213) | |
| customerSpecific | No | Optional filter for customer-specific codes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description is consistent with that ('Get', 'Returns'). It adds useful context by scoping to codes 'configured in the Tebra practice' and by naming the returned fields, which is valuable given there is no output schema.
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 tight sentences with no filler. It front-loads the core purpose, then covers filtering and return contents efficiently.
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 read-only lookup tool with three optional filters and no output schema, the description covers purpose, scope, filters, and return fields. It does not mention pagination or limits, but the annotations already cover the read-only and open-world safety profile.
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?
The input schema already documents all three optional parameters with 100% coverage. The description paraphrases those same filters (CPT code, active status, customer-specific) but adds no deeper semantics such as matching behavior, defaults, or interaction between filters.
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 identifies a specific resource ('procedure codes configured in the Tebra practice') and a specific action ('Get'), and adds meaningful detail about filters and returned fields. This distinguishes it from sibling tools like charges, appointments, or payments.
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?
No guidance is given about when to use this tool versus alternatives, and no exclusions or prerequisites are mentioned. Sibling tools like tebra_get_charges and tebra_get_transactions exist, but the description does not explain how procedure codes fit into that selection space.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_providersGet ProvidersARead-only
Get providers with IDs, names, specialties, NPI, and active status. Optionally filter by full name, practice, department, or provider type. Used to resolve provider names to IDs for appointments and encounters.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Optional provider type filter | |
| fullName | No | Optional provider full name filter | |
| practiceId | No | Optional practice ID filter | |
| practiceName | No | Optional practice name filter | |
| departmentName | No | Optional department name filter |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, covering the safety and non-exhaustive nature of the result set. The description adds context about returned fields and filter options, but it does not disclose pagination behavior, whether results are limited, or how filters match (exact vs partial). Given the annotation coverage, this is adequate but not extensive.
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 no filler: the first states the core operation and output, the second covers the filters and use case. Information 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 read-only lookup tool with five optional parameters and no output schema, the description provides the key facts: what is returned, what filters exist, and why to use it. It could be more complete by explicitly stating the response shape (e.g., list vs single object), but the 'Get providers with...' phrasing and readOnlyHint make the expectation reasonably clear.
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 description coverage is 100%, so all five optional parameters are already documented with their names and filters. The description restates the filter capabilities ('full name, practice, department, or provider type') but adds no detail beyond the schema about matching semantics or value formats. Baseline 3 applies because the schema carries the load.
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 states a specific verb and resource — 'Get providers' — and enumerates the returned fields: IDs, names, specialties, NPI, and active status. This clearly distinguishes it from sibling getter tools like tebra_get_practices or tebra_get_service_locations by naming the exact resource and its purpose.
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 gives a clear usage context: 'Used to resolve provider names to IDs for appointments and encounters.' This tells an agent when to reach for this tool, though it does not explicitly state when not to use it or name alternatives like tebra_get_practices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_service_locationsGet Service LocationsARead-only
Get all service locations (offices/facilities). Required for creating appointments and encounters. Optionally filter by practice or location ID.
| Name | Required | Description | Default |
|---|---|---|---|
| practiceId | No | Optional practice ID filter | |
| practiceName | No | Optional practice name filter | |
| serviceLocationId | No | Optional service location ID lookup |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only nature is covered. The description adds the contextual fact that it is required for appointment/encounter creation, but does not disclose additional behavioral traits such as pagination, sorting, result limits, or the format of returned data. Given that annotations carry the safety profile, the description adds modest value but is not rich in behavior. It does not contradict 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 compact: one sentence for the core purpose, one for the usage context, and one for the optional filters. It front-loads the most important information and has zero fluff. Every sentence contributes meaning, and it is easy to scan.
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 read-only lookup tool with three optional filters and no output schema, the description covers the essential context: what it returns (service locations), why it is needed (for appointments/encounters), and how to narrow results. It does not mention return format, pagination, or field details, but given the tool's simplicity and the annotations covering safety, these omissions are minor. The 'required for' context is particularly valuable for an agent planning multi-step workflows.
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?
The input schema has 100% coverage with each parameter individually described (practiceId, practiceName, serviceLocationId). The description only mentions filtering 'by practice or location ID,' which omits practiceName and slightly mischaracterizes it as an ID filter (it is a name filter). Since the schema fully documents the parameters, the description adds little beyond what is already present, and the slight inaccuracy prevents a higher score.
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 states a specific verb ('Get') and a clear resource ('service locations') and clarifies they are offices/facilities. It also ties the tool to a concrete downstream need ('Required for creating appointments and encounters'), which immediately distinguishes it from sibling tools like tebra_get_appointments or tebra_get_practices. The purpose is unambiguous and well-scoped.
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 explicitly says the tool is 'Required for creating appointments and encounters,' giving a strong contextual trigger for when to call it. It also mentions optional filters, implying usage scenarios. However, it does not explicitly state when NOT to use it or name alternative tools for other reference data (e.g., providers, procedures), though the context makes that fairly clear. It's a solid usage guideline with no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_throttlesGet ThrottlesARead-only
Get the per-endpoint API throttle intervals (milliseconds between calls) that Tebra enforces for this account. Useful for monitoring API usage limits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only and non-exhaustive nature is covered. The description adds meaningful behavior context: results are account-specific, broken down per endpoint, and expressed in milliseconds. No contradiction with annotations exists.
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 short sentences deliver the full definition and the intended use case in a front-loaded manner. Every word earns its place, and there is no repetition of schema fields or annotations.
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 zero-parameter read-only utility, the description adequately conveys what is returned (per-endpoint throttle intervals in milliseconds) and why an agent would use it. There is no output schema, but the open-ended nature of the result is reasonably inferable; a sample response would be a nice enhancement, not a necessity.
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?
The tool has zero parameters and no required inputs, so there is no parameter documentation burden for the description to carry. The mention that throttles are enforced 'for this account' usefully clarifies that the response is account-scoped without needing any caller-supplied arguments.
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 states a specific verb and resource: it returns the per-endpoint API throttle intervals in milliseconds that Tebra enforces for the current account. This clearly distinguishes it from sibling tools that operate on charges, appointments, patients, or documents. The resource and scope are unambiguous.
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 phrase 'useful for monitoring API usage limits' gives a clear practical context for when to call this tool. It does not name explicit alternatives or when-not conditions, but no sibling tool appears to be a competing throttles endpoint, so the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_get_transactionsGet TransactionsARead-only
Get financial transactions from Tebra with optional date range, type, payer, procedure code, and practice filters. Returns transaction details with patient, claim, and insurance info.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| payerType | No | Optional payer type filter | |
| practiceName | No | Optional practice name filter | |
| procedureCode | No | Optional CPT/procedure code filter | |
| toPostingDate | No | Optional end posting date filter (ISO 8601) | |
| toServiceDate | No | Optional end service date filter (ISO 8601) | |
| insuranceOrder | No | Optional insurance order filter (e.g. Primary, Secondary) | |
| fromPostingDate | No | Optional start posting date filter (ISO 8601) | |
| fromServiceDate | No | Optional start service date filter (ISO 8601) | |
| transactionType | No | Optional transaction type filter (sent as WSDL Type member) | |
| toTransactionDate | No | Optional end transaction date filter (ISO 8601) | |
| toLastModifiedDate | No | Optional end last-modified date filter (ISO 8601) | |
| fromTransactionDate | No | Optional start transaction date filter (ISO 8601) | |
| fromLastModifiedDate | No | Optional start last-modified date filter (ISO 8601) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the description only needs to add context beyond those. It adds the return shape (patient, claim, insurance) but does not disclose pagination, result volume, or PHI handling beyond what appears in the fields parameter schema. No contradictions with 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 two short sentences with no filler. The core action and filter scope are front-loaded, and the return summary is included without repeating schema-level parameter details.
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?
With no output schema, the description correctly provides a high-level return summary. Combined with fully documented parameters and safety-carrying annotations, it is largely complete for a retrieval tool, though it could optionally mention pagination or large-result-set behavior for a financial transaction query.
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 description coverage is 100% and all 14 parameters have individual descriptions. The tool description only restates filter categories (date range, type, payer, procedure code, practice) and adds no syntax or semantic detail beyond the schema, so the baseline of 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 names a concrete resource (financial transactions from Tebra) and a retrieval verb, and summarizes the returned data (patient, claim, insurance). It is clear what the tool does, but it does not explicitly distinguish it from financial siblings like tebra_get_charges or tebra_get_payments.
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 usage when the agent needs transaction-level financial records with optional filters, but it provides no explicit when-to-use/when-not-to-use guidance and names no alternatives. Given the sibling list contains other financial record tools, the routing is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_register_external_vendorRegister External VendorA
Register a new external vendor in Tebra for external ID mapping. Returns the vendor ID to use with tebra_update_patient_external_id.
| Name | Required | Description | Default |
|---|---|---|---|
| vendorName | Yes | Vendor name to register |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate readOnlyHint=false and idempotentHint=false, so the agent knows it's a mutating, non-idempotent operation. The description adds that it returns the vendor ID, which is useful for subsequent calls. However, it doesn't mention any side effects, such as duplicate handling or state changes beyond registration, which would be valuable given the lack of idempotency.
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 concise at two sentences, with the purpose front-loaded in the first sentence and the return value in the second. Every word adds value, and there is no redundancy with the schema or annotations.
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 simple one-parameter tool with full schema coverage and no output schema, the description adequately covers the primary purpose and return value. The reference to tebra_update_patient_external_id provides necessary context for the agent's workflow. Minor gap: it doesn't mention whether the vendor name must be unique or how to handle errors, but these are not critical for correct invocation.
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?
The schema description coverage is 100%, so the single parameter 'vendorName' is already well-documented. The description adds a bit of context by noting the purpose is 'for external ID mapping', but it does not provide additional semantics like formatting constraints or examples beyond the schema. A baseline of 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 states a specific action ('Register a new external vendor') with a clear resource ('in Tebra') and a specific purpose ('for external ID mapping'). It also names the downstream use ('Returns the vendor ID to use with tebra_update_patient_external_id'), which clearly distinguishes it from siblings like tebra_get_external_vendors.
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 it (before calling tebra_update_patient_external_id), and the mention of the sibling tool provides context. However, it does not explicitly state when NOT to use it or when to prefer alternatives, such as tebra_get_external_vendors for listing existing vendors.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_search_patientsSearch PatientsARead-only
Search for patients in Tebra with flexible filters. Use query/fullName for name search, or combine specific filters like firstName, lastName, DOB range, insurance company, practice, etc. Returns demographics, MRN, contact info, and primary/secondary insurance. Note: MRN and external ID are not server-side filters — use tebra_get_patient for external ID lookup.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Search by full name (backward-compatible alias for fullName) | |
| fields | No | Optional list of result fields to return (dotted paths for nested values, e.g. "cases.policies.companyName"). Omit for the default field set. Request only the fields you need — results contain protected health information. | |
| gender | No | Filter by gender (Tebra GenderCode: Male, Female, Unknown) | |
| fullName | No | Search by full name | |
| isActive | No | Filter by active/inactive status | |
| lastName | No | Filter by last name | |
| firstName | No | Filter by first name | |
| dateOfBirth | No | Exact date of birth (YYYY-MM-DD); sent as a single-day DOB range | |
| practiceName | No | Practice name filter | |
| toCreatedDate | No | Created date range end (YYYY-MM-DD) | |
| toDateOfBirth | No | DOB range end (YYYY-MM-DD) | |
| fromCreatedDate | No | Created date range start (YYYY-MM-DD) | |
| fromDateOfBirth | No | DOB range start (YYYY-MM-DD) | |
| toLastModifiedDate | No | Modified date range end (YYYY-MM-DD) | |
| toLastEncounterDate | No | Last-encounter date range end (YYYY-MM-DD) | |
| fromLastModifiedDate | No | Modified date range start (YYYY-MM-DD) | |
| insuranceCompanyName | No | Primary insurance company name filter | |
| fromLastEncounterDate | No | Last-encounter date range start (YYYY-MM-DD) | |
| referringProviderName | No | Referring provider full name filter |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with readOnlyHint=true and openWorldHint=true in annotations, the description adds useful behavioral context: it states the returned data categories (demographics, MRN, contact info, insurance) and explicitly warns that MRN and external ID are not server-side filters. This goes beyond the annotations and helps an agent avoid an invalid lookup path.
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 three sentences, front-loaded with the core purpose den, then filters, then return-value summary, then an important caveat. Every sentence earns its place, and the caveat is positioned last without burying the main action.
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 19-parameter search tool with no output schema, the description covers the essential invocation facts: what can be filtered, what is returned, and the limitation around MRN/external ID. It omits details like pagination, default result limits, or sorting, which would be useful, but the core selection and invocation guidance 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?
The input schema already covers all 19 parameters with descriptions, so the baseline is a 3. The description adds meaningful grouping semantics: query is a backward-compatible alias for fullName, filters can be combined, and MRN/external ID are not server-side filters. This is non-obvious context that genuinely helps parameter selection.
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 opens with a clear verb and resource: "Search for patients in Tebra with flexible filters." It goes beyond a generic search by enumerating the filter dimensions (name, firstName, lastName, DOB range, insurance, practice) and clarifying what the tool returns. It also implicitly separates itself from the sibling tebra_get_patient by excluding MRN/external ID server-side filters.
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 gives actionable guidance: use query/fullName for name searches, or combine specific filters for broader lookups. It explicitly names an alternative (tebra_get_patient) for external ID lookup)Skip saying when not to use this tool relative to tebra_get_all_patients or tebra_create_patient, but the search-vs-specific-lookup distinction is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_set_primary_patient_caseSet Primary Patient CaseAIdempotent
Promote an existing patient case to be the primary case, by case ID. Find case IDs via tebra_get_patient (cases[].caseId). Note: this cannot rename a case or change its payer scenario.
| Name | Required | Description | Default |
|---|---|---|---|
| patientCaseId | Yes | Tebra patient case ID to promote to primary |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false (mutation) and destructiveHint=false, but the description confirms the mutation intent and importantly clarifies that changes are limited to primary status, not renaming or payer scenario. This adds 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?
One concise sentence with clear action, parameter reference, and an exclusions note. Front-loaded with the purpose and usage.
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?
With a single parameter, full schema coverage, and no output schema, the description provides sufficient guidance: what it does, how to find the ID, and what it can't do. Minor gap: no mention of idempotency or potential side effects, but annotations cover idempotentHint.
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%, and the description reinforces the parameter's purpose ('to promote to primary') but adds minimal extra meaning beyond the schema's own description. Baseline 3 applies.
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?
Clearly states the verb 'promote' with the resource 'existing patient case' and specifies the operation is by case ID. Distinguishes it from other tools like tebra_update_patient by focusing on setting primary status.
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 instructs how to find case IDs via tebra_get_patient, providing a concrete usage path. Also lists exclusions (cannot rename or change payer scenario), which helps the agent avoid misusing the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_update_appointmentUpdate AppointmentAIdempotent
Update an existing appointment in Tebra. Only provided fields will be changed. When changing startDate, also provide endDate or duration. To only change the status, prefer tebra_update_appointment_status.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Optional updated notes | |
| endDate | No | Optional new end date/time (ISO 8601) | |
| duration | No | Optional new duration in minutes (computes end time from startDate) | |
| patientId | No | Patient ID (required by Tebra; auto-hydrated from the existing appointment if omitted) | |
| startDate | No | Optional new start date/time (ISO 8601); provide endDate or duration with it | |
| providerId | No | Optional new provider ID | |
| appointmentId | Yes | Tebra appointment ID to update | |
| appointmentMode | No | Optional new mode | |
| appointmentStatus | No | Optional new status | |
| serviceLocationId | No | Service location ID (required by Tebra; auto-hydrated from the existing appointment if omitted) | |
| confirmationStatus | No | Deprecated alias for appointmentStatus | |
| appointmentReasonId | No | Optional new appointment reason ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate the tool is not read-only and not destructive. The description adds the partial-update behavior ('Only provided fields will be changed') and the dependency between startDate and endDate/duration, which are not covered by annotations. This adds useful behavioral context without contradiction.
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 no filler. The purpose, partial-update behavior, parameter dependency, and sibling preference are all front-loaded and clearly separated. Every sentence 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 with 12 parameters but full schema coverage and no output schema, the description covers the essential usage nuances: partial updates, the startDate dependency, and the status-only alternative. It does not explain return values, but that is not required without an output schema. It is sufficient for an agent to call it correctly.
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 description coverage is 100%, so all parameters are already documented. The description adds the key rule that changing startDate requires endDate or duration, which is not in the schema. This extra guidance raises the value beyond the baseline for high coverage.
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?
Clearly states the tool updates an existing appointment in Tebra and distinguishes itself from the sibling tebra_update_appointment_status by explicitly preferring that tool for status-only changes. The verb 'update' and resource 'appointment' are specific and unambiguous.
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?
Provides explicit guidance: when changing startDate, also provide endDate or duration, and when only changing status, prefer a different tool. This directly tells an agent when to use this tool versus an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_update_appointment_statusUpdate Appointment StatusAIdempotent
Update only the status of an appointment (e.g. Confirmed, CheckedIn, NoShow, Cancelled). Lighter than tebra_update_appointment — use for check-in/check-out workflows.
| Name | Required | Description | Default |
|---|---|---|---|
| appointmentId | Yes | Tebra appointment ID | |
| appointmentStatus | Yes | New appointment status |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, destructiveHint=false, and idempotentHint=true. The description adds the behavioral scope 'only the status' and 'lighter', which clarifies that this operation does not modify other appointment fields. No contradiction with annotations, and the added context is meaningful.
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, compact sentence that front-loads the core purpose ('Update only the status') and then adds the sibling contrast. Every word earns its place, with no filler or repetition.
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 low complexity (2 params, no nested objects), full schema coverage, and strong annotations, the description is nearly complete for an agent to select and invoke the tool. The only minor gap is that it doesn't describe the return value or response behavior, but that is not critical for this simple update 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 description coverage is 100%, so both parameters are already fully documented in the schema, including the complete enum for appointmentStatus. The description only repeats a few example values and does not add new semantic details, matching the baseline for high schema coverage.
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 states a specific verb and resource ('Update only the status of an appointment') and gives concrete example statuses. It also distinguishes itself from the sibling tebra_update_appointment by calling itself 'Lighter than' that tool, so an agent can immediately tell what this tool does and what it does not do.
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 explicitly names the alternative tebra_update_appointment and specifies the intended use case: 'use for check-in/check-out workflows.' This gives clear when-to-use guidance and implies when NOT to use it (when more than status needs updating).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_update_encounter_statusUpdate Encounter StatusAIdempotent
Update the status of an encounter in Tebra. Moves encounters through the billing workflow: Draft → Submitted → Approved (triggers billing) or Rejected (returns to Draft); Unpayable closes it out. Note: Tebra's UI shows Submitted encounters under 'Review'.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | New status | |
| practiceId | No | Optional practice ID (recommended for multi-practice accounts) | |
| encounterId | Yes | Tebra encounter ID | |
| practiceName | No | Optional practice name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a write operation (readOnlyHint=false) and idempotent (idempotentHint=true). The description adds crucial behavioral context: Approved triggers billing, Rejected returns to Draft, Unpayable closes the encounter, and the UI displays Submitted encounters under 'Review'. This goes beyond annotations to inform the agent of side effects and a UI quirk, with no contradiction.
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 with no filler. The main action and workflow are stated upfront, followed by a useful UI note. Every clause adds value, and the structure is easy to parse.
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 mutation tool with no output schema, the description covers the essential aspects: what it does, the valid status transitions, and their consequences. It also includes a UI nuance. All parameters are documented in the schema, and the description integrates them into the workflow. The only minor gap is not explicitly contrasting with similar update tools, but that is not critical for an agent to use it correctly.
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 description coverage is 100%, with each parameter documented. The description enriches the 'status' parameter by explaining the workflow implications of each enum value, which is not in the schema. It also clarifies that practiceId/practiceName are optional and useful for multi-practice accounts, though this is already in the schema. Overall, the description adds meaningful semantics beyond the 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 opens with a specific verb and resource ('Update the status of an encounter in Tebra') and immediately explains the billing workflow it drives. It goes beyond a generic 'update' by enumerating the valid state transitions and their consequences, making the tool's purpose unmistakable and distinct from other update tools like tebra_update_appointment_status.
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 clearly conveys when to use the tool: to move encounters through the billing workflow. It explains the order (Draft → Submitted → Approved/Rejected → Unpayable) and the side effects of each transition. It does not explicitly state when NOT to use it or name alternatives, but the context is strong enough for an agent to infer the appropriate use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_update_patientUpdate PatientAIdempotent
Update an existing patient in Tebra. Only provided fields will be changed. The practice is required by Tebra; if practiceName/practiceId are omitted, the account's first practice is used automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Optional updated city | |
| No | Optional updated email address | ||
| state | No | Optional updated state | |
| gender | No | Optional updated gender | |
| zipCode | No | Optional updated ZIP code | |
| address1 | No | Optional updated street address line 1 | |
| address2 | No | Optional updated street address line 2 | |
| lastName | No | Optional updated last name | |
| firstName | No | Optional updated first name | |
| homePhone | No | Optional updated home phone number | |
| patientId | Yes | Tebra patient ID to update | |
| practiceId | No | Practice ID (alternative to practiceName) | |
| dateOfBirth | No | Optional updated date of birth (ISO 8601) | |
| mobilePhone | No | Optional updated mobile phone number | |
| practiceName | No | Practice name (auto-resolved to the account's first practice if omitted) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=true, so the safety profile is covered. The description adds meaningful behavioral detail beyond the annotations: only provided fields are changed, and omitted practiceName/practiceId falls back to the account's first practice. No contradiction with 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 two tight sentences with the core update semantics front-loaded and no filler. Every sentence adds value, and the practice fallback nuance 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?
The schema covers all parameters and annotations cover the safety profile. The description handles the update semantics and the practice requirement nuance. The only minor omission is return behavior, but for an update operation without an output schema this is not critical.
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 description coverage is 100%, with all 15 parameters individually documented. The description adds useful context for practiceName/practiceId resolution, but the schema already carries the parameter semantics. 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 states a specific verb and resource: 'Update an existing patient in Tebra.' It also clarifies partial update semantics with 'Only provided fields will be changed,' which distinguishes it from create_patient and get_patient. The purpose is unambiguous.
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 its usage context: updating an existing patient, and it explains the practice defaulting behavior. However, it does not explicitly say when to use this tool versus alternatives like create_patient for new patients or search_patients to resolve patient IDs. Usage is inferable but not directly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_update_patient_external_idUpdate Patient External IDAIdempotent
Set or update a patient external ID in Tebra, linking the patient to an external system. Register the vendor first with tebra_register_external_vendor and pass its numeric ID as externalVendorId.
| Name | Required | Description | Default |
|---|---|---|---|
| patientId | Yes | Tebra patient ID | |
| externalId | Yes | External system ID to assign | |
| practiceId | No | Optional practice ID | |
| externalVendorId | No | External vendor ID from tebra_get_external_vendors (recommended) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, which align with the 'Set or update' action. The description adds behavioral context about the prerequisite of vendor registration, which is beyond what annotations provide. However, it doesn't disclose potential side effects (e.g., overwriting an existing ID) or error conditions, but with annotations covering 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?
Two sentences with zero fluff. The primary action and purpose are front-loaded, followed immediately by the critical prerequisite. 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 with 4 parameters (2 required) and no output schema, the description covers the core function, the prerequisite, and the source of a key parameter. It doesn't discuss error handling or what happens if the vendor is not registered, but those are less critical given the clarity provided. The description is sufficient for an agent to call the tool correctly in the intended flow.
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 description coverage is 100%, so the baseline is 3. The description adds value by specifying that externalVendorId is a 'numeric ID' and connecting it to the registration step, which clarifies the expected format and source beyond the schema's generic description. This extra guidance merits 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 the action ('Set or update'), the resource ('patient external ID'), and the purpose ('linking the patient to an external system'). It also distinguishes this tool from other update tools by focusing on external IDs. The verb+resource combination is specific and unambiguous.
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 a clear prerequisite: 'Register the vendor first with tebra_register_external_vendor and pass its numeric ID as externalVendorId.' This gives explicit context on how to prepare for using the tool. It doesn't explicitly state when not to use it, but the prerequisite and focus on external IDs effectively differentiate it from sibling update tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tebra_validate_connectionValidate ConnectionARead-only
Validate the Tebra API credentials by retrieving the customer ID and authorization flag. Use as a health check.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the read-only nature is covered. The description adds the specific detail of retrieving customer ID and authorization flag, which is useful but does not disclose additional behavioral aspects like error handling or side effects. With annotations covering safety, 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?
Two sentences with no wasted words. The main purpose is front-loaded, and the health-check usage is stated clearly. Perfectly concise and 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?
For a zero-parameter, read-only health-check tool with annotations covering safety, the description fully explains what it does and when to use it. No output schema is needed, and nothing critical is missing.
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?
The tool has zero parameters, and schema coverage is 100% (vacuously). The description does not need to explain parameters, and the baseline for zero-parameter tools is 4. No additional parameter semantics are required.
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 verb 'validate' and the resource (Tebra API credentials), and specifies that it retrieves the customer ID and authorization flag. This is distinct from all sibling tools which perform CRUD or other operations.
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 explicitly says 'Use as a health check,' which gives a clear context for when to invoke this tool. It does not mention alternatives or exclusions, but given the unique purpose, no alternative is needed. Slight lack of explicit 'when not to use' but sufficient for a health check.
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.
27 tool updates
v0.6.0- Changed
tebra_create_appointment10 fields changed- added
Input schema / properties / appointmentModeAdded value: +{ + "description": "Optional appointment mode", + "enum": [ + "InOffice", + "Telehealth" + ], + "type": "string" +} - added
Input schema / properties / appointmentNameAdded value: +{ + "description": "Optional appointment display name", + "type": "string" +} - changed
Input schema / properties / appointmentReasonId / descriptionPrevious value: -"Tebra appointment reason ID"New value: +"Optional Tebra appointment reason ID" - added
Input schema / properties / appointmentStatusAdded value: +{ + "description": "Optional initial status (default 'Scheduled')", + "enum": [ + "Unknown", + "Scheduled", + "ReminderSent", + "Confirmed", + "CheckedIn", + "Roomed", + "CheckedOut", + "NeedsReschedule", + "ReadyToBeSeen", + "NoShow", + "Cancelled", + "Rescheduled", + "Tentative" + ], + "type": "string" +} - removed
Input schema / properties / confirmationStatusRemoved value: -{ - "description": "Optional confirmation status (e.g. Confirmed, Unconfirmed)", - "type": "string" -} - changed
Input schema / properties / duration / descriptionPrevious value: -"Optional duration in minutes (defaults to appointment reason default)"New value: +"Duration in minutes (used to compute end time when endDate is omitted)" - added
Input schema / properties / endDateAdded value: +{ + "description": "Appointment end date/time (ISO 8601); alternative to duration", + "type": "string" +} - added
Input schema / properties / insurancePolicyAuthorizationIdAdded value: +{ + "description": "Optional insurance authorization ID to link", + "type": "string" +} - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Practice ID (required by Tebra; auto-resolved to the account's first practice if omitted)", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "patientId", - "providerId", - "serviceLocationId", - "appointmentReasonId", - "startDate" -]New value: +[ + "patientId", + "providerId", + "serviceLocationId", + "startDate" +]
- Changed
tebra_create_appointment_reason4 fields changed- removed
Input schema / properties / categoryRemoved value: -{ - "description": "Optional category", - "type": "string" -} - changed
Input schema / properties / color / descriptionPrevious value: -"Optional color code (hex or named color)"New value: +"Optional Tebra color code (integer)" - changed
Input schema / properties / color / typePrevious value: -"string"New value: +"number" - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Optional practice ID", + "type": "string" +}
- Changed
tebra_create_document7 fields changed- changed
Input schema / properties / documentLabel / descriptionPrevious value: -"Document category label (e.g. Lab Results, Referral Letter)"New value: +"Document category label from the Tebra DocumentLabel enum (e.g. MedicalReport, PatientAuthorizationOrReferral, PatientCorrespondence, PatientDemographics, PatientInsuranceCard, PatientDriversLicense, Other). Spaces are stripped automatically." - added
Input schema / properties / documentNameAdded value: +{ + "description": "Optional display name for the document (defaults to fileName)", + "type": "string" +} - changed
Input schema / properties / encounterDate / descriptionPrevious value: -"Optional encounter date to associate with (ISO 8601)"New value: +"Optional document date to associate with (ISO 8601)" - changed
Input schema / properties / fileName / descriptionPrevious value: -"File name with extension (e.g. lab_results.pdf)"New value: +"File name with extension (e.g. lab_results.pdf) — the extension determines the file type" - removed
Input schema / properties / fileTypeRemoved value: -{ - "description": "File type: PDF, JPG, PNG, or TIFF", - "enum": [ - "PDF", - "JPG", - "PNG", - "TIFF" - ], - "type": "string" -} - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Practice ID (required by Tebra; auto-resolved to the account's first practice if omitted)", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "patientId", - "documentLabel", - "fileName", - "fileContent", - "fileType" -]New value: +[ + "patientId", + "documentLabel", + "fileName", + "fileContent" +]
- Changed
tebra_create_encounter15 fields changed- changed
Input schema / properties / authorizationId / descriptionPrevious value: -"Optional authorization ID to link"New value: +"Optional authorization number to link" - added
Input schema / properties / caseIdAdded value: +{ + "description": "Optional patient case ID to bill under", + "type": "string" +} - changed
Input schema / properties / diagnoses / descriptionPrevious value: -"Array of diagnosis codes"New value: +"Encounter-level diagnosis codes; the first 4 are applied to each service line" - changed
Input schema / properties / diagnoses / items / properties / description / descriptionPrevious value: -"Diagnosis description"New value: +"Diagnosis description (informational only — not sent to Tebra)" - changed
Input schema / properties / diagnoses / items / requiredPrevious value: -[ - "code", - "description" -]New value: +[ + "code" +] - added
Input schema / properties / encounterStatusAdded value: +{ + "description": "Initial encounter status (default 'Draft'; 'Approved' triggers billing)", + "enum": [ + "Draft", + "Submitted", + "Approved" + ], + "type": "string" +} - added
Input schema / properties / placeOfServiceCodeAdded value: +{ + "description": "Optional place of service code (e.g. 11 for office)", + "type": "string" +} - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Practice ID (alternative to practiceName)", + "type": "string" +} - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Practice name (strongly recommended; required by Tebra on most accounts)", + "type": "string" +} - changed
Input schema / properties / procedures / descriptionPrevious value: -"Array of procedure codes"New value: +"Array of procedures; each becomes one service line" - added
Input schema / properties / procedures / items / properties / diagnosisCodesAdded value: +{ + "description": "Optional per-line ICD-10 codes (max 4; overrides encounter-level diagnoses)", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / procedures / items / properties / modifiers / descriptionPrevious value: -"CPT modifiers (e.g. [\"-25\", \"-59\"])"New value: +"CPT modifiers (e.g. [\"25\", \"59\"])" - added
Input schema / properties / procedures / items / properties / unitChargeAdded value: +{ + "description": "Optional unit charge in dollars (defaults to fee schedule)", + "type": "number" +} - changed
Input schema / properties / providerId / descriptionPrevious value: -"Tebra provider ID"New value: +"Rendering provider ID" - added
Input schema / properties / serviceLocationIdAdded value: +{ + "description": "Optional service location ID", + "type": "string" +}
- Changed
tebra_create_patient10 fields changed- changed
Input schema / properties / gender / descriptionPrevious value: -"Optional gender (Male, Female, Other)"New value: +"Optional gender (Tebra GenderCode: Male, Female, Unknown)" - added
Input schema / properties / gender / enumAdded value: +[ + "Male", + "Female", + "Unknown" +] - changed
Input schema / properties / guarantor / properties / relationship / descriptionPrevious value: -"Optional relationship to patient"New value: +"Patient relationship to guarantor (default Other)" - added
Input schema / properties / guarantor / properties / relationship / enumAdded value: +[ + "Child", + "Other", + "Self", + "Spouse" +] - added
Input schema / properties / mrnAdded value: +{ + "description": "Optional medical record number", + "type": "string" +} - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Practice ID (alternative to practiceName)", + "type": "string" +} - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Practice name (auto-resolved to the account's first practice if omitted)", + "type": "string" +} - changed
Input schema / properties / primaryInsurance / descriptionPrevious value: -"Optional primary insurance information"New value: +"Optional primary insurance (created inside a default patient case)" - changed
Input schema / properties / primaryInsurance / properties / memberId / descriptionPrevious value: -"Member/subscriber ID"New value: +"Member/policy number" - changed
Input schema / properties / ssn / descriptionPrevious value: -"Optional SSN (will be transmitted securely)"New value: +"Optional SSN"
- Changed
tebra_create_payment4 fields changed- removed
Input schema / properties / notesRemoved value: -{ - "description": "Optional payment notes", - "type": "string" -} - added
Input schema / properties / payerTypeAdded value: +{ + "description": "Optional payer type (defaults to 'Patient')", + "type": "string" +} - changed
Input schema / properties / paymentDate / descriptionPrevious value: -"Optional payment date (ISO 8601, defaults to today)"New value: +"Optional payment post date (ISO 8601, defaults to today server-side)" - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Optional practice name (recommended for multi-practice accounts)", + "type": "string" +}
- Changed
tebra_get_all_patients3 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / isActive / descriptionPrevious value: -"Optional filter: true for active patients only, false for inactive only"New value: +"Optional filter: true for active patients only, false for inactive only (applied client-side; the returned count reflects the filtered page)" - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Optional practice ID filter", + "type": "string" +}
- Changed
tebra_get_appointment_detail1 field changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
tebra_get_appointment_reasons1 field changed- added
Input schema / properties / practiceIdAdded value: +{ + "description": "Practice ID (defaults to the account's first practice)", + "type": "string" +}
- Changed
tebra_get_appointments6 fields changed- changed
Input schema / properties / confirmationStatus / enumPrevious value: -[ - "Confirmed", - "CheckedIn", - "NoShow", - "CheckedOut", - "Rescheduled", - "Scheduled", - "Cancelled" -]New value: +[ + "Scheduled", + "ReminderSent", + "Confirmed", + "CheckedIn", + "Roomed", + "ReadyToBeSeen", + "CheckedOut", + "NeedsReschedule", + "NoShow", + "Cancelled", + "Rescheduled", + "Tentative" +] - added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Filter by practice name", + "type": "string" +} - removed
Input schema / properties / providerIdRemoved value: -{ - "description": "Tebra provider ID to filter by", - "type": "string" -} - added
Input schema / properties / resourceNameAdded value: +{ + "description": "Scheduler resource name to filter by — for provider filtering, pass the provider full name", + "type": "string" +} - added
Input schema / properties / timeZoneOffsetFromGMTAdded value: +{ + "description": "Time zone offset from GMT for returned times (e.g. -8)", + "type": "string" +}
- Changed
tebra_get_charges6 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / fromPostingDate / descriptionPrevious value: -"Posting date range start (YYYY-MM-DD)"New value: +"Posting date range start (YYYY-MM-DD); max 60 days from toPostingDate" - removed
Input schema / properties / patientIdRemoved value: -{ - "description": "Tebra patient ID to filter by", - "type": "string" -} - added
Input schema / properties / patientNameAdded value: +{ + "description": "Patient full name to filter by (ChargeFilter has no patient ID member)", + "type": "string" +} - changed
Input schema / properties / status / descriptionPrevious value: -"Charge status filter"New value: +"Charge status filter. Observed values include 'Pending', 'Completed', 'Error - Rejection', 'Voided', 'Ready'. Note: 'Denied' is not a status Tebra uses; rejected claims carry 'Error - Rejection'." - changed
Input schema / properties / toPostingDate / descriptionPrevious value: -"Posting date range end (YYYY-MM-DD)"New value: +"Posting date range end (YYYY-MM-DD); max 60 days from fromPostingDate"
- Changed
tebra_get_encounter1 field changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
tebra_get_patient5 fields changed- added
Input schema / properties / externalIdAdded value: +{ + "description": "External system ID (alternative to patientId)", + "type": "string" +} - added
Input schema / properties / externalVendorIdAdded value: +{ + "description": "Optional external vendor ID to scope the externalId lookup", + "type": "string" +} - added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / patientId / descriptionPrevious value: -"Tebra patient ID"New value: +"Tebra patient ID (numeric)" - changed
Input schema / requiredPrevious value: -[ - "patientId" -]New value: +[]
- Changed
tebra_get_payments8 fields changed- added
Input schema / properties / amountAdded value: +{ + "description": "Optional exact amount filter", + "type": "string" +} - added
Input schema / properties / appointmentIdAdded value: +{ + "description": "Optional appointment ID filter", + "type": "string" +} - added
Input schema / properties / fromCreatedDateAdded value: +{ + "description": "Optional start created date filter (ISO 8601)", + "type": "string" +} - removed
Input schema / properties / patientIdRemoved value: -{ - "description": "Optional Tebra patient ID filter", - "type": "string" -} - added
Input schema / properties / payerTypeAdded value: +{ + "description": "Optional payer type filter (e.g. Patient, Insurance)", + "type": "string" +} - added
Input schema / properties / paymentIdAdded value: +{ + "description": "Optional payment ID lookup", + "type": "string" +} - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Optional practice name filter", + "type": "string" +} - added
Input schema / properties / toCreatedDateAdded value: +{ + "description": "Optional end created date filter (ISO 8601)", + "type": "string" +}
- Changed
tebra_get_procedure_codes3 fields changed- added
Input schema / properties / activeAdded value: +{ + "description": "Optional filter for active codes only", + "type": "boolean" +} - added
Input schema / properties / customerSpecificAdded value: +{ + "description": "Optional filter for customer-specific codes", + "type": "boolean" +} - changed
Input schema / properties / searchTerm / descriptionPrevious value: -"Optional CPT code or search term to filter by"New value: +"Optional CPT/procedure code to filter by (e.g. 99213)"
- Changed
tebra_get_providers4 fields changed- added
Input schema / properties / departmentNameAdded value: +{ + "description": "Optional department name filter", + "type": "string" +} - added
Input schema / properties / fullNameAdded value: +{ + "description": "Optional provider full name filter", + "type": "string" +} - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Optional practice ID filter", + "type": "string" +} - added
Input schema / properties / typeAdded value: +{ + "description": "Optional provider type filter", + "type": "string" +}
- Changed
tebra_get_service_locations2 fields changed- added
Input schema / properties / practiceIdAdded value: +{ + "description": "Optional practice ID filter", + "type": "string" +} - added
Input schema / properties / serviceLocationIdAdded value: +{ + "description": "Optional service location ID lookup", + "type": "string" +}
- Changed
tebra_get_transactions5 fields changed- added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / fromLastModifiedDateAdded value: +{ + "description": "Optional start last-modified date filter (ISO 8601)", + "type": "string" +} - added
Input schema / properties / insuranceOrderAdded value: +{ + "description": "Optional insurance order filter (e.g. Primary, Secondary)", + "type": "string" +} - added
Input schema / properties / toLastModifiedDateAdded value: +{ + "description": "Optional end last-modified date filter (ISO 8601)", + "type": "string" +} - changed
Input schema / properties / transactionType / descriptionPrevious value: -"Optional transaction type filter"New value: +"Optional transaction type filter (sent as WSDL Type member)"
- Changed
tebra_register_external_vendor1 field changed- removed
Input schema / properties / vendorDescriptionRemoved value: -{ - "description": "Optional vendor description", - "type": "string" -}
- Changed
tebra_search_patients10 fields changed- changed
Input schema / properties / dateOfBirth / descriptionPrevious value: -"Exact date of birth (YYYY-MM-DD)"New value: +"Exact date of birth (YYYY-MM-DD); sent as a single-day DOB range" - removed
Input schema / properties / externalIdRemoved value: -{ - "description": "External system ID", - "type": "string" -} - added
Input schema / properties / fieldsAdded value: +{ + "description": "Optional list of result fields to return (dotted paths for nested values, e.g. \"cases.policies.companyName\"). Omit for the default field set. Request only the fields you need — results contain protected health information.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / fromLastEncounterDateAdded value: +{ + "description": "Last-encounter date range start (YYYY-MM-DD)", + "type": "string" +} - changed
Input schema / properties / gender / descriptionPrevious value: -"Filter by gender"New value: +"Filter by gender (Tebra GenderCode: Male, Female, Unknown)" - changed
Input schema / properties / gender / enumPrevious value: -[ - "Male", - "Female", - "Other", - "Unknown" -]New value: +[ + "Male", + "Female", + "Unknown" +] - changed
Input schema / properties / insuranceCompanyName / descriptionPrevious value: -"Insurance company name filter"New value: +"Primary insurance company name filter" - removed
Input schema / properties / mrnRemoved value: -{ - "description": "Medical Record Number", - "type": "string" -} - changed
Input schema / properties / referringProviderName / descriptionPrevious value: -"Referring provider name filter"New value: +"Referring provider full name filter" - added
Input schema / properties / toLastEncounterDateAdded value: +{ + "description": "Last-encounter date range end (YYYY-MM-DD)", + "type": "string" +}
- Added
tebra_set_primary_patient_case - Changed
tebra_update_appointment10 fields changed- added
Input schema / properties / appointmentModeAdded value: +{ + "description": "Optional new mode", + "enum": [ + "InOffice", + "Telehealth" + ], + "type": "string" +} - added
Input schema / properties / appointmentReasonIdAdded value: +{ + "description": "Optional new appointment reason ID", + "type": "string" +} - added
Input schema / properties / appointmentStatusAdded value: +{ + "description": "Optional new status", + "enum": [ + "Unknown", + "Scheduled", + "ReminderSent", + "Confirmed", + "CheckedIn", + "Roomed", + "CheckedOut", + "NeedsReschedule", + "ReadyToBeSeen", + "NoShow", + "Cancelled", + "Rescheduled", + "Tentative" + ], + "type": "string" +} - removed
Input schema / properties / cancellationReasonRemoved value: -{ - "description": "Optional cancellation reason (for cancelled appointments)", - "type": "string" -} - changed
Input schema / properties / confirmationStatus / descriptionPrevious value: -"Optional new confirmation status"New value: +"Deprecated alias for appointmentStatus" - changed
Input schema / properties / duration / descriptionPrevious value: -"Optional new duration in minutes"New value: +"Optional new duration in minutes (computes end time from startDate)" - added
Input schema / properties / endDateAdded value: +{ + "description": "Optional new end date/time (ISO 8601)", + "type": "string" +} - added
Input schema / properties / patientIdAdded value: +{ + "description": "Patient ID (required by Tebra; auto-hydrated from the existing appointment if omitted)", + "type": "string" +} - added
Input schema / properties / serviceLocationIdAdded value: +{ + "description": "Service location ID (required by Tebra; auto-hydrated from the existing appointment if omitted)", + "type": "string" +} - changed
Input schema / properties / startDate / descriptionPrevious value: -"Optional new start date/time (ISO 8601)"New value: +"Optional new start date/time (ISO 8601); provide endDate or duration with it"
- Added
tebra_update_appointment_status - Changed
tebra_update_encounter_status5 fields changed- added
Input schema / properties / practiceIdAdded value: +{ + "description": "Optional practice ID (recommended for multi-practice accounts)", + "type": "string" +} - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Optional practice name", + "type": "string" +} - removed
Input schema / properties / reviewNoteRemoved value: -{ - "description": "Optional note explaining the status change", - "type": "string" -} - changed
Input schema / properties / status / descriptionPrevious value: -"New status: Draft, Review, Approved, or Rejected"New value: +"New status" - changed
Input schema / properties / status / enumPrevious value: -[ - "Draft", - "Review", - "Approved", - "Rejected" -]New value: +[ + "Draft", + "Submitted", + "Approved", + "Rejected", + "Unpayable" +]
- Changed
tebra_update_patient3 fields changed- added
Input schema / properties / gender / enumAdded value: +[ + "Male", + "Female", + "Unknown" +] - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Practice ID (alternative to practiceName)", + "type": "string" +} - added
Input schema / properties / practiceNameAdded value: +{ + "description": "Practice name (auto-resolved to the account's first practice if omitted)", + "type": "string" +}
- Removed
tebra_update_patient_case - Changed
tebra_update_patient_external_id3 fields changed- added
Input schema / properties / externalVendorIdAdded value: +{ + "description": "External vendor ID from tebra_get_external_vendors (recommended)", + "type": "string" +} - added
Input schema / properties / practiceIdAdded value: +{ + "description": "Optional practice ID", + "type": "string" +} - removed
Input schema / properties / vendorNameRemoved value: -{ - "description": "Optional external vendor name", - "type": "string" -}
33 tool updates
v0.2.5- First observed
tebra_check_insurance_eligibility - First observed
tebra_create_appointment - First observed
tebra_create_appointment_reason - First observed
tebra_create_document - First observed
tebra_create_encounter - First observed
tebra_create_patient - First observed
tebra_create_payment - First observed
tebra_delete_appointment - First observed
tebra_delete_document - First observed
tebra_get_all_patients - First observed
tebra_get_appointment_detail - First observed
tebra_get_appointment_reasons - First observed
tebra_get_appointments - First observed
tebra_get_charges - First observed
tebra_get_encounter - First observed
tebra_get_external_vendors - First observed
tebra_get_patient - First observed
tebra_get_patient_authorizations - First observed
tebra_get_payments - First observed
tebra_get_practices - First observed
tebra_get_procedure_codes - First observed
tebra_get_providers - First observed
tebra_get_service_locations - First observed
tebra_get_throttles - First observed
tebra_get_transactions - First observed
tebra_register_external_vendor - First observed
tebra_search_patients - First observed
tebra_update_appointment - First observed
tebra_update_encounter_status - First observed
tebra_update_patient - First observed
tebra_update_patient_case - First observed
tebra_update_patient_external_id - First observed
tebra_validate_connection
TDQS
Scored across 34 tools
Most tools target a distinct Tebra resource and action, and descriptions clearly separate similar entities like appointments vs. appointment details and patients vs. patient searches. A few adjacent pairs such as get_charges/get_payments/get_transactions or check_insurance_eligibility/get_patient_authorizations could be confused, but the descriptions draw reasonable boundaries.
Every tool follows the tebra_ prefix with a consistent verb_noun snake_case pattern, such as get_patient, create_appointment, update_encounter_status, and delete_document. There are no mixed conventions, vague verbs, or unpredictable naming styles.
With 34 tools, the server is well beyond the typical well-scoped range and adds significant selection overhead for an agent. While most tools serve distinct purposes, the overall surface feels heavy for a single MCP server.
Core patient, appointment, encounter, and payment workflows are substantially covered, including create/read/update/status operations. However, there are notable gaps such as no encounter detail editing, no document retrieval/listing, and no creation or update of authorizations or patient cases.
Maintenance
Related MCP Connectors
Hosted MCP server for Cliniko — patients, appointments, availability, and invoices for AI agents.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Related MCP Servers
- AlicenseBqualityCmaintenanceAn MCP server that connects AI assistants to OpenEMR instances to manage patient records, clinical trends, and medication safety. It provides 17 tools for tasks such as patient search, drug interaction checks, and generating comprehensive health trajectories and visit preparations.17MIT
- AlicenseNot gradedqualityDmaintenanceClinical decision-support MCP server that lets AI agents reason over live FHIR patient data for medication review, appointment scheduling, and care gap identification.6,166 npmMIT
- AlicenseNot gradedqualityBmaintenanceMCP server for the Semble practice-management API, enabling AI agents to search for patients, contacts, and users, as well as retrieve patient relationships via read-only tools.MIT

LangCare MCP FHIR Serverofficial
AlicenseNot gradedqualityDmaintenanceEnterprise-grade MCP Server for FHIR-based EMRs. Enables AI agents to read, search, create, and update any FHIR R4 resource across major EHR systems like EPIC, Cerner, and OpenEMR.285 npm56MIT