-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix 307 Temporary Redirect when use streamable_http #781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix 307 Temporary Redirect when use streamable_http #781
Conversation
when we set the default /mcp, the log will be, in some env will
in some env will be hanging, because 307 Temporary Redirect to /byoa/mcp/mcp/, this is unreachable
when we set the streamable_http to '/mcp/', it will be good, as the log:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for identifying and reporting this redirect issue! However, I don't think changing the default
streamable_http_path is the right approach here.
The core issue: This change creates inconsistency across the codebase rather than solving the root problem.
- All client code constructs URLs with /mcp (no trailing slash) - see examples/clients/simple-auth-client/main.py:344
- All example servers mount at /mcp (no trailing slash) - see both simple-streamablehttp examples
- All tests use /mcp (no trailing slash) consistently - see tests/shared/test_streamable_http.py:238
- Only FastMCP would have a different default with this change
Problems with this approach:
- Breaking consistency: Makes FastMCP behave differently from all examples and existing usage patterns
- Incomplete fix: The examples and tests still use /mcp without trailing slash, so the inconsistency remains
- Wrong direction: The entire ecosystem already standardized on /mcp - we shouldn't change that
Alterative:
- Keep the default as /mcp and fix the ASGI mounting logic to handle redirects properly
- Add logic to FastMCP to handle both /mcp and /mcp/ transparently at the mount level
- Document the trailing slash behavior so users can choose the approach that works for their environment
The redirect issue you've identified is real and needs fixing, but changing the default path creates more problems than
it solves. Let's find a solution that maintains consistency while addressing the underlying ASGI routing behavior.
The default mount path of Streamable HTTP is /mcp, but in some environments, a 307 Temporary Redirect to /mcp/mcp/ will appear, causing the request to hang or fail. When the streamable_http path is set to /mcp/, everything works fine.
Code Analysis
Mount Path
In the server.py and simple-streamablehttp-stateless examples, the ASGI routes are Mount("/mcp", app=handle_streamable_http), that is, there is no trailing slash.
In the Settings class of server.py, the default value of streamable_http_path is "/mcp" (also without a slash).
Redirection Issue
Mount("/mcp", ...) route of Starlette/FastAPI, if /mcp is requested, will automatically 307 redirect to /mcp/ (with a slash).
But if the client requests /mcp/ and the server only mounts /mcp, a redirect chain of /mcp/mcp/ will appear in some environments, resulting in "unreachable".
This is related to the "strict slash matching" of ASGI routing.
Solution
Recommended practice: Always use /mcp/ as the mounting path (with a slash) and let the client request /mcp/, so there will be no redirection problem.
Or, when mounting /mcp, make sure the client only requests /mcp without a slash.
Motivation and Context
How Has This Been Tested?
Breaking Changes
Types of changes
Checklist
Additional context