rm randomly truncated file

oops
This commit is contained in:
zzstoatzz 2025-06-03 11:04:54 -05:00
commit 33304cbb18

View file

@ -170,4 +170,117 @@ New applications should use Streamable HTTP transport instead.
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/`
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/`).
<CodeGroup>
```python {6} server.py
from fastmcp import FastMCP
mcp = FastMCP()
if __name__ == "__main__":
mcp.run(transport="sse")
```
```python {3,7} client.py
import asyncio
from fastmcp import Client
from fastmcp.client.transports import SSETransport
async def example():
async with Client(
transport=SSETransport("http://127.0.0.1:8000/sse")
) as client:
await client.ping()
if __name__ == "__main__":
asyncio.run(example())
```
</CodeGroup>
<Tip>
Notice that the client in the above example uses an explicit `SSETransport` to connect to the server. FastMCP will attempt to infer the appropriate transport from the provided configuration, but HTTP URLs are assumed to be Streamable HTTP (as of FastMCP 2.3.0).
</Tip>
To customize the host, port, or log level, provide appropriate keyword arguments to the `run()` method. You can also adjust the SSE path (which clients should connect to) and the message POST endpoint (which clients use to send subsequent messages).
<CodeGroup>
```python {8-12} server.py
from fastmcp import FastMCP
mcp = FastMCP()
if __name__ == "__main__":
mcp.run(
transport="sse",
host="127.0.0.1",
port=4200,
log_level="debug",
path="/my-custom-sse-path",
)
```
```python {7} client.py
import asyncio
from fastmcp import Client
from fastmcp.client.transports import SSETransport
async def example():
async with Client(
transport=SSETransport("http://127.0.0.1:4200/my-custom-sse-path")
) as client:
await client.ping()
if __name__ == "__main__":
asyncio.run(example())
```
</CodeGroup>
## 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
You can also add custom web routes to your FastMCP server, which will be exposed alongside the MCP endpoint. To do so, use the `@custom_route` decorator. Note that this is less flexible than using a full ASGI framework, but can be useful for adding simple endpoints like health checks to your standalone server.
```python
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import PlainTextResponse
mcp = FastMCP("MyServer")
@mcp.custom_route("/health", methods=["GET"])
async def health_check(request: Request) -> PlainTextResponse:
return PlainTextResponse("OK")
if __name__ == "__main__":
mcp.run()
```