@@ -824,11 +824,10 @@ async def handle_sse(scope: Scope, receive: Receive, send: Send):
824824 # Determine resource metadata URL
825825 resource_metadata_url = None
826826 if self .settings .auth and self .settings .auth .resource_server_url :
827- from pydantic import AnyHttpUrl
827+ from mcp . server . auth . routes import build_resource_metadata_url
828828
829- resource_metadata_url = AnyHttpUrl (
830- str (self .settings .auth .resource_server_url ).rstrip ("/" ) + "/.well-known/oauth-protected-resource"
831- )
829+ # Build compliant metadata URL for WWW-Authenticate header
830+ resource_metadata_url = build_resource_metadata_url (self .settings .auth .resource_server_url )
832831
833832 # Auth is enabled, wrap the endpoints with RequireAuthMiddleware
834833 routes .append (
@@ -937,18 +936,10 @@ def streamable_http_app(self) -> Starlette:
937936 # Determine resource metadata URL
938937 resource_metadata_url = None
939938 if self .settings .auth and self .settings .auth .resource_server_url :
940- from urllib .parse import urlparse
941-
942- from pydantic import AnyHttpUrl
939+ from mcp .server .auth .routes import build_resource_metadata_url
943940
944- # RFC 9728 §3.1: Insert /.well-known/oauth-protected-resource between host and resource path
945- # This URL will be used in WWW-Authenticate header for client discovery
946- parsed = urlparse (str (self .settings .auth .resource_server_url ))
947- # Handle trailing slash: if path is just "/", treat as empty
948- resource_path = parsed .path if parsed .path != "/" else ""
949- resource_metadata_url = AnyHttpUrl (
950- f"{ parsed .scheme } ://{ parsed .netloc } /.well-known/oauth-protected-resource{ resource_path } "
951- )
941+ # Build compliant metadata URL for WWW-Authenticate header
942+ resource_metadata_url = build_resource_metadata_url (self .settings .auth .resource_server_url )
952943
953944 routes .append (
954945 Route (
@@ -967,32 +958,13 @@ def streamable_http_app(self) -> Starlette:
967958
968959 # Add protected resource metadata endpoint if configured as RS
969960 if self .settings .auth and self .settings .auth .resource_server_url :
970- from urllib .parse import urlparse
971-
972- from mcp .server .auth .handlers .metadata import ProtectedResourceMetadataHandler
973- from mcp .server .auth .routes import cors_middleware
974- from mcp .shared .auth import ProtectedResourceMetadata
975-
976- protected_resource_metadata = ProtectedResourceMetadata (
977- resource = self .settings .auth .resource_server_url ,
978- authorization_servers = [self .settings .auth .issuer_url ],
979- scopes_supported = self .settings .auth .required_scopes ,
980- )
981-
982- # RFC 9728 §3.1: Register route at /.well-known/oauth-protected-resource + resource path
983- parsed = urlparse (str (self .settings .auth .resource_server_url ))
984- # Handle trailing slash: if path is just "/", treat as empty
985- resource_path = parsed .path if parsed .path != "/" else ""
986- well_known_path = f"/.well-known/oauth-protected-resource{ resource_path } "
961+ from mcp .server .auth .routes import create_protected_resource_routes
987962
988- routes .append (
989- Route (
990- well_known_path ,
991- endpoint = cors_middleware (
992- ProtectedResourceMetadataHandler (protected_resource_metadata ).handle ,
993- ["GET" , "OPTIONS" ],
994- ),
995- methods = ["GET" , "OPTIONS" ],
963+ routes .extend (
964+ create_protected_resource_routes (
965+ resource_url = self .settings .auth .resource_server_url ,
966+ authorization_servers = [self .settings .auth .issuer_url ],
967+ scopes_supported = self .settings .auth .required_scopes ,
996968 )
997969 )
998970
0 commit comments