fastmcp 2.12.5__py3-none-any.whl → 2.14.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. fastmcp/__init__.py +2 -23
  2. fastmcp/cli/__init__.py +0 -3
  3. fastmcp/cli/__main__.py +5 -0
  4. fastmcp/cli/cli.py +19 -33
  5. fastmcp/cli/install/claude_code.py +6 -6
  6. fastmcp/cli/install/claude_desktop.py +3 -3
  7. fastmcp/cli/install/cursor.py +18 -12
  8. fastmcp/cli/install/gemini_cli.py +3 -3
  9. fastmcp/cli/install/mcp_json.py +3 -3
  10. fastmcp/cli/install/shared.py +0 -15
  11. fastmcp/cli/run.py +13 -8
  12. fastmcp/cli/tasks.py +110 -0
  13. fastmcp/client/__init__.py +9 -9
  14. fastmcp/client/auth/oauth.py +123 -225
  15. fastmcp/client/client.py +697 -95
  16. fastmcp/client/elicitation.py +11 -5
  17. fastmcp/client/logging.py +18 -14
  18. fastmcp/client/messages.py +7 -5
  19. fastmcp/client/oauth_callback.py +85 -171
  20. fastmcp/client/roots.py +2 -1
  21. fastmcp/client/sampling.py +1 -1
  22. fastmcp/client/tasks.py +614 -0
  23. fastmcp/client/transports.py +117 -30
  24. fastmcp/contrib/component_manager/__init__.py +1 -1
  25. fastmcp/contrib/component_manager/component_manager.py +2 -2
  26. fastmcp/contrib/component_manager/component_service.py +10 -26
  27. fastmcp/contrib/mcp_mixin/README.md +32 -1
  28. fastmcp/contrib/mcp_mixin/__init__.py +2 -2
  29. fastmcp/contrib/mcp_mixin/mcp_mixin.py +14 -2
  30. fastmcp/dependencies.py +25 -0
  31. fastmcp/experimental/sampling/handlers/openai.py +3 -3
  32. fastmcp/experimental/server/openapi/__init__.py +20 -21
  33. fastmcp/experimental/utilities/openapi/__init__.py +16 -47
  34. fastmcp/mcp_config.py +3 -4
  35. fastmcp/prompts/__init__.py +1 -1
  36. fastmcp/prompts/prompt.py +54 -51
  37. fastmcp/prompts/prompt_manager.py +16 -101
  38. fastmcp/resources/__init__.py +5 -5
  39. fastmcp/resources/resource.py +43 -21
  40. fastmcp/resources/resource_manager.py +9 -168
  41. fastmcp/resources/template.py +161 -61
  42. fastmcp/resources/types.py +30 -24
  43. fastmcp/server/__init__.py +1 -1
  44. fastmcp/server/auth/__init__.py +9 -14
  45. fastmcp/server/auth/auth.py +197 -46
  46. fastmcp/server/auth/handlers/authorize.py +326 -0
  47. fastmcp/server/auth/jwt_issuer.py +236 -0
  48. fastmcp/server/auth/middleware.py +96 -0
  49. fastmcp/server/auth/oauth_proxy.py +1469 -298
  50. fastmcp/server/auth/oidc_proxy.py +91 -20
  51. fastmcp/server/auth/providers/auth0.py +40 -21
  52. fastmcp/server/auth/providers/aws.py +29 -3
  53. fastmcp/server/auth/providers/azure.py +312 -131
  54. fastmcp/server/auth/providers/debug.py +114 -0
  55. fastmcp/server/auth/providers/descope.py +86 -29
  56. fastmcp/server/auth/providers/discord.py +308 -0
  57. fastmcp/server/auth/providers/github.py +29 -8
  58. fastmcp/server/auth/providers/google.py +48 -9
  59. fastmcp/server/auth/providers/in_memory.py +29 -5
  60. fastmcp/server/auth/providers/introspection.py +281 -0
  61. fastmcp/server/auth/providers/jwt.py +48 -31
  62. fastmcp/server/auth/providers/oci.py +233 -0
  63. fastmcp/server/auth/providers/scalekit.py +238 -0
  64. fastmcp/server/auth/providers/supabase.py +188 -0
  65. fastmcp/server/auth/providers/workos.py +35 -17
  66. fastmcp/server/context.py +236 -116
  67. fastmcp/server/dependencies.py +503 -18
  68. fastmcp/server/elicitation.py +286 -48
  69. fastmcp/server/event_store.py +177 -0
  70. fastmcp/server/http.py +71 -20
  71. fastmcp/server/low_level.py +165 -2
  72. fastmcp/server/middleware/__init__.py +1 -1
  73. fastmcp/server/middleware/caching.py +476 -0
  74. fastmcp/server/middleware/error_handling.py +14 -10
  75. fastmcp/server/middleware/logging.py +50 -39
  76. fastmcp/server/middleware/middleware.py +29 -16
  77. fastmcp/server/middleware/rate_limiting.py +3 -3
  78. fastmcp/server/middleware/tool_injection.py +116 -0
  79. fastmcp/server/openapi/__init__.py +35 -0
  80. fastmcp/{experimental/server → server}/openapi/components.py +15 -10
  81. fastmcp/{experimental/server → server}/openapi/routing.py +3 -3
  82. fastmcp/{experimental/server → server}/openapi/server.py +6 -5
  83. fastmcp/server/proxy.py +72 -48
  84. fastmcp/server/server.py +1415 -733
  85. fastmcp/server/tasks/__init__.py +21 -0
  86. fastmcp/server/tasks/capabilities.py +22 -0
  87. fastmcp/server/tasks/config.py +89 -0
  88. fastmcp/server/tasks/converters.py +205 -0
  89. fastmcp/server/tasks/handlers.py +356 -0
  90. fastmcp/server/tasks/keys.py +93 -0
  91. fastmcp/server/tasks/protocol.py +355 -0
  92. fastmcp/server/tasks/subscriptions.py +205 -0
  93. fastmcp/settings.py +125 -113
  94. fastmcp/tools/__init__.py +1 -1
  95. fastmcp/tools/tool.py +138 -55
  96. fastmcp/tools/tool_manager.py +30 -112
  97. fastmcp/tools/tool_transform.py +12 -21
  98. fastmcp/utilities/cli.py +67 -28
  99. fastmcp/utilities/components.py +10 -5
  100. fastmcp/utilities/inspect.py +79 -23
  101. fastmcp/utilities/json_schema.py +4 -4
  102. fastmcp/utilities/json_schema_type.py +8 -8
  103. fastmcp/utilities/logging.py +118 -8
  104. fastmcp/utilities/mcp_config.py +1 -2
  105. fastmcp/utilities/mcp_server_config/__init__.py +3 -3
  106. fastmcp/utilities/mcp_server_config/v1/environments/base.py +1 -2
  107. fastmcp/utilities/mcp_server_config/v1/environments/uv.py +6 -6
  108. fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +5 -5
  109. fastmcp/utilities/mcp_server_config/v1/schema.json +3 -0
  110. fastmcp/utilities/mcp_server_config/v1/sources/base.py +0 -1
  111. fastmcp/{experimental/utilities → utilities}/openapi/README.md +7 -35
  112. fastmcp/utilities/openapi/__init__.py +63 -0
  113. fastmcp/{experimental/utilities → utilities}/openapi/director.py +14 -15
  114. fastmcp/{experimental/utilities → utilities}/openapi/formatters.py +5 -5
  115. fastmcp/{experimental/utilities → utilities}/openapi/json_schema_converter.py +7 -3
  116. fastmcp/{experimental/utilities → utilities}/openapi/parser.py +37 -16
  117. fastmcp/utilities/tests.py +92 -5
  118. fastmcp/utilities/types.py +86 -16
  119. fastmcp/utilities/ui.py +626 -0
  120. {fastmcp-2.12.5.dist-info → fastmcp-2.14.0.dist-info}/METADATA +24 -15
  121. fastmcp-2.14.0.dist-info/RECORD +156 -0
  122. {fastmcp-2.12.5.dist-info → fastmcp-2.14.0.dist-info}/WHEEL +1 -1
  123. fastmcp/cli/claude.py +0 -135
  124. fastmcp/server/auth/providers/bearer.py +0 -25
  125. fastmcp/server/openapi.py +0 -1083
  126. fastmcp/utilities/openapi.py +0 -1568
  127. fastmcp/utilities/storage.py +0 -204
  128. fastmcp-2.12.5.dist-info/RECORD +0 -134
  129. fastmcp/{experimental/server → server}/openapi/README.md +0 -0
  130. fastmcp/{experimental/utilities → utilities}/openapi/models.py +3 -3
  131. fastmcp/{experimental/utilities → utilities}/openapi/schemas.py +2 -2
  132. {fastmcp-2.12.5.dist-info → fastmcp-2.14.0.dist-info}/entry_points.txt +0 -0
  133. {fastmcp-2.12.5.dist-info → fastmcp-2.14.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,188 @@
1
+ """Supabase authentication provider for FastMCP.
2
+
3
+ This module provides SupabaseProvider - a complete authentication solution that integrates
4
+ with Supabase Auth's JWT verification, supporting Dynamic Client Registration (DCR)
5
+ for seamless MCP client authentication.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Literal
11
+
12
+ import httpx
13
+ from pydantic import AnyHttpUrl, field_validator
14
+ from pydantic_settings import BaseSettings, SettingsConfigDict
15
+ from starlette.responses import JSONResponse
16
+ from starlette.routing import Route
17
+
18
+ from fastmcp.server.auth import RemoteAuthProvider, TokenVerifier
19
+ from fastmcp.server.auth.providers.jwt import JWTVerifier
20
+ from fastmcp.settings import ENV_FILE
21
+ from fastmcp.utilities.auth import parse_scopes
22
+ from fastmcp.utilities.logging import get_logger
23
+ from fastmcp.utilities.types import NotSet, NotSetT
24
+
25
+ logger = get_logger(__name__)
26
+
27
+
28
+ class SupabaseProviderSettings(BaseSettings):
29
+ model_config = SettingsConfigDict(
30
+ env_prefix="FASTMCP_SERVER_AUTH_SUPABASE_",
31
+ env_file=ENV_FILE,
32
+ extra="ignore",
33
+ )
34
+
35
+ project_url: AnyHttpUrl
36
+ base_url: AnyHttpUrl
37
+ algorithm: Literal["HS256", "RS256", "ES256"] = "ES256"
38
+ required_scopes: list[str] | None = None
39
+
40
+ @field_validator("required_scopes", mode="before")
41
+ @classmethod
42
+ def _parse_scopes(cls, v):
43
+ return parse_scopes(v)
44
+
45
+
46
+ class SupabaseProvider(RemoteAuthProvider):
47
+ """Supabase metadata provider for DCR (Dynamic Client Registration).
48
+
49
+ This provider implements Supabase Auth integration using metadata forwarding.
50
+ This approach allows Supabase to handle the OAuth flow directly while FastMCP acts
51
+ as a resource server, verifying JWTs issued by Supabase Auth.
52
+
53
+ IMPORTANT SETUP REQUIREMENTS:
54
+
55
+ 1. Supabase Project Setup:
56
+ - Create a Supabase project at https://supabase.com
57
+ - Note your project URL (e.g., "https://abc123.supabase.co")
58
+ - Configure your JWT algorithm in Supabase Auth settings (HS256, RS256, or ES256)
59
+ - Asymmetric keys (RS256/ES256) are recommended for production
60
+
61
+ 2. JWT Verification:
62
+ - FastMCP verifies JWTs using the JWKS endpoint at {project_url}/auth/v1/.well-known/jwks.json
63
+ - JWTs are issued by {project_url}/auth/v1
64
+ - Tokens are cached for up to 10 minutes by Supabase's edge servers
65
+ - Algorithm must match your Supabase Auth configuration
66
+
67
+ 3. Authorization:
68
+ - Supabase uses Row Level Security (RLS) policies for database authorization
69
+ - OAuth-level scopes are an upcoming feature in Supabase Auth
70
+ - Both approaches will be supported once scope handling is available
71
+
72
+ For detailed setup instructions, see:
73
+ https://supabase.com/docs/guides/auth/jwts
74
+
75
+ Example:
76
+ ```python
77
+ from fastmcp.server.auth.providers.supabase import SupabaseProvider
78
+
79
+ # Create Supabase metadata provider (JWT verifier created automatically)
80
+ supabase_auth = SupabaseProvider(
81
+ project_url="https://abc123.supabase.co",
82
+ base_url="https://your-fastmcp-server.com",
83
+ algorithm="ES256", # Match your Supabase Auth configuration
84
+ )
85
+
86
+ # Use with FastMCP
87
+ mcp = FastMCP("My App", auth=supabase_auth)
88
+ ```
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ *,
94
+ project_url: AnyHttpUrl | str | NotSetT = NotSet,
95
+ base_url: AnyHttpUrl | str | NotSetT = NotSet,
96
+ algorithm: Literal["HS256", "RS256", "ES256"] | NotSetT = NotSet,
97
+ required_scopes: list[str] | NotSetT | None = NotSet,
98
+ token_verifier: TokenVerifier | None = None,
99
+ ):
100
+ """Initialize Supabase metadata provider.
101
+
102
+ Args:
103
+ project_url: Your Supabase project URL (e.g., "https://abc123.supabase.co")
104
+ base_url: Public URL of this FastMCP server
105
+ algorithm: JWT signing algorithm (HS256, RS256, or ES256). Must match your
106
+ Supabase Auth configuration. Defaults to ES256.
107
+ required_scopes: Optional list of scopes to require for all requests.
108
+ Note: Supabase currently uses RLS policies for authorization. OAuth-level
109
+ scopes are an upcoming feature.
110
+ token_verifier: Optional token verifier. If None, creates JWT verifier for Supabase
111
+ """
112
+ settings = SupabaseProviderSettings.model_validate(
113
+ {
114
+ k: v
115
+ for k, v in {
116
+ "project_url": project_url,
117
+ "base_url": base_url,
118
+ "algorithm": algorithm,
119
+ "required_scopes": required_scopes,
120
+ }.items()
121
+ if v is not NotSet
122
+ }
123
+ )
124
+
125
+ self.project_url = str(settings.project_url).rstrip("/")
126
+ self.base_url = AnyHttpUrl(str(settings.base_url).rstrip("/"))
127
+
128
+ # Create default JWT verifier if none provided
129
+ if token_verifier is None:
130
+ token_verifier = JWTVerifier(
131
+ jwks_uri=f"{self.project_url}/auth/v1/.well-known/jwks.json",
132
+ issuer=f"{self.project_url}/auth/v1",
133
+ algorithm=settings.algorithm,
134
+ required_scopes=settings.required_scopes,
135
+ )
136
+
137
+ # Initialize RemoteAuthProvider with Supabase as the authorization server
138
+ super().__init__(
139
+ token_verifier=token_verifier,
140
+ authorization_servers=[AnyHttpUrl(f"{self.project_url}/auth/v1")],
141
+ base_url=self.base_url,
142
+ )
143
+
144
+ def get_routes(
145
+ self,
146
+ mcp_path: str | None = None,
147
+ ) -> list[Route]:
148
+ """Get OAuth routes including Supabase authorization server metadata forwarding.
149
+
150
+ This returns the standard protected resource routes plus an authorization server
151
+ metadata endpoint that forwards Supabase's OAuth metadata to clients.
152
+
153
+ Args:
154
+ mcp_path: The path where the MCP endpoint is mounted (e.g., "/mcp")
155
+ This is used to advertise the resource URL in metadata.
156
+ """
157
+ # Get the standard protected resource routes from RemoteAuthProvider
158
+ routes = super().get_routes(mcp_path)
159
+
160
+ async def oauth_authorization_server_metadata(request):
161
+ """Forward Supabase OAuth authorization server metadata with FastMCP customizations."""
162
+ try:
163
+ async with httpx.AsyncClient() as client:
164
+ response = await client.get(
165
+ f"{self.project_url}/auth/v1/.well-known/oauth-authorization-server"
166
+ )
167
+ response.raise_for_status()
168
+ metadata = response.json()
169
+ return JSONResponse(metadata)
170
+ except Exception as e:
171
+ return JSONResponse(
172
+ {
173
+ "error": "server_error",
174
+ "error_description": f"Failed to fetch Supabase metadata: {e}",
175
+ },
176
+ status_code=500,
177
+ )
178
+
179
+ # Add Supabase authorization server metadata forwarding
180
+ routes.append(
181
+ Route(
182
+ "/.well-known/oauth-authorization-server",
183
+ endpoint=oauth_authorization_server_metadata,
184
+ methods=["GET"],
185
+ )
186
+ )
187
+
188
+ return routes
@@ -10,9 +10,8 @@ Choose based on your WorkOS setup and authentication requirements.
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- from typing import Any
14
-
15
13
  import httpx
