advancedmd-connector
Centralized MCP server that provides a unified tool surface for accessing AdvancedMD data, managing credentials, sessions, and rate limits for multiple backend workflows and AI agents via HTTP or MCP.
README
advancedmd-connector
advancedmd-connector is the one process in the organization that talks to AdvancedMD. Every consumer of AdvancedMD data — backend workflows (appointment-validator, srt-auths, note-audit, patient-intake), the admin-console credential check, and AI agents (Adam and any Claude Code, Cursor, or Desktop agent) — sends it a tool call over HTTP or MCP and gets back a JSON result. It holds the only AdvancedMD credentials, the only login session, and the only rate clock.
Today fifteen processes each hold AdvancedMD credentials, log in independently, and rate-limit independently against AdvancedMD's per-office-key caps (which bill $0.01 per excess call and refuse logins faster than about once a minute). The connector fixes that by owning the session and the clock centrally: one process, one rate clock, one tool surface, unchanged tool names and result shapes for every existing consumer. See SPEC.md for the full contract and docs/CONNECTOR_DECISIONS.md for why each choice was made.
Architecture
backend workflows ------ JSON tool call ------> +-----------------------------+
(validator, srt-auths, | advancedmd-connector |
note-audit, intake, | |
admin-console, chatbot) | HTTP API MCP surface |
| \ / |
agents ----------------- MCP tool call -------> | receivers (one per |
(Adam via remote MCP; | open request) |
Cursor, Claude Code, | | |
Desktop via stdio shim | entry queue |
or remote MCP) | | |
| worker loop (1 at a |
| | time) |
| handler |
| | |
| request queue |
| | |
| sender loop (clock, |
| | session) |
+----------|------------------+
| XML over HTTPS
v
AdvancedMD
One process. One port (default 8820). Everything above the dashed box is a consumer; nothing outside the box holds AMD credentials or sends XML.
Run locally in five commands
cp .env.example .env # fill AMD_USERNAME, AMD_PASSWORD, AMD_OFFICE_KEY
pip install -e ".[dev]"
export $(cat .env | grep -v '^#' | xargs) CONNECTOR_TOKENS_PATH=/tmp/tokens.json
connector tokens add myapp --priority interactive --tools '*' # prints a token once
uvicorn --factory connector.app:build_app --host 0.0.0.0 --port 8820
GET http://localhost:8820/health should answer {"status": "starting"}
or "ok" once the first login attempt completes. docker compose up --build runs the same thing containerized, reading the same .env.
Attach an agent
Tool names, argument schemas, and redacted result shapes are identical across all three attachment methods (SPEC 12.1), so an agent config can move from one to another without changing prompts.
Remote MCP (hosted agents, e.g. Adam) — point at the connector's streamable-HTTP surface directly:
{"mcpServers": {"amd-patients": {"type": "http",
"url": "http://advancedmd-connector:8820/mcp/patients",
"headers": {"Authorization": "Bearer <agent token>"}}}}
Ten routes are served: /mcp/patients, /mcp/visits, /mcp/providers,
/mcp/codes, /mcp/billing, /mcp/payments, /mcp/masterfiles,
/mcp/system, /mcp/ehr, and /mcp/all (the union).
Local stdio shim (agents on a workstation) — install the published
advancedmd-mcp package and point it at the connector over the network;
it holds no credentials and no tool logic:
{"mcpServers": {"amd-patients": {"command": "uvx",
"args": ["advancedmd-mcp", "--domain", "patients"],
"env": {"ADVANCEDMD_CONNECTOR_URL": "http://100.94.62.115:8820",
"ADVANCEDMD_CONNECTOR_TOKEN": "<agent token>"}}}}
Claude Code plugin — plugin/ declares all nine stdio servers with
${ADVANCEDMD_CONNECTOR_URL} and ${ADVANCEDMD_CONNECTOR_TOKEN}
environment references:
claude plugin add <path or repo>/plugin
The same plugin/.mcp.json is valid for Cursor and Claude Desktop by
copy.
Use it from a workflow
Backend Python services use the SDK in
orlando-derm-backend/lib/advancedmd_connector/, which keeps every
existing method name and typed result:
from lib.advancedmd_connector import AmdConnector
connector = AmdConnector.from_env() # ADVANCEDMD_CONNECTOR_URL, ADVANCEDMD_CONNECTOR_TOKEN
bundle = await connector.get_patient_bundle(patient_id)
result = await connector.tool("getdemographic", patient_id=patient_id) # generic call
The SDK holds no AMD credentials, no XML, and no AMD URL — it is HTTP only. See SPEC 13 for the full method table and exception mapping.
Issue a token
Tokens are issued and revoked with the bundled connector CLI against
the token table file (CONNECTOR_TOKENS_PATH):
connector tokens add appointment-validator --priority batch --tools '*'
connector tokens add my-agent --priority interactive --tools getdemographic,lookuppatient
connector tokens list
connector tokens revoke my-agent
A plaintext token is printed once at issuance and never stored or recoverable. See docs/OPERATIONS.md for the full flag reference and docs/TOKENS.md for the token model.
Where to look when something is slow
GET /health(no token, internal network only) — session state, entry-queue depth and oldest wait, request-queue depth, and the rate clock's used/limit per tier, all in one call.GET /metrics(no token) — Prometheus text: tool call counts and wait histograms by caller/tool/outcome, AMD request counts and post-time histograms by tier, clock used/limit/sleep-time per tier, relogin and login-refusal counters, queue depths. See SPEC 18 for the full metric list and the alert conditions in SPEC 18.2.- A slow AMD reply must never delay
/health— the sender loop and/healthrun on the same event loop but blocking I/O is forbidden (SPEC 4.4), so a hung AMD call shows up as clock/queue pressure on/health, not as an unresponsive connector.
Batch schedule
The connector itself runs no batch jobs; it serializes whatever its
batch-priority callers send. The consumers currently scheduled against
it (SPEC 22 migration table) are appointment-validator (one nightly
run), srt-auths (scan and event runs), and note-audit (one daily run).
Batch-priority requests age into promotion after BATCH_AGING_MS
(default 60 s) so a long batch backlog cannot starve interactive calls
indefinitely (SPEC 5.3); deploys should still avoid these windows since
a restart drops the in-memory session (SPEC 16.3).
Further reading
- SPEC.md — the full build contract.
- docs/CONNECTOR_DECISIONS.md — why each choice was made.
- docs/API.md — the HTTP API, mirrored from SPEC 11.
- docs/OPERATIONS.md — tokens CLI, deploy, rollback, alerts, and the fixture procedure.
- docs/TOOL_TO_XML_MAP.md — per-tool AMD request map and verification ledger.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。