tebra-mcp-server 0.1.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 -0
- package/README.md +103 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/soap-client.d.ts +14 -0
- package/dist/soap-client.d.ts.map +1 -0
- package/dist/soap-client.js +108 -0
- package/dist/soap-client.js.map +1 -0
- package/dist/tools/appointments.d.ts +33 -0
- package/dist/tools/appointments.d.ts.map +1 -0
- package/dist/tools/appointments.js +80 -0
- package/dist/tools/appointments.js.map +1 -0
- package/dist/tools/authorizations.d.ts +25 -0
- package/dist/tools/authorizations.d.ts.map +1 -0
- package/dist/tools/authorizations.js +101 -0
- package/dist/tools/authorizations.js.map +1 -0
- package/dist/tools/charges.d.ts +33 -0
- package/dist/tools/charges.d.ts.map +1 -0
- package/dist/tools/charges.js +78 -0
- package/dist/tools/charges.js.map +1 -0
- package/dist/tools/eligibility.d.ts +29 -0
- package/dist/tools/eligibility.d.ts.map +1 -0
- package/dist/tools/eligibility.js +98 -0
- package/dist/tools/eligibility.js.map +1 -0
- package/dist/tools/encounters.d.ts +100 -0
- package/dist/tools/encounters.d.ts.map +1 -0
- package/dist/tools/encounters.js +186 -0
- package/dist/tools/encounters.js.map +1 -0
- package/dist/tools/patients.d.ts +40 -0
- package/dist/tools/patients.d.ts.map +1 -0
- package/dist/tools/patients.js +151 -0
- package/dist/tools/patients.js.map +1 -0
- package/dist/tools/procedure-codes.d.ts +25 -0
- package/dist/tools/procedure-codes.d.ts.map +1 -0
- package/dist/tools/procedure-codes.js +56 -0
- package/dist/tools/procedure-codes.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 James Rosing / Allure MD
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @allure-md/tebra-mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server for Tebra (Kareo) practice management. Exposes patient data, encounters, authorizations, appointments, charges, eligibility, and procedure codes to Claude and other MCP-compatible clients.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 18+
|
|
8
|
+
- Tebra SOAP API credentials (generated in Tebra PM admin under Settings > API)
|
|
9
|
+
|
|
10
|
+
## Environment Variables
|
|
11
|
+
|
|
12
|
+
| Variable | Required | Description |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `TEBRA_SOAP_USER` | Yes | SOAP API user (email) |
|
|
15
|
+
| `TEBRA_SOAP_PASSWORD` | Yes | SOAP API password |
|
|
16
|
+
| `TEBRA_CUSTOMER_KEY` | Yes | Customer key from Tebra PM admin |
|
|
17
|
+
| `TEBRA_SOAP_ENDPOINT` | No | Override SOAP endpoint (for testing) |
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd tebra-mcp-server
|
|
23
|
+
npm install
|
|
24
|
+
npm run build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Direct execution
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
TEBRA_SOAP_USER=user@practice.com \
|
|
33
|
+
TEBRA_SOAP_PASSWORD=secret \
|
|
34
|
+
TEBRA_CUSTOMER_KEY=abc123 \
|
|
35
|
+
node dist/index.js
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Claude Desktop configuration
|
|
39
|
+
|
|
40
|
+
Add to your Claude Desktop config (`claude_desktop_config.json`):
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"mcpServers": {
|
|
45
|
+
"tebra": {
|
|
46
|
+
"command": "node",
|
|
47
|
+
"args": ["/path/to/tebra-mcp-server/dist/index.js"],
|
|
48
|
+
"env": {
|
|
49
|
+
"TEBRA_SOAP_USER": "user@practice.com",
|
|
50
|
+
"TEBRA_SOAP_PASSWORD": "your-password",
|
|
51
|
+
"TEBRA_CUSTOMER_KEY": "your-customer-key"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Claude Code configuration
|
|
59
|
+
|
|
60
|
+
Add to `.mcp.json` in your project root:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"mcpServers": {
|
|
65
|
+
"tebra": {
|
|
66
|
+
"command": "node",
|
|
67
|
+
"args": ["./tebra-mcp-server/dist/index.js"],
|
|
68
|
+
"env": {
|
|
69
|
+
"TEBRA_SOAP_USER": "user@practice.com",
|
|
70
|
+
"TEBRA_SOAP_PASSWORD": "your-password",
|
|
71
|
+
"TEBRA_CUSTOMER_KEY": "your-customer-key"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Available Tools
|
|
79
|
+
|
|
80
|
+
| Tool | Description |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `tebra_search_patients` | Search patients by name, DOB, MRN, or external ID |
|
|
83
|
+
| `tebra_get_patient` | Get full patient record with insurance and authorizations |
|
|
84
|
+
| `tebra_get_patient_authorizations` | Get all authorizations across cases with status and remaining visits |
|
|
85
|
+
| `tebra_get_encounter` | Get encounter details with linked charges and procedures |
|
|
86
|
+
| `tebra_create_encounter` | Create a new encounter (superbill) with diagnoses and procedures |
|
|
87
|
+
| `tebra_get_appointments` | Get appointments within a date range, optionally by provider |
|
|
88
|
+
| `tebra_check_insurance_eligibility` | Check insurance eligibility based on on-file data |
|
|
89
|
+
| `tebra_get_charges` | Get charges with payment status, filterable by date and patient |
|
|
90
|
+
| `tebra_get_procedure_codes` | Get practice procedure codes with fees |
|
|
91
|
+
|
|
92
|
+
## API Reference
|
|
93
|
+
|
|
94
|
+
The server wraps the Tebra/Kareo SOAP API v2.1:
|
|
95
|
+
- Endpoint: `https://webservice.kareo.com/services/soap/2.1/KareoServices.svc`
|
|
96
|
+
- Auth: RequestHeader with User, Password, CustomerKey
|
|
97
|
+
- All requests include retry with exponential backoff (3 attempts)
|
|
98
|
+
|
|
99
|
+
## Development
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run dev # Uses tsx for direct TypeScript execution
|
|
103
|
+
```
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loader for the Tebra MCP server.
|
|
3
|
+
* Validates required environment variables at startup.
|
|
4
|
+
*/
|
|
5
|
+
export interface TebraConfig {
|
|
6
|
+
user: string;
|
|
7
|
+
password: string;
|
|
8
|
+
customerKey: string;
|
|
9
|
+
endpoint: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Load and validate Tebra configuration from environment variables.
|
|
13
|
+
* Fails fast with a clear error if required vars are missing.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getConfig(): TebraConfig;
|
|
16
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAKD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,WAAW,CAuBvC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration loader for the Tebra MCP server.
|
|
4
|
+
* Validates required environment variables at startup.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getConfig = getConfig;
|
|
8
|
+
const TEBRA_SOAP_ENDPOINT = 'https://webservice.kareo.com/services/soap/2.1/KareoServices.svc';
|
|
9
|
+
/**
|
|
10
|
+
* Load and validate Tebra configuration from environment variables.
|
|
11
|
+
* Fails fast with a clear error if required vars are missing.
|
|
12
|
+
*/
|
|
13
|
+
function getConfig() {
|
|
14
|
+
const user = process.env.TEBRA_SOAP_USER;
|
|
15
|
+
const password = process.env.TEBRA_SOAP_PASSWORD;
|
|
16
|
+
const customerKey = process.env.TEBRA_CUSTOMER_KEY;
|
|
17
|
+
const missing = [];
|
|
18
|
+
if (!user)
|
|
19
|
+
missing.push('TEBRA_SOAP_USER');
|
|
20
|
+
if (!password)
|
|
21
|
+
missing.push('TEBRA_SOAP_PASSWORD');
|
|
22
|
+
if (!customerKey)
|
|
23
|
+
missing.push('TEBRA_CUSTOMER_KEY');
|
|
24
|
+
if (missing.length > 0) {
|
|
25
|
+
throw new Error(`Missing required environment variables: ${missing.join(', ')}.\n` +
|
|
26
|
+
'Set these in your environment or .env file before starting the MCP server.');
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
user: user.trim(),
|
|
30
|
+
password: password.trim(),
|
|
31
|
+
customerKey: customerKey.trim(),
|
|
32
|
+
endpoint: process.env.TEBRA_SOAP_ENDPOINT?.trim() ?? TEBRA_SOAP_ENDPOINT,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAgBH,8BAuBC;AA9BD,MAAM,mBAAmB,GACvB,kEAAkE,CAAC;AAErE;;;GAGG;AACH,SAAgB,SAAS;IACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACjD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAEnD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAErD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,2CAA2C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAClE,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,IAAK,CAAC,IAAI,EAAE;QAClB,QAAQ,EAAE,QAAS,CAAC,IAAI,EAAE;QAC1B,WAAW,EAAE,WAAY,CAAC,IAAI,EAAE;QAChC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,mBAAmB;KACzE,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Tebra MCP Server entry point.
|
|
4
|
+
*
|
|
5
|
+
* Exposes Tebra/Kareo practice management operations as MCP tools
|
|
6
|
+
* for use with Claude Code, Claude Desktop, or any MCP-compatible client.
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* TEBRA_SOAP_USER — SOAP API user (email)
|
|
10
|
+
* TEBRA_SOAP_PASSWORD — SOAP API password
|
|
11
|
+
* TEBRA_CUSTOMER_KEY — Customer key from Tebra PM admin
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* npx @allure-md/tebra-mcp-server
|
|
15
|
+
* TEBRA_SOAP_USER=... TEBRA_SOAP_PASSWORD=... TEBRA_CUSTOMER_KEY=... node dist/index.js
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Tebra MCP Server entry point.
|
|
5
|
+
*
|
|
6
|
+
* Exposes Tebra/Kareo practice management operations as MCP tools
|
|
7
|
+
* for use with Claude Code, Claude Desktop, or any MCP-compatible client.
|
|
8
|
+
*
|
|
9
|
+
* Environment variables:
|
|
10
|
+
* TEBRA_SOAP_USER — SOAP API user (email)
|
|
11
|
+
* TEBRA_SOAP_PASSWORD — SOAP API password
|
|
12
|
+
* TEBRA_CUSTOMER_KEY — Customer key from Tebra PM admin
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* npx @allure-md/tebra-mcp-server
|
|
16
|
+
* TEBRA_SOAP_USER=... TEBRA_SOAP_PASSWORD=... TEBRA_CUSTOMER_KEY=... node dist/index.js
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
20
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
21
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
22
|
+
const config_js_1 = require("./config.js");
|
|
23
|
+
const patients_js_1 = require("./tools/patients.js");
|
|
24
|
+
const encounters_js_1 = require("./tools/encounters.js");
|
|
25
|
+
const authorizations_js_1 = require("./tools/authorizations.js");
|
|
26
|
+
const appointments_js_1 = require("./tools/appointments.js");
|
|
27
|
+
const eligibility_js_1 = require("./tools/eligibility.js");
|
|
28
|
+
const charges_js_1 = require("./tools/charges.js");
|
|
29
|
+
const procedure_codes_js_1 = require("./tools/procedure-codes.js");
|
|
30
|
+
// ─── Validate config on startup ─────────────────────────────────
|
|
31
|
+
const config = (0, config_js_1.getConfig)();
|
|
32
|
+
// ─── Create MCP Server ──────────────────────────────────────────
|
|
33
|
+
const server = new index_js_1.Server({
|
|
34
|
+
name: '@allure-md/tebra-mcp-server',
|
|
35
|
+
version: '0.1.0',
|
|
36
|
+
}, {
|
|
37
|
+
capabilities: {
|
|
38
|
+
tools: {},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
// ─── Aggregate all tools ────────────────────────────────────────
|
|
42
|
+
const allTools = [
|
|
43
|
+
...patients_js_1.patientTools,
|
|
44
|
+
...encounters_js_1.encounterTools,
|
|
45
|
+
...authorizations_js_1.authorizationTools,
|
|
46
|
+
...appointments_js_1.appointmentTools,
|
|
47
|
+
...eligibility_js_1.eligibilityTools,
|
|
48
|
+
...charges_js_1.chargeTools,
|
|
49
|
+
...procedure_codes_js_1.procedureCodeTools,
|
|
50
|
+
];
|
|
51
|
+
// ─── Tool Listing ───────────────────────────────────────────────
|
|
52
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
53
|
+
return { tools: allTools };
|
|
54
|
+
});
|
|
55
|
+
// ─── Tool Execution ─────────────────────────────────────────────
|
|
56
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
57
|
+
const { name, arguments: args } = request.params;
|
|
58
|
+
try {
|
|
59
|
+
// Route to the correct handler by exact tool name
|
|
60
|
+
const safeArgs = args ?? {};
|
|
61
|
+
switch (name) {
|
|
62
|
+
case 'tebra_search_patients':
|
|
63
|
+
case 'tebra_get_patient':
|
|
64
|
+
return await (0, patients_js_1.handlePatientTool)(name, safeArgs, config);
|
|
65
|
+
case 'tebra_get_patient_authorizations':
|
|
66
|
+
return await (0, authorizations_js_1.handleAuthorizationTool)(name, safeArgs, config);
|
|
67
|
+
case 'tebra_get_encounter':
|
|
68
|
+
case 'tebra_create_encounter':
|
|
69
|
+
return await (0, encounters_js_1.handleEncounterTool)(name, safeArgs, config);
|
|
70
|
+
case 'tebra_get_appointments':
|
|
71
|
+
return await (0, appointments_js_1.handleAppointmentTool)(name, safeArgs, config);
|
|
72
|
+
case 'tebra_check_insurance_eligibility':
|
|
73
|
+
return await (0, eligibility_js_1.handleEligibilityTool)(name, safeArgs, config);
|
|
74
|
+
case 'tebra_get_charges':
|
|
75
|
+
return await (0, charges_js_1.handleChargeTool)(name, safeArgs, config);
|
|
76
|
+
case 'tebra_get_procedure_codes':
|
|
77
|
+
return await (0, procedure_codes_js_1.handleProcedureCodeTool)(name, safeArgs, config);
|
|
78
|
+
default:
|
|
79
|
+
return {
|
|
80
|
+
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
81
|
+
isError: true,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
87
|
+
return {
|
|
88
|
+
content: [{ type: 'text', text: `Error in ${name}: ${message}` }],
|
|
89
|
+
isError: true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// ─── Start Server ───────────────────────────────────────────────
|
|
94
|
+
async function main() {
|
|
95
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
96
|
+
await server.connect(transport);
|
|
97
|
+
// Server is now running and listening on stdio
|
|
98
|
+
}
|
|
99
|
+
main().catch((error) => {
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.error('Tebra MCP server failed to start:', error);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA;;;;;;;;;;;;;;GAcG;;AAEH,wEAAmE;AACnE,wEAAiF;AACjF,iEAG4C;AAE5C,2CAAwC;AACxC,qDAAsE;AACtE,yDAA4E;AAC5E,iEAAwF;AACxF,6DAAkF;AAClF,2DAAiF;AACjF,mDAAmE;AACnE,mEAAyF;AAEzF,mEAAmE;AAEnE,MAAM,MAAM,GAAG,IAAA,qBAAS,GAAE,CAAC;AAE3B,mEAAmE;AAEnE,MAAM,MAAM,GAAG,IAAI,iBAAM,CACvB;IACE,IAAI,EAAE,6BAA6B;IACnC,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF,mEAAmE;AAEnE,MAAM,QAAQ,GAAG;IACf,GAAG,0BAAY;IACf,GAAG,8BAAc;IACjB,GAAG,sCAAkB;IACrB,GAAG,kCAAgB;IACnB,GAAG,iCAAgB;IACnB,GAAG,wBAAW;IACd,GAAG,uCAAkB;CACtB,CAAC;AAEF,mEAAmE;AAEnE,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,mEAAmE;AAEnE,MAAM,CAAC,iBAAiB,CAAC,gCAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjD,IAAI,CAAC;QACH,kDAAkD;QAClD,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;QAE5B,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,uBAAuB,CAAC;YAC7B,KAAK,mBAAmB;gBACtB,OAAO,MAAM,IAAA,+BAAiB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAEzD,KAAK,kCAAkC;gBACrC,OAAO,MAAM,IAAA,2CAAuB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE/D,KAAK,qBAAqB,CAAC;YAC3B,KAAK,wBAAwB;gBAC3B,OAAO,MAAM,IAAA,mCAAmB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE3D,KAAK,wBAAwB;gBAC3B,OAAO,MAAM,IAAA,uCAAqB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE7D,KAAK,mCAAmC;gBACtC,OAAO,MAAM,IAAA,sCAAqB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE7D,KAAK,mBAAmB;gBACtB,OAAO,MAAM,IAAA,6BAAgB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAExD,KAAK,2BAA2B;gBAC9B,OAAO,MAAM,IAAA,4CAAuB,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE/D;gBACE,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;oBAC1D,OAAO,EAAE,IAAI;iBACd,CAAC;QACN,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,IAAI,KAAK,OAAO,EAAE,EAAE,CAAC;YACjE,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,mEAAmE;AAEnE,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,+CAA+C;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOAP client for the Tebra MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Standalone version (no Next.js dependencies).
|
|
5
|
+
* Builds SOAP XML envelopes, sends via fetch, parses responses.
|
|
6
|
+
* Retry with exponential backoff: 3 attempts at 1s, 2s, 4s.
|
|
7
|
+
*/
|
|
8
|
+
import type { TebraConfig } from './config.js';
|
|
9
|
+
export declare function escapeXml(str: string): string;
|
|
10
|
+
export declare function extractTag(xml: string, tagName: string): string;
|
|
11
|
+
export declare function extractAllTags(xml: string, tagName: string): string[];
|
|
12
|
+
export declare function extractNumber(xml: string, tagName: string): number;
|
|
13
|
+
export declare function soapRequest(config: TebraConfig, action: string, bodyXml: string): Promise<string>;
|
|
14
|
+
//# sourceMappingURL=soap-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soap-client.d.ts","sourceRoot":"","sources":["../src/soap-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU/C,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAO/D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIlE;AA6BD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAqDjB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SOAP client for the Tebra MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Standalone version (no Next.js dependencies).
|
|
6
|
+
* Builds SOAP XML envelopes, sends via fetch, parses responses.
|
|
7
|
+
* Retry with exponential backoff: 3 attempts at 1s, 2s, 4s.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.escapeXml = escapeXml;
|
|
11
|
+
exports.extractTag = extractTag;
|
|
12
|
+
exports.extractAllTags = extractAllTags;
|
|
13
|
+
exports.extractNumber = extractNumber;
|
|
14
|
+
exports.soapRequest = soapRequest;
|
|
15
|
+
// ─── Constants ──────────────────────────────────────────────────
|
|
16
|
+
const MAX_RETRIES = 3;
|
|
17
|
+
const BASE_DELAY_MS = 1000;
|
|
18
|
+
const SOAP_NAMESPACE = 'http://www.kareo.com/api/schemas/';
|
|
19
|
+
// ─── XML Helpers ────────────────────────────────────────────────
|
|
20
|
+
function escapeXml(str) {
|
|
21
|
+
return str
|
|
22
|
+
.replace(/&/g, '&')
|
|
23
|
+
.replace(/</g, '<')
|
|
24
|
+
.replace(/>/g, '>')
|
|
25
|
+
.replace(/"/g, '"')
|
|
26
|
+
.replace(/'/g, ''');
|
|
27
|
+
}
|
|
28
|
+
function extractTag(xml, tagName) {
|
|
29
|
+
const pattern = new RegExp(`<(?:[a-zA-Z0-9]+:)?${tagName}[^>]*>([\\s\\S]*?)</(?:[a-zA-Z0-9]+:)?${tagName}>`, 'i');
|
|
30
|
+
const match = xml.match(pattern);
|
|
31
|
+
return match?.[1]?.trim() ?? '';
|
|
32
|
+
}
|
|
33
|
+
function extractAllTags(xml, tagName) {
|
|
34
|
+
const pattern = new RegExp(`<(?:[a-zA-Z0-9]+:)?${tagName}[^>]*>[\\s\\S]*?</(?:[a-zA-Z0-9]+:)?${tagName}>`, 'gi');
|
|
35
|
+
return xml.match(pattern) ?? [];
|
|
36
|
+
}
|
|
37
|
+
function extractNumber(xml, tagName) {
|
|
38
|
+
const val = extractTag(xml, tagName);
|
|
39
|
+
const num = parseInt(val, 10);
|
|
40
|
+
return isNaN(num) ? 0 : num;
|
|
41
|
+
}
|
|
42
|
+
// ─── Envelope Builder ───────────────────────────────────────────
|
|
43
|
+
function buildEnvelope(config, action, bodyXml) {
|
|
44
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
45
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
|
46
|
+
xmlns:kar="${SOAP_NAMESPACE}">
|
|
47
|
+
<soap:Header>
|
|
48
|
+
<kar:RequestHeader>
|
|
49
|
+
<kar:User>${escapeXml(config.user)}</kar:User>
|
|
50
|
+
<kar:Password>${escapeXml(config.password)}</kar:Password>
|
|
51
|
+
<kar:CustomerKey>${escapeXml(config.customerKey)}</kar:CustomerKey>
|
|
52
|
+
</kar:RequestHeader>
|
|
53
|
+
</soap:Header>
|
|
54
|
+
<soap:Body>
|
|
55
|
+
<kar:${action}>
|
|
56
|
+
${bodyXml}
|
|
57
|
+
</kar:${action}>
|
|
58
|
+
</soap:Body>
|
|
59
|
+
</soap:Envelope>`;
|
|
60
|
+
}
|
|
61
|
+
// ─── SOAP Request with Retry ────────────────────────────────────
|
|
62
|
+
function sleep(ms) {
|
|
63
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
64
|
+
}
|
|
65
|
+
async function soapRequest(config, action, bodyXml) {
|
|
66
|
+
const soapAction = `${SOAP_NAMESPACE}${action}`;
|
|
67
|
+
const envelope = buildEnvelope(config, action, bodyXml);
|
|
68
|
+
let lastError = null;
|
|
69
|
+
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
70
|
+
try {
|
|
71
|
+
const response = await fetch(config.endpoint, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: {
|
|
74
|
+
'Content-Type': 'text/xml; charset=utf-8',
|
|
75
|
+
SOAPAction: soapAction,
|
|
76
|
+
},
|
|
77
|
+
body: envelope,
|
|
78
|
+
});
|
|
79
|
+
const responseText = await response.text();
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
const faultString = extractTag(responseText, 'faultstring');
|
|
82
|
+
throw new Error(`SOAP ${action} failed (HTTP ${response.status}): ${faultString || response.statusText}`);
|
|
83
|
+
}
|
|
84
|
+
const faultString = extractTag(responseText, 'faultstring');
|
|
85
|
+
if (faultString) {
|
|
86
|
+
throw new Error(`SOAP fault from ${action}: ${faultString}`);
|
|
87
|
+
}
|
|
88
|
+
const errorResponse = extractTag(responseText, 'ErrorResponse');
|
|
89
|
+
if (errorResponse) {
|
|
90
|
+
const isError = extractTag(errorResponse, 'IsError');
|
|
91
|
+
if (isError.toLowerCase() === 'true') {
|
|
92
|
+
const errorMsg = extractTag(errorResponse, 'ErrorMessage');
|
|
93
|
+
throw new Error(`Tebra ${action} error: ${errorMsg || 'Unknown error'}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return responseText;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
100
|
+
if (attempt < MAX_RETRIES) {
|
|
101
|
+
const delayMs = BASE_DELAY_MS * Math.pow(2, attempt - 1);
|
|
102
|
+
await sleep(delayMs);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`SOAP ${action} failed after ${MAX_RETRIES} attempts: ${lastError?.message ?? 'Unknown error'}`);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=soap-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soap-client.js","sourceRoot":"","sources":["../src/soap-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tebra MCP tools: Appointment retrieval.
|
|
3
|
+
*/
|
|
4
|
+
import type { TebraConfig } from '../config.js';
|
|
5
|
+
export declare const appointmentTools: {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object";
|
|
10
|
+
properties: {
|
|
11
|
+
startDate: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
endDate: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
providerId: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
required: string[];
|
|
25
|
+
};
|
|
26
|
+
}[];
|
|
27
|
+
export declare function handleAppointmentTool(name: string, args: Record<string, unknown>, config: TebraConfig): Promise<{
|
|
28
|
+
content: Array<{
|
|
29
|
+
type: string;
|
|
30
|
+
text: string;
|
|
31
|
+
}>;
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=appointments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appointments.d.ts","sourceRoot":"","sources":["../../src/tools/appointments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;GAwB5B,CAAC;AAIF,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAoD7D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tebra MCP tools: Appointment retrieval.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.appointmentTools = void 0;
|
|
7
|
+
exports.handleAppointmentTool = handleAppointmentTool;
|
|
8
|
+
const soap_client_js_1 = require("../soap-client.js");
|
|
9
|
+
// ─── Tool Definitions ───────────────────────────────────────────
|
|
10
|
+
exports.appointmentTools = [
|
|
11
|
+
{
|
|
12
|
+
name: 'tebra_get_appointments',
|
|
13
|
+
description: 'Get appointments from Tebra within a date range. Optionally filter by provider.',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
startDate: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Start date (ISO 8601, e.g. 2026-03-25)',
|
|
20
|
+
},
|
|
21
|
+
endDate: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'End date (ISO 8601, e.g. 2026-03-31)',
|
|
24
|
+
},
|
|
25
|
+
providerId: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'Optional Tebra provider ID to filter by',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
required: ['startDate', 'endDate'],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
// ─── Tool Handler ───────────────────────────────────────────────
|
|
35
|
+
async function handleAppointmentTool(name, args, config) {
|
|
36
|
+
if (name !== 'tebra_get_appointments') {
|
|
37
|
+
return { content: [{ type: 'text', text: `Unknown appointment tool: ${name}` }] };
|
|
38
|
+
}
|
|
39
|
+
const startDate = String(args.startDate ?? '');
|
|
40
|
+
const endDate = String(args.endDate ?? '');
|
|
41
|
+
if (!startDate || !endDate) {
|
|
42
|
+
return { content: [{ type: 'text', text: 'startDate and endDate are required.' }] };
|
|
43
|
+
}
|
|
44
|
+
const providerId = args.providerId ? String(args.providerId) : undefined;
|
|
45
|
+
const bodyXml = `
|
|
46
|
+
<kar:request>
|
|
47
|
+
<kar:Fields>
|
|
48
|
+
<kar:StartDate>${(0, soap_client_js_1.escapeXml)(startDate)}</kar:StartDate>
|
|
49
|
+
<kar:EndDate>${(0, soap_client_js_1.escapeXml)(endDate)}</kar:EndDate>
|
|
50
|
+
${providerId ? `<kar:ProviderID>${(0, soap_client_js_1.escapeXml)(providerId)}</kar:ProviderID>` : ''}
|
|
51
|
+
</kar:Fields>
|
|
52
|
+
</kar:request>`;
|
|
53
|
+
const xml = await (0, soap_client_js_1.soapRequest)(config, 'GetAppointments', bodyXml);
|
|
54
|
+
const blocks = (0, soap_client_js_1.extractAllTags)(xml, 'AppointmentData');
|
|
55
|
+
const appointments = blocks.map((block) => ({
|
|
56
|
+
appointmentId: (0, soap_client_js_1.extractTag)(block, 'AppointmentID') || (0, soap_client_js_1.extractTag)(block, 'ID'),
|
|
57
|
+
patientId: (0, soap_client_js_1.extractTag)(block, 'PatientID'),
|
|
58
|
+
patientName: `${(0, soap_client_js_1.extractTag)(block, 'PatientFirstName')} ${(0, soap_client_js_1.extractTag)(block, 'PatientLastName')}`.trim(),
|
|
59
|
+
providerId: (0, soap_client_js_1.extractTag)(block, 'ProviderID'),
|
|
60
|
+
providerName: (0, soap_client_js_1.extractTag)(block, 'ProviderFullName'),
|
|
61
|
+
startDate: (0, soap_client_js_1.extractTag)(block, 'StartDate'),
|
|
62
|
+
endDate: (0, soap_client_js_1.extractTag)(block, 'EndDate'),
|
|
63
|
+
type: (0, soap_client_js_1.extractTag)(block, 'AppointmentType'),
|
|
64
|
+
status: (0, soap_client_js_1.extractTag)(block, 'Status') || (0, soap_client_js_1.extractTag)(block, 'AppointmentStatus'),
|
|
65
|
+
}));
|
|
66
|
+
if (appointments.length === 0) {
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: `No appointments found between ${startDate} and ${endDate}.`,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: 'text', text: JSON.stringify(appointments, null, 2) }],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=appointments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appointments.js","sourceRoot":"","sources":["../../src/tools/appointments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tebra MCP tools: Patient authorization retrieval.
|
|
3
|
+
*/
|
|
4
|
+
import type { TebraConfig } from '../config.js';
|
|
5
|
+
export declare const authorizationTools: {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object";
|
|
10
|
+
properties: {
|
|
11
|
+
patientId: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
required: string[];
|
|
17
|
+
};
|
|
18
|
+
}[];
|
|
19
|
+
export declare function handleAuthorizationTool(name: string, args: Record<string, unknown>, config: TebraConfig): Promise<{
|
|
20
|
+
content: Array<{
|
|
21
|
+
type: string;
|
|
22
|
+
text: string;
|
|
23
|
+
}>;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=authorizations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizations.d.ts","sourceRoot":"","sources":["../../src/tools/authorizations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAWhD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;GAgB9B,CAAC;AAIF,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAqF7D"}
|