Skip to content

fix: rewrite bare /mcp to /mcp/ in MCPPathRewriteMiddleware so stream…#4282

Open
omorros wants to merge 1 commit intoIBM:mainfrom
omorros:fix/mcp-path-rewrite-streaming-4275
Open

fix: rewrite bare /mcp to /mcp/ in MCPPathRewriteMiddleware so stream…#4282
omorros wants to merge 1 commit intoIBM:mainfrom
omorros:fix/mcp-path-rewrite-streaming-4275

Conversation

@omorros
Copy link
Copy Markdown
Contributor

@omorros omorros commented Apr 17, 2026

🔗 Related Issue

Closes #4275


📝 Summary

MCPPathRewriteMiddleware only rewrote /servers/<id>/mcp to /mcp/, leaving bare /mcp untouched. Because the Starlette mount is at
/mcp (compiled as /mcp/{path:path}), /mcp without the trailing slash did not match and FastAPI's router emitted a 307 redirect to
/mcp/. For chunked Streamable HTTP POSTs the client cannot replay the body across a redirect, so the handshake failed with httpx.ReadError
during initialize.

This PR normalises bare /mcp to /mcp/ inside the middleware so the mount matches directly without a redirect. It also mirrors every
rewrite into scope["raw_path"] alongside scope["path"] (both the new bare-/mcp branch and the existing /servers/<id>/mcp branch),
keeping downstream URL reconstruction consistent with the rewritten path.

Security posture is unchanged: arbitrary prefixes ending in /mcp (e.g. /foo/mcp) still pass through unrewritten, and empty server IDs
(/servers//mcp) still return 404.


🏷️ Type of Change

  • Bug fix
  • Feature / Enhancement
  • Documentation
  • Refactor
  • Chore (deps, CI, tooling)
  • Other (describe below)

🧪 Verification

Check Command Status
Lint suite make lint ✅ ruff/isort/black clean on changed lines (pre-existing drift untouched)
Unit tests make test ✅ 1864+ related tests pass (main, middleware, auth, streamable HTTP transport)
Coverage ≥ 80% make coverage ⏳ to be verified in CI

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes
  • Documentation updated (if applicable)
  • No secrets or credentials committed

📓 Notes (optional)

Four new unit tests in TestMCPPathRewriteMiddleware cover:

  • test_rewrite_bare_mcp_to_trailing_slash/mcp/mcp/
  • test_rewrite_bare_mcp_with_root_path/gateway/mcp/gateway/mcp/ (reverse-proxy prefix)
  • test_rewrite_updates_raw_path/servers/<id>/mcp rewrite keeps raw_path aligned
  • test_bare_mcp_updates_raw_path — bare-/mcp rewrite syncs raw_path

…ing POSTs bypass Starlette's 307 redirect (IBM#4275)

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: MCPPathRewriteMiddleware breaks streaming POST when rewriting /mcp to /mcp/

1 participant