14
+ from key_value.aio.protocols import AsyncKeyValue
16
15
  from pydantic import AnyHttpUrl, SecretStr, field_validator
17
16
  from pydantic_settings import BaseSettings, SettingsConfigDict
18
17
  from starlette.responses import JSONResponse
@@ -21,9 +20,9 @@ from starlette.routing import Route
21
20
  from fastmcp.server.auth import AccessToken, RemoteAuthProvider, TokenVerifier
22
21
  from fastmcp.server.auth.oauth_proxy import OAuthProxy
23
22
  from fastmcp.server.auth.providers.jwt import JWTVerifier
23
+ from fastmcp.settings import ENV_FILE
24
24
  from fastmcp.utilities.auth import parse_scopes
25
25
  from fastmcp.utilities.logging import get_logger
26
- from fastmcp.utilities.storage import KVStorage
27
26
  from fastmcp.utilities.types import NotSet, NotSetT
28
27
 
29
28
  logger = get_logger(__name__)
@@ -34,7 +33,7 @@ class WorkOSProviderSettings(BaseSettings):
34
33
 
35
34
  model_config = SettingsConfigDict(
36
35
  env_prefix="FASTMCP_SERVER_AUTH_WORKOS_",
37
- env_file=".env",
36
+ env_file=ENV_FILE,
38
37
  extra="ignore",
39
38
  )
