diff --git a/README.md b/README.md index a0daf5c6d..304bea78c 100644 --- a/README.md +++ b/README.md @@ -132,14 +132,14 @@ Let's create a simple MCP server that exposes a calculator tool and some data: """ FastMCP quickstart example. -cd to the `examples/snippets/clients` directory and run: - uv run server fastmcp_quickstart stdio +Run from the repository root: + uv run examples/snippets/servers/fastmcp_quickstart.py """ from mcp.server.fastmcp import FastMCP # Create an MCP server -mcp = FastMCP("Demo") +mcp = FastMCP("Demo", stateless_http=True, json_response=True) # 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}." + + +# 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)_ -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 -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 -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? 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: @@ -888,6 +901,8 @@ class SimpleTokenVerifier(TokenVerifier): # Create FastMCP instance as a Resource Server mcp = FastMCP( "Weather Service", + stateless_http=True, + json_response=True, # Token verifier for authentication token_verifier=SimpleTokenVerifier(), # Auth settings for RFC 9728 Protected Resource Metadata @@ -1103,7 +1118,7 @@ Note that `uv run mcp run` or `uv run mcp dev` only supports server using FastMC ### 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. ```python @@ -1114,15 +1129,15 @@ Run from the repository root: from mcp.server.fastmcp import FastMCP -# Stateful server (maintains session state) -mcp = FastMCP("StatefulServer") +# Stateless server with JSON responses (recommended) +mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True) # Other configuration options: -# Stateless server (no session persistence) +# Stateless server with SSE streaming responses # mcp = FastMCP("StatelessServer", stateless_http=True) -# Stateless server (no session persistence, no sse stream with supported client) -# mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True) +# Stateful server with session persistence +# mcp = FastMCP("StatefulServer") # Add a simple tool to demonstrate the server @@ -1157,7 +1172,7 @@ from starlette.routing import Mount from mcp.server.fastmcp import FastMCP # 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() @@ -1167,7 +1182,7 @@ def echo(message: str) -> str: # 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() @@ -1268,7 +1283,7 @@ from starlette.routing import Mount from mcp.server.fastmcp import FastMCP # Create MCP server -mcp = FastMCP("My App") +mcp = FastMCP("My App", stateless_http=True, json_response=True) @mcp.tool() @@ -1305,7 +1320,7 @@ from starlette.routing import Host from mcp.server.fastmcp import FastMCP # Create MCP server -mcp = FastMCP("MCP Host App") +mcp = FastMCP("MCP Host App", stateless_http=True, json_response=True) @mcp.tool() @@ -1342,8 +1357,8 @@ from starlette.routing import Mount from mcp.server.fastmcp import FastMCP # Create multiple MCP servers -api_mcp = FastMCP("API Server") -chat_mcp = FastMCP("Chat Server") +api_mcp = FastMCP("API Server", stateless_http=True, json_response=True) +chat_mcp = FastMCP("Chat Server", stateless_http=True, json_response=True) @api_mcp.tool() @@ -1393,7 +1408,12 @@ from mcp.server.fastmcp import FastMCP # Configure streamable_http_path during initialization # 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", + stateless_http=True, + json_response=True, + streamable_http_path="/", +) @mcp_at_root.tool() diff --git a/docs/index.md b/docs/index.md index 139afca4a..bc4bb048b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,7 +17,7 @@ Here's a simple MCP server that exposes a tool, resource, and prompt: ```python title="server.py" from mcp.server.fastmcp import FastMCP -mcp = FastMCP("Test Server") +mcp = FastMCP("Test Server", stateless_http=True, json_response=True) @mcp.tool() @@ -36,12 +36,22 @@ def get_greeting(name: str) -> str: def greet_user(name: str, style: str = "friendly") -> str: """Generate a greeting prompt""" return f"Write a {style} greeting for someone named {name}." + + +if __name__ == "__main__": + mcp.run(transport="streamable-http") +``` + +Run the server: + +```bash +uv run --with mcp server.py ``` -Test it with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector): +Then open the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) and connect to `http://localhost:8000/mcp`: ```bash -uv run mcp dev server.py +npx -y @modelcontextprotocol/inspector ``` ## Getting Started diff --git a/examples/snippets/servers/fastmcp_quickstart.py b/examples/snippets/servers/fastmcp_quickstart.py index d7aef8c61..3af39c22a 100644 --- a/examples/snippets/servers/fastmcp_quickstart.py +++ b/examples/snippets/servers/fastmcp_quickstart.py @@ -1,14 +1,14 @@ """ FastMCP quickstart example. -cd to the `examples/snippets/clients` directory and run: - uv run server fastmcp_quickstart stdio +Run from the repository root: + uv run examples/snippets/servers/fastmcp_quickstart.py """ from mcp.server.fastmcp import FastMCP # Create an MCP server -mcp = FastMCP("Demo") +mcp = FastMCP("Demo", stateless_http=True, json_response=True) # 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}." + + +# Run with streamable HTTP transport +if __name__ == "__main__": + mcp.run(transport="streamable-http") diff --git a/examples/snippets/servers/oauth_server.py b/examples/snippets/servers/oauth_server.py index bd317e1ae..e31a79bd2 100644 --- a/examples/snippets/servers/oauth_server.py +++ b/examples/snippets/servers/oauth_server.py @@ -20,6 +20,8 @@ async def verify_token(self, token: str) -> AccessToken | None: # Create FastMCP instance as a Resource Server mcp = FastMCP( "Weather Service", + stateless_http=True, + json_response=True, # Token verifier for authentication token_verifier=SimpleTokenVerifier(), # Auth settings for RFC 9728 Protected Resource Metadata diff --git a/examples/snippets/servers/streamable_config.py b/examples/snippets/servers/streamable_config.py index e265f6381..d351a45d8 100644 --- a/examples/snippets/servers/streamable_config.py +++ b/examples/snippets/servers/streamable_config.py @@ -5,15 +5,15 @@ from mcp.server.fastmcp import FastMCP -# Stateful server (maintains session state) -mcp = FastMCP("StatefulServer") +# Stateless server with JSON responses (recommended) +mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True) # Other configuration options: -# Stateless server (no session persistence) +# Stateless server with SSE streaming responses # mcp = FastMCP("StatelessServer", stateless_http=True) -# Stateless server (no session persistence, no sse stream with supported client) -# mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True) +# Stateful server with session persistence +# mcp = FastMCP("StatefulServer") # Add a simple tool to demonstrate the server diff --git a/examples/snippets/servers/streamable_http_basic_mounting.py b/examples/snippets/servers/streamable_http_basic_mounting.py index abcc0e572..e2c65ca40 100644 --- a/examples/snippets/servers/streamable_http_basic_mounting.py +++ b/examples/snippets/servers/streamable_http_basic_mounting.py @@ -11,7 +11,7 @@ from mcp.server.fastmcp import FastMCP # Create MCP server -mcp = FastMCP("My App") +mcp = FastMCP("My App", stateless_http=True, json_response=True) @mcp.tool() diff --git a/examples/snippets/servers/streamable_http_host_mounting.py b/examples/snippets/servers/streamable_http_host_mounting.py index d48558cc8..a02e3fba3 100644 --- a/examples/snippets/servers/streamable_http_host_mounting.py +++ b/examples/snippets/servers/streamable_http_host_mounting.py @@ -11,7 +11,7 @@ from mcp.server.fastmcp import FastMCP # Create MCP server -mcp = FastMCP("MCP Host App") +mcp = FastMCP("MCP Host App", stateless_http=True, json_response=True) @mcp.tool() diff --git a/examples/snippets/servers/streamable_http_multiple_servers.py b/examples/snippets/servers/streamable_http_multiple_servers.py index df347b7b3..2aeaa2214 100644 --- a/examples/snippets/servers/streamable_http_multiple_servers.py +++ b/examples/snippets/servers/streamable_http_multiple_servers.py @@ -11,8 +11,8 @@ from mcp.server.fastmcp import FastMCP # Create multiple MCP servers -api_mcp = FastMCP("API Server") -chat_mcp = FastMCP("Chat Server") +api_mcp = FastMCP("API Server", stateless_http=True, json_response=True) +chat_mcp = FastMCP("Chat Server", stateless_http=True, json_response=True) @api_mcp.tool() diff --git a/examples/snippets/servers/streamable_http_path_config.py b/examples/snippets/servers/streamable_http_path_config.py index 71228423e..48420f607 100644 --- a/examples/snippets/servers/streamable_http_path_config.py +++ b/examples/snippets/servers/streamable_http_path_config.py @@ -12,7 +12,12 @@ # Configure streamable_http_path during initialization # 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", + stateless_http=True, + json_response=True, + streamable_http_path="/", +) @mcp_at_root.tool() diff --git a/examples/snippets/servers/streamable_starlette_mount.py b/examples/snippets/servers/streamable_starlette_mount.py index 57d2d2ea5..b3a630b0f 100644 --- a/examples/snippets/servers/streamable_starlette_mount.py +++ b/examples/snippets/servers/streamable_starlette_mount.py @@ -11,7 +11,7 @@ from mcp.server.fastmcp import FastMCP # 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() @@ -21,7 +21,7 @@ def echo(message: str) -> str: # 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()