@@ -863,72 +863,102 @@ Note that `uv run mcp run` or `uv run mcp dev` only supports server using FastMC
863863
864864> ** Note** : Streamable HTTP transport is superseding SSE transport for production deployments.
865865
866+ <!-- snippet-source examples/snippets/servers/streamable_config.py -->
866867``` python
868+ """ Streamable HTTP server configuration examples.
869+
870+ This example shows different configuration options for
871+ streamable HTTP servers.
872+
873+ Run from the repository root:
874+ uv run examples/snippets/servers/streamable_config.py
875+ """
876+
867877from mcp.server.fastmcp import FastMCP
868878
869879# Stateful server (maintains session state)
870880mcp = FastMCP(" StatefulServer" )
871881
882+ # Other configuration options:
872883# Stateless server (no session persistence)
873- mcp = FastMCP(" StatelessServer" , stateless_http = True )
884+ # mcp = FastMCP("StatelessServer", stateless_http=True)
874885
875886# Stateless server (no session persistence, no sse stream with supported client)
876- mcp = FastMCP(" StatelessServer" , stateless_http = True , json_response = True )
887+ # mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True)
888+
889+
890+ # Add a simple tool to demonstrate the server
891+ @mcp.tool ()
892+ def greet (name : str = " World" ) -> str :
893+ """ Greet someone by name."""
894+ return f " Hello, { name} ! "
895+
877896
878897# Run server with streamable_http transport
879- mcp.run(transport = " streamable-http" )
898+ if __name__ == " __main__" :
899+ mcp.run(transport = " streamable-http" )
880900```
881901
902+ _ Full example: [ examples/snippets/servers/streamable_config.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_config.py ) _
903+ <!-- /snippet-source -->
904+
882905You can mount multiple FastMCP servers in a FastAPI application:
883906
907+ <!-- snippet-source examples/snippets/servers/streamable_fastapi_mount.py -->
884908``` python
885- # echo.py
909+ """ Example of mounting multiple FastMCP servers in a FastAPI application.
910+
911+ This example shows how to create multiple MCP servers and mount them
912+ at different endpoints in a single FastAPI application.
913+
914+ Run from the repository root:
915+ uvicorn examples.snippets.servers.streamable_fastapi_mount:app --reload
916+ """
917+
918+ import contextlib
919+
920+ from fastapi import FastAPI
921+
886922from mcp.server.fastmcp import FastMCP
887923
888- mcp = FastMCP(name = " EchoServer" , stateless_http = True )
924+ # Create the Echo server
925+ echo_mcp = FastMCP(name = " EchoServer" , stateless_http = True )
889926
890927
891- @mcp .tool ()
928+ @echo_mcp .tool ()
892929def echo (message : str ) -> str :
893930 """ A simple echo tool"""
894931 return f " Echo: { message} "
895- ```
896932
897- ``` python
898- # math.py
899- from mcp.server.fastmcp import FastMCP
900933
901- mcp = FastMCP(name = " MathServer" , stateless_http = True )
934+ # Create the Math server
935+ math_mcp = FastMCP(name = " MathServer" , stateless_http = True )
902936
903937
904- @mcp .tool ()
938+ @math_mcp .tool ()
905939def add_two (n : int ) -> int :
906940 """ Tool to add two to the input"""
907941 return n + 2
908- ```
909-
910- ``` python
911- # main.py
912- import contextlib
913- from fastapi import FastAPI
914- from mcp.echo import echo
915- from mcp.math import math
916942
917943
918944# Create a combined lifespan to manage both session managers
919945@contextlib.asynccontextmanager
920946async def lifespan (app : FastAPI):
921947 async with contextlib.AsyncExitStack() as stack:
922- await stack.enter_async_context(echo.mcp .session_manager.run())
923- await stack.enter_async_context(math.mcp .session_manager.run())
948+ await stack.enter_async_context(echo_mcp .session_manager.run())
949+ await stack.enter_async_context(math_mcp .session_manager.run())
924950 yield
925951
926952
953+ # Create the FastAPI app and mount the MCP servers
927954app = FastAPI(lifespan = lifespan)
928- app.mount(" /echo" , echo.mcp .streamable_http_app())
929- app.mount(" /math" , math.mcp .streamable_http_app())
955+ app.mount(" /echo" , echo_mcp .streamable_http_app())
956+ app.mount(" /math" , math_mcp .streamable_http_app())
930957```
931958
959+ _ Full example: [ examples/snippets/servers/streamable_fastapi_mount.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_fastapi_mount.py ) _
960+ <!-- /snippet-source -->
961+
932962For low level server with Streamable HTTP implementations, see:
933963
934964- Stateful server: [ ` examples/servers/simple-streamablehttp/ ` ] ( examples/servers/simple-streamablehttp/ )
@@ -945,26 +975,6 @@ The streamable HTTP transport supports:
945975
946976By default, SSE servers are mounted at ` /sse ` and Streamable HTTP servers are mounted at ` /mcp ` . You can customize these paths using the methods described below.
947977
948- #### Streamable HTTP servers
949-
950- The following example shows how to use ` streamable_http_app() ` , a method that returns a ` Starlette ` application object.
951- You can then append additional routes to that application as needed.
952-
953- ``` python
954- mcp = FastMCP(" My App" )
955-
956- app = mcp.streamable_http_app()
957- # Additional non-MCP routes can be added like so:
958- # from starlette.routing import Route
959- # app.router.routes.append(Route("/", endpoint=other_route_function))
960- ```
961-
962- To customize the route from the default of "/mcp", either specify the ` streamable_http_path ` option for the ` FastMCP ` constructor,
963- or set ` FASTMCP_STREAMABLE_HTTP_PATH ` environment variable.
964-
965- Note that in Starlette and FastAPI (which is based on Starlette), the "/mcp" route will redirect to "/mcp/",
966- so you may need to use "/mcp/" when pointing MCP clients at your servers.
967-
968978For more information on mounting applications in Starlette, see the [ Starlette documentation] ( https://www.starlette.io/routing/#submounting-routes ) .
969979
970980#### SSE servers
@@ -1437,14 +1447,26 @@ _Full example: [examples/snippets/clients/stdio_client.py](https://github.com/mo
14371447
14381448Clients can also connect using [ Streamable HTTP transport] ( https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http ) :
14391449
1450+ <!-- snippet-source examples/snippets/clients/streamable_basic.py -->
14401451``` python
1441- from mcp.client.streamable_http import streamablehttp_client
1452+ """ Basic streamable HTTP client example.
1453+
1454+ This example shows the minimal code needed to connect to
1455+ a streamable HTTP server and call a tool.
1456+
1457+ Run from the repository root:
1458+ uv run examples/snippets/clients/streamable_basic.py
1459+ """
1460+
1461+ import asyncio
1462+
14421463from mcp import ClientSession
1464+ from mcp.client.streamable_http import streamablehttp_client
14431465
14441466
14451467async def main ():
14461468 # Connect to a streamable HTTP server
1447- async with streamablehttp_client(" example /mcp" ) as (
1469+ async with streamablehttp_client(" http://localhost:8000 /mcp" ) as (
14481470 read_stream,
14491471 write_stream,
14501472 _,
@@ -1453,10 +1475,18 @@ async def main():
14531475 async with ClientSession(read_stream, write_stream) as session:
14541476 # Initialize the connection
14551477 await session.initialize()
1456- # Call a tool
1457- tool_result = await session.call_tool(" echo" , {" message" : " hello" })
1478+ # List available tools
1479+ tools = await session.list_tools()
1480+ print (f " Available tools: { [tool.name for tool in tools.tools]} " )
1481+
1482+
1483+ if __name__ == " __main__" :
1484+ asyncio.run(main())
14581485```
14591486
1487+ _ Full example: [ examples/snippets/clients/streamable_basic.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/streamable_basic.py ) _
1488+ <!-- /snippet-source -->
1489+
14601490### Client Display Utilities
14611491
14621492When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts:
0 commit comments