2020from mcp .server .streamable_http import MCP_PROTOCOL_VERSION_HEADER
2121from mcp .shared .auth import OAuthMetadata , ProtectedResourceMetadata
2222
23+ DEFAULT_AUTH_CORS_ORIGIN_REGEX = r"^https?://(localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$"
24+
2325
2426def validate_issuer_url (url : AnyHttpUrl ):
2527 """Validate that the issuer URL meets OAuth 2.0 requirements.
@@ -55,10 +57,17 @@ def validate_issuer_url(url: AnyHttpUrl):
5557def cors_middleware (
5658 handler : Callable [[Request ], Response | Awaitable [Response ]],
5759 allow_methods : list [str ],
60+ * ,
61+ allow_origin_regex : str | None = None ,
5862) -> ASGIApp :
63+ # Default: allow loopback browser clients (e.g., MCP Inspector) without allowing arbitrary sites.
64+ if allow_origin_regex is None :
65+ allow_origin_regex = DEFAULT_AUTH_CORS_ORIGIN_REGEX
66+
5967 cors_app = CORSMiddleware (
6068 app = request_response (handler ),
61- allow_origins = "*" ,
69+ allow_origins = [],
70+ allow_origin_regex = allow_origin_regex ,
6271 allow_methods = allow_methods ,
6372 allow_headers = [MCP_PROTOCOL_VERSION_HEADER ],
6473 )
@@ -71,6 +80,7 @@ def create_auth_routes(
7180 service_documentation_url : AnyHttpUrl | None = None ,
7281 client_registration_options : ClientRegistrationOptions | None = None ,
7382 revocation_options : RevocationOptions | None = None ,
83+ cors_origin_regex : str | None = None ,
7484) -> list [Route ]:
7585 validate_issuer_url (issuer_url )
7686
@@ -94,6 +104,7 @@ def create_auth_routes(
94104 endpoint = cors_middleware (
95105 MetadataHandler (metadata ).handle ,
96106 ["GET" , "OPTIONS" ],
107+ allow_origin_regex = cors_origin_regex ,
97108 ),
98109 methods = ["GET" , "OPTIONS" ],
99110 ),
@@ -109,6 +120,7 @@ def create_auth_routes(
109120 endpoint = cors_middleware (
110121 TokenHandler (provider , client_authenticator ).handle ,
111122 ["POST" , "OPTIONS" ],
123+ allow_origin_regex = cors_origin_regex ,
112124 ),
113125 methods = ["POST" , "OPTIONS" ],
114126 ),
@@ -125,6 +137,7 @@ def create_auth_routes(
125137 endpoint = cors_middleware (
126138 registration_handler .handle ,
127139 ["POST" , "OPTIONS" ],
140+ allow_origin_regex = cors_origin_regex ,
128141 ),
129142 methods = ["POST" , "OPTIONS" ],
130143 )
@@ -138,6 +151,7 @@ def create_auth_routes(
138151 endpoint = cors_middleware (
139152 revocation_handler .handle ,
140153 ["POST" , "OPTIONS" ],
154+ allow_origin_regex = cors_origin_regex ,
141155 ),
142156 methods = ["POST" , "OPTIONS" ],
143157 )
0 commit comments