tebra-mcp-server 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +267 -35
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/fhir-client.d.ts +22 -0
- package/dist/fhir-client.d.ts.map +1 -0
- package/dist/fhir-client.js +86 -0
- package/dist/fhir-client.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -6
- package/dist/index.js.map +1 -1
- package/dist/integrations/epic-notes-integration.d.ts +145 -0
- package/dist/integrations/epic-notes-integration.d.ts.map +1 -0
- package/dist/integrations/epic-notes-integration.js +227 -0
- package/dist/integrations/epic-notes-integration.js.map +1 -0
- package/dist/integrations/fal-integration.d.ts +109 -0
- package/dist/integrations/fal-integration.d.ts.map +1 -0
- package/dist/integrations/fal-integration.js +192 -0
- package/dist/integrations/fal-integration.js.map +1 -0
- package/dist/soap-client.d.ts +1 -0
- package/dist/soap-client.d.ts.map +1 -1
- package/dist/soap-client.js +68 -1
- package/dist/soap-client.js.map +1 -1
- package/dist/tools/appointment-crud.d.ts +117 -0
- package/dist/tools/appointment-crud.d.ts.map +1 -0
- package/dist/tools/appointment-crud.js +218 -0
- package/dist/tools/appointment-crud.js.map +1 -0
- package/dist/tools/appointment-detail.d.ts +25 -0
- package/dist/tools/appointment-detail.d.ts.map +1 -0
- package/dist/tools/appointment-detail.js +85 -0
- package/dist/tools/appointment-detail.js.map +1 -0
- package/dist/tools/appointment-reasons.d.ts +20 -0
- package/dist/tools/appointment-reasons.d.ts.map +1 -0
- package/dist/tools/appointment-reasons.js +48 -0
- package/dist/tools/appointment-reasons.js.map +1 -0
- package/dist/tools/appointments.d.ts +46 -0
- package/dist/tools/appointments.d.ts.map +1 -1
- package/dist/tools/appointments.js +71 -4
- package/dist/tools/appointments.js.map +1 -1
- package/dist/tools/authorizations.js +5 -5
- package/dist/tools/bulk-patients.d.ts +33 -0
- package/dist/tools/bulk-patients.d.ts.map +1 -0
- package/dist/tools/bulk-patients.js +81 -0
- package/dist/tools/bulk-patients.js.map +1 -0
- package/dist/tools/charges.d.ts +61 -0
- package/dist/tools/charges.d.ts.map +1 -1
- package/dist/tools/charges.js +98 -14
- package/dist/tools/charges.js.map +1 -1
- package/dist/tools/documents.d.ts +71 -0
- package/dist/tools/documents.d.ts.map +1 -0
- package/dist/tools/documents.js +139 -0
- package/dist/tools/documents.js.map +1 -0
- package/dist/tools/eligibility.js +5 -5
- package/dist/tools/encounter-status.d.ts +34 -0
- package/dist/tools/encounter-status.d.ts.map +1 -0
- package/dist/tools/encounter-status.js +73 -0
- package/dist/tools/encounter-status.js.map +1 -0
- package/dist/tools/encounters.js +29 -29
- package/dist/tools/external-ids.d.ts +66 -0
- package/dist/tools/external-ids.d.ts.map +1 -0
- package/dist/tools/external-ids.js +140 -0
- package/dist/tools/external-ids.js.map +1 -0
- package/dist/tools/fhir-clinical.d.ts +187 -0
- package/dist/tools/fhir-clinical.d.ts.map +1 -0
- package/dist/tools/fhir-clinical.js +597 -0
- package/dist/tools/fhir-clinical.js.map +1 -0
- package/dist/tools/patient-crud.d.ts +190 -0
- package/dist/tools/patient-crud.d.ts.map +1 -0
- package/dist/tools/patient-crud.js +297 -0
- package/dist/tools/patient-crud.js.map +1 -0
- package/dist/tools/patients.d.ts +87 -1
- package/dist/tools/patients.d.ts.map +1 -1
- package/dist/tools/patients.js +108 -8
- package/dist/tools/patients.js.map +1 -1
- package/dist/tools/payments.d.ts +105 -0
- package/dist/tools/payments.d.ts.map +1 -0
- package/dist/tools/payments.js +206 -0
- package/dist/tools/payments.js.map +1 -0
- package/dist/tools/practices.d.ts +20 -0
- package/dist/tools/practices.d.ts.map +1 -0
- package/dist/tools/practices.js +54 -0
- package/dist/tools/practices.js.map +1 -0
- package/dist/tools/procedure-codes.js +5 -5
- package/dist/tools/providers.d.ts +25 -0
- package/dist/tools/providers.d.ts.map +1 -0
- package/dist/tools/providers.js +62 -0
- package/dist/tools/providers.js.map +1 -0
- package/dist/tools/service-locations.d.ts +25 -0
- package/dist/tools/service-locations.d.ts.map +1 -0
- package/dist/tools/service-locations.js +62 -0
- package/dist/tools/service-locations.js.map +1 -0
- package/dist/tools/system.d.ts +81 -0
- package/dist/tools/system.d.ts.map +1 -0
- package/dist/tools/system.js +184 -0
- package/dist/tools/system.js.map +1 -0
- package/dist/tools/transactions.d.ts +61 -0
- package/dist/tools/transactions.d.ts.map +1 -0
- package/dist/tools/transactions.js +122 -0
- package/dist/tools/transactions.js.map +1 -0
- package/package.json +60 -54
package/dist/index.js
CHANGED
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
* TEBRA_SOAP_PASSWORD — SOAP API password
|
|
12
12
|
* TEBRA_CUSTOMER_KEY — Customer key from Tebra PM admin
|
|
13
13
|
*
|
|
14
|
+
* Optional FHIR (clinical data):
|
|
15
|
+
* TEBRA_FHIR_CLIENT_ID — FHIR OAuth2 client ID
|
|
16
|
+
* TEBRA_FHIR_CLIENT_SECRET — FHIR OAuth2 client secret
|
|
17
|
+
*
|
|
14
18
|
* Usage:
|
|
15
19
|
* npx @allure-md/tebra-mcp-server
|
|
16
20
|
* TEBRA_SOAP_USER=... TEBRA_SOAP_PASSWORD=... TEBRA_CUSTOMER_KEY=... node dist/index.js
|
|
@@ -20,6 +24,8 @@ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
|
20
24
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
21
25
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
22
26
|
const config_js_1 = require("./config.js");
|
|
27
|
+
const fhir_client_js_1 = require("./fhir-client.js");
|
|
28
|
+
// SOAP tool imports
|
|
23
29
|
const patients_js_1 = require("./tools/patients.js");
|
|
24
30
|
const encounters_js_1 = require("./tools/encounters.js");
|
|
25
31
|
const authorizations_js_1 = require("./tools/authorizations.js");
|
|
@@ -27,12 +33,28 @@ const appointments_js_1 = require("./tools/appointments.js");
|
|
|
27
33
|
const eligibility_js_1 = require("./tools/eligibility.js");
|
|
28
34
|
const charges_js_1 = require("./tools/charges.js");
|
|
29
35
|
const procedure_codes_js_1 = require("./tools/procedure-codes.js");
|
|
36
|
+
const providers_js_1 = require("./tools/providers.js");
|
|
37
|
+
const service_locations_js_1 = require("./tools/service-locations.js");
|
|
38
|
+
const appointment_reasons_js_1 = require("./tools/appointment-reasons.js");
|
|
39
|
+
const appointment_crud_js_1 = require("./tools/appointment-crud.js");
|
|
40
|
+
const appointment_detail_js_1 = require("./tools/appointment-detail.js");
|
|
41
|
+
const patient_crud_js_1 = require("./tools/patient-crud.js");
|
|
42
|
+
const encounter_status_js_1 = require("./tools/encounter-status.js");
|
|
43
|
+
const payments_js_1 = require("./tools/payments.js");
|
|
44
|
+
const transactions_js_1 = require("./tools/transactions.js");
|
|
45
|
+
const practices_js_1 = require("./tools/practices.js");
|
|
46
|
+
const documents_js_1 = require("./tools/documents.js");
|
|
47
|
+
const bulk_patients_js_1 = require("./tools/bulk-patients.js");
|
|
48
|
+
const external_ids_js_1 = require("./tools/external-ids.js");
|
|
49
|
+
const system_js_1 = require("./tools/system.js");
|
|
50
|
+
// FHIR tool imports
|
|
51
|
+
const fhir_clinical_js_1 = require("./tools/fhir-clinical.js");
|
|
30
52
|
// ─── Validate config on startup ─────────────────────────────────
|
|
31
53
|
const config = (0, config_js_1.getConfig)();
|
|
32
54
|
// ─── Create MCP Server ──────────────────────────────────────────
|
|
33
55
|
const server = new index_js_1.Server({
|
|
34
56
|
name: '@allure-md/tebra-mcp-server',
|
|
35
|
-
version: '0.
|
|
57
|
+
version: '0.2.0', // Keep in sync with package.json
|
|
36
58
|
}, {
|
|
37
59
|
capabilities: {
|
|
38
60
|
tools: {},
|
|
@@ -47,7 +69,30 @@ const allTools = [
|
|
|
47
69
|
...eligibility_js_1.eligibilityTools,
|
|
48
70
|
...charges_js_1.chargeTools,
|
|
49
71
|
...procedure_codes_js_1.procedureCodeTools,
|
|
72
|
+
...providers_js_1.providerTools,
|
|
73
|
+
...service_locations_js_1.serviceLocationTools,
|
|
74
|
+
...appointment_reasons_js_1.appointmentReasonTools,
|
|
75
|
+
...appointment_crud_js_1.appointmentCrudTools,
|
|
76
|
+
...appointment_detail_js_1.appointmentDetailTools,
|
|
77
|
+
...patient_crud_js_1.patientCrudTools,
|
|
78
|
+
...encounter_status_js_1.encounterStatusTools,
|
|
79
|
+
...payments_js_1.paymentTools,
|
|
80
|
+
...transactions_js_1.transactionTools,
|
|
81
|
+
...practices_js_1.practiceTools,
|
|
82
|
+
...documents_js_1.documentTools,
|
|
83
|
+
...bulk_patients_js_1.bulkPatientTools,
|
|
84
|
+
...external_ids_js_1.externalIdTools,
|
|
85
|
+
...system_js_1.systemTools,
|
|
50
86
|
];
|
|
87
|
+
// Conditionally register FHIR tools when credentials are available
|
|
88
|
+
if ((0, fhir_client_js_1.isFhirConfigured)()) {
|
|
89
|
+
allTools.push(...fhir_clinical_js_1.fhirClinicalTools);
|
|
90
|
+
console.error('FHIR tools enabled — 12 clinical data tools registered');
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.error('FHIR tools disabled — set TEBRA_FHIR_CLIENT_ID and TEBRA_FHIR_CLIENT_SECRET to enable clinical data tools');
|
|
94
|
+
}
|
|
95
|
+
console.error(`Tebra MCP server: ${allTools.length} tools registered`);
|
|
51
96
|
// ─── Tool Listing ───────────────────────────────────────────────
|
|
52
97
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
53
98
|
return { tools: allTools };
|
|
@@ -56,26 +101,75 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
|
56
101
|
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
57
102
|
const { name, arguments: args } = request.params;
|
|
58
103
|
try {
|
|
59
|
-
// Route to the correct handler by exact tool name
|
|
60
104
|
const safeArgs = args ?? {};
|
|
61
105
|
switch (name) {
|
|
106
|
+
// ─── Patient tools ──────────────────────────────
|
|
62
107
|
case 'tebra_search_patients':
|
|
63
108
|
case 'tebra_get_patient':
|
|
64
109
|
return await (0, patients_js_1.handlePatientTool)(name, safeArgs, config);
|
|
110
|
+
case 'tebra_create_patient':
|
|
111
|
+
case 'tebra_update_patient':
|
|
112
|
+
return await (0, patient_crud_js_1.handlePatientCrudTool)(name, safeArgs, config);
|
|
113
|
+
case 'tebra_get_all_patients':
|
|
114
|
+
return await (0, bulk_patients_js_1.handleBulkPatientTool)(name, safeArgs, config);
|
|
115
|
+
// ─── Authorization & eligibility ────────────────
|
|
65
116
|
case 'tebra_get_patient_authorizations':
|
|
66
117
|
return await (0, authorizations_js_1.handleAuthorizationTool)(name, safeArgs, config);
|
|
118
|
+
case 'tebra_check_insurance_eligibility':
|
|
119
|
+
return await (0, eligibility_js_1.handleEligibilityTool)(name, safeArgs, config);
|
|
120
|
+
// ─── Encounter tools ────────────────────────────
|
|
67
121
|
case 'tebra_get_encounter':
|
|
68
122
|
case 'tebra_create_encounter':
|
|
69
123
|
return await (0, encounters_js_1.handleEncounterTool)(name, safeArgs, config);
|
|
124
|
+
case 'tebra_update_encounter_status':
|
|
125
|
+
return await (0, encounter_status_js_1.handleEncounterStatusTool)(name, safeArgs, config);
|
|
126
|
+
// ─── Appointment tools ──────────────────────────
|
|
70
127
|
case 'tebra_get_appointments':
|
|
71
128
|
return await (0, appointments_js_1.handleAppointmentTool)(name, safeArgs, config);
|
|
72
|
-
case '
|
|
73
|
-
return await (0,
|
|
129
|
+
case 'tebra_get_appointment_detail':
|
|
130
|
+
return await (0, appointment_detail_js_1.handleAppointmentDetailTool)(name, safeArgs, config);
|
|
131
|
+
case 'tebra_create_appointment':
|
|
132
|
+
case 'tebra_update_appointment':
|
|
133
|
+
case 'tebra_delete_appointment':
|
|
134
|
+
return await (0, appointment_crud_js_1.handleAppointmentCrudTool)(name, safeArgs, config);
|
|
135
|
+
case 'tebra_get_appointment_reasons':
|
|
136
|
+
return await (0, appointment_reasons_js_1.handleAppointmentReasonTool)(name, safeArgs, config);
|
|
137
|
+
// ─── Financial tools ────────────────────────────
|
|
74
138
|
case 'tebra_get_charges':
|
|
75
139
|
return await (0, charges_js_1.handleChargeTool)(name, safeArgs, config);
|
|
140
|
+
case 'tebra_get_payments':
|
|
141
|
+
case 'tebra_create_payment':
|
|
142
|
+
return await (0, payments_js_1.handlePaymentTool)(name, safeArgs, config);
|
|
143
|
+
case 'tebra_get_transactions':
|
|
144
|
+
return await (0, transactions_js_1.handleTransactionTool)(name, safeArgs, config);
|
|
145
|
+
// ─── Practice configuration ─────────────────────
|
|
146
|
+
case 'tebra_get_providers':
|
|
147
|
+
return await (0, providers_js_1.handleProviderTool)(name, safeArgs, config);
|
|
148
|
+
case 'tebra_get_service_locations':
|
|
149
|
+
return await (0, service_locations_js_1.handleServiceLocationTool)(name, safeArgs, config);
|
|
150
|
+
case 'tebra_get_practices':
|
|
151
|
+
return await (0, practices_js_1.handlePracticeTool)(name, safeArgs, config);
|
|
76
152
|
case 'tebra_get_procedure_codes':
|
|
77
153
|
return await (0, procedure_codes_js_1.handleProcedureCodeTool)(name, safeArgs, config);
|
|
154
|
+
// ─── Document tools ─────────────────────────────
|
|
155
|
+
case 'tebra_create_document':
|
|
156
|
+
case 'tebra_delete_document':
|
|
157
|
+
return await (0, documents_js_1.handleDocumentTool)(name, safeArgs, config);
|
|
158
|
+
// ─── System / admin tools ───────────────────────
|
|
159
|
+
case 'tebra_update_patient_external_id':
|
|
160
|
+
case 'tebra_register_external_vendor':
|
|
161
|
+
case 'tebra_get_external_vendors':
|
|
162
|
+
return await (0, external_ids_js_1.handleExternalIdTool)(name, safeArgs, config);
|
|
163
|
+
case 'tebra_get_throttles':
|
|
164
|
+
case 'tebra_validate_connection':
|
|
165
|
+
case 'tebra_update_patient_case':
|
|
166
|
+
case 'tebra_create_appointment_reason':
|
|
167
|
+
return await (0, system_js_1.handleSystemTool)(name, safeArgs, config);
|
|
78
168
|
default:
|
|
169
|
+
// Route FHIR tools by prefix
|
|
170
|
+
if (name.startsWith('tebra_fhir_')) {
|
|
171
|
+
return await (0, fhir_clinical_js_1.handleFhirClinicalTool)(name, safeArgs);
|
|
172
|
+
}
|
|
79
173
|
return {
|
|
80
174
|
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
81
175
|
isError: true,
|
|
@@ -94,10 +188,8 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
|
94
188
|
async function main() {
|
|
95
189
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
96
190
|
await server.connect(transport);
|
|
97
|
-
// Server is now running and listening on stdio
|
|
98
191
|
}
|
|
99
192
|
main().catch((error) => {
|
|
100
|
-
// eslint-disable-next-line no-console
|
|
101
193
|
console.error('Tebra MCP server failed to start:', error);
|
|
102
194
|
process.exit(1);
|
|
103
195
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tebra MCP Integration Service for EPIC Notes
|
|
3
|
+
*
|
|
4
|
+
* Wraps Tebra MCP tool calls for EPIC Notes use cases:
|
|
5
|
+
* - Schedule pre-seeding (today's appointments for a provider)
|
|
6
|
+
* - Appointment context for note creation
|
|
7
|
+
* - Pushing signed notes back to Tebra (encounter + document upload)
|
|
8
|
+
*
|
|
9
|
+
* DEPLOYMENT: Copy this file to your EPIC Notes project:
|
|
10
|
+
* /src/lib/services/tebra-integration.ts
|
|
11
|
+
*
|
|
12
|
+
* This module communicates with the Tebra MCP server via an McpToolCaller
|
|
13
|
+
* interface. Wire it to @modelcontextprotocol/sdk/client or any MCP-compatible
|
|
14
|
+
* transport.
|
|
15
|
+
*
|
|
16
|
+
* The MCP server itself requires TEBRA_SOAP_USER, TEBRA_SOAP_PASSWORD,
|
|
17
|
+
* and TEBRA_CUSTOMER_KEY in its environment.
|
|
18
|
+
*/
|
|
19
|
+
export interface Appointment {
|
|
20
|
+
appointmentId: string;
|
|
21
|
+
patientId: string;
|
|
22
|
+
patientName: string;
|
|
23
|
+
providerId: string;
|
|
24
|
+
providerName: string;
|
|
25
|
+
startDate: string;
|
|
26
|
+
endDate: string;
|
|
27
|
+
type: string;
|
|
28
|
+
status: string;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface PatientDemographics {
|
|
32
|
+
patientId: string;
|
|
33
|
+
firstName: string;
|
|
34
|
+
lastName: string;
|
|
35
|
+
dateOfBirth: string;
|
|
36
|
+
mrn: string;
|
|
37
|
+
insurances: Array<{
|
|
38
|
+
payerName: string;
|
|
39
|
+
memberId: string;
|
|
40
|
+
isPrimary: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
export interface Authorization {
|
|
44
|
+
authorizationId: string;
|
|
45
|
+
authNumber: string;
|
|
46
|
+
insurancePlan: string;
|
|
47
|
+
status: string;
|
|
48
|
+
approvedVisits: number;
|
|
49
|
+
usedVisits: number;
|
|
50
|
+
remainingVisits: number;
|
|
51
|
+
startDate: string;
|
|
52
|
+
endDate: string;
|
|
53
|
+
approvedCptCodes: string[];
|
|
54
|
+
}
|
|
55
|
+
export interface ClinicalSnapshot {
|
|
56
|
+
allergies: string[];
|
|
57
|
+
medications: string[];
|
|
58
|
+
conditions: string[];
|
|
59
|
+
recentVitals: Record<string, string> | null;
|
|
60
|
+
}
|
|
61
|
+
export interface EligibilityResult {
|
|
62
|
+
eligible: boolean;
|
|
63
|
+
planName: string | null;
|
|
64
|
+
memberId: string | null;
|
|
65
|
+
authRequired: boolean;
|
|
66
|
+
insurancePoliciesOnFile: number;
|
|
67
|
+
}
|
|
68
|
+
export interface NoteCreationContext {
|
|
69
|
+
appointment: Appointment;
|
|
70
|
+
patient: PatientDemographics;
|
|
71
|
+
authorizations: Authorization[];
|
|
72
|
+
eligibility: EligibilityResult;
|
|
73
|
+
clinical: ClinicalSnapshot | null;
|
|
74
|
+
}
|
|
75
|
+
export interface SignedNote {
|
|
76
|
+
appointmentId: string;
|
|
77
|
+
patientId: string;
|
|
78
|
+
providerId: string;
|
|
79
|
+
serviceDate: string;
|
|
80
|
+
diagnoses: Array<{
|
|
81
|
+
code: string;
|
|
82
|
+
description: string;
|
|
83
|
+
}>;
|
|
84
|
+
procedures: Array<{
|
|
85
|
+
code: string;
|
|
86
|
+
modifiers?: string[];
|
|
87
|
+
units?: number;
|
|
88
|
+
}>;
|
|
89
|
+
authorizationId?: string;
|
|
90
|
+
noteTitle: string;
|
|
91
|
+
pdfBase64?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface EncounterResult {
|
|
94
|
+
encounterId: string;
|
|
95
|
+
status: string;
|
|
96
|
+
}
|
|
97
|
+
export interface McpToolCaller {
|
|
98
|
+
callTool(name: string, args: Record<string, unknown>): Promise<McpToolResult>;
|
|
99
|
+
}
|
|
100
|
+
export interface McpToolResult {
|
|
101
|
+
content: Array<{
|
|
102
|
+
type: string;
|
|
103
|
+
text: string;
|
|
104
|
+
}>;
|
|
105
|
+
isError?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get today's schedule for a provider.
|
|
109
|
+
* Used to pre-seed the EPIC Notes schedule view when a provider opens the app.
|
|
110
|
+
*
|
|
111
|
+
* @param mcp - MCP tool caller instance
|
|
112
|
+
* @param providerId - Optional Tebra provider ID. If omitted, returns all providers' appointments.
|
|
113
|
+
* @returns Array of today's appointments sorted by start time
|
|
114
|
+
*/
|
|
115
|
+
export declare function getTodaySchedule(mcp: McpToolCaller, providerId?: string): Promise<Appointment[]>;
|
|
116
|
+
/**
|
|
117
|
+
* Get full context for note creation when a provider taps an appointment.
|
|
118
|
+
* Fetches patient demographics, authorizations, eligibility, and clinical data in parallel.
|
|
119
|
+
*
|
|
120
|
+
* @param mcp - MCP tool caller instance
|
|
121
|
+
* @param appointmentId - Tebra appointment ID
|
|
122
|
+
* @returns Complete context needed to populate a new note template
|
|
123
|
+
*/
|
|
124
|
+
export declare function getAppointmentContext(mcp: McpToolCaller, appointmentId: string): Promise<NoteCreationContext>;
|
|
125
|
+
/**
|
|
126
|
+
* Push a signed note to Tebra: create an encounter (superbill) and optionally
|
|
127
|
+
* upload the note PDF to the patient chart, then advance the encounter to
|
|
128
|
+
* the Review status.
|
|
129
|
+
*
|
|
130
|
+
* @param mcp - MCP tool caller instance
|
|
131
|
+
* @param note - Signed note data including diagnoses, procedures, and optional PDF
|
|
132
|
+
* @returns The created encounter ID and final status
|
|
133
|
+
*/
|
|
134
|
+
export declare function pushSignedNoteToTebra(mcp: McpToolCaller, note: SignedNote): Promise<EncounterResult>;
|
|
135
|
+
/**
|
|
136
|
+
* Upload a signed note PDF to the patient's chart in Tebra.
|
|
137
|
+
*
|
|
138
|
+
* @param mcp - MCP tool caller instance
|
|
139
|
+
* @param patientId - Tebra patient ID
|
|
140
|
+
* @param noteTitle - Title for the document in Tebra
|
|
141
|
+
* @param procedureDate - Date of the procedure/visit (ISO 8601)
|
|
142
|
+
* @param pdfBase64 - Base64-encoded PDF content
|
|
143
|
+
*/
|
|
144
|
+
export declare function uploadNoteToPaChart(mcp: McpToolCaller, patientId: string, noteTitle: string, procedureDate: string, pdfBase64: string): Promise<void>;
|
|
145
|
+
//# sourceMappingURL=epic-notes-integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epic-notes-integration.d.ts","sourceRoot":"","sources":["../../src/integrations/epic-notes-integration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tebra MCP Integration Service for EPIC Notes
|
|
4
|
+
*
|
|
5
|
+
* Wraps Tebra MCP tool calls for EPIC Notes use cases:
|
|
6
|
+
* - Schedule pre-seeding (today's appointments for a provider)
|
|
7
|
+
* - Appointment context for note creation
|
|
8
|
+
* - Pushing signed notes back to Tebra (encounter + document upload)
|
|
9
|
+
*
|
|
10
|
+
* DEPLOYMENT: Copy this file to your EPIC Notes project:
|
|
11
|
+
* /src/lib/services/tebra-integration.ts
|
|
12
|
+
*
|
|
13
|
+
* This module communicates with the Tebra MCP server via an McpToolCaller
|
|
14
|
+
* interface. Wire it to @modelcontextprotocol/sdk/client or any MCP-compatible
|
|
15
|
+
* transport.
|
|
16
|
+
*
|
|
17
|
+
* The MCP server itself requires TEBRA_SOAP_USER, TEBRA_SOAP_PASSWORD,
|
|
18
|
+
* and TEBRA_CUSTOMER_KEY in its environment.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.getTodaySchedule = getTodaySchedule;
|
|
22
|
+
exports.getAppointmentContext = getAppointmentContext;
|
|
23
|
+
exports.pushSignedNoteToTebra = pushSignedNoteToTebra;
|
|
24
|
+
exports.uploadNoteToPaChart = uploadNoteToPaChart;
|
|
25
|
+
// ─── MCP Tool Name Constants ────────────────────────────────────
|
|
26
|
+
// Centralized so tool name changes only require one update.
|
|
27
|
+
const TOOL = {
|
|
28
|
+
GET_APPOINTMENTS: 'tebra_get_appointments',
|
|
29
|
+
GET_APPOINTMENT_DETAIL: 'tebra_get_appointment_detail',
|
|
30
|
+
GET_PATIENT: 'tebra_get_patient',
|
|
31
|
+
GET_PATIENT_AUTHORIZATIONS: 'tebra_get_patient_authorizations',
|
|
32
|
+
CHECK_ELIGIBILITY: 'tebra_check_insurance_eligibility',
|
|
33
|
+
CREATE_ENCOUNTER: 'tebra_create_encounter',
|
|
34
|
+
UPDATE_ENCOUNTER_STATUS: 'tebra_update_encounter_status',
|
|
35
|
+
CREATE_DOCUMENT: 'tebra_create_document',
|
|
36
|
+
GET_PROVIDERS: 'tebra_get_providers',
|
|
37
|
+
// FHIR tools for clinical context
|
|
38
|
+
FHIR_GET_ALLERGIES: 'tebra_fhir_get_allergies',
|
|
39
|
+
FHIR_GET_MEDICATIONS: 'tebra_fhir_get_medications',
|
|
40
|
+
FHIR_GET_CONDITIONS: 'tebra_fhir_get_conditions',
|
|
41
|
+
FHIR_GET_VITALS: 'tebra_fhir_get_vitals',
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Parse the text content from an MCP tool result.
|
|
45
|
+
* Most Tebra tools return JSON in the first text content block.
|
|
46
|
+
*/
|
|
47
|
+
function parseToolResult(result) {
|
|
48
|
+
if (result.isError) {
|
|
49
|
+
const errorText = result.content[0]?.text ?? 'Unknown MCP tool error';
|
|
50
|
+
throw new Error(errorText);
|
|
51
|
+
}
|
|
52
|
+
const text = result.content[0]?.text ?? '{}';
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(text);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error(`Unexpected non-JSON response from MCP tool: ${text}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ─── Service Functions ──────────────────────────────────────────
|
|
61
|
+
/**
|
|
62
|
+
* Get today's schedule for a provider.
|
|
63
|
+
* Used to pre-seed the EPIC Notes schedule view when a provider opens the app.
|
|
64
|
+
*
|
|
65
|
+
* @param mcp - MCP tool caller instance
|
|
66
|
+
* @param providerId - Optional Tebra provider ID. If omitted, returns all providers' appointments.
|
|
67
|
+
* @returns Array of today's appointments sorted by start time
|
|
68
|
+
*/
|
|
69
|
+
async function getTodaySchedule(mcp, providerId) {
|
|
70
|
+
const today = new Date().toISOString().split('T')[0];
|
|
71
|
+
const args = {
|
|
72
|
+
startDate: today,
|
|
73
|
+
endDate: today,
|
|
74
|
+
};
|
|
75
|
+
if (providerId) {
|
|
76
|
+
args.providerId = providerId;
|
|
77
|
+
}
|
|
78
|
+
const result = await mcp.callTool(TOOL.GET_APPOINTMENTS, args);
|
|
79
|
+
const text = result.content[0]?.text ?? '';
|
|
80
|
+
// Handle "No appointments found" responses gracefully
|
|
81
|
+
if (text.startsWith('No appointments')) {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
const appointments = parseToolResult(result);
|
|
85
|
+
return appointments.sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get full context for note creation when a provider taps an appointment.
|
|
89
|
+
* Fetches patient demographics, authorizations, eligibility, and clinical data in parallel.
|
|
90
|
+
*
|
|
91
|
+
* @param mcp - MCP tool caller instance
|
|
92
|
+
* @param appointmentId - Tebra appointment ID
|
|
93
|
+
* @returns Complete context needed to populate a new note template
|
|
94
|
+
*/
|
|
95
|
+
async function getAppointmentContext(mcp, appointmentId) {
|
|
96
|
+
// Step 1: Get appointment detail to extract patientId
|
|
97
|
+
const appointmentResult = await mcp.callTool(TOOL.GET_APPOINTMENT_DETAIL, {
|
|
98
|
+
appointmentId,
|
|
99
|
+
});
|
|
100
|
+
const appointment = parseToolResult(appointmentResult);
|
|
101
|
+
const { patientId } = appointment;
|
|
102
|
+
// Step 2: Fetch patient data, authorizations, eligibility, and clinical in parallel
|
|
103
|
+
const [patientResult, authResult, eligibilityResult, clinicalSnapshot] = await Promise.all([
|
|
104
|
+
mcp.callTool(TOOL.GET_PATIENT, { patientId }),
|
|
105
|
+
mcp.callTool(TOOL.GET_PATIENT_AUTHORIZATIONS, { patientId }),
|
|
106
|
+
mcp.callTool(TOOL.CHECK_ELIGIBILITY, { patientId }),
|
|
107
|
+
fetchClinicalSnapshot(mcp, patientId),
|
|
108
|
+
]);
|
|
109
|
+
const patient = parseToolResult(patientResult);
|
|
110
|
+
// Authorizations may return "No authorizations found" -- not an error
|
|
111
|
+
let authorizations = [];
|
|
112
|
+
try {
|
|
113
|
+
authorizations = parseToolResult(authResult);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// No authorizations on file
|
|
117
|
+
}
|
|
118
|
+
const eligibility = parseToolResult(eligibilityResult);
|
|
119
|
+
return {
|
|
120
|
+
appointment,
|
|
121
|
+
patient,
|
|
122
|
+
authorizations,
|
|
123
|
+
eligibility,
|
|
124
|
+
clinical: clinicalSnapshot,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Push a signed note to Tebra: create an encounter (superbill) and optionally
|
|
129
|
+
* upload the note PDF to the patient chart, then advance the encounter to
|
|
130
|
+
* the Review status.
|
|
131
|
+
*
|
|
132
|
+
* @param mcp - MCP tool caller instance
|
|
133
|
+
* @param note - Signed note data including diagnoses, procedures, and optional PDF
|
|
134
|
+
* @returns The created encounter ID and final status
|
|
135
|
+
*/
|
|
136
|
+
async function pushSignedNoteToTebra(mcp, note) {
|
|
137
|
+
// Step 1: Create the encounter (superbill)
|
|
138
|
+
const createResult = await mcp.callTool(TOOL.CREATE_ENCOUNTER, {
|
|
139
|
+
patientId: note.patientId,
|
|
140
|
+
providerId: note.providerId,
|
|
141
|
+
serviceDate: note.serviceDate,
|
|
142
|
+
diagnoses: note.diagnoses,
|
|
143
|
+
procedures: note.procedures,
|
|
144
|
+
authorizationId: note.authorizationId,
|
|
145
|
+
});
|
|
146
|
+
const encounter = parseToolResult(createResult);
|
|
147
|
+
// Step 2: Upload PDF and advance status in parallel
|
|
148
|
+
const parallelOps = [];
|
|
149
|
+
if (note.pdfBase64) {
|
|
150
|
+
parallelOps.push(uploadNoteToPaChart(mcp, note.patientId, note.noteTitle, note.serviceDate, note.pdfBase64));
|
|
151
|
+
}
|
|
152
|
+
// Advance encounter to Review status
|
|
153
|
+
parallelOps.push(mcp.callTool(TOOL.UPDATE_ENCOUNTER_STATUS, {
|
|
154
|
+
encounterId: encounter.encounterId,
|
|
155
|
+
status: 'Review',
|
|
156
|
+
}));
|
|
157
|
+
await Promise.all(parallelOps);
|
|
158
|
+
return {
|
|
159
|
+
encounterId: encounter.encounterId,
|
|
160
|
+
status: 'Review',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Upload a signed note PDF to the patient's chart in Tebra.
|
|
165
|
+
*
|
|
166
|
+
* @param mcp - MCP tool caller instance
|
|
167
|
+
* @param patientId - Tebra patient ID
|
|
168
|
+
* @param noteTitle - Title for the document in Tebra
|
|
169
|
+
* @param procedureDate - Date of the procedure/visit (ISO 8601)
|
|
170
|
+
* @param pdfBase64 - Base64-encoded PDF content
|
|
171
|
+
*/
|
|
172
|
+
async function uploadNoteToPaChart(mcp, patientId, noteTitle, procedureDate, pdfBase64) {
|
|
173
|
+
await mcp.callTool(TOOL.CREATE_DOCUMENT, {
|
|
174
|
+
patientId,
|
|
175
|
+
title: noteTitle,
|
|
176
|
+
date: procedureDate,
|
|
177
|
+
contentBase64: pdfBase64,
|
|
178
|
+
contentType: 'application/pdf',
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// ─── Internal Helpers ───────────────────────────────────────────
|
|
182
|
+
/**
|
|
183
|
+
* Fetch clinical snapshot from FHIR endpoints.
|
|
184
|
+
* Returns null if FHIR credentials are not configured (non-fatal).
|
|
185
|
+
*/
|
|
186
|
+
async function fetchClinicalSnapshot(mcp, patientId) {
|
|
187
|
+
try {
|
|
188
|
+
const [allergiesResult, medsResult, conditionsResult, vitalsResult] = await Promise.all([
|
|
189
|
+
mcp.callTool(TOOL.FHIR_GET_ALLERGIES, { patientId }),
|
|
190
|
+
mcp.callTool(TOOL.FHIR_GET_MEDICATIONS, { patientId }),
|
|
191
|
+
mcp.callTool(TOOL.FHIR_GET_CONDITIONS, { patientId }),
|
|
192
|
+
mcp.callTool(TOOL.FHIR_GET_VITALS, { patientId }),
|
|
193
|
+
]);
|
|
194
|
+
return {
|
|
195
|
+
allergies: safeParseStringArray(allergiesResult),
|
|
196
|
+
medications: safeParseStringArray(medsResult),
|
|
197
|
+
conditions: safeParseStringArray(conditionsResult),
|
|
198
|
+
recentVitals: safeParseRecord(vitalsResult),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// FHIR not configured or unavailable -- degrade gracefully
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function safeParseStringArray(result) {
|
|
207
|
+
try {
|
|
208
|
+
const parsed = JSON.parse(result.content[0]?.text ?? '[]');
|
|
209
|
+
if (Array.isArray(parsed)) {
|
|
210
|
+
return parsed.map((item) => typeof item === 'string' ? item : JSON.stringify(item));
|
|
211
|
+
}
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function safeParseRecord(result) {
|
|
219
|
+
try {
|
|
220
|
+
const parsed = JSON.parse(result.content[0]?.text ?? 'null');
|
|
221
|
+
return typeof parsed === 'object' && parsed !== null ? parsed : null;
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=epic-notes-integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epic-notes-integration.js","sourceRoot":"","sources":["../../src/integrations/epic-notes-integration.ts"],"names":[],"mappings":"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"}
|