docs: Update examples to use stateless HTTP with JSON responses (#1499)
Some checks failed
Main branch checks / checks (push) Has been cancelled
Some checks failed
Main branch checks / checks (push) Has been cancelled
This commit is contained in:
parent
9c8f763aa8
commit
fcffa14b5b
10 changed files with 76 additions and 38 deletions
58
README.md
58
README.md
|
|
@ -132,14 +132,14 @@ Let's create a simple MCP server that exposes a calculator tool and some data:
|
||||||
"""
|
"""
|
||||||
FastMCP quickstart example.
|
FastMCP quickstart example.
|
||||||
|
|
||||||
cd to the `examples/snippets/clients` directory and run:
|
Run from the repository root:
|
||||||
uv run server fastmcp_quickstart stdio
|
uv run examples/snippets/servers/fastmcp_quickstart.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create an MCP server
|
# Create an MCP server
|
||||||
mcp = FastMCP("Demo")
|
mcp = FastMCP("Demo", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
# Add an addition tool
|
# Add an addition tool
|
||||||
|
|
@ -167,23 +167,36 @@ def greet_user(name: str, style: str = "friendly") -> str:
|
||||||
}
|
}
|
||||||
|
|
||||||
return f"{styles.get(style, styles['friendly'])} for someone named {name}."
|
return f"{styles.get(style, styles['friendly'])} for someone named {name}."
|
||||||
|
|
||||||
|
|
||||||
|
# Run with streamable HTTP transport
|
||||||
|
if __name__ == "__main__":
|
||||||
|
mcp.run(transport="streamable-http")
|
||||||
```
|
```
|
||||||
|
|
||||||
_Full example: [examples/snippets/servers/fastmcp_quickstart.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/fastmcp_quickstart.py)_
|
_Full example: [examples/snippets/servers/fastmcp_quickstart.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/fastmcp_quickstart.py)_
|
||||||
<!-- /snippet-source -->
|
<!-- /snippet-source -->
|
||||||
|
|
||||||
You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running:
|
You can install this server in [Claude Code](https://docs.claude.com/en/docs/claude-code/mcp) and interact with it right away. First, run the server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run mcp install server.py
|
uv run --with mcp examples/snippets/servers/fastmcp_quickstart.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can test it with the MCP Inspector:
|
Then add it to Claude Code:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run mcp dev server.py
|
claude mcp add --transport http my-server http://localhost:8000/mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Alternatively, you can test it with the MCP Inspector. Start the server as above, then in a separate terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx -y @modelcontextprotocol/inspector
|
||||||
|
```
|
||||||
|
|
||||||
|
In the inspector UI, connect to `http://localhost:8000/mcp`.
|
||||||
|
|
||||||
## What is MCP?
|
## What is MCP?
|
||||||
|
|
||||||
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:
|
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:
|
||||||
|
|
@ -943,6 +956,7 @@ class SimpleTokenVerifier(TokenVerifier):
|
||||||
# Create FastMCP instance as a Resource Server
|
# Create FastMCP instance as a Resource Server
|
||||||
mcp = FastMCP(
|
mcp = FastMCP(
|
||||||
"Weather Service",
|
"Weather Service",
|
||||||
|
json_response=True,
|
||||||
# Token verifier for authentication
|
# Token verifier for authentication
|
||||||
token_verifier=SimpleTokenVerifier(),
|
token_verifier=SimpleTokenVerifier(),
|
||||||
# Auth settings for RFC 9728 Protected Resource Metadata
|
# Auth settings for RFC 9728 Protected Resource Metadata
|
||||||
|
|
@ -1158,7 +1172,7 @@ Note that `uv run mcp run` or `uv run mcp dev` only supports server using FastMC
|
||||||
|
|
||||||
### Streamable HTTP Transport
|
### Streamable HTTP Transport
|
||||||
|
|
||||||
> **Note**: Streamable HTTP transport is superseding SSE transport for production deployments.
|
> **Note**: Streamable HTTP transport is the recommended transport for production deployments. Use `stateless_http=True` and `json_response=True` for optimal scalability.
|
||||||
|
|
||||||
<!-- snippet-source examples/snippets/servers/streamable_config.py -->
|
<!-- snippet-source examples/snippets/servers/streamable_config.py -->
|
||||||
```python
|
```python
|
||||||
|
|
@ -1169,15 +1183,15 @@ Run from the repository root:
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Stateful server (maintains session state)
|
# Stateless server with JSON responses (recommended)
|
||||||
mcp = FastMCP("StatefulServer")
|
mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True)
|
||||||
|
|
||||||
# Other configuration options:
|
# Other configuration options:
|
||||||
# Stateless server (no session persistence)
|
# Stateless server with SSE streaming responses
|
||||||
# mcp = FastMCP("StatelessServer", stateless_http=True)
|
# mcp = FastMCP("StatelessServer", stateless_http=True)
|
||||||
|
|
||||||
# Stateless server (no session persistence, no sse stream with supported client)
|
# Stateful server with session persistence
|
||||||
# mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True)
|
# mcp = FastMCP("StatefulServer")
|
||||||
|
|
||||||
|
|
||||||
# Add a simple tool to demonstrate the server
|
# Add a simple tool to demonstrate the server
|
||||||
|
|
@ -1212,7 +1226,7 @@ from starlette.routing import Mount
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create the Echo server
|
# Create the Echo server
|
||||||
echo_mcp = FastMCP(name="EchoServer", stateless_http=True)
|
echo_mcp = FastMCP(name="EchoServer", stateless_http=True, json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@echo_mcp.tool()
|
@echo_mcp.tool()
|
||||||
|
|
@ -1222,7 +1236,7 @@ def echo(message: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
# Create the Math server
|
# Create the Math server
|
||||||
math_mcp = FastMCP(name="MathServer", stateless_http=True)
|
math_mcp = FastMCP(name="MathServer", stateless_http=True, json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@math_mcp.tool()
|
@math_mcp.tool()
|
||||||
|
|
@ -1323,7 +1337,7 @@ from starlette.routing import Mount
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create MCP server
|
# Create MCP server
|
||||||
mcp = FastMCP("My App")
|
mcp = FastMCP("My App", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
|
|
@ -1360,7 +1374,7 @@ from starlette.routing import Host
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create MCP server
|
# Create MCP server
|
||||||
mcp = FastMCP("MCP Host App")
|
mcp = FastMCP("MCP Host App", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
|
|
@ -1397,8 +1411,8 @@ from starlette.routing import Mount
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create multiple MCP servers
|
# Create multiple MCP servers
|
||||||
api_mcp = FastMCP("API Server")
|
api_mcp = FastMCP("API Server", json_response=True)
|
||||||
chat_mcp = FastMCP("Chat Server")
|
chat_mcp = FastMCP("Chat Server", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@api_mcp.tool()
|
@api_mcp.tool()
|
||||||
|
|
@ -1448,7 +1462,11 @@ from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Configure streamable_http_path during initialization
|
# Configure streamable_http_path during initialization
|
||||||
# This server will mount at the root of wherever it's mounted
|
# This server will mount at the root of wherever it's mounted
|
||||||
mcp_at_root = FastMCP("My Server", streamable_http_path="/")
|
mcp_at_root = FastMCP(
|
||||||
|
"My Server",
|
||||||
|
json_response=True,
|
||||||
|
streamable_http_path="/",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mcp_at_root.tool()
|
@mcp_at_root.tool()
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ Here's a simple MCP server that exposes a tool, resource, and prompt:
|
||||||
```python title="server.py"
|
```python title="server.py"
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
mcp = FastMCP("Test Server")
|
mcp = FastMCP("Test Server", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
|
|
@ -36,12 +36,22 @@ def get_greeting(name: str) -> str:
|
||||||
def greet_user(name: str, style: str = "friendly") -> str:
|
def greet_user(name: str, style: str = "friendly") -> str:
|
||||||
"""Generate a greeting prompt"""
|
"""Generate a greeting prompt"""
|
||||||
return f"Write a {style} greeting for someone named {name}."
|
return f"Write a {style} greeting for someone named {name}."
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
mcp.run(transport="streamable-http")
|
||||||
```
|
```
|
||||||
|
|
||||||
Test it with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
|
Run the server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run mcp dev server.py
|
uv run --with mcp server.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Then open the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) and connect to `http://localhost:8000/mcp`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx -y @modelcontextprotocol/inspector
|
||||||
```
|
```
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
"""
|
"""
|
||||||
FastMCP quickstart example.
|
FastMCP quickstart example.
|
||||||
|
|
||||||
cd to the `examples/snippets/clients` directory and run:
|
Run from the repository root:
|
||||||
uv run server fastmcp_quickstart stdio
|
uv run examples/snippets/servers/fastmcp_quickstart.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create an MCP server
|
# Create an MCP server
|
||||||
mcp = FastMCP("Demo")
|
mcp = FastMCP("Demo", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
# Add an addition tool
|
# Add an addition tool
|
||||||
|
|
@ -36,3 +36,8 @@ def greet_user(name: str, style: str = "friendly") -> str:
|
||||||
}
|
}
|
||||||
|
|
||||||
return f"{styles.get(style, styles['friendly'])} for someone named {name}."
|
return f"{styles.get(style, styles['friendly'])} for someone named {name}."
|
||||||
|
|
||||||
|
|
||||||
|
# Run with streamable HTTP transport
|
||||||
|
if __name__ == "__main__":
|
||||||
|
mcp.run(transport="streamable-http")
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class SimpleTokenVerifier(TokenVerifier):
|
||||||
# Create FastMCP instance as a Resource Server
|
# Create FastMCP instance as a Resource Server
|
||||||
mcp = FastMCP(
|
mcp = FastMCP(
|
||||||
"Weather Service",
|
"Weather Service",
|
||||||
|
json_response=True,
|
||||||
# Token verifier for authentication
|
# Token verifier for authentication
|
||||||
token_verifier=SimpleTokenVerifier(),
|
token_verifier=SimpleTokenVerifier(),
|
||||||
# Auth settings for RFC 9728 Protected Resource Metadata
|
# Auth settings for RFC 9728 Protected Resource Metadata
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,15 @@ Run from the repository root:
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Stateful server (maintains session state)
|
# Stateless server with JSON responses (recommended)
|
||||||
mcp = FastMCP("StatefulServer")
|
mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True)
|
||||||
|
|
||||||
# Other configuration options:
|
# Other configuration options:
|
||||||
# Stateless server (no session persistence)
|
# Stateless server with SSE streaming responses
|
||||||
# mcp = FastMCP("StatelessServer", stateless_http=True)
|
# mcp = FastMCP("StatelessServer", stateless_http=True)
|
||||||
|
|
||||||
# Stateless server (no session persistence, no sse stream with supported client)
|
# Stateful server with session persistence
|
||||||
# mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True)
|
# mcp = FastMCP("StatefulServer")
|
||||||
|
|
||||||
|
|
||||||
# Add a simple tool to demonstrate the server
|
# Add a simple tool to demonstrate the server
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from starlette.routing import Mount
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create MCP server
|
# Create MCP server
|
||||||
mcp = FastMCP("My App")
|
mcp = FastMCP("My App", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from starlette.routing import Host
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create MCP server
|
# Create MCP server
|
||||||
mcp = FastMCP("MCP Host App")
|
mcp = FastMCP("MCP Host App", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ from starlette.routing import Mount
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create multiple MCP servers
|
# Create multiple MCP servers
|
||||||
api_mcp = FastMCP("API Server")
|
api_mcp = FastMCP("API Server", json_response=True)
|
||||||
chat_mcp = FastMCP("Chat Server")
|
chat_mcp = FastMCP("Chat Server", json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@api_mcp.tool()
|
@api_mcp.tool()
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,11 @@ from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Configure streamable_http_path during initialization
|
# Configure streamable_http_path during initialization
|
||||||
# This server will mount at the root of wherever it's mounted
|
# This server will mount at the root of wherever it's mounted
|
||||||
mcp_at_root = FastMCP("My Server", streamable_http_path="/")
|
mcp_at_root = FastMCP(
|
||||||
|
"My Server",
|
||||||
|
json_response=True,
|
||||||
|
streamable_http_path="/",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mcp_at_root.tool()
|
@mcp_at_root.tool()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from starlette.routing import Mount
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
# Create the Echo server
|
# Create the Echo server
|
||||||
echo_mcp = FastMCP(name="EchoServer", stateless_http=True)
|
echo_mcp = FastMCP(name="EchoServer", stateless_http=True, json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@echo_mcp.tool()
|
@echo_mcp.tool()
|
||||||
|
|
@ -21,7 +21,7 @@ def echo(message: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
# Create the Math server
|
# Create the Math server
|
||||||
math_mcp = FastMCP(name="MathServer", stateless_http=True)
|
math_mcp = FastMCP(name="MathServer", stateless_http=True, json_response=True)
|
||||||
|
|
||||||
|
|
||||||
@math_mcp.tool()
|
@math_mcp.tool()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue