例行检查
你的版本
问题描述
我们在 FastGPT 私有化环境中接入 Streamable HTTP MCP endpoint 时,发现 runTool 可以正常执行工具并返回 200,但 getTools 解析/刷新工具列表时失败。
后端日志显示:getTools 阶段先尝试 StreamableHTTP,失败后 fallback 到 SSE;由于该 MCP endpoint 不支持 SSE GET,最终报 405。
[POST] /api/core/app/mcpTools/getTools
StreamableHTTP connect failed, falling back to SSE
SSE error: Non-200 status code (405)
[POST] /api/core/app/mcpTools/getTools - 500
但同一个 MCP endpoint 执行工具时可以成功:
[POST] /api/core/app/mcpTools/runTool
MCP client calling tool
[POST] /api/core/app/mcpTools/runTool - 200
我们单独测试 MCP endpoint,结果是:
POST initialize:成功
POST tools/list:成功
GET:405
SSE GET:405
因此该 MCP 服务本身可用,问题集中在 FastGPT 的 getTools 链路:getTools 失败后 fallback 到 SSE,而该 endpoint 不是 SSE endpoint。
最小复现 MCP 服务
from fastapi import FastAPI, Request, Response
from fastapi.responses import JSONResponse
import uvicorn, json
app = FastAPI()
TOKEN = "demo-token"
def ok_auth(req: Request):
return req.headers.get("authorization") == f"Bearer {TOKEN}"
def err(i, code, msg, status=200):
return JSONResponse(status_code=status, content={"jsonrpc":"2.0","id":i,"error":{"code":code,"message":msg}})
@app.get("/services/mcp")
async def get_mcp(req: Request):
return JSONResponse(status_code=405, content={"message":"Method not allowed"})
@app.get("/services/mcp/sse")
async def get_sse(req: Request):
return JSONResponse(status_code=405, content={"message":"Method not allowed"})
@app.post("/services/mcp")
async def post_mcp(req: Request):
body = await req.json()
i = body.get("id")
m = body.get("method")
if not ok_auth(req):
return err(i, -32600, "Authentication failed: No bearer token provided", 401)
if m == "initialize":
return {"jsonrpc":"2.0","id":i,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"serverInfo":{"name":"mock-mcp","version":"1.0.0"}}}
if m == "notifications/initialized":
return Response(status_code=200)
if m == "tools/list":
return {"jsonrpc":"2.0","id":i,"result":{"tools":[{"name":"demo_get_info","description":"demo tool","inputSchema":{"type":"object","properties":{}}}]}}
if m == "tools/call":
result = {"status":"ok","message":"tool call success"}
return {"jsonrpc":"2.0","id":i,"result":{"content":[{"type":"text","text":json.dumps(result)}],"structuredContent":result}}
return err(i, -32601, f"Method {m} not found")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=18089)
启动:
pip install fastapi uvicorn
python mock_mcp_server.py
FastGPT 中配置:
MCP 地址:http://<server-ip>:18089/services/mcp
鉴权 Header:Authorization: Bearer demo-token
复现步骤
- 在 FastGPT 中添加上述 MCP 地址。
- 配置 Header:
Authorization: Bearer demo-token。
- 点击解析/刷新工具列表。
- 观察 FastGPT 后端日志。
- 如果
getTools 失败后 fallback 到 SSE,会出现 SSE error: Non-200 status code (405)。
- 执行已存在工具时,
runTool 可以正常返回 200。
预期结果
对于 Streamable HTTP MCP endpoint:
getTools 使用 Streamable HTTP / POST JSON-RPC 获取工具列表;
runTool 使用 Streamable HTTP / POST JSON-RPC 执行工具;
getTools 和 runTool 调用逻辑保持一致;
- 如果 StreamableHTTP 失败,建议不要默认 fallback 到 SSE,或提供关闭 SSE fallback 的配置。
实际结果
runTool 可以成功,但 getTools 阶段失败后 fallback 到 SSE,最终触发 405。
例行检查
你的版本
问题描述
我们在 FastGPT 私有化环境中接入 Streamable HTTP MCP endpoint 时,发现
runTool可以正常执行工具并返回 200,但getTools解析/刷新工具列表时失败。后端日志显示:
getTools阶段先尝试 StreamableHTTP,失败后 fallback 到 SSE;由于该 MCP endpoint 不支持 SSE GET,最终报 405。但同一个 MCP endpoint 执行工具时可以成功:
我们单独测试 MCP endpoint,结果是:
因此该 MCP 服务本身可用,问题集中在 FastGPT 的
getTools链路:getTools失败后 fallback 到 SSE,而该 endpoint 不是 SSE endpoint。最小复现 MCP 服务
启动:
FastGPT 中配置:
复现步骤
Authorization: Bearer demo-token。getTools失败后 fallback 到 SSE,会出现SSE error: Non-200 status code (405)。runTool可以正常返回 200。预期结果
对于 Streamable HTTP MCP endpoint:
getTools使用 Streamable HTTP / POST JSON-RPC 获取工具列表;runTool使用 Streamable HTTP / POST JSON-RPC 执行工具;getTools和runTool调用逻辑保持一致;实际结果
runTool可以成功,但getTools阶段失败后 fallback 到 SSE,最终触发 405。