Merge pull request #401 from jlowin/deprecate-methods

Deprecate transport-specific methods on FastMCP server
This commit is contained in:
Jeremiah Lowin 2025-05-10 12:18:20 -04:00 committed by GitHub
commit aa6dde48cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 293 additions and 79 deletions

View file

@ -5,6 +5,9 @@ description: Integrate FastMCP servers into existing Starlette, FastAPI, or othe
icon: plug
---
import { VersionBadge } from '/snippets/version-badge.mdx'
While FastMCP provides standalone server capabilities, you can also integrate your FastMCP server into existing web applications. This approach is useful for:
- Adding MCP functionality to an existing website or API
@ -16,10 +19,13 @@ Please note that all FastMCP servers have a `run()` method that can be used to s
## ASGI Server
FastMCP servers can be created as [Starlette](https://www.starlette.io/) ASGI apps for straightforward hosting or integration into existing applications.
The first step is to obtain a Starlette application instance from your FastMCP server using either the `streamable_http_app()` (preferred) or `sse_app()` (legacy) methods:
The first step is to obtain a Starlette application instance from your FastMCP server using the `http_app()` method:
<Tip>
The `http_app()` method is new in FastMCP 2.3.2. In older versions, use `sse_app()` for SSE transport or `streamable_http_app()` for Streamable HTTP transport.
</Tip>
```python
from fastmcp import FastMCP
@ -30,18 +36,23 @@ mcp = FastMCP("MyServer")
def hello(name: str) -> str:
return f"Hello, {name}!"
# Get a Starlette app instance for the preferred transport
http_app = mcp.streamable_http_app() # For Streamable HTTP transport
sse_app = mcp.sse_app() # For SSE transport
# Get a Starlette app instance for Streamable HTTP transport (recommended)
http_app = mcp.http_app()
# For legacy SSE transport (deprecated)
sse_app = mcp.http_app(transport="sse")
```
Both methods return a Starlette application that can be integrated with other ASGI-compatible web frameworks.
Both approaches return a Starlette application that can be integrated with other ASGI-compatible web frameworks.
The MCP server's endpoint is mounted at the root path `/mcp` for Streamable HTTP transport, and `/sse` for SSE transport, though you can change these paths by passing a `path` argument to the `streamable_http_app()` or `sse_app()` methods:
The MCP server's endpoint is mounted at the root path `/mcp` for Streamable HTTP transport, and `/sse` for SSE transport, though you can change these paths by passing a `path` argument to the `http_app()` method:
```python
http_app = mcp.streamable_http_app(path="/custom-mcp-path")
sse_app = mcp.sse_app(path="/custom-sse-path")
# For Streamable HTTP transport
http_app = mcp.http_app(path="/custom-mcp-path")
# For SSE transport (deprecated)
sse_app = mcp.http_app(path="/custom-sse-path", transport="sse")
```
### Running the Server
@ -49,9 +60,12 @@ sse_app = mcp.sse_app(path="/custom-sse-path")
To run the FastMCP server, you can use the `uvicorn` ASGI server:
```python
from fastmcp import FastMCP
import uvicorn
# (define the app here)
mcp = FastMCP("MyServer")
http_app = mcp.http_app()
if __name__ == "__main__":
uvicorn.run(http_app, host="0.0.0.0", port=8000)
@ -83,7 +97,7 @@ custom_middleware = [
]
# Create ASGI app with custom middleware
http_app = mcp.streamable_http_app(middleware=custom_middleware)
http_app = mcp.http_app(middleware=custom_middleware)
```
@ -91,7 +105,7 @@ http_app = mcp.streamable_http_app(middleware=custom_middleware)
<VersionBadge version="2.3.1" />
You can mount your FastMCP server in another Starlette application using the `Mount` class.
You can mount your FastMCP server in another Starlette application:
```python
from fastmcp import FastMCP
@ -102,7 +116,7 @@ from starlette.routing import Mount
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.streamable_http_app(path='/mcp')
mcp_app = mcp.http_app(path='/mcp')
# Create a Starlette app and mount the MCP server
app = Starlette(
@ -134,7 +148,7 @@ from starlette.routing import Mount
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.streamable_http_app(path='/mcp')
mcp_app = mcp.http_app(path='/mcp')
# Create nested application structure
inner_app = Starlette(routes=[Mount("/inner", app=mcp_app)])
@ -164,7 +178,7 @@ from starlette.routing import Mount
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.streamable_http_app(path='/mcp')
mcp_app = mcp.http_app(path='/mcp')
# Create a FastAPI app and mount the MCP server
app = FastAPI(lifespan=mcp_app.router.lifespan_context)

View file

@ -68,8 +68,8 @@ Below is a comparison of available transport options to help you choose the righ
| Transport | Use Cases | Recommendation |
| --------- | --------- | -------------- |
| **STDIO** | Local tools, command-line scripts, and integrations with clients like Claude Desktop | Best for local tools and when clients manage server processes |
| **Streamable HTTP** | Web-based deployments, microservices, exposing MCP over a network | Recommended choice for new web-based deployments |
| **SSE** | Existing web-based deployments that rely on SSE | Suitable for compatibility with SSE clients; prefer Streamable HTTP for new projects |
| **Streamable HTTP** | Web-based deployments, microservices, exposing MCP over a network | Recommended choice for web-based deployments |
| **SSE** | Existing web-based deployments that rely on SSE | Deprecated - prefer Streamable HTTP for new projects |
### STDIO
@ -92,7 +92,7 @@ When using Stdio transport, you will typically *not* run the server yourself as
<VersionBadge version="2.3.0" />
Streamable HTTP is a modern, efficient transport for exposing your MCP server via HTTP. It is generally recommended over SSE for new web-based deployments.
Streamable HTTP is a modern, efficient transport for exposing your MCP server via HTTP. It is the recommended transport for web-based deployments.
To run a server using Streamable HTTP, you can use the `run()` method with the `transport` argument set to `"streamable-http"`. This will start a Uvicorn server on the default host (`127.0.0.1`), port (`8000`), and path (`/mcp`).
<CodeGroup>
@ -150,7 +150,12 @@ if __name__ == "__main__":
### SSE
Server-Sent Events (SSE) is an HTTP-based protocol for server-to-client streaming. While FastMCP supports SSE, Streamable HTTP is preferred for new projects.
<Warning>
The SSE transport is deprecated and may be removed in a future version.
New applications should use Streamable HTTP transport instead.
</Warning>
Server-Sent Events (SSE) is an HTTP-based protocol for server-to-client streaming. While FastMCP still supports SSE, it is deprecated and Streamable HTTP is preferred for new projects.
To run a server using SSE, you can use the `run()` method with the `transport` argument set to `"sse"`. This will start a Uvicorn server on the default host (`127.0.0.1`), port (`8000`), and with default SSE path (`/sse`) and message path (`/messages/`).
@ -198,7 +203,6 @@ if __name__ == "__main__":
port=4200,
log_level="debug",
path="/my-custom-sse-path",
message_path="/my-custom-message-path/",
)
```
```python {7} client.py
@ -217,9 +221,37 @@ if __name__ == "__main__":
```
</CodeGroup>
Your client only needs to know the host, port, and "main" path; the message path will be transmitted to it as part of the connection handshake.
## Async Usage
FastMCP provides both synchronous and asynchronous APIs for running your server. The `run()` method seen in previous examples is a synchronous method that internally uses `anyio.run()` to run the asynchronous server. For applications that are already running in an async context, FastMCP provides the `run_async()` method.
```python {10-12}
from fastmcp import FastMCP
import asyncio
mcp = FastMCP(name="MyServer")
@mcp.tool()
def hello(name: str) -> str:
return f"Hello, {name}!"
async def main():
# Use run_async() in async contexts
await mcp.run_async(transport="streamable-http")
if __name__ == "__main__":
asyncio.run(main())
```
<Warning>
The `run()` method cannot be called from inside an async function because it already creates its own async event loop internally. If you attempt to call `run()` from inside an async function, you'll get an error about the event loop already running.
Always use `run_async()` inside async functions and `run()` in synchronous contexts.
</Warning>
Both `run()` and `run_async()` accept the same transport arguments, so all the examples above apply to both methods.
## Custom Routes

View file

@ -44,7 +44,7 @@ FastMCP root path: ~/Developer/fastmcp
```
## Upgrading from the Official MCP SDK
Upgrading from the official MCP SDK's FastMCP 1.0 to FastMCP 2.0 is easy! The core server API is highly compatible, so after you install the `fastmcp` package, just change your import statement from `from mcp.server.fastmcp import FastMCP` to `from fastmcp import FastMCP`.
Upgrading from the official MCP SDK's FastMCP 1.0 to FastMCP 2.0 is generally straightforward. The core server API is highly compatible, and in many cases, changing your import statement from `from mcp.server.fastmcp import FastMCP` to `from fastmcp import FastMCP` will be sufficient.
```python {1-5}
@ -56,8 +56,9 @@ from fastmcp import FastMCP
mcp = FastMCP("My MCP Server")
```
While the 1.0 server API is very stable for common use cases, FastMCP 2.0 introduces many new features (like the Client, proxying, composition) documented throughout this site. Review the documentation for details on new capabilities.
<Warning>
Prior to `fastmcp==2.3.0` and `mcp==1.8.0`, the 2.x API always mirrored the 1.0 API. However, as the projects diverge, this can not be guaranteed. You may see deprecation warnings if you attempt to use 1.0 APIs in FastMCP 2.x. Please refer to this documentation for details on new capabilities.
</Warning>
## Installing for Development

View file

@ -27,7 +27,7 @@ if __name__ == "__main__":
## FastMCP 2.0 and the Official MCP SDK
<Tip>
Recognize the `FastMCP` name? You might have used the version integrated into the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), which was based on **FastMCP 1.0**.
Recognize the `FastMCP` name? You might have seen the version that was contributed to the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), which was based on **FastMCP 1.0**.
**Welcome to FastMCP 2.0!** This is the [actively developed successor](https://github.com/jlowin/fastmcp), and it significantly expands on 1.0 by introducing powerful client capabilities, server proxying & composition, OpenAPI/FastAPI integration, and more advanced features.

View file

@ -114,11 +114,16 @@ if __name__ == "__main__":
# This runs the server, defaulting to STDIO transport
mcp.run()
# To use a different transport, e.g., Streamable HTTP:
# To use a different transport, e.g., HTTP:
# mcp.run(transport="streamable-http", host="127.0.0.1", port=9000)
```
FastMCP supports several transport options like STDIO (default, for local tools), Streamable HTTP (recommended for web services), and SSE (legacy web transport). The server can also be run using the FastMCP CLI.
FastMCP supports several transport options:
- STDIO (default, for local tools)
- Streamable HTTP (recommended for web services)
- SSE (legacy web transport, deprecated)
The server can also be run using the FastMCP CLI.
For detailed information on each transport, how to configure them (host, port, paths), and when to use which, please refer to the [**Running Your FastMCP Server**](/deployment/running-server) guide.