@@ -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
@@ -631,7 +632,7 @@ server = Server("example-server", lifespan=server_lifespan)
631
632
# Access lifespan context in handlers
632
633
@server.call_tool ()
633
634
async def query_db (name : str , arguments : dict ) -> list :
634
- ctx = server.get_context()
635
+ ctx = server.request_context
635
636
db = ctx.lifespan_context[" db" ]
636
637
return await db.query(arguments[" query" ])
637
638
```
@@ -796,6 +797,60 @@ async def main():
796
797
tool_result = await session.call_tool(" echo" , {" message" : " hello" })
797
798
```
798
799
800
+ ### OAuth Authentication for Clients
801
+
802
+ The SDK includes [ authorization support] ( https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization ) for connecting to protected MCP servers:
803
+
804
+ ``` python
805
+ from mcp.client.auth import OAuthClientProvider, TokenStorage
806
+ from mcp.client.session import ClientSession
807
+ from mcp.client.streamable_http import streamablehttp_client
808
+ from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
809
+
810
+
811
+ class CustomTokenStorage (TokenStorage ):
812
+ """ Simple in-memory token storage implementation."""
813
+
814
+ async def get_tokens (self ) -> OAuthToken | None :
815
+ pass
816
+
817
+ async def set_tokens (self , tokens : OAuthToken) -> None :
818
+ pass
819
+
820
+ async def get_client_info (self ) -> OAuthClientInformationFull | None :
821
+ pass
822
+
823
+ async def set_client_info (self , client_info : OAuthClientInformationFull) -> None :
824
+ pass
825
+
826
+
827
+ async def main ():
828
+ # Set up OAuth authentication
829
+ oauth_auth = OAuthClientProvider(
830
+ server_url = " https://api.example.com" ,
831
+ client_metadata = OAuthClientMetadata(
832
+ client_name = " My Client" ,
833
+ redirect_uris = [" http://localhost:3000/callback" ],
834
+ grant_types = [" authorization_code" , " refresh_token" ],
835
+ response_types = [" code" ],
836
+ ),
837
+ storage = CustomTokenStorage(),
838
+ redirect_handler = lambda url : print (f " Visit: { url} " ),
839
+ callback_handler = lambda : (" auth_code" , None ),
840
+ )
841
+
842
+ # Use with streamable HTTP client
843
+ async with streamablehttp_client(
844
+ " https://api.example.com/mcp" , auth = oauth_auth
845
+ ) as (read, write, _):
846
+ async with ClientSession(read, write) as session:
847
+ await session.initialize()
848
+ # Authenticated session ready
849
+ ```
850
+
851
+ For a complete working example, see [ ` examples/clients/simple-auth-client/ ` ] ( examples/clients/simple-auth-client/ ) .
852
+
853
+
799
854
### MCP Primitives
800
855
801
856
The MCP protocol defines three core primitives that servers can implement:
0 commit comments