40
39
 
@@ -42,10 +41,12 @@ class WorkOSProviderSettings(BaseSettings):
42
41
  client_secret: SecretStr | None = None
43
42
  authkit_domain: str | None = None # e.g., "https://your-app.authkit.app"
44
43
  base_url: AnyHttpUrl | str | None = None
44
+ issuer_url: AnyHttpUrl | str | None = None
45
45
  redirect_path: str | None = None
46
46
  required_scopes: list[str] | None = None
47
47
  timeout_seconds: int | None = None
48
48
  allowed_client_redirect_uris: list[str] | None = None
49
+ jwt_signing_key: str | None = None
49
50
 
50
51
  @field_validator("required_scopes", mode="before")
51
52
  @classmethod
@@ -166,11 +167,14 @@ class WorkOSProvider(OAuthProxy):
166
167
  client_secret: str | NotSetT = NotSet,
167
168
  authkit_domain: str | NotSetT = NotSet,
168
169
  base_url: AnyHttpUrl | str | NotSetT = NotSet,
170
+ issuer_url: AnyHttpUrl | str | NotSetT = NotSet,
169
171
  redirect_path: str | NotSetT = NotSet,
170
- required_scopes: list[str] | None | NotSetT = NotSet,
172
+ required_scopes: list[str] | NotSetT | None = NotSet,
171
173
  timeout_seconds: int | NotSetT = NotSet,
