diff --git a/README.md b/README.md index 1b1635f..5bb6dba 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,8 @@ qmt_bridge/ │ ├── test_subscription.py ← 订阅/退订/tick mock 测试 │ ├── test_ws_push.py ← WS 推送链路 mock 测试 │ ├── test_ws_real.py ← 真实 QMT WS 推送验证 -│ └── test_sub_no_ws.py ← 无 WS 连接时订阅行为测试 +│ ├── test_sub_no_ws.py ← 无 WS 连接时订阅行为测试 +│ └── test_mcp.py ← MCP 端点 mock 测试(纯标准库,无需 pandas) ├── reference/ ← 参考材料(xtquant_big_convert 等,只读) └── deploy_elevated.bat ← 部署脚本(自动提权) ``` @@ -77,7 +78,7 @@ bridge_subscription.py ──import──► bridge_util.py, bridge_ws_server.py | bridge_util.py | 日志、工具、共享状态(CTX/QMT_API/交易缓存) | | qmt_strategy_entry.py | QMT 策略入口(热重载: 重跑时清模块缓存+释放端口) | -## 当前接口(12 个,详见 docs/api_spec/openapi.yaml) +## 当前接口(12 个 HTTP + WS + MCP,详见 docs/api_spec/openapi.yaml) - GET `/health` — 健康检查 - GET `/data/kline` — K线(先下载后查询,fields 可筛选,默认完整 OHLCV) @@ -92,7 +93,7 @@ bridge_subscription.py ──import──► bridge_util.py, bridge_ws_server.py - GET `/trade/orders` — 委托(code/status/strategy_name 过滤) - GET `/trade/trades` — 成交 - WS `/ws` — 单通道推送(接收 `{"type":"whole","data":{code:tick_dict}}` 增量) -- POST `/mcp` — **MCP 端点**(JSON-RPC 2.0): `initialize` / `ping` / `tools/list` / `tools/call`,9 个工具与 HTTP 接口 1:1(`qmt_kline`/`qmt_quote`/`qmt_tick`/`qmt_instrument`/`qmt_trading_dates`/`qmt_positions`/`qmt_asset`/`qmt_orders`/`qmt_trades`),详见 `docs/迭代记录/MCP服务.md` +- POST `/mcp` — **MCP 端点**(JSON-RPC 2.0,9 个工具与 HTTP 接口 1:1),详见下文「MCP 服务」章节 **待实现**: `/trade/order`(下单)、`/trade/cancel`(撤单)、`/trade/order/status`、WS 账号交易通知(trade_result 等)、MCP `qmt_order`/`qmt_cancel`/SSE 流式。 @@ -115,6 +116,54 @@ bridge_subscription.py ──import──► bridge_util.py, bridge_ws_server.py - 辅助: `python tools/push_apifox.py`(生成 json + 打印步骤) - 开放 API 自动推送未打通(沙箱代理伪造 201 / PowerShell 422) +## MCP 服务(AI 助手接入) + +桥在 8610 端口提供 **MCP(Model Context Protocol)端点**,AI 助手(Claude Desktop / Cursor / 支持 MCP 的客户端)可通过 `tools/call` 直接调用桥的行情/交易能力,无需自己解析 HTTP。 + +### 端点与接入 + +``` +URL: http://127.0.0.1:8610/mcp (Streamable HTTP,非流式) +鉴权: X-Token header 或 ?token=(与桥 TOKEN 一致;未设 TOKEN 时无需) +方法: initialize → notifications/initialized → ping → tools/list → tools/call +``` + +Claude Desktop 配置示例(`claude_desktop_config.json`): +```json +{ + "mcpServers": { + "qmt_bridge": { + "type": "http", + "url": "http://127.0.0.1:8610/mcp", + "headers": { "X-Token": "<桥 TOKEN,如有>" } + } + } +} +``` + +### 工具清单(9 个,与 HTTP 接口 1:1) + +| 工具 | 对应 HTTP | 说明 | +|------|-----------|------| +| `qmt_kline` | GET /data/kline | K线(先下载后查询,fields 可筛选) | +| `qmt_quote` | GET /data/quote | 实时快照(单票 full tick,含五档) | +| `qmt_tick` | GET /data/tick | 批量 tick 快照(codes 逗号分隔) | +| `qmt_instrument` | GET /data/instrument | 合约详情(涨跌停价/名称) | +| `qmt_trading_dates` | GET /data/calendar/trading_dates | 交易日历 | +| `qmt_positions` | GET /trade/positions | 全部持仓(语义化字段 + summary) | +| `qmt_asset` | GET /trade/asset | 资金资产 | +| `qmt_orders` | GET /trade/orders | 委托(code/status/strategy_name 过滤) | +| `qmt_trades` | GET /trade/trades | 成交 | + +### 实现要点 + +- **为什么桥内嵌**: QMT 内置 Python 3.6.8 纯标准库,官方 mcp SDK 要求 Python ≥ 3.10;桥手写 JSON-RPC 2.0(仅 json/socket/threading),零依赖 +- **线程约束一致**: 全部工具复用 `bridge_data_adapter` → 与 HTTP 接口同模式(行情 worker 直调,交易读缓存),不违反 QMT 线程约束 +- **错误语义**: JSON-RPC 错误走 HTTP 200(parse -32700 / invalid request -32600 / method not found -32601 / invalid params -32602 / internal -32603);非法 body 走 400 +- **CORS**: 响应带 `Access-Control-Allow-Origin: *`,`OPTIONS /mcp` 预检 204 +- **不做订阅/长连接**: MCP 仅查询(请求-响应);实时数据走 HTTP 订阅 + WS `/ws` 推送 +- 详细设计见 `docs/迭代记录/MCP服务.md` + ## 本地测试 ```bash