fastmcp 2.12.1__py3-none-any.whl → 2.13.2__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 (109) hide show
  1. fastmcp/__init__.py +2 -2
  2. fastmcp/cli/cli.py +56 -36
  3. fastmcp/cli/install/__init__.py +2 -0
  4. fastmcp/cli/install/claude_code.py +7 -16
  5. fastmcp/cli/install/claude_desktop.py +4 -12
  6. fastmcp/cli/install/cursor.py +20 -30
  7. fastmcp/cli/install/gemini_cli.py +241 -0
  8. fastmcp/cli/install/mcp_json.py +4 -12
  9. fastmcp/cli/run.py +15 -94
  10. fastmcp/client/__init__.py +9 -9
  11. fastmcp/client/auth/oauth.py +117 -206
  12. fastmcp/client/client.py +123 -47
  13. fastmcp/client/elicitation.py +6 -1
  14. fastmcp/client/logging.py +18 -14
  15. fastmcp/client/oauth_callback.py +85 -171
  16. fastmcp/client/sampling.py +1 -1
  17. fastmcp/client/transports.py +81 -26
  18. fastmcp/contrib/component_manager/__init__.py +1 -1
  19. fastmcp/contrib/component_manager/component_manager.py +2 -2
  20. fastmcp/contrib/component_manager/component_service.py +7 -7
  21. fastmcp/contrib/mcp_mixin/README.md +35 -4
  22. fastmcp/contrib/mcp_mixin/__init__.py +2 -2
  23. fastmcp/contrib/mcp_mixin/mcp_mixin.py +54 -7
  24. fastmcp/experimental/sampling/handlers/openai.py +2 -2
  25. fastmcp/experimental/server/openapi/__init__.py +5 -8
  26. fastmcp/experimental/server/openapi/components.py +11 -7
  27. fastmcp/experimental/server/openapi/routing.py +2 -2
  28. fastmcp/experimental/utilities/openapi/__init__.py +10 -15
  29. fastmcp/experimental/utilities/openapi/director.py +16 -10
  30. fastmcp/experimental/utilities/openapi/json_schema_converter.py +6 -2
  31. fastmcp/experimental/utilities/openapi/models.py +3 -3
  32. fastmcp/experimental/utilities/openapi/parser.py +37 -16
  33. fastmcp/experimental/utilities/openapi/schemas.py +33 -7
  34. fastmcp/mcp_config.py +3 -4
  35. fastmcp/prompts/__init__.py +1 -1
  36. fastmcp/prompts/prompt.py +32 -27
  37. fastmcp/prompts/prompt_manager.py +16 -101
  38. fastmcp/resources/__init__.py +5 -5
  39. fastmcp/resources/resource.py +28 -20
  40. fastmcp/resources/resource_manager.py +9 -168
  41. fastmcp/resources/template.py +119 -27
  42. fastmcp/resources/types.py +30 -24
  43. fastmcp/server/__init__.py +1 -1
  44. fastmcp/server/auth/__init__.py +9 -5
  45. fastmcp/server/auth/auth.py +80 -47
  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 +1556 -265
  50. fastmcp/server/auth/oidc_proxy.py +412 -0
  51. fastmcp/server/auth/providers/auth0.py +193 -0
  52. fastmcp/server/auth/providers/aws.py +263 -0
  53. fastmcp/server/auth/providers/azure.py +314 -129
  54. fastmcp/server/auth/providers/bearer.py +1 -1
  55. fastmcp/server/auth/providers/debug.py +114 -0
  56. fastmcp/server/auth/providers/descope.py +229 -0
  57. fastmcp/server/auth/providers/discord.py +308 -0
  58. fastmcp/server/auth/providers/github.py +31 -6
  59. fastmcp/server/auth/providers/google.py +50 -7
  60. fastmcp/server/auth/providers/in_memory.py +27 -3
  61. fastmcp/server/auth/providers/introspection.py +281 -0
  62. fastmcp/server/auth/providers/jwt.py +48 -31
  63. fastmcp/server/auth/providers/oci.py +233 -0
  64. fastmcp/server/auth/providers/scalekit.py +238 -0
  65. fastmcp/server/auth/providers/supabase.py +188 -0
  66. fastmcp/server/auth/providers/workos.py +37 -15
  67. fastmcp/server/context.py +194 -67
  68. fastmcp/server/dependencies.py +56 -16
  69. fastmcp/server/elicitation.py +1 -1
  70. fastmcp/server/http.py +57 -18
  71. fastmcp/server/low_level.py +121 -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 +158 -116
  76. fastmcp/server/middleware/middleware.py +30 -16
  77. fastmcp/server/middleware/rate_limiting.py +3 -3
  78. fastmcp/server/middleware/tool_injection.py +116 -0
  79. fastmcp/server/openapi.py +15 -7
  80. fastmcp/server/proxy.py +22 -11
  81. fastmcp/server/server.py +744 -254
  82. fastmcp/settings.py +65 -15
  83. fastmcp/tools/__init__.py +1 -1
  84. fastmcp/tools/tool.py +173 -108
  85. fastmcp/tools/tool_manager.py +30 -112
  86. fastmcp/tools/tool_transform.py +13 -11
  87. fastmcp/utilities/cli.py +67 -28
  88. fastmcp/utilities/components.py +7 -2
  89. fastmcp/utilities/inspect.py +79 -23
  90. fastmcp/utilities/json_schema.py +21 -4
  91. fastmcp/utilities/json_schema_type.py +4 -4
  92. fastmcp/utilities/logging.py +182 -10
  93. fastmcp/utilities/mcp_server_config/__init__.py +3 -3
  94. fastmcp/utilities/mcp_server_config/v1/environments/base.py +1 -2
  95. fastmcp/utilities/mcp_server_config/v1/environments/uv.py +10 -45
  96. fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +8 -7
  97. fastmcp/utilities/mcp_server_config/v1/schema.json +5 -1
  98. fastmcp/utilities/mcp_server_config/v1/sources/base.py +0 -1
  99. fastmcp/utilities/openapi.py +11 -11
  100. fastmcp/utilities/tests.py +93 -10
  101. fastmcp/utilities/types.py +87 -21
  102. fastmcp/utilities/ui.py +626 -0
  103. {fastmcp-2.12.1.dist-info → fastmcp-2.13.2.dist-info}/METADATA +141 -60
  104. fastmcp-2.13.2.dist-info/RECORD +144 -0
  105. {fastmcp-2.12.1.dist-info → fastmcp-2.13.2.dist-info}/WHEEL +1 -1
  106. fastmcp/cli/claude.py +0 -144
  107. fastmcp-2.12.1.dist-info/RECORD +0 -128
  108. {fastmcp-2.12.1.dist-info → fastmcp-2.13.2.dist-info}/entry_points.txt +0 -0
  109. {fastmcp-2.12.1.dist-info → fastmcp-2.13.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,263 @@
1
+ """AWS Cognito OAuth provider for FastMCP.
2
+
3
+ This module provides a complete AWS Cognito OAuth integration that's ready to use
4
+ with a user pool ID, domain prefix, client ID and client secret. It handles all
5
+ the complexity of AWS Cognito's OAuth flow, token validation, and user management.
6
+
7
+ Example:
8
+ ```python
9
+ from fastmcp import FastMCP
10
+ from fastmcp.server.auth.providers.aws_cognito import AWSCognitoProvider
11
+
12
+ # Simple AWS Cognito OAuth protection
13
+ auth = AWSCognitoProvider(
14
+ user_pool_id="your-user-pool-id",
15
+ aws_region="eu-central-1",
16
+ client_id="your-cognito-client-id",
17
+ client_secret="your-cognito-client-secret"
18
+ )
19
+
20
+ mcp = FastMCP("My Protected Server", auth=auth)
21
+ ```
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from key_value.aio.protocols import AsyncKeyValue
27
+ from pydantic import AnyHttpUrl, SecretStr, field_validator
28
+ from pydantic_settings import BaseSettings, SettingsConfigDict
29
+
30
+ from fastmcp.server.auth import TokenVerifier
31
+ from fastmcp.server.auth.auth import AccessToken
32
+ from fastmcp.server.auth.oidc_proxy import OIDCProxy
33
+ from fastmcp.server.auth.providers.jwt import JWTVerifier
34
+ from fastmcp.settings import ENV_FILE
35
+ from fastmcp.utilities.auth import parse_scopes
36
+ from fastmcp.utilities.logging import get_logger
37
+ from fastmcp.utilities.types import NotSet, NotSetT
38
+
39
+ logger = get_logger(__name__)
40
+
41
+
42
+ class AWSCognitoProviderSettings(BaseSettings):
43
+ """Settings for AWS Cognito OAuth provider."""
44
+
45
+ model_config = SettingsConfigDict(
46
+ env_prefix="FASTMCP_SERVER_AUTH_AWS_COGNITO_",
47
+ env_file=ENV_FILE,
48
+ extra="ignore",
49
+ )
50
+
51
+ user_pool_id: str | None = None
52
+ aws_region: str | None = None
53
+ client_id: str | None = None
54
+ client_secret: SecretStr | None = None
55
+ base_url: AnyHttpUrl | str | None = None
56
+ issuer_url: AnyHttpUrl | str | None = None
57
+ redirect_path: str | None = None
58
+ required_scopes: list[str] | None = None
59
+ allowed_client_redirect_uris: list[str] | None = None
60
+ jwt_signing_key: str | None = None
61
+
62
+ @field_validator("required_scopes", mode="before")
63
+ @classmethod
64
+ def _parse_scopes(cls, v):
65
+ return parse_scopes(v)
66
+
67
+
68
+ class AWSCognitoTokenVerifier(JWTVerifier):
69
+ """Token verifier that filters claims to Cognito-specific subset."""
70
+
71
+ async def verify_token(self, token: str) -> AccessToken | None:
72
+ """Verify token and filter claims to Cognito-specific subset."""
73
+ # Use base JWT verification
74
+ access_token = await super().verify_token(token)
75
+ if not access_token:
76
+ return None
77
+
78
+ # Filter claims to Cognito-specific subset
79
+ cognito_claims = {
80
+ "sub": access_token.claims.get("sub"),
81
+ "username": access_token.claims.get("username"),
82
+ "cognito:groups": access_token.claims.get("cognito:groups", []),
83
+ }
84
+
85
+ # Return new AccessToken with filtered claims
86
+ return AccessToken(
87
+ token=access_token.token,
88
+ client_id=access_token.client_id,
89
+ scopes=access_token.scopes,
90
+ expires_at=access_token.expires_at,
91
+ claims=cognito_claims,
92
+ )
93
+
94
+
95
+ class AWSCognitoProvider(OIDCProxy):
96
+ """Complete AWS Cognito OAuth provider for FastMCP.
97
+
98
+ This provider makes it trivial to add AWS Cognito OAuth protection to any
99
+ FastMCP server using OIDC Discovery. Just provide your Cognito User Pool details,
100
+ client credentials, and a base URL, and you're ready to go.
101
+
102
+ Features:
103
+ - Automatic OIDC Discovery from AWS Cognito User Pool
104
+ - Automatic JWT token validation via Cognito's public keys
105
+ - Cognito-specific claim filtering (sub, username, cognito:groups)
106
+ - Support for Cognito User Pools
107
+
108
+ Example:
109
+ ```python
110
+ from fastmcp import FastMCP
111
+ from fastmcp.server.auth.providers.aws_cognito import AWSCognitoProvider
112
+
113
+ auth = AWSCognitoProvider(
114
+ user_pool_id="eu-central-1_XXXXXXXXX",
115
+ aws_region="eu-central-1",
116
+ client_id="your-cognito-client-id",
117
+ client_secret="your-cognito-client-secret",
118
+ base_url="https://my-server.com",
119
+ redirect_path="/custom/callback",
120
+ )
121
+
122
+ mcp = FastMCP("My App", auth=auth)
123
+ ```
124
+ """
125
+
126
+ def __init__(
127
+ self,
128
+ *,
129
+ user_pool_id: str | NotSetT = NotSet,
130
+ aws_region: str | NotSetT = NotSet,
131
+ client_id: str | NotSetT = NotSet,
132
+ client_secret: str | NotSetT = NotSet,
133
+ base_url: AnyHttpUrl | str | NotSetT = NotSet,
134
+ issuer_url: AnyHttpUrl | str | NotSetT = NotSet,
135
+ redirect_path: str | NotSetT = NotSet,
136
+ required_scopes: list[str] | NotSetT = NotSet,
137
+ allowed_client_redirect_uris: list[str] | NotSetT = NotSet,
138
+ client_storage: AsyncKeyValue | None = None,
139
+ jwt_signing_key: str | bytes | NotSetT = NotSet,
140
+ require_authorization_consent: bool = True,
141
+ ):
142
+ """Initialize AWS Cognito OAuth provider.
143
+
144
+ Args:
145
+ user_pool_id: Your Cognito User Pool ID (e.g., "eu-central-1_XXXXXXXXX")
146
+ aws_region: AWS region where your User Pool is located (defaults to "eu-central-1")
147
+ client_id: Cognito app client ID
148
+ client_secret: Cognito app client secret
149
+ base_url: Public URL where OAuth endpoints will be accessible (includes any mount path)
150
+ issuer_url: Issuer URL for OAuth metadata (defaults to base_url). Use root-level URL
151
+ to avoid 404s during discovery when mounting under a path.
152
+ redirect_path: Redirect path configured in Cognito app (defaults to "/auth/callback")
153
+ required_scopes: Required Cognito scopes (defaults to ["openid"])
154
+ allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients.
155
+ If None (default), all URIs are allowed. If empty list, no URIs are allowed.
156
+ client_storage: Storage backend for OAuth state (client registrations, encrypted tokens).
157
+ If None, a DiskStore will be created in the data directory (derived from `platformdirs`). The
158
+ disk store will be encrypted using a key derived from the JWT Signing Key.
159
+ jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). If bytes are provided,
160
+ they will be used as is. If a string is provided, it will be derived into a 32-byte key. If not
161
+ provided, the upstream client secret will be used to derive a 32-byte key using PBKDF2.
162
+ require_authorization_consent: Whether to require user consent before authorizing clients (default True).
163
+ When True, users see a consent screen before being redirected to AWS Cognito.
164
+ When False, authorization proceeds directly without user confirmation.
165
+ SECURITY WARNING: Only disable for local development or testing environments.
166
+ """
167
+
168
+ settings = AWSCognitoProviderSettings.model_validate(
169
+ {
170
+ k: v
171
+ for k, v in {
172
+ "user_pool_id": user_pool_id,
173
+ "aws_region": aws_region,
174
+ "client_id": client_id,
175
+ "client_secret": client_secret,
176
+ "base_url": base_url,
177
+ "issuer_url": issuer_url,
178
+ "redirect_path": redirect_path,
179
+ "required_scopes": required_scopes,
180
+ "allowed_client_redirect_uris": allowed_client_redirect_uris,
181
+ "jwt_signing_key": jwt_signing_key,
182
+ }.items()
183
+ if v is not NotSet
184
+ }
185
+ )
186
+
187
+ # Validate required settings
188
+ if not settings.user_pool_id:
189
+ raise ValueError(
190
+ "user_pool_id is required - set via parameter or FASTMCP_SERVER_AUTH_AWS_COGNITO_USER_POOL_ID"
191
+ )
192
+ if not settings.client_id:
193
+ raise ValueError(
194
+ "client_id is required - set via parameter or FASTMCP_SERVER_AUTH_AWS_COGNITO_CLIENT_ID"
195
+ )
196
+ if not settings.client_secret:
197
+ raise ValueError(
198
+ "client_secret is required - set via parameter or FASTMCP_SERVER_AUTH_AWS_COGNITO_CLIENT_SECRET"
199
+ )
200
+
201
+ # Apply defaults
202
+ required_scopes_final = settings.required_scopes or ["openid"]
203
+ allowed_client_redirect_uris_final = settings.allowed_client_redirect_uris
204
+ aws_region_final = settings.aws_region or "eu-central-1"
205
+ redirect_path_final = settings.redirect_path or "/auth/callback"
206
+
207
+ # Construct OIDC discovery URL
208
+ config_url = f"https://cognito-idp.{aws_region_final}.amazonaws.com/{settings.user_pool_id}/.well-known/openid-configuration"
209
+
210
+ # Extract secret string from SecretStr
211
+ client_secret_str = (
212
+ settings.client_secret.get_secret_value() if settings.client_secret else ""
213
+ )
214
+
215
+ # Store Cognito-specific info for claim filtering
216
+ self.user_pool_id = settings.user_pool_id
217
+ self.aws_region = aws_region_final
218
+
219
+ # Initialize OIDC proxy with Cognito discovery
220
+ super().__init__(
221
+ config_url=config_url,
222
+ client_id=settings.client_id,
223
+ client_secret=client_secret_str,
224
+ algorithm="RS256",
225
+ required_scopes=required_scopes_final,
226
+ base_url=settings.base_url,
227
+ issuer_url=settings.issuer_url,
228
+ redirect_path=redirect_path_final,
229
+ allowed_client_redirect_uris=allowed_client_redirect_uris_final,
230
+ client_storage=client_storage,
231
+ jwt_signing_key=settings.jwt_signing_key,
232
+ require_authorization_consent=require_authorization_consent,
233
+ )
234
+
235
+ logger.debug(
236
+ "Initialized AWS Cognito OAuth provider for client %s with scopes: %s",
237
+ settings.client_id,
238
+ required_scopes_final,
239
+ )
240
+
241
+ def get_token_verifier(
242
+ self,
243
+ *,
244
+ algorithm: str | None = None,
245
+ audience: str | None = None,
246
+ required_scopes: list[str] | None = None,
247
+ timeout_seconds: int | None = None,
248
+ ) -> TokenVerifier:
249
+ """Creates a Cognito-specific token verifier with claim filtering.
250
+
251
+ Args:
252
+ algorithm: Optional token verifier algorithm
253
+ audience: Optional token verifier audience
254
+ required_scopes: Optional token verifier required_scopes
255
+ timeout_seconds: HTTP request timeout in seconds
256
+ """
257
+ return AWSCognitoTokenVerifier(
258
+ issuer=str(self.oidc_config.issuer),
259
+ audience=audience,
260
+ algorithm=algorithm,
261
+ jwks_uri=str(self.oidc_config.jwks_uri),
262
+ required_scopes=required_scopes,
263
+ )