172
174
  allowed_client_redirect_uris: list[str] | NotSetT = NotSet,
173
- client_storage: KVStorage | None = None,
175
+ client_storage: AsyncKeyValue | None = None,
176
+ jwt_signing_key: str | bytes | NotSetT = NotSet,
177
+ require_authorization_consent: bool = True,
174
178
  ):
175
179
  """Initialize WorkOS OAuth provider.
176
180
 
@@ -178,14 +182,24 @@ class WorkOSProvider(OAuthProxy):
178
182
  client_id: WorkOS client ID
179
183
  client_secret: WorkOS client secret
180
184
  authkit_domain: Your WorkOS AuthKit domain (e.g., "https://your-app.authkit.app")
181
- base_url: Public URL of your FastMCP server (for OAuth callbacks)
185
+ base_url: Public URL where OAuth endpoints will be accessible (includes any mount path)
186
+ issuer_url: Issuer URL for OAuth metadata (defaults to base_url). Use root-level URL
187
+ to avoid 404s during discovery when mounting under a path.
182
188
  redirect_path: Redirect path configured in WorkOS (defaults to "/auth/callback")
183
189
  required_scopes: Required OAuth scopes (no default)
184
190
  timeout_seconds: HTTP request timeout for WorkOS API calls
185
191
  allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients.
186
192
  If None (default), all URIs are allowed. If empty list, no URIs are allowed.
187
- client_storage: Storage implementation for OAuth client registrations.
188
- Defaults to file-based storage if not specified.
193
+ client_storage: Storage backend for OAuth state (client registrations, encrypted tokens).
194
+ If None, a DiskStore will be created in the data directory (derived from `platformdirs`). The
195
+ disk store will be encrypted using a key derived from the JWT Signing Key.
196
+ jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). If bytes are provided,
197
+ they will be used as is. If a string is provided, it will be derived into a 32-byte key. If not
198
+ provided, the upstream client secret will be used to derive a 32-byte key using PBKDF2.
199
+ require_authorization_consent: Whether to require user consent before authorizing clients (default True).
200
+ When True, users see a consent screen before being redirected to WorkOS.
201
+ When False, authorization proceeds directly without user confirmation.
202
+ SECURITY WARNING: Only disable for local development or testing environments.
189
203
  """
