From f140ed9218aaac069a0be8b48c125f9a1d59948d Mon Sep 17 00:00:00 2001 From: "mula.liu" Date: Thu, 2 Apr 2026 21:33:05 +0800 Subject: [PATCH] fix mcp --- backend/main.py | 2 ++ docs/MCP_HTTP_INTEGRATION.md | 22 ++++++++++++---------- docs/UPGRADE_v0.9.6.md | 12 ++++++------ frontend/nginx.conf | 19 ++++++++++++++++++- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/backend/main.py b/backend/main.py index b93443c..703690d 100644 --- a/backend/main.py +++ b/backend/main.py @@ -48,6 +48,8 @@ app.add_middleware( allow_credentials=True, allow_methods=["*"], allow_headers=["*"], + # Browser-based MCP clients may need to read the negotiated session header. + expose_headers=["mcp-session-id", "Mcp-Session-Id"], ) # 注册 API 路由 diff --git a/docs/MCP_HTTP_INTEGRATION.md b/docs/MCP_HTTP_INTEGRATION.md index f83e516..f468ae5 100644 --- a/docs/MCP_HTTP_INTEGRATION.md +++ b/docs/MCP_HTTP_INTEGRATION.md @@ -9,7 +9,7 @@ NexDocs 现在不再使用项目根目录下的独立 `mcp_server/`。 - 业务 REST API 继续走 `/api/v1/...` - MCP 入口挂载在同一个 backend 服务上 - 传输协议为 `streamableHttp` -- MCP 地址为 `/mcp/` +- MCP 地址为 `/mcp`(`/mcp/` 也兼容) - 认证方式为 `X-Bot-Id` + `X-Bot-Secret` 这意味着: @@ -24,20 +24,21 @@ NexDocs 现在不再使用项目根目录下的独立 `mcp_server/`。 MCP 对外地址: ```text -http://:/mcp/ +http://:/mcp ``` 例如: ```text -http://backend.internal:8000/mcp/ +http://backend.internal:8000/mcp ``` 说明: -- 请直接使用带尾部 `/` 的地址 -- 请求 `/mcp` 会被后端重定向到 `/mcp/` -- 未携带 bot 凭证时,访问 `/mcp/` 会返回 `401` +- 推荐优先使用 `/mcp` +- `/mcp/` 也兼容 +- 如果前面还有 Nginx/网关,请不要对 `/mcp` 做 `301`/`302` 重定向 +- 未携带 bot 凭证时,访问 `/mcp` 或 `/mcp/` 都会返回 `401` ## 3. 认证模型 @@ -206,7 +207,7 @@ delete_file "mcpServers": { "biz_mcp": { "type": "streamableHttp", - "url": "http://backend.internal:8000/mcp/", + "url": "http://backend.internal:8000/mcp", "headers": { "X-Bot-Id": "nexbot_xxxxxxxxxxxxxxxx", "X-Bot-Secret": "nxbotsec_xxxxxxxxxxxxxxxxxxxxxxxx" @@ -220,9 +221,10 @@ delete_file 注意: -- `url` 建议使用 `/mcp/` +- `url` 建议使用 `/mcp` - `headers` 中不需要再放业务用户名密码 - `X-Bot-Secret` 只应发给受信任的调用端 +- 如果客户端运行在浏览器环境,记得把对应站点加入后端 `CORS_ORIGINS` ## 7. 后端部署要求 @@ -269,13 +271,13 @@ env -u HTTP_PROXY -u HTTPS_PROXY ./venv312/bin/pip install -r requirements.txt - Python 3.12 环境可正常启动 backend - `/health` 返回 `200` -- `/mcp/` 已挂载成功 +- `/mcp` 与 `/mcp/` 均可访问 - 未传 `X-Bot-Id` / `X-Bot-Secret` 时返回 `401` 调试使用地址: ```text -http://127.0.0.1:8012/mcp/ +http://127.0.0.1:8012/mcp ``` 生产或测试环境请替换为你的 backend 实际域名或 IP。 diff --git a/docs/UPGRADE_v0.9.6.md b/docs/UPGRADE_v0.9.6.md index 503ba78..1fee7be 100644 --- a/docs/UPGRADE_v0.9.6.md +++ b/docs/UPGRADE_v0.9.6.md @@ -27,7 +27,7 @@ 当前 MCP 入口: ```text -/mcp/ +/mcp ``` 当前支持的工具: @@ -59,12 +59,12 @@ ### 3. Nginx 统一入口支持 MCP -前端 Nginx 已新增 `/mcp/` 反向代理配置。 +前端 Nginx 已新增 `/mcp` 与 `/mcp/` 兼容的反向代理配置。 现在在只暴露一个公网入口端口的部署模式下,可以通过统一入口访问: ```text -http(s):///mcp/ +http(s):///mcp ``` 不再要求调用端直连 backend 容器端口。 @@ -122,7 +122,7 @@ backend Docker 镜像构建已做以下处理: - 基础镜像切换为 `python:3.12-slim` - 增加 pip 构建工具升级 - pip 安装支持国内源失败后回退官方源 -- Nginx 已补充 `/mcp/` 代理配置 +- Nginx 已补充 `/mcp` 与 `/mcp/` 兼容代理配置 ### 3. 数据持久化目录调整 @@ -159,7 +159,7 @@ storage/ 如果当前部署是通过前端 Nginx 暴露统一入口,推荐改为: ```text -http(s):///mcp/ +http(s):///mcp ``` 调用头保持不变: @@ -179,6 +179,6 @@ http(s):///mcp/ 建议升级到 `v0.9.6` 后按以下顺序验证: 1. 验证 backend `/health` 是否正常 -2. 验证统一入口 `/api/` 与 `/mcp/` 是否可访问 +2. 验证统一入口 `/api/`、`/mcp` 与 `/mcp/` 是否可访问 3. 验证 MCP client 是否能正常完成 `initialize` 4. 验证个人中心的 MCP 凭证展示与轮换功能 diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 4a741bb..04d5e7a 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -42,8 +42,25 @@ server { } # MCP Streamable HTTP 反向代理 + # 不对 /mcp 做 301/302 重定向,避免部分 MCP client 在跳转后丢失 POST body 或请求方法 location = /mcp { - return 301 /mcp/; + proxy_pass http://backend:8000/mcp/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Connection ""; + + proxy_buffering off; + proxy_request_buffering off; + + proxy_connect_timeout 60s; + proxy_send_timeout 3600s; + proxy_read_timeout 3600s; + + add_header Cache-Control "no-cache, no-store, must-revalidate"; } location /mcp/ {