66
77from typing import Any , Callable , Dict , Optional
88
9- from fastapi import Request , Response
9+ from starlette .requests import Request
10+ from starlette .responses import Response
1011from pydantic import ValidationError
11- from starlette .responses import JSONResponse , Response as StarletteResponse
1212
1313from mcp .server .auth .errors import (
1414 InvalidRequestError ,
1515 ServerError ,
1616 OAuthError ,
1717)
18+ from mcp .server .auth .middleware import client_auth
1819from mcp .server .auth .provider import OAuthServerProvider
1920from mcp .shared .auth import OAuthClientInformationFull , OAuthTokenRevocationRequest
21+ from mcp .server .auth .middleware .client_auth import ClientAuthRequest , ClientAuthenticator
2022
23+ class RevocationRequest (OAuthTokenRevocationRequest , ClientAuthRequest ):
24+ pass
2125
22- def create_revocation_handler (provider : OAuthServerProvider ) -> Callable :
26+ def create_revocation_handler (provider : OAuthServerProvider , client_authenticator : ClientAuthenticator ) -> Callable :
2327 """
2428 Create a handler for OAuth 2.0 Token Revocation.
2529
@@ -29,25 +33,27 @@ def create_revocation_handler(provider: OAuthServerProvider) -> Callable:
2933 provider: The OAuth server provider
3034
3135 Returns:
32- A FastAPI route handler function
36+ A Starlette endpoint handler function
3337 """
3438
35- async def revocation_handler (request : Request , client_auth : OAuthClientInformationFull ) -> Response :
39+ async def revocation_handler (request : Request ) -> Response :
3640 """
3741 Handler for the OAuth 2.0 Token Revocation endpoint.
3842 """
39- # Validate revocation request
4043 try :
41- revocation_request = OAuthTokenRevocationRequest .model_validate_json (await request .body ())
44+ revocation_request = RevocationRequest .model_validate_json (await request .body ())
4245 except ValidationError as e :
43- raise InvalidRequestError (str (e ))
46+ raise InvalidRequestError (f"Invalid request body: { e } " )
47+
48+ # Authenticate client
49+ client_auth_result = await client_authenticator (revocation_request )
4450
4551 # Revoke token
4652 if provider .revoke_token :
47- await provider .revoke_token (client_auth , revocation_request )
53+ await provider .revoke_token (client_auth_result , revocation_request )
4854
4955 # Return successful empty response
50- return StarletteResponse (
56+ return Response (
5157 status_code = 200 ,
5258 headers = {
5359 "Cache-Control" : "no-store" ,
0 commit comments