190
204
 
191
205
  settings = WorkOSProviderSettings.model_validate(
@@ -196,10 +210,12 @@ class WorkOSProvider(OAuthProxy):
196
210
  "client_secret": client_secret,
197
211
  "authkit_domain": authkit_domain,
198
212
  "base_url": base_url,
213
+ "issuer_url": issuer_url,
199
214
  "redirect_path": redirect_path,
200
215
  "required_scopes": required_scopes,
201
216
  "timeout_seconds": timeout_seconds,
202
217
  "allowed_client_redirect_uris": allowed_client_redirect_uris,
218
+ "jwt_signing_key": jwt_signing_key,
203
219
  }.items()
204
220
  if v is not NotSet
205
221
  }
@@ -249,12 +265,15 @@ class WorkOSProvider(OAuthProxy):
249
265
  token_verifier=token_verifier,
250
266
  base_url=settings.base_url,
251
267
  redirect_path=settings.redirect_path,
252
- issuer_url=settings.base_url,
268
+ issuer_url=settings.issuer_url
269
+ or settings.base_url, # Default to base_url if not specified
253
270
  allowed_client_redirect_uris=allowed_client_redirect_uris_final,
254
271
  client_storage=client_storage,
272
+ jwt_signing_key=settings.jwt_signing_key,
273
+ require_authorization_consent=require_authorization_consent,
255
274
  )
256
275
 
257
- logger.info(
276
+ logger.debug(
258
277
  "Initialized WorkOS OAuth provider for client %s with AuthKit domain %s",
259
278
  settings.client_id,
260
279
  authkit_domain_final,
@@ -264,7 +283,7 @@ class WorkOSProvider(OAuthProxy):
264
283
  class AuthKitProviderSettings(BaseSettings):
265
284
  model_config = SettingsConfigDict(
266
285
  env_prefix="FASTMCP_SERVER_AUTH_AUTHKITPROVIDER_",
267
- env_file=".env",
286
+ env_file=ENV_FILE,
268
287
  extra="ignore",
269
288
  )
270
289
 
@@ -319,7 +338,7 @@ class AuthKitProvider(RemoteAuthProvider):
319
338
  *,
320
339
  authkit_domain: AnyHttpUrl | str | NotSetT = NotSet,
321
340
  base_url: AnyHttpUrl | str | NotSetT = NotSet,
322
- required_scopes: list[str] | None | NotSetT = NotSet,
341
+ required_scopes: list[str] | NotSetT | None = NotSet,
323
342
  token_verifier: TokenVerifier | None = None,
324
343
  ):
325
344
  """Initialize AuthKit metadata provider.
@@ -343,7 +362,7 @@ class AuthKitProvider(RemoteAuthProvider):
343
362
  )
344
363
 
345
364
  self.authkit_domain = str(settings.authkit_domain).rstrip("/")
346
- self.base_url = str(settings.base_url).rstrip("/")
365
+ self.base_url = AnyHttpUrl(str(settings.base_url).rstrip("/"))
347
366
 
348
367
  # Create default JWT verifier if none provided
349
368
  if token_verifier is None:
@@ -364,7 +383,6 @@ class AuthKitProvider(RemoteAuthProvider):
364
383
  def get_routes(
365
384
  self,
366
385
  mcp_path: str | None = None,
367
- mcp_endpoint: Any | None = None,
368
386
  ) -> list[Route]:
369
387
  """Get OAuth routes including AuthKit authorization server metadata forwarding.
370
388
 
@@ -373,10 +391,10 @@ class AuthKitProvider(RemoteAuthProvider):
373
391
 
374
392
  Args:
375
393
  mcp_path: The path where the MCP endpoint is mounted (e.g., "/mcp")
376
- mcp_endpoint: The MCP endpoint handler to protect with auth
394
+ This is used to advertise the resource URL in metadata.
377
395
  """
378
396
  # Get the standard protected resource routes from RemoteAuthProvider
379
- routes = super().get_routes(mcp_path, mcp_endpoint)
397
+ routes = super().get_routes(mcp_path)
380
398
 
381
399
  async def oauth_authorization_server_metadata(request):
382
400
  """Forward AuthKit OAuth authorization server metadata with FastMCP customizations."""