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
fastmcp/settings.py CHANGED
@@ -1,88 +1,153 @@
1
1
  from __future__ import annotations as _annotations
2
2
 
3
3
  import inspect
4
+ import os
4
5
  import warnings
6
+ from datetime import timedelta
5
7
  from pathlib import Path
6
8
  from typing import TYPE_CHECKING, Annotated, Any, Literal
7
9
 
10
+ from platformdirs import user_data_dir
8
11
  from pydantic import Field, ImportString, field_validator
9
- from pydantic.fields import FieldInfo
10
12
  from pydantic_settings import (
11
13
  BaseSettings,
12
- EnvSettingsSource,
13
- PydanticBaseSettingsSource,
14
14
  SettingsConfigDict,
15
15
  )
16
- from typing_extensions import Self
17
16
 
18
17
  from fastmcp.utilities.logging import get_logger
19
18
 
20
19
  logger = get_logger(__name__)
21
20
 
21
+ ENV_FILE = os.getenv("FASTMCP_ENV_FILE", ".env")
22
+
22
23
  LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
23
24
 
24
25
  DuplicateBehavior = Literal["warn", "error", "replace", "ignore"]
25
26
 
27
+ TEN_MB_IN_BYTES = 1024 * 1024 * 10
28
+
26
29
  if TYPE_CHECKING:
27
30
  from fastmcp.server.auth.auth import AuthProvider
28
31
 
29
32
 
30
- class ExtendedEnvSettingsSource(EnvSettingsSource):
31
- """
32
- A special EnvSettingsSource that allows for multiple env var prefixes to be used.
33
+ class DocketSettings(BaseSettings):
34
+ """Docket worker configuration."""
33
35
 
34
- Raises a deprecation warning if the old `FASTMCP_SERVER_` prefix is used.
35
- """
36
+ model_config = SettingsConfigDict(
37
+ env_prefix="FASTMCP_DOCKET_",
38
+ extra="ignore",
39
+ )
36
40
 
37
- def get_field_value(
38
- self, field: FieldInfo, field_name: str
39
- ) -> tuple[Any, str, bool]:
40
- if prefixes := self.config.get("env_prefixes"):
41
- for prefix in prefixes:
42
- self.env_prefix = prefix
43
- env_val, field_key, value_is_complex = super().get_field_value(
44
- field, field_name
45
- )
46
- if env_val is not None:
47
- if prefix == "FASTMCP_SERVER_":
48
- # Deprecated in 2.8.0
49
- logger.warning(
50
- "Using `FASTMCP_SERVER_` environment variables is deprecated. Use `FASTMCP_` instead.",
51
- )
52
- return env_val, field_key, value_is_complex
41
+ name: Annotated[
42
+ str,
43
+ Field(
44
+ description=inspect.cleandoc(
45
+ """
46
+ Name for the Docket queue. All servers/workers sharing the same name
47
+ and backend URL will share a task queue.
48
+ """
49
+ ),
50
+ ),
51
+ ] = "fastmcp"
53
52
 
54
- return super().get_field_value(field, field_name)
53
+ url: Annotated[
54
+ str,
55
+ Field(
56
+ description=inspect.cleandoc(
57
+ """
58
+ URL for the Docket backend. Supports:
59
+ - memory:// - In-memory backend (single process only)
60
+ - redis://host:port/db - Redis/Valkey backend (distributed, multi-process)
55
61
 
62
+ Example: redis://localhost:6379/0
56
63
 
57
- class ExtendedSettingsConfigDict(SettingsConfigDict, total=False):
58
- env_prefixes: list[str] | None
64
+ Default is memory:// for single-process scenarios. Use Redis or Valkey
65
+ when coordinating tasks across multiple processes (e.g., additional
66
+ workers via the fastmcp tasks CLI).
67
+ """
68
+ ),
69
+ ),
70
+ ] = "memory://"
59
71
 
72
+ worker_name: Annotated[
73
+ str | None,
74
+ Field(
75
+ description=inspect.cleandoc(
76
+ """
77
+ Name for the Docket worker. If None, Docket will auto-generate
78
+ a unique worker name.
79
+ """
80
+ ),
81
+ ),
82
+ ] = None
60
83
 
61
- class ExperimentalSettings(BaseSettings):
62
- model_config = SettingsConfigDict(
63
- env_prefix="FASTMCP_EXPERIMENTAL_",
64
- extra="ignore",
65
- )
84
+ concurrency: Annotated[
85
+ int,
86
+ Field(
87
+ description=inspect.cleandoc(
88
+ """
89
+ Maximum number of tasks the worker can process concurrently.
90
+ """
91
+ ),
92
+ ),
93
+ ] = 10
66
94
 
67
- enable_new_openapi_parser: Annotated[
68
- bool,
95
+ redelivery_timeout: Annotated[
96
+ timedelta,
69
97
  Field(
70
98
  description=inspect.cleandoc(
71
99
  """
72
- Whether to use the new OpenAPI parser. This parser was introduced
73
- for testing in 2.11 and will become the default soon.
100
+ Task redelivery timeout. If a worker doesn't complete
101
+ a task within this time, the task will be redelivered to another
102
+ worker.
74
103
  """
75
104
  ),
76
105
  ),
77
- ] = False
106
+ ] = timedelta(seconds=300)
107
+
108
+ reconnection_delay: Annotated[
109
+ timedelta,
110
+ Field(
111
+ description=inspect.cleandoc(
112
+ """
113
+ Delay between reconnection attempts when the worker
114
+ loses connection to the Docket backend.
115
+ """
116
+ ),
117
+ ),
118
+ ] = timedelta(seconds=5)
119
+
120
+
121
+ class ExperimentalSettings(BaseSettings):
122
+ model_config = SettingsConfigDict(
123
+ env_prefix="FASTMCP_EXPERIMENTAL_",
124
+ extra="ignore",
125
+ validate_assignment=True,
126
+ )
127
+
128
+ # Deprecated in 2.14 - the new OpenAPI parser is now the default and only parser
129
+ enable_new_openapi_parser: bool = False
130
+
131
+ @field_validator("enable_new_openapi_parser", mode="after")
132
+ @classmethod
133
+ def _warn_openapi_parser_deprecated(cls, v: bool) -> bool:
134
+ if v:
135
+ warnings.warn(
136
+ "enable_new_openapi_parser is deprecated. "
137
+ "The new OpenAPI parser is now the default (and only) parser. "
138
+ "You can remove this setting.",
139
+ DeprecationWarning,
140
+ stacklevel=2,
141
+ )
142
+ return v
78
143
 
79
144
 
80
145
  class Settings(BaseSettings):
81
146
  """FastMCP settings."""
82
147
 
83
- model_config = ExtendedSettingsConfigDict(
84
- env_prefixes=["FASTMCP_", "FASTMCP_SERVER_"],
85
- env_file=".env",
148
+ model_config = SettingsConfigDict(
149
+ env_prefix="FASTMCP_",
150
+ env_file=ENV_FILE,
86
151
  extra="ignore",
87
152
  env_nested_delimiter="__",
88
153
  nested_model_default_partial_update=True,
@@ -115,37 +180,7 @@ class Settings(BaseSettings):
115
180
  settings = getattr(settings, parent_attr)
116
181
  setattr(settings, attr, value)
117
182
 
118
- @classmethod
119
- def settings_customise_sources(
120
- cls,
121
- settings_cls: type[BaseSettings],
122
- init_settings: PydanticBaseSettingsSource,
123
- env_settings: PydanticBaseSettingsSource,
124
- dotenv_settings: PydanticBaseSettingsSource,
125
- file_secret_settings: PydanticBaseSettingsSource,
126
- ) -> tuple[PydanticBaseSettingsSource, ...]:
127
- # can remove this classmethod after deprecated FASTMCP_SERVER_ prefix is
128
- # removed
129
- return (
130
- init_settings,
131
- ExtendedEnvSettingsSource(settings_cls),
132
- dotenv_settings,
133
- file_secret_settings,
134
- )
135
-
136
- @property
137
- def settings(self) -> Self:
138
- """
139
- This property is for backwards compatibility with FastMCP < 2.8.0,
140
- which accessed fastmcp.settings.settings
141
- """
142
- # Deprecated in 2.8.0
143
- logger.warning(
144
- "Using fastmcp.settings.settings is deprecated. Use fastmcp.settings instead.",
145
- )
146
- return self
147
-
148
- home: Path = Path.home() / ".fastmcp"
183
+ home: Path = Path(user_data_dir("fastmcp", appauthor=False))
149
184
 
150
185
  test_mode: bool = False
151
186
 
@@ -161,6 +196,8 @@ class Settings(BaseSettings):
161
196
 
162
197
  experimental: ExperimentalSettings = ExperimentalSettings()
163
198
 
199
+ docket: DocketSettings = DocketSettings()
200
+
164
201
  enable_rich_tracebacks: Annotated[
165
202
  bool,
166
203
  Field(
@@ -189,7 +226,6 @@ class Settings(BaseSettings):
189
226
  client_raise_first_exceptiongroup_error: Annotated[
190
227
  bool,
191
228
  Field(
192
- default=True,
193
229
  description=inspect.cleandoc(
194
230
  """
195
231
  Many MCP components operate in anyio taskgroups, and raise
@@ -202,20 +238,6 @@ class Settings(BaseSettings):
202
238
  ),
203
239
  ] = True
204
240
 
205
- resource_prefix_format: Annotated[
206
- Literal["protocol", "path"],
207
- Field(
208
- default="path",
209
- description=inspect.cleandoc(
210
- """
211
- When perfixing a resource URI, either use path formatting (resource://prefix/path)
212
- or protocol formatting (prefix+resource://path). Protocol formatting was the default in FastMCP < 2.4;
213
- path formatting is current default.
214
- """
215
- ),
216
- ),
217
- ] = "path"
218
-
219
241
  client_init_timeout: Annotated[
220
242
  float | None,
221
243
  Field(
@@ -235,7 +257,6 @@ class Settings(BaseSettings):
235
257
  mask_error_details: Annotated[
236
258
  bool,
237
259
  Field(
238
- default=False,
239
260
  description=inspect.cleandoc(
240
261
  """
241
262
  If True, error details from user-supplied functions (tool, resource, prompt)
@@ -248,6 +269,22 @@ class Settings(BaseSettings):
248
269
  ),
249
270
  ] = False
250
271
 
272
+ strict_input_validation: Annotated[
273
+ bool,
274
+ Field(
275
+ description=inspect.cleandoc(
276
+ """
277
+ If True, tool inputs are strictly validated against the input
278
+ JSON schema. For example, providing the string \"10\" to an
279
+ integer field will raise an error. If False, compatible inputs
280
+ will be coerced to match the schema, which can increase
281
+ compatibility. For example, providing the string \"10\" to an
282
+ integer field will be coerced to 10. Defaults to False.
283
+ """
284
+ ),
285
+ ),
286
+ ] = False
287
+
251
288
  server_dependencies: list[str] = Field(
252
289
  default_factory=list,
253
290
  description="List of dependencies to install in the server environment",
@@ -293,7 +330,6 @@ class Settings(BaseSettings):
293
330
  include_tags: Annotated[
294
331
  set[str] | None,
295
332
  Field(
296
- default=None,
297
333
  description=inspect.cleandoc(
298
334
  """
299
335
  If provided, only components that match these tags will be
@@ -306,7 +342,6 @@ class Settings(BaseSettings):
306
342
  exclude_tags: Annotated[
307
343
  set[str] | None,
308
344
  Field(
309
- default=None,
310
345
  description=inspect.cleandoc(
311
346
  """
312
347
  If provided, components that match these tags will be excluded
@@ -320,7 +355,6 @@ class Settings(BaseSettings):
320
355
  include_fastmcp_meta: Annotated[
321
356
  bool,
322
357
  Field(
323
- default=True,
324
358
  description=inspect.cleandoc(
325
359
  """
326
360
  Whether to include FastMCP meta in the server's MCP responses.
@@ -335,7 +369,6 @@ class Settings(BaseSettings):
335
369
  mounted_components_raise_on_load_error: Annotated[
336
370
  bool,
337
371
  Field(
338
- default=False,
339
372
  description=inspect.cleandoc(
340
373
  """
341
374
  If True, errors encountered when loading mounted components (tools, resources, prompts)
@@ -349,7 +382,6 @@ class Settings(BaseSettings):
349
382
  show_cli_banner: Annotated[
350
383
  bool,
351
384
  Field(
352
- default=True,
353
385
  description=inspect.cleandoc(
354
386
  """
355
387
  If True, the server banner will be displayed when running the server via CLI.
@@ -378,23 +410,3 @@ class Settings(BaseSettings):
378
410
  auth_class = type_adapter.validate_python(self.server_auth)
379
411
 
380
412
  return auth_class
381
-
382
-
383
- def __getattr__(name: str):
384
- """
385
- Used to deprecate the module-level Image class; can be removed once it is no longer imported to root.
386
- """
387
- if name == "settings":
388
- import fastmcp
389
-
390
- settings = fastmcp.settings
391
- # Deprecated in 2.10.2
392
- if settings.deprecation_warnings:
393
- warnings.warn(
394
- "`from fastmcp.settings import settings` is deprecated. use `fastmcp.settings` instead.",
395
- DeprecationWarning,
396
- stacklevel=2,
397
- )
398
- return settings
399
-
400
- raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
fastmcp/tools/__init__.py CHANGED
@@ -2,4 +2,4 @@ from .tool import Tool, FunctionTool
2
2
  from .tool_manager import ToolManager
3
3
  from .tool_transform import forward, forward_raw
4
4
 
5
- __all__ = ["Tool", "ToolManager", "FunctionTool", "forward", "forward_raw"]
5
+ __all__ = ["FunctionTool", "Tool", "ToolManager", "forward", "forward_raw"]