python-sdk icon indicating copy to clipboard operation
python-sdk copied to clipboard

Add root_path support to properly route subpaths for SSE and streamable-http endpoints when behind Nginx or other HTTP reverse proxies

Open LiangYang666 opened this issue 9 months ago • 1 comments

This PR adds support for root_path in subpath routing of SSE andstreamable-http endpoints when using Nginx or other HTTP middleware as a reverse proxy.

Motivation and Context

When deploying applications behind a reverse proxy (e.g., Nginx), it's common to route requests via subpaths like /server1/ or /server2/ . Without proper handling of these subpaths, SSE and streamable-http endpoints may fail to receive correctly routed requests.

This issue was originally reported in https://github.com/modelcontextprotocol/python-sdk/issues/242

Similar functionality exists in other web applications:

How Has This Been Tested?

Yes, this has been tested and running stably in production environments for several days. Both sse and streamable-http endpoints have been verified to work correctly under subpaths behind Nginx.

Breaking Changes

No breaking changes are introduced. Users do not need to update their code or configuration files. This is an optional enhancement that activates only when root_path is provided.

Types of changes

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)
  • [ ] Documentation update

Checklist

  • [x] I have read the MCP Documentation
  • [x] My code follows the repository's style guidelines
  • [x] New and existing tests pass locally
  • [x] I have added appropriate error handling
  • [ ] I have added or updated documentation as needed

Additional context

This change ensures that the application respects the root_path setting for streaming endpoints by utilizing Uvicorn’s built-in support for it. It does not introduce any custom routing logic but instead makes sure that streaming responses behave consistently with regular HTTP responses under subpath deployments.

LiangYang666 avatar May 24 '25 10:05 LiangYang666

cc @ihrpr

LiangYang666 avatar May 27 '25 06:05 LiangYang666

@felixweinberger, I confirmed that mount_path does NOT address the use case. In fact, I don't see any difference in behavior.

However, I did find a different workaround. In my particular case, I'm running FastMCP mounted to a FastAPI server, that is served behind a proxy, which strips prefixes.

It turns out FastAPI has a bug, which, if I workaround that, also seems to resolve the issue here.

In this setting, FastAPI docs instruct us to provide root_path:

Passing the root_path to FastAPI would be the equivalent of passing the --root-path command line option to Uvicorn or Hypercorn.

This is wrong. It is NOT equivalent.

There is a very old PR to address this: https://github.com/fastapi/fastapi/pull/11160

Long story short, switching to providing --root-path via command line option, rather than as a parameter to FastAPI, also resolved our issue here.

lukehsiao avatar Sep 10 '25 15:09 lukehsiao

@felixweinberger, I confirmed that mount_path does NOT address the use case. In fact, I don't see any difference in behavior.

However, I did find a different workaround. In my particular case, I'm running FastMCP mounted to a FastAPI server, that is served behind a proxy, which strips prefixes.

It turns out FastAPI has a bug, which, if I workaround that, also seems to resolve the issue here.

In this setting, FastAPI docs instruct us to provide root_path:

Passing the root_path to FastAPI would be the equivalent of passing the --root-path command line option to Uvicorn or Hypercorn.

This is wrong. It is NOT equivalent.

There is a very old PR to address this: fastapi/fastapi#11160

Long story short, switching to providing --root-path via command line option, rather than as a parameter to FastAPI, also resolved our issue here.

Thank you for reporting back and the additional details on your workaround!

Given this sounds like the workaround needed to address a FastAPI specific issue, I'm going to close this PR for now. If you find yourself needing this feature in future for some other purpose, happy to look at a resubmission.

felixweinberger avatar Sep 16 '25 14:09 felixweinberger