fastmcp 2.14.4__py3-none-any.whl → 3.0.0b1__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 (175) hide show
  1. fastmcp/_vendor/__init__.py +1 -0
  2. fastmcp/_vendor/docket_di/README.md +7 -0
  3. fastmcp/_vendor/docket_di/__init__.py +163 -0
  4. fastmcp/cli/cli.py +112 -28
  5. fastmcp/cli/install/claude_code.py +1 -5
  6. fastmcp/cli/install/claude_desktop.py +1 -5
  7. fastmcp/cli/install/cursor.py +1 -5
  8. fastmcp/cli/install/gemini_cli.py +1 -5
  9. fastmcp/cli/install/mcp_json.py +1 -6
  10. fastmcp/cli/run.py +146 -5
  11. fastmcp/client/__init__.py +7 -9
  12. fastmcp/client/auth/oauth.py +18 -17
  13. fastmcp/client/client.py +100 -870
  14. fastmcp/client/elicitation.py +1 -1
  15. fastmcp/client/mixins/__init__.py +13 -0
  16. fastmcp/client/mixins/prompts.py +295 -0
  17. fastmcp/client/mixins/resources.py +325 -0
  18. fastmcp/client/mixins/task_management.py +157 -0
  19. fastmcp/client/mixins/tools.py +397 -0
  20. fastmcp/client/sampling/handlers/anthropic.py +2 -2
  21. fastmcp/client/sampling/handlers/openai.py +1 -1
  22. fastmcp/client/tasks.py +3 -3
  23. fastmcp/client/telemetry.py +47 -0
  24. fastmcp/client/transports/__init__.py +38 -0
  25. fastmcp/client/transports/base.py +82 -0
  26. fastmcp/client/transports/config.py +170 -0
  27. fastmcp/client/transports/http.py +145 -0
  28. fastmcp/client/transports/inference.py +154 -0
  29. fastmcp/client/transports/memory.py +90 -0
  30. fastmcp/client/transports/sse.py +89 -0
  31. fastmcp/client/transports/stdio.py +543 -0
  32. fastmcp/contrib/component_manager/README.md +4 -10
  33. fastmcp/contrib/component_manager/__init__.py +1 -2
  34. fastmcp/contrib/component_manager/component_manager.py +95 -160
  35. fastmcp/contrib/component_manager/example.py +1 -1
  36. fastmcp/contrib/mcp_mixin/example.py +4 -4
  37. fastmcp/contrib/mcp_mixin/mcp_mixin.py +11 -4
  38. fastmcp/decorators.py +41 -0
  39. fastmcp/dependencies.py +12 -1
  40. fastmcp/exceptions.py +4 -0
  41. fastmcp/experimental/server/openapi/__init__.py +18 -15
  42. fastmcp/mcp_config.py +13 -4
  43. fastmcp/prompts/__init__.py +6 -3
  44. fastmcp/prompts/function_prompt.py +465 -0
  45. fastmcp/prompts/prompt.py +321 -271
  46. fastmcp/resources/__init__.py +5 -3
  47. fastmcp/resources/function_resource.py +335 -0
  48. fastmcp/resources/resource.py +325 -115
  49. fastmcp/resources/template.py +215 -43
  50. fastmcp/resources/types.py +27 -12
  51. fastmcp/server/__init__.py +2 -2
  52. fastmcp/server/auth/__init__.py +14 -0
  53. fastmcp/server/auth/auth.py +30 -10
  54. fastmcp/server/auth/authorization.py +190 -0
  55. fastmcp/server/auth/oauth_proxy/__init__.py +14 -0
  56. fastmcp/server/auth/oauth_proxy/consent.py +361 -0
  57. fastmcp/server/auth/oauth_proxy/models.py +178 -0
  58. fastmcp/server/auth/{oauth_proxy.py → oauth_proxy/proxy.py} +24 -778
  59. fastmcp/server/auth/oauth_proxy/ui.py +277 -0
  60. fastmcp/server/auth/oidc_proxy.py +2 -2
  61. fastmcp/server/auth/providers/auth0.py +24 -94
  62. fastmcp/server/auth/providers/aws.py +26 -95
  63. fastmcp/server/auth/providers/azure.py +41 -129
  64. fastmcp/server/auth/providers/descope.py +18 -49
  65. fastmcp/server/auth/providers/discord.py +25 -86
  66. fastmcp/server/auth/providers/github.py +23 -87
  67. fastmcp/server/auth/providers/google.py +24 -87
  68. fastmcp/server/auth/providers/introspection.py +60 -79
  69. fastmcp/server/auth/providers/jwt.py +30 -67
  70. fastmcp/server/auth/providers/oci.py +47 -110
  71. fastmcp/server/auth/providers/scalekit.py +23 -61
  72. fastmcp/server/auth/providers/supabase.py +18 -47
  73. fastmcp/server/auth/providers/workos.py +34 -127
  74. fastmcp/server/context.py +372 -419
  75. fastmcp/server/dependencies.py +541 -251
  76. fastmcp/server/elicitation.py +20 -18
  77. fastmcp/server/event_store.py +3 -3
  78. fastmcp/server/http.py +16 -6
  79. fastmcp/server/lifespan.py +198 -0
  80. fastmcp/server/low_level.py +92 -2
  81. fastmcp/server/middleware/__init__.py +5 -1
  82. fastmcp/server/middleware/authorization.py +312 -0
  83. fastmcp/server/middleware/caching.py +101 -54
  84. fastmcp/server/middleware/middleware.py +6 -9
  85. fastmcp/server/middleware/ping.py +70 -0
  86. fastmcp/server/middleware/tool_injection.py +2 -2
  87. fastmcp/server/mixins/__init__.py +7 -0
  88. fastmcp/server/mixins/lifespan.py +217 -0
  89. fastmcp/server/mixins/mcp_operations.py +392 -0
  90. fastmcp/server/mixins/transport.py +342 -0
  91. fastmcp/server/openapi/__init__.py +41 -21
  92. fastmcp/server/openapi/components.py +16 -339
  93. fastmcp/server/openapi/routing.py +34 -118
  94. fastmcp/server/openapi/server.py +67 -392
  95. fastmcp/server/providers/__init__.py +71 -0
  96. fastmcp/server/providers/aggregate.py +261 -0
  97. fastmcp/server/providers/base.py +578 -0
  98. fastmcp/server/providers/fastmcp_provider.py +674 -0
  99. fastmcp/server/providers/filesystem.py +226 -0
  100. fastmcp/server/providers/filesystem_discovery.py +327 -0
  101. fastmcp/server/providers/local_provider/__init__.py +11 -0
  102. fastmcp/server/providers/local_provider/decorators/__init__.py +15 -0
  103. fastmcp/server/providers/local_provider/decorators/prompts.py +256 -0
  104. fastmcp/server/providers/local_provider/decorators/resources.py +240 -0
  105. fastmcp/server/providers/local_provider/decorators/tools.py +315 -0
  106. fastmcp/server/providers/local_provider/local_provider.py +465 -0
  107. fastmcp/server/providers/openapi/__init__.py +39 -0
  108. fastmcp/server/providers/openapi/components.py +332 -0
  109. fastmcp/server/providers/openapi/provider.py +405 -0
  110. fastmcp/server/providers/openapi/routing.py +109 -0
  111. fastmcp/server/providers/proxy.py +867 -0
  112. fastmcp/server/providers/skills/__init__.py +59 -0
  113. fastmcp/server/providers/skills/_common.py +101 -0
  114. fastmcp/server/providers/skills/claude_provider.py +44 -0
  115. fastmcp/server/providers/skills/directory_provider.py +153 -0
  116. fastmcp/server/providers/skills/skill_provider.py +432 -0
  117. fastmcp/server/providers/skills/vendor_providers.py +142 -0
  118. fastmcp/server/providers/wrapped_provider.py +140 -0
  119. fastmcp/server/proxy.py +34 -700
  120. fastmcp/server/sampling/run.py +341 -2
  121. fastmcp/server/sampling/sampling_tool.py +4 -3
  122. fastmcp/server/server.py +1214 -2171
  123. fastmcp/server/tasks/__init__.py +2 -1
  124. fastmcp/server/tasks/capabilities.py +13 -1
  125. fastmcp/server/tasks/config.py +66 -3
  126. fastmcp/server/tasks/handlers.py +65 -273
  127. fastmcp/server/tasks/keys.py +4 -6
  128. fastmcp/server/tasks/requests.py +474 -0
  129. fastmcp/server/tasks/routing.py +76 -0
  130. fastmcp/server/tasks/subscriptions.py +20 -11
  131. fastmcp/server/telemetry.py +131 -0
  132. fastmcp/server/transforms/__init__.py +244 -0
  133. fastmcp/server/transforms/namespace.py +193 -0
  134. fastmcp/server/transforms/prompts_as_tools.py +175 -0
  135. fastmcp/server/transforms/resources_as_tools.py +190 -0
  136. fastmcp/server/transforms/tool_transform.py +96 -0
  137. fastmcp/server/transforms/version_filter.py +124 -0
  138. fastmcp/server/transforms/visibility.py +526 -0
  139. fastmcp/settings.py +34 -96
  140. fastmcp/telemetry.py +122 -0
  141. fastmcp/tools/__init__.py +10 -3
  142. fastmcp/tools/function_parsing.py +201 -0
  143. fastmcp/tools/function_tool.py +467 -0
  144. fastmcp/tools/tool.py +215 -362
  145. fastmcp/tools/tool_transform.py +38 -21
  146. fastmcp/utilities/async_utils.py +69 -0
  147. fastmcp/utilities/components.py +152 -91
  148. fastmcp/utilities/inspect.py +8 -20
  149. fastmcp/utilities/json_schema.py +12 -5
  150. fastmcp/utilities/json_schema_type.py +17 -15
  151. fastmcp/utilities/lifespan.py +56 -0
  152. fastmcp/utilities/logging.py +12 -4
  153. fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +3 -3
  154. fastmcp/utilities/openapi/parser.py +3 -3
  155. fastmcp/utilities/pagination.py +80 -0
  156. fastmcp/utilities/skills.py +253 -0
  157. fastmcp/utilities/tests.py +0 -16
  158. fastmcp/utilities/timeout.py +47 -0
  159. fastmcp/utilities/types.py +1 -1
  160. fastmcp/utilities/versions.py +285 -0
  161. {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/METADATA +8 -5
  162. fastmcp-3.0.0b1.dist-info/RECORD +228 -0
  163. fastmcp/client/transports.py +0 -1170
  164. fastmcp/contrib/component_manager/component_service.py +0 -209
  165. fastmcp/prompts/prompt_manager.py +0 -117
  166. fastmcp/resources/resource_manager.py +0 -338
  167. fastmcp/server/tasks/converters.py +0 -206
  168. fastmcp/server/tasks/protocol.py +0 -359
  169. fastmcp/tools/tool_manager.py +0 -170
  170. fastmcp/utilities/mcp_config.py +0 -56
  171. fastmcp-2.14.4.dist-info/RECORD +0 -161
  172. /fastmcp/server/{openapi → providers/openapi}/README.md +0 -0
  173. {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/WHEEL +0 -0
  174. {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/entry_points.txt +0 -0
  175. {fastmcp-2.14.4.dist-info → fastmcp-3.0.0b1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,315 @@
1
+ """Tool decorator mixin for LocalProvider.
2
+
3
+ This module provides the ToolDecoratorMixin class that adds tool
4
+ registration functionality to LocalProvider.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import inspect
10
+ import warnings
11
+ from collections.abc import Callable
12
+ from functools import partial
13
+ from typing import TYPE_CHECKING, Any, Literal, overload
14
+
15
+ import mcp.types
16
+ from mcp.types import AnyFunction, ToolAnnotations
17
+
18
+ import fastmcp
19
+ from fastmcp.server.tasks.config import TaskConfig
20
+ from fastmcp.tools.function_tool import FunctionTool
21
+ from fastmcp.tools.tool import AuthCheckCallable, Tool
22
+ from fastmcp.utilities.types import NotSet, NotSetT
23
+
24
+ if TYPE_CHECKING:
25
+ from fastmcp.server.providers.local_provider import LocalProvider
26
+ from fastmcp.tools.tool import ToolResultSerializerType
27
+
28
+ DuplicateBehavior = Literal["error", "warn", "replace", "ignore"]
29
+
30
+
31
+ class ToolDecoratorMixin:
32
+ """Mixin class providing tool decorator functionality for LocalProvider.
33
+
34
+ This mixin contains all methods related to:
35
+ - Tool registration via add_tool()
36
+ - Tool decorator (@provider.tool)
37
+ """
38
+
39
+ def add_tool(self: LocalProvider, tool: Tool | Callable[..., Any]) -> Tool:
40
+ """Add a tool to this provider's storage.
41
+
42
+ Accepts either a Tool object or a decorated function with __fastmcp__ metadata.
43
+ """
44
+ enabled = True
45
+ if not isinstance(tool, Tool):
46
+ from fastmcp.decorators import get_fastmcp_meta
47
+ from fastmcp.tools.function_tool import ToolMeta
48
+
49
+ meta = get_fastmcp_meta(tool)
50
+ if meta is not None and isinstance(meta, ToolMeta):
51
+ resolved_task = meta.task if meta.task is not None else False
52
+ enabled = meta.enabled
53
+ tool = Tool.from_function(
54
+ tool,
55
+ name=meta.name,
56
+ version=meta.version,
57
+ title=meta.title,
58
+ description=meta.description,
59
+ icons=meta.icons,
60
+ tags=meta.tags,
61
+ output_schema=meta.output_schema,
62
+ annotations=meta.annotations,
63
+ meta=meta.meta,
64
+ task=resolved_task,
65
+ exclude_args=meta.exclude_args,
66
+ serializer=meta.serializer,
67
+ timeout=meta.timeout,
68
+ auth=meta.auth,
69
+ )
70
+ else:
71
+ tool = Tool.from_function(tool)
72
+ self._add_component(tool)
73
+ if not enabled:
74
+ self.disable(keys={tool.key})
75
+ return tool
76
+
77
+ @overload
78
+ def tool(
79
+ self: LocalProvider,
80
+ name_or_fn: AnyFunction,
81
+ *,
82
+ name: str | None = None,
83
+ version: str | int | None = None,
84
+ title: str | None = None,
85
+ description: str | None = None,
86
+ icons: list[mcp.types.Icon] | None = None,
87
+ tags: set[str] | None = None,
88
+ output_schema: dict[str, Any] | NotSetT | None = NotSet,
89
+ annotations: ToolAnnotations | dict[str, Any] | None = None,
90
+ exclude_args: list[str] | None = None,
91
+ meta: dict[str, Any] | None = None,
92
+ enabled: bool = True,
93
+ task: bool | TaskConfig | None = None,
94
+ serializer: ToolResultSerializerType | None = None, # Deprecated
95
+ timeout: float | None = None,
96
+ auth: AuthCheckCallable | list[AuthCheckCallable] | None = None,
97
+ ) -> FunctionTool: ...
98
+
99
+ @overload
100
+ def tool(
101
+ self: LocalProvider,
102
+ name_or_fn: str | None = None,
103
+ *,
104
+ name: str | None = None,
105
+ version: str | int | None = None,
106
+ title: str | None = None,
107
+ description: str | None = None,
108
+ icons: list[mcp.types.Icon] | None = None,
109
+ tags: set[str] | None = None,
110
+ output_schema: dict[str, Any] | NotSetT | None = NotSet,
111
+ annotations: ToolAnnotations | dict[str, Any] | None = None,
112
+ exclude_args: list[str] | None = None,
113
+ meta: dict[str, Any] | None = None,
114
+ enabled: bool = True,
115
+ task: bool | TaskConfig | None = None,
116
+ serializer: ToolResultSerializerType | None = None, # Deprecated
117
+ timeout: float | None = None,
118
+ auth: AuthCheckCallable | list[AuthCheckCallable] | None = None,
119
+ ) -> Callable[[AnyFunction], FunctionTool]: ...
120
+
121
+ # NOTE: This method mirrors fastmcp.tools.tool() but adds registration,
122
+ # the `enabled` param, and supports deprecated params (serializer, exclude_args).
123
+ # When deprecated params are removed, this should delegate to the standalone
124
+ # decorator to reduce duplication.
125
+ def tool(
126
+ self: LocalProvider,
127
+ name_or_fn: str | AnyFunction | None = None,
128
+ *,
129
+ name: str | None = None,
130
+ version: str | int | None = None,
131
+ title: str | None = None,
132
+ description: str | None = None,
133
+ icons: list[mcp.types.Icon] | None = None,
134
+ tags: set[str] | None = None,
135
+ output_schema: dict[str, Any] | NotSetT | None = NotSet,
136
+ annotations: ToolAnnotations | dict[str, Any] | None = None,
137
+ exclude_args: list[str] | None = None,
138
+ meta: dict[str, Any] | None = None,
139
+ enabled: bool = True,
140
+ task: bool | TaskConfig | None = None,
141
+ serializer: ToolResultSerializerType | None = None, # Deprecated
142
+ timeout: float | None = None,
143
+ auth: AuthCheckCallable | list[AuthCheckCallable] | None = None,
144
+ ) -> (
145
+ Callable[[AnyFunction], FunctionTool]
146
+ | FunctionTool
147
+ | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
148
+ ):
149
+ """Decorator to register a tool.
150
+
151
+ This decorator supports multiple calling patterns:
152
+ - @provider.tool (without parentheses)
153
+ - @provider.tool() (with empty parentheses)
154
+ - @provider.tool("custom_name") (with name as first argument)
155
+ - @provider.tool(name="custom_name") (with name as keyword argument)
156
+ - provider.tool(function, name="custom_name") (direct function call)
157
+
158
+ Args:
159
+ name_or_fn: Either a function (when used as @tool), a string name, or None
160
+ name: Optional name for the tool (keyword-only, alternative to name_or_fn)
161
+ title: Optional title for the tool
162
+ description: Optional description of what the tool does
163
+ icons: Optional icons for the tool
164
+ tags: Optional set of tags for categorizing the tool
165
+ output_schema: Optional JSON schema for the tool's output
166
+ annotations: Optional annotations about the tool's behavior
167
+ exclude_args: Optional list of argument names to exclude from the tool schema
168
+ meta: Optional meta information about the tool
169
+ enabled: Whether the tool is enabled (default True). If False, adds to blocklist.
170
+ task: Optional task configuration for background execution
171
+ serializer: Deprecated. Return ToolResult from your tools for full control over serialization.
172
+
173
+ Returns:
174
+ The registered FunctionTool or a decorator function.
175
+
176
+ Example:
177
+ ```python
178
+ provider = LocalProvider()
179
+
180
+ @provider.tool
181
+ def greet(name: str) -> str:
182
+ return f"Hello, {name}!"
183
+
184
+ @provider.tool("custom_name")
185
+ def my_tool(x: int) -> str:
186
+ return str(x)
187
+ ```
188
+ """
189
+ if serializer is not None and fastmcp.settings.deprecation_warnings:
190
+ warnings.warn(
191
+ "The `serializer` parameter is deprecated. "
192
+ "Return ToolResult from your tools for full control over serialization. "
193
+ "See https://gofastmcp.com/servers/tools#custom-serialization for migration examples.",
194
+ DeprecationWarning,
195
+ stacklevel=2,
196
+ )
197
+ if isinstance(annotations, dict):
198
+ annotations = ToolAnnotations(**annotations)
199
+
200
+ if isinstance(name_or_fn, classmethod):
201
+ raise TypeError(
202
+ "To decorate a classmethod, use @classmethod above @tool. "
203
+ "See https://gofastmcp.com/servers/tools#using-with-methods"
204
+ )
205
+
206
+ def decorate_and_register(
207
+ fn: AnyFunction, tool_name: str | None
208
+ ) -> FunctionTool | AnyFunction:
209
+ # Check for unbound method
210
+ try:
211
+ params = list(inspect.signature(fn).parameters.keys())
212
+ except (ValueError, TypeError):
213
+ params = []
214
+ if params and params[0] in ("self", "cls"):
215
+ fn_name = getattr(fn, "__name__", "function")
216
+ raise TypeError(
217
+ f"The function '{fn_name}' has '{params[0]}' as its first parameter. "
218
+ f"Use the standalone @tool decorator and register the bound method:\n\n"
219
+ f" from fastmcp.tools import tool\n\n"
220
+ f" class MyClass:\n"
221
+ f" @tool\n"
222
+ f" def {fn_name}(...):\n"
223
+ f" ...\n\n"
224
+ f" obj = MyClass()\n"
225
+ f" mcp.add_tool(obj.{fn_name})\n\n"
226
+ f"See https://gofastmcp.com/servers/tools#using-with-methods"
227
+ )
228
+
229
+ resolved_task: bool | TaskConfig = task if task is not None else False
230
+
231
+ if fastmcp.settings.decorator_mode == "object":
232
+ tool_obj = Tool.from_function(
233
+ fn,
234
+ name=tool_name,
235
+ version=version,
236
+ title=title,
237
+ description=description,
238
+ icons=icons,
239
+ tags=tags,
240
+ output_schema=output_schema,
241
+ annotations=annotations,
242
+ exclude_args=exclude_args,
243
+ meta=meta,
244
+ serializer=serializer,
245
+ task=resolved_task,
246
+ timeout=timeout,
247
+ auth=auth,
248
+ )
249
+ self._add_component(tool_obj)
250
+ if not enabled:
251
+ self.disable(keys={tool_obj.key})
252
+ return tool_obj
253
+ else:
254
+ from fastmcp.tools.function_tool import ToolMeta
255
+
256
+ metadata = ToolMeta(
257
+ name=tool_name,
258
+ version=version,
259
+ title=title,
260
+ description=description,
261
+ icons=icons,
262
+ tags=tags,
263
+ output_schema=output_schema,
264
+ annotations=annotations,
265
+ meta=meta,
266
+ task=task,
267
+ exclude_args=exclude_args,
268
+ serializer=serializer,
269
+ timeout=timeout,
270
+ auth=auth,
271
+ enabled=enabled,
272
+ )
273
+ target = fn.__func__ if hasattr(fn, "__func__") else fn
274
+ target.__fastmcp__ = metadata # type: ignore[attr-defined]
275
+ tool_obj = self.add_tool(fn)
276
+ return fn
277
+
278
+ if inspect.isroutine(name_or_fn):
279
+ return decorate_and_register(name_or_fn, name)
280
+
281
+ elif isinstance(name_or_fn, str):
282
+ # Case 3: @tool("custom_name") - name passed as first argument
283
+ if name is not None:
284
+ raise TypeError(
285
+ "Cannot specify both a name as first argument and as keyword argument. "
286
+ f"Use either @tool('{name_or_fn}') or @tool(name='{name}'), not both."
287
+ )
288
+ tool_name = name_or_fn
289
+ elif name_or_fn is None:
290
+ # Case 4: @tool() or @tool(name="something") - use keyword name
291
+ tool_name = name
292
+ else:
293
+ raise TypeError(
294
+ f"First argument to @tool must be a function, string, or None, got {type(name_or_fn)}"
295
+ )
296
+
297
+ # Return partial for cases where we need to wait for the function
298
+ return partial(
299
+ self.tool,
300
+ name=tool_name,
301
+ version=version,
302
+ title=title,
303
+ description=description,
304
+ icons=icons,
305
+ tags=tags,
306
+ output_schema=output_schema,
307
+ annotations=annotations,
308
+ exclude_args=exclude_args,
309
+ meta=meta,
310
+ enabled=enabled,
311
+ task=task,
312
+ serializer=serializer,
313
+ timeout=timeout,
314
+ auth=auth,
315
+ )