使用说明
诊所MCP服务器
用于SQLite支持的诊所调度域(用户、支付方式、医生、插槽、预约)的演示MCP服务器。
支持 三次运输:
- 标准 (本地MCP客户/代理商)
- 可流式传输http
- SSE
支持 JWT授权 用于HTTP传输(可配置)。
项目结构
data/ # database file. git ignored
src/clinic_mcp_server/
__init__.py / __main__.py # entry point
cli.py # Typer CLI (run / reset-db)
clinic/
clinic_service.py # domain service
domain/ # data types, repo Protocol, enums
sqlite/ # SQLite repo + seed data
mcp/
clinic_server.py # FastMCP tool definitions
auth/ # JWT + ASGI middleware
runtime/ # settings, runner, health endpoint
tests/
...
发展
先决条件
- python 3.12+
uv安装
检查:
python --version
uv --version
安装(dev)
从repo根目录:
uv venv
uv sync
推荐的开发依赖关系:
pytestpytest-asynciopytest-covtyperuvicornruffpyright
运行测试
uv run pytest -q
覆盖范围:
uv run pytest -q --cov=clinic_mcp_server --cov-report=term-missing
棉绒/类型检查
拉夫
uv run ruff check .
自动修复:
uv run ruff check --fix .
Pyright
安装:
uv add --dev pyright
运行:
uv run pyright
通过Python包使用
入口点支持两者 新的Typer子命令样式 和 遗留标志 (为了向后兼容性)。
1) 流式HTTP(推荐)
uv run python -m clinic_mcp_server run \
--transport streamable-http \
--host 0.0.0.0 \
--port 8080
2) SSE运输
uv run python -m clinic_mcp_server run \
--transport sse \
--host 0.0.0.0 \
--port 8080
3) STDIO传输
uv run python -m clinic_mcp_server run --transport stdio
数据库位置
默认情况下,SQLite文件是在以下位置创建的:
data/clinic.db
以(权力)否决
export CLINIC_DB_PATH="/tmp/clinic.db"
JWT授权
默认情况下,JWT为 必需的 用于HTTP传输。
启动时,服务器打印 演示令牌. 这样使用它:
Authorization: Bearer <token>
使用env变量配置JWT:
export JWT_SECRET="dev-secret-change-me"
export JWT_REQUIRED="true" # default true for HTTP, false for stdio
export JWT_ALLOWLIST_PATHS="/health" # endpoints that bypass auth
export JWT_AUDIENCE="clinic" # optional
export JWT_ISSUER="clinic-mcp" # optional
禁用JWT(除测试/本地外不建议使用):
export JWT_REQUIRED="false"
码头工人
塑造形象
从repo根目录(您的Dockerfile所在的位置):
podman build -t clinic-mcp-server:dev .
运行(可流式传输http)
podman run --rm -p 8080:8080 \
-e JWT_SECRET="dev-secret-change-me" \
-e JWT_REQUIRED="true" \
-e CLINIC_DB_PATH="/data/clinic.db" \
-v "$(pwd)/data:/data" \
clinic-mcp-server:dev \
uv run python -m clinic_mcp_server run --transport streamable-http --host 0.0.0.0 --port 8080
持久数据库卷
上述支架 ./data 从主机进入容器 /data,所以DB仍然存在。
运行(SSE)
podman run --rm -p 8080:8080 \
-e JWT_REQUIRED="false" \
-e CLINIC_DB_PATH="/data/clinic.db" \
-v "$(pwd)/data:/data" \
clinic-mcp-server:dev \
uv run python -m clinic_mcp_server run --transport sse --host 0.0.0.0 --port 8080
运行(stdio)
通常stdio在本地使用(在Docker中不常见)
注意事项/故障排除
“没有这样的选择:--运输”
这意味着您在没有命令的情况下调用了Typer。使用以下选项之一:
python -m clinic_mcp_server run --transport streamable-http ...
SQLite并发
这是一个演示。如果您希望并发写入:
- 启用WAL模式
- 按请求使用连接
- 或迁移到Postgres
许可证
演示/内部使用。
卷发秘籍(健康+JWT+MCP)
重要提示: MCP端点为 不 常规REST端点。
对于 可流式传输的HTTP,您必须使用 JSON-RPC帖子.
对于 上海证券交易所,您必须首先打开SSE流,然后将JSON-RPC POST到返回的/messages/?session_id=...终点。
示例中使用的环境变量
export TOKEN="YOUR_JWT_TOKEN_HERE"
1) 流式HTTP(启用JWT)
假设:
- 基本URL:
http://127.0.0.1:8080 - MCP端点:
/mcp
健康(如果没有JWT /health 已分配)
curl -i http://127.0.0.1:8080/health
健康(与智威汤逊合作)
curl -i -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8080/health
MCP端点应在没有JWT的情况下拒绝
curl -i http://127.0.0.1:8080/mcp
# expected: 401 Unauthorized
使用JWT列出工具(JSON-RPC)
curl -sS \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-X POST http://127.0.0.1:8080/mcp \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
2) SSE(启用JWT)
假设:
- 基本URL:
http://127.0.0.1:8081 - SSE端点:
/sse
健康(如果没有JWT /health 已分配)
curl -i http://127.0.0.1:8081/health
健康(与智威汤逊合作)
curl -i -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8081/health
SSE端点应在没有JWT的情况下拒绝
curl -i -H "Accept: text/event-stream" http://127.0.0.1:8081/sse
# expected: 401 Unauthorized
连接SSE流(使用JWT)
curl -N \
-H "Accept: text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8081/sse
预期输出包括以下内容:
event: endpoint
data: /messages/?session_id=ac5e39fe0f2c4a7abb2906454d2f499c
通过SSE调用工具(POST JSON-RPC到/消息)
更换 session_id 使用您从SSE流中获得的一个:
curl -sS \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-X POST "http://127.0.0.1:8081/messages/?session_id=YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
(3)舞台
Stdio设计用于 SDK客户端,而不是卷曲。
使用Python MCP客户端:
uv run python scripts/simple_client.py
通过curl流式传输HTTP(启用JWT)
流式HTTP是 基于会话 在FastMCP中。
这意味着:
- 你必须打电话
initialize第一。- 服务器返回会话id。
- 您必须使用以下命令在每个下一个请求中包含该会话id:
mcp-session-id: ...此外,FastMCP需要此标头:
Accept: application/json, text/event-stream
步骤0——设置JWT令牌
export TOKEN="YOUR_JWT_TOKEN_HERE"
步骤1——初始化会话(打印 mcp-session-id 在响应标头中)
curl -i \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-X POST http://127.0.0.1:8080/mcp \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"initialize",
"params":{
"protocolVersion":"2025-03-26",
"capabilities":{},
"clientInfo":{"name":"curl","version":"0"}
}
}'
Look for a response header like:
```text
mcp-session-id: XXXXXXXXXX
复制值或定义为导出。
export SESSION_ID=XXXXXXXXXX
步骤2——列出工具(基于会话的请求)
curl -sS \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: $SESSION_ID" \
-X POST http://127.0.0.1:8080/mcp \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
预期产量:
{"jsonrpc":"2.0","id":2,"result":{"tools":[...]}}
SSE通过curl(完整工作示例)
SSE是一个双通道流:
- 您打开了一个长期的SSE连接(
/sse)--这就是响应到达的地方。- 您将JSON-RPC消息发布到
/messages/?session_id=....这
/messagesPOST通常会返回Accepted.
这 实际回应 以如下方式到达SSE流event: message.
步骤0——设置JWT令牌
export TOKEN="YOUR_JWT_TOKEN_HERE"
步骤1——打开SSE流(终端1)
curl -N \
-H "Accept: text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8081/sse
预期产出包括:
event: endpoint
data: /messages/?session_id=XXXXXXXX
复制值或定义为导出。
export SESSION_ID=XXXXXXXX
步骤2——初始化会话(终端2)
curl -sS \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-X POST "http://127.0.0.1:8081/messages/?session_id=$SESSION_ID" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"initialize",
"params":{
"protocolVersion":"2025-03-26",
"capabilities":{},
"clientInfo":{"name":"curl","version":"0"}
}
}'
响应将显示在 端子1 如:
event: message
data: {"jsonrpc":"2.0","id":1,"result":{...}}
步骤3——列出工具(终端2)
curl -sS \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-X POST "http://127.0.0.1:8081/messages/?session_id=$SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
工具列表响应将出现在 端子1:
event: message
data: {"jsonrpc":"2.0","id":2,"result":{"tools":[...]}}
