Repository navigation
fix(mcp): advertise a relative SSE endpoint so clients work behind the /server proxy - #1855
Conversation
The SSE endpoint event advertised the absolute path /mcp/messages, which drops the /server prefix when clients connect through the bundled nginx proxy on port 20211. Clients then POST to /mcp/messages, nginx serves it as a static file and returns 404, so MCP clients can't connect via the proxy. A relative path resolves against whichever SSE URL the client used, so it works both directly and behind the prefix.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Change: Bug fix · Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to
|
📌 Description
The MCP SSE stream advertises its message endpoint as the absolute path
/mcp/messages?session_id=.... MCP clients resolve that against the origin, so a client connected through the bundled nginx proxy (http://<host>:20211/server/mcp/sse) posts to/mcp/messagesinstead of/server/mcp/messages. nginx has no route for that path, falls through to static file serving (open() "/app/front/mcp/messages" failed), returns 404, and the client never finishes connecting.This change advertises a relative path (
messages?session_id=...) instead. Clients resolve it against whichever SSE URL they used::20212/mcp/sse(direct)/mcp/messages✅/mcp/messages✅:20211/server/mcp/sse(proxy)/mcp/messages❌ 404/server/mcp/messages✅No routes, nginx config or settings change.
🔍 Related Issues
Fixes #1854
📋 Type of Change
📷 Screenshots or Logs (if applicable)
New test before the fix:
After the fix:
🧪 Testing Steps
test/api_endpoints/test_mcp_sse_endpoint.py. It opens/mcp/sse, reads theendpointevent and resolves it withurljoin(as the Python MCP SDK does) against both a direct and a/server-prefixed SSE URL. Wrote it first and confirmed the proxy case failed, then applied the fix.pytest -m 'not (docker or compose or feature_complete)'): 1738 passed, 30 skipped, 0 failed.test/docker_testswas excluded locally because building the image through the Docker socket fails on Docker Desktop for macOS (build context not visible to the host daemon); unrelated to this change.flake8with the CI settings passes on the changed files./server/mcp/messages?session_id=...through port 20211 returns 202, the unprefixed path returns 404.✅ Checklist
🙋 Additional Notes
urljoin(url, sse.data)and the TypeScript SDK usesnew URL(data, this._url), both of which resolve relative paths. Both SDKs' same-origin checks still pass, since a relative path can't change the origin.origin + data(not per spec) would be affected; such a client already can't work behind the proxy./mcp/messagesroute, which is unchanged, and don't describe the event payload.Summary by CodeRabbit
Bug Fixes
Tests