@@ -798,88 +798,38 @@ async def main():
798798
799799### OAuth Authentication for Clients
800800
801- The SDK supports OAuth 2.0 client authentication for secure access to MCP servers that require authentication :
801+ The SDK includes OAuth 2.0 support for connecting to protected MCP servers:
802802
803803``` python
804- from mcp.client.auth import UnauthorizedError
805- from mcp.client.oauth_providers import InMemoryOAuthProvider
804+ from mcp.client.auth import OAuthClientProvider
806805from mcp.client.streamable_http import streamablehttp_client
807806from mcp.shared.auth import OAuthClientMetadata
808- from mcp import ClientSession
807+ import webbrowser
809808
810- # Create an OAuth provider
811- oauth_provider = InMemoryOAuthProvider (
812- redirect_url = " http ://localhost:8080/callback " ,
809+ # Set up OAuth authentication
810+ oauth_auth = OAuthClientProvider (
811+ server_url = " https ://api.example.com " ,
813812 client_metadata = OAuthClientMetadata(
814- redirect_uris = [" http://localhost:8080/callback" ],
815- client_name = " My MCP Client" ,
816- scope = " tools resources" , # Request specific scopes
813+ client_name = " My Client" ,
814+ redirect_uris = [" http://localhost:3000/callback" ],
815+ grant_types = [" authorization_code" , " refresh_token" ],
816+ response_types = [" code" ],
817+ scope = " read write"
817818 ),
819+ storage = InMemoryTokenStorage(), # Implement TokenStorage protocol
820+ redirect_handler = lambda url : webbrowser.open(url),
821+ callback_handler = handle_oauth_callback, # Handle OAuth callback
818822)
819823
820-
821- async def main ():
822- # Connect with OAuth authentication
823- async with streamablehttp_client(
824- " https://example.com/mcp" ,
825- auth_provider = oauth_provider,
826- ) as (read_stream, write_stream, _):
827- # Create a session
828- async with ClientSession(read_stream, write_stream) as session:
829- # Initialize (this may trigger OAuth flow)
830- try :
831- await session.initialize()
832- # Use authenticated session
833- result = await session.call_tool(" protected_tool" , {" arg" : " value" })
834- except UnauthorizedError:
835- # Handle authorization required
836- print (" Authorization required. Check your browser." )
837-
838-
839- # Handle OAuth callback after user authorization
840- async def handle_callback (authorization_code : str ):
841- from mcp.client.streamable_http import StreamableHTTPTransport
842-
843- # Create a transport instance to handle auth completion
844- transport = StreamableHTTPTransport(
845- url = " https://example.com/mcp" ,
846- auth_provider = oauth_provider,
847- )
848-
849- # Exchange authorization code for tokens
850- await transport.finish_auth(authorization_code)
851- print (" Authorization successful!" )
852- ```
853-
854- #### Custom OAuth Providers
855-
856- You can implement custom OAuth storage by creating your own provider:
857-
858- ``` python
859- from mcp.client.oauth_providers import InMemoryOAuthProvider
860-
861-
862- class DatabaseOAuthProvider (InMemoryOAuthProvider ):
863- async def save_tokens (self , tokens ):
864- # Save to database
865- # await db.save_tokens(self.client_id, tokens)
866- pass
867-
868- async def tokens (self ):
869- # Load from database
870- # return await db.load_tokens(self.client_id)
871- return None
872-
873- # Implement other methods as needed...
824+ # Use with streamable HTTP client
825+ async with streamablehttp_client(" https://api.example.com/mcp" , auth = oauth_auth) as (read, write, _):
826+ async with ClientSession(read, write) as session:
827+ await session.initialize()
828+ # Authenticated session ready
874829```
875830
876- The OAuth client implementation supports:
831+ For a complete working example, see [ ` examples/clients/simple-auth-client/ ` ] ( examples/clients/simple-auth-client/ ) .
877832
878- - Dynamic client registration
879- - Authorization code flow with PKCE
880- - Token refresh
881- - Multiple storage providers (in-memory and file-based included)
882- - Automatic token management and retry logic
883833
884834### MCP Primitives
885835
0 commit comments