@@ -532,9 +532,7 @@ Client usage:
532
532
533
533
<!-- snippet-source examples/snippets/clients/completion_client.py -->
534
534
``` python
535
- """ MCP client example showing completion usage.
536
-
537
- This example demonstrates how to use the completion feature in MCP clients.
535
+ """
538
536
cd to the `examples/snippets` directory and run:
539
537
uv run completion-client
540
538
"""
@@ -863,72 +861,99 @@ Note that `uv run mcp run` or `uv run mcp dev` only supports server using FastMC
863
861
864
862
> ** Note** : Streamable HTTP transport is superseding SSE transport for production deployments.
865
863
864
+ <!-- snippet-source examples/snippets/servers/streamable_config.py -->
866
865
``` python
866
+ """
867
+ Run from the repository root:
868
+ uv run examples/snippets/servers/streamable_config.py
869
+ """
870
+
867
871
from mcp.server.fastmcp import FastMCP
868
872
869
873
# Stateful server (maintains session state)
870
874
mcp = FastMCP(" StatefulServer" )
871
875
876
+ # Other configuration options:
872
877
# Stateless server (no session persistence)
873
- mcp = FastMCP(" StatelessServer" , stateless_http = True )
878
+ # mcp = FastMCP("StatelessServer", stateless_http=True)
874
879
875
880
# Stateless server (no session persistence, no sse stream with supported client)
876
- mcp = FastMCP(" StatelessServer" , stateless_http = True , json_response = True )
881
+ # mcp = FastMCP("StatelessServer", stateless_http=True, json_response=True)
882
+
883
+
884
+ # Add a simple tool to demonstrate the server
885
+ @mcp.tool ()
886
+ def greet (name : str = " World" ) -> str :
887
+ """ Greet someone by name."""
888
+ return f " Hello, { name} ! "
889
+
877
890
878
891
# Run server with streamable_http transport
879
- mcp.run(transport = " streamable-http" )
892
+ if __name__ == " __main__" :
893
+ mcp.run(transport = " streamable-http" )
880
894
```
881
895
882
- You can mount multiple FastMCP servers in a FastAPI application:
896
+ _ Full example: [ examples/snippets/servers/streamable_config.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_config.py ) _
897
+ <!-- /snippet-source -->
898
+
899
+ You can mount multiple FastMCP servers in a Starlette application:
883
900
901
+ <!-- snippet-source examples/snippets/servers/streamable_starlette_mount.py -->
884
902
``` python
885
- # echo.py
903
+ """
904
+ Run from the repository root:
905
+ uvicorn examples.snippets.servers.streamable_starlette_mount:app --reload
906
+ """
907
+
908
+ import contextlib
909
+
910
+ from starlette.applications import Starlette
911
+ from starlette.routing import Mount
912
+
886
913
from mcp.server.fastmcp import FastMCP
887
914
888
- mcp = FastMCP(name = " EchoServer" , stateless_http = True )
915
+ # Create the Echo server
916
+ echo_mcp = FastMCP(name = " EchoServer" , stateless_http = True )
889
917
890
918
891
- @mcp .tool ()
919
+ @echo_mcp .tool ()
892
920
def echo (message : str ) -> str :
893
921
""" A simple echo tool"""
894
922
return f " Echo: { message} "
895
- ```
896
923
897
- ``` python
898
- # math.py
899
- from mcp.server.fastmcp import FastMCP
900
924
901
- mcp = FastMCP(name = " MathServer" , stateless_http = True )
925
+ # Create the Math server
926
+ math_mcp = FastMCP(name = " MathServer" , stateless_http = True )
902
927
903
928
904
- @mcp .tool ()
929
+ @math_mcp .tool ()
905
930
def add_two (n : int ) -> int :
906
931
""" Tool to add two to the input"""
907
932
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
916
933
917
934
918
935
# Create a combined lifespan to manage both session managers
919
936
@contextlib.asynccontextmanager
920
- async def lifespan (app : FastAPI ):
937
+ async def lifespan (app : Starlette ):
921
938
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())
939
+ await stack.enter_async_context(echo_mcp .session_manager.run())
940
+ await stack.enter_async_context(math_mcp .session_manager.run())
924
941
yield
925
942
926
943
927
- app = FastAPI(lifespan = lifespan)
928
- app.mount(" /echo" , echo.mcp.streamable_http_app())
929
- app.mount(" /math" , math.mcp.streamable_http_app())
944
+ # Create the Starlette app and mount the MCP servers
945
+ app = Starlette(
946
+ routes = [
947
+ Mount(" /echo" , echo_mcp.streamable_http_app()),
948
+ Mount(" /math" , math_mcp.streamable_http_app()),
949
+ ],
950
+ lifespan = lifespan,
951
+ )
930
952
```
931
953
954
+ _ Full example: [ examples/snippets/servers/streamable_starlette_mount.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/streamable_starlette_mount.py ) _
955
+ <!-- /snippet-source -->
956
+
932
957
For low level server with Streamable HTTP implementations, see:
933
958
934
959
- Stateful server: [ ` examples/servers/simple-streamablehttp/ ` ] ( examples/servers/simple-streamablehttp/ )
@@ -945,26 +970,6 @@ The streamable HTTP transport supports:
945
970
946
971
By 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.
947
972
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
-
968
973
For more information on mounting applications in Starlette, see the [ Starlette documentation] ( https://www.starlette.io/routing/#submounting-routes ) .
969
974
970
975
#### SSE servers
@@ -1336,9 +1341,7 @@ The SDK provides a high-level client interface for connecting to MCP servers usi
1336
1341
1337
1342
<!-- snippet-source examples/snippets/clients/stdio_client.py -->
1338
1343
``` python
1339
- """ MCP client example using stdio transport.
1340
-
1341
- This is a documentation example showing how to write an MCP client.
1344
+ """
1342
1345
cd to the `examples/snippets/clients` directory and run:
1343
1346
uv run client
1344
1347
"""
@@ -1428,14 +1431,22 @@ _Full example: [examples/snippets/clients/stdio_client.py](https://github.com/mo
1428
1431
1429
1432
Clients can also connect using [ Streamable HTTP transport] ( https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http ) :
1430
1433
1434
+ <!-- snippet-source examples/snippets/clients/streamable_basic.py -->
1431
1435
``` python
1432
- from mcp.client.streamable_http import streamablehttp_client
1436
+ """
1437
+ Run from the repository root:
1438
+ uv run examples/snippets/clients/streamable_basic.py
1439
+ """
1440
+
1441
+ import asyncio
1442
+
1433
1443
from mcp import ClientSession
1444
+ from mcp.client.streamable_http import streamablehttp_client
1434
1445
1435
1446
1436
1447
async def main ():
1437
1448
# Connect to a streamable HTTP server
1438
- async with streamablehttp_client(" example /mcp" ) as (
1449
+ async with streamablehttp_client(" http://localhost:8000 /mcp" ) as (
1439
1450
read_stream,
1440
1451
write_stream,
1441
1452
_,
@@ -1444,21 +1455,25 @@ async def main():
1444
1455
async with ClientSession(read_stream, write_stream) as session:
1445
1456
# Initialize the connection
1446
1457
await session.initialize()
1447
- # Call a tool
1448
- tool_result = await session.call_tool(" echo" , {" message" : " hello" })
1458
+ # List available tools
1459
+ tools = await session.list_tools()
1460
+ print (f " Available tools: { [tool.name for tool in tools.tools]} " )
1461
+
1462
+
1463
+ if __name__ == " __main__" :
1464
+ asyncio.run(main())
1449
1465
```
1450
1466
1467
+ _ Full example: [ examples/snippets/clients/streamable_basic.py] ( https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/streamable_basic.py ) _
1468
+ <!-- /snippet-source -->
1469
+
1451
1470
### Client Display Utilities
1452
1471
1453
1472
When building MCP clients, the SDK provides utilities to help display human-readable names for tools, resources, and prompts:
1454
1473
1455
1474
<!-- snippet-source examples/snippets/clients/display_utilities.py -->
1456
1475
``` python
1457
- """ Client display utilities example.
1458
-
1459
- This example shows how to use the SDK's display utilities to show
1460
- human-readable names for tools, resources, and prompts.
1461
-
1476
+ """
1462
1477
cd to the `examples/snippets` directory and run:
1463
1478
uv run display-utilities-client
1464
1479
"""
0 commit comments