mirror of
https://github.com/aljazceru/mcp-python-sdk.git
synced 2025-12-19 14:54:24 +01:00
Option to mount SSE server to existing ASGI server (#312)
* Option to mount SSE server to existing ASGI server Fixes #311 Add option to mount SSE server to an existing ASGI server. * Add a new method `sse_app` in `src/mcp/server/fastmcp/server.py` to return an instance of the SSE server app. * Update the `run_sse_async` method in `src/mcp/server/fastmcp/server.py` to use the new `sse_app` method. * Update the documentation in `README.md` to include instructions on how to mount the SSE server to an existing ASGI server. * Fix the example in `README.md` to use `app.mount('/', mcp.sse_app())` instead. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/modelcontextprotocol/python-sdk/issues/311?shareId=XXXX-XXXX-XXXX-XXXX). * Add `sse_app` method and update `run_sse_async` method in `server.py` * Add `sse_app` method to return an instance of the SSE server app * Update `run_sse_async` method to use the new `sse_app` method Update `README.md` to include instructions for mounting SSE server * Add section on mounting the SSE server to an existing ASGI server * fix: Move import statements to the top of the file/ * docs: Update README to reflect changes in mounting SSE server with Starlette * docs: Formatting of SSE server mounting example in README
This commit is contained in:
26
README.md
26
README.md
@@ -31,6 +31,7 @@
|
||||
- [Development Mode](#development-mode)
|
||||
- [Claude Desktop Integration](#claude-desktop-integration)
|
||||
- [Direct Execution](#direct-execution)
|
||||
- [Mounting to an Existing ASGI Server](#mounting-to-an-existing-asgi-server)
|
||||
- [Examples](#examples)
|
||||
- [Echo Server](#echo-server)
|
||||
- [SQLite Explorer](#sqlite-explorer)
|
||||
@@ -346,6 +347,31 @@ python server.py
|
||||
mcp run server.py
|
||||
```
|
||||
|
||||
### Mounting to an Existing ASGI Server
|
||||
|
||||
You can mount the SSE server to an existing ASGI server using the `sse_app` method. This allows you to integrate the SSE server with other ASGI applications.
|
||||
|
||||
```python
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routes import Mount, Host
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
|
||||
mcp = FastMCP("My App")
|
||||
|
||||
# Mount the SSE server to the existing ASGI server
|
||||
app = Starlette(
|
||||
routes=[
|
||||
Mount('/', app=mcp.sse_app()),
|
||||
]
|
||||
)
|
||||
|
||||
# or dynamically mount as host
|
||||
app.router.routes.append(Host('mcp.acme.corp', app=mcp.sse_app()))
|
||||
```
|
||||
|
||||
For more information on mounting applications in Starlette, see the [Starlette documentation](https://www.starlette.io/routing/#submounting-routes).
|
||||
|
||||
## Examples
|
||||
|
||||
### Echo Server
|
||||
|
||||
@@ -19,6 +19,8 @@ import uvicorn
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic.networks import AnyUrl
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routing import Mount, Route
|
||||
|
||||
from mcp.server.fastmcp.exceptions import ResourceError
|
||||
from mcp.server.fastmcp.prompts import Prompt, PromptManager
|
||||
@@ -461,9 +463,19 @@ class FastMCP:
|
||||
|
||||
async def run_sse_async(self) -> None:
|
||||
"""Run the server using SSE transport."""
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routing import Mount, Route
|
||||
starlette_app = self.sse_app()
|
||||
|
||||
config = uvicorn.Config(
|
||||
starlette_app,
|
||||
host=self.settings.host,
|
||||
port=self.settings.port,
|
||||
log_level=self.settings.log_level.lower(),
|
||||
)
|
||||
server = uvicorn.Server(config)
|
||||
await server.serve()
|
||||
|
||||
def sse_app(self) -> Starlette:
|
||||
"""Return an instance of the SSE server app."""
|
||||
sse = SseServerTransport("/messages/")
|
||||
|
||||
async def handle_sse(request):
|
||||
@@ -476,7 +488,7 @@ class FastMCP:
|
||||
self._mcp_server.create_initialization_options(),
|
||||
)
|
||||
|
||||
starlette_app = Starlette(
|
||||
return Starlette(
|
||||
debug=self.settings.debug,
|
||||
routes=[
|
||||
Route("/sse", endpoint=handle_sse),
|
||||
@@ -484,15 +496,6 @@ class FastMCP:
|
||||
],
|
||||
)
|
||||
|
||||
config = uvicorn.Config(
|
||||
starlette_app,
|
||||
host=self.settings.host,
|
||||
port=self.settings.port,
|
||||
log_level=self.settings.log_level.lower(),
|
||||
)
|
||||
server = uvicorn.Server(config)
|
||||
await server.serve()
|
||||
|
||||
async def list_prompts(self) -> list[MCPPrompt]:
|
||||
"""List all available prompts."""
|
||||
prompts = self._prompt_manager.list_prompts()
|
||||
|
||||
Reference in New Issue
Block a user