@@ -160,7 +160,7 @@ from dataclasses import dataclass
160
160
161
161
from fake_database import Database # Replace with your actual DB type
162
162
163
- from mcp.server.fastmcp import Context, FastMCP
163
+ from mcp.server.fastmcp import FastMCP
164
164
165
165
# Create a named server
166
166
mcp = FastMCP(" My App" )
@@ -192,9 +192,10 @@ mcp = FastMCP("My App", lifespan=app_lifespan)
192
192
193
193
# Access type-safe lifespan context in tools
194
194
@mcp.tool ()
195
- def query_db (ctx : Context ) -> str :
195
+ def query_db () -> str :
196
196
""" Tool that uses initialized resources"""
197
- db = ctx.request_context.lifespan_context.db
197
+ ctx = mcp.get_context()
198
+ db = ctx.request_context.lifespan_context[" db" ]
198
199
return db.query()
199
200
```
200
201
@@ -314,27 +315,42 @@ async def long_task(files: list[str], ctx: Context) -> str:
314
315
Authentication can be used by servers that want to expose tools accessing protected resources.
315
316
316
317
` mcp.server.auth ` implements an OAuth 2.0 server interface, which servers can use by
317
- providing an implementation of the ` OAuthServerProvider ` protocol.
318
+ providing an implementation of the ` OAuthAuthorizationServerProvider ` protocol.
318
319
319
- ```
320
- mcp = FastMCP("My App",
321
- auth_server_provider=MyOAuthServerProvider(),
322
- auth=AuthSettings(
323
- issuer_url="https://myapp.com",
324
- revocation_options=RevocationOptions(
325
- enabled=True,
326
- ),
327
- client_registration_options=ClientRegistrationOptions(
328
- enabled=True,
329
- valid_scopes=["myscope", "myotherscope"],
330
- default_scopes=["myscope"],
331
- ),
332
- required_scopes=["myscope"],
320
+ ``` python
321
+ from mcp import FastMCP
322
+ from mcp.server.auth.provider import OAuthAuthorizationServerProvider
323
+ from mcp.server.auth.settings import (
324
+ AuthSettings,
325
+ ClientRegistrationOptions,
326
+ RevocationOptions,
327
+ )
328
+
329
+
330
+ class MyOAuthServerProvider (OAuthAuthorizationServerProvider ):
331
+ # See an example on how to implement at `examples/servers/simple-auth`
332
+ ...
333
+
334
+
335
+ mcp = FastMCP(
336
+ " My App" ,
337
+ auth_server_provider = MyOAuthServerProvider(),
338
+ auth = AuthSettings(
339
+ issuer_url = " https://myapp.com" ,
340
+ revocation_options = RevocationOptions(
341
+ enabled = True ,
342
+ ),
343
+ client_registration_options = ClientRegistrationOptions(
344
+ enabled = True ,
345
+ valid_scopes = [" myscope" , " myotherscope" ],
346
+ default_scopes = [" myscope" ],
333
347
),
348
+ required_scopes = [" myscope" ],
349
+ ),
334
350
)
335
351
```
336
352
337
- See [ OAuthServerProvider ] ( src/mcp/server/auth/provider.py ) for more details.
353
+ See [ OAuthAuthorizationServerProvider ] ( src/mcp/server/auth/provider.py ) for more details.
338
354
339
355
## Running Your Server
340
356
@@ -461,15 +477,12 @@ For low level server with Streamable HTTP implementations, see:
461
477
- Stateful server: [ ` examples/servers/simple-streamablehttp/ ` ] ( examples/servers/simple-streamablehttp/ )
462
478
- Stateless server: [ ` examples/servers/simple-streamablehttp-stateless/ ` ] ( examples/servers/simple-streamablehttp-stateless/ )
463
479
464
-
465
-
466
480
The streamable HTTP transport supports:
467
481
- Stateful and stateless operation modes
468
482
- Resumability with event stores
469
- - JSON or SSE response formats
483
+ - JSON or SSE response formats
470
484
- Better scalability for multi-node deployments
471
485
472
-
473
486
### Mounting to an Existing ASGI Server
474
487
475
488
> ** Note** : SSE transport is being superseded by [ Streamable HTTP transport] ( https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http ) .
@@ -631,7 +644,7 @@ server = Server("example-server", lifespan=server_lifespan)
631
644
# Access lifespan context in handlers
632
645
@server.call_tool ()
633
646
async def query_db (name : str , arguments : dict ) -> list :
634
- ctx = server.get_context()
647
+ ctx = server.request_context
635
648
db = ctx.lifespan_context[" db" ]
636
649
return await db.query(arguments[" query" ])
637
650
```
@@ -796,6 +809,60 @@ async def main():
796
809
tool_result = await session.call_tool(" echo" , {" message" : " hello" })
797
810
```
798
811
812
+ ### OAuth Authentication for Clients
813
+
814
+ The SDK includes [ authorization support] ( https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization ) for connecting to protected MCP servers:
815
+
816
+ ``` python
817
+ from mcp.client.auth import OAuthClientProvider, TokenStorage
818
+ from mcp.client.session import ClientSession
819
+ from mcp.client.streamable_http import streamablehttp_client
820
+ from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
821
+
822
+
823
+ class CustomTokenStorage (TokenStorage ):
824
+ """ Simple in-memory token storage implementation."""
825
+
826
+ async def get_tokens (self ) -> OAuthToken | None :
827
+ pass
828
+
829
+ async def set_tokens (self , tokens : OAuthToken) -> None :
830
+ pass
831
+
832
+ async def get_client_info (self ) -> OAuthClientInformationFull | None :
833
+ pass
834
+
835
+ async def set_client_info (self , client_info : OAuthClientInformationFull) -> None :
836
+ pass
837
+
838
+
839
+ async def main ():
840
+ # Set up OAuth authentication
841
+ oauth_auth = OAuthClientProvider(
842
+ server_url = " https://api.example.com" ,
843
+ client_metadata = OAuthClientMetadata(
844
+ client_name = " My Client" ,
845
+ redirect_uris = [" http://localhost:3000/callback" ],
846
+ grant_types = [" authorization_code" , " refresh_token" ],
847
+ response_types = [" code" ],
848
+ ),
849
+ storage = CustomTokenStorage(),
850
+ redirect_handler = lambda url : print (f " Visit: { url} " ),
851
+ callback_handler = lambda : (" auth_code" , None ),
852
+ )
853
+
854
+ # Use with streamable HTTP client
855
+ async with streamablehttp_client(
856
+ " https://api.example.com/mcp" , auth = oauth_auth
857
+ ) as (read, write, _):
858
+ async with ClientSession(read, write) as session:
859
+ await session.initialize()
860
+ # Authenticated session ready
861
+ ```
862
+
863
+ For a complete working example, see [ ` examples/clients/simple-auth-client/ ` ] ( examples/clients/simple-auth-client/ ) .
864
+
865
+
799
866
### MCP Primitives
800
867
801
868
The MCP protocol defines three core primitives that servers can implement:
0 commit comments