fastmcp 2.12.1__py3-none-any.whl → 2.12.3__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 (37) hide show
  1. fastmcp/cli/claude.py +1 -10
  2. fastmcp/cli/cli.py +45 -25
  3. fastmcp/cli/install/__init__.py +2 -0
  4. fastmcp/cli/install/claude_code.py +1 -10
  5. fastmcp/cli/install/claude_desktop.py +1 -9
  6. fastmcp/cli/install/cursor.py +2 -18
  7. fastmcp/cli/install/gemini_cli.py +242 -0
  8. fastmcp/cli/install/mcp_json.py +1 -9
  9. fastmcp/cli/run.py +0 -84
  10. fastmcp/client/auth/oauth.py +1 -1
  11. fastmcp/client/client.py +6 -6
  12. fastmcp/client/elicitation.py +6 -1
  13. fastmcp/client/transports.py +1 -1
  14. fastmcp/contrib/component_manager/component_service.py +1 -1
  15. fastmcp/contrib/mcp_mixin/README.md +1 -1
  16. fastmcp/contrib/mcp_mixin/mcp_mixin.py +41 -6
  17. fastmcp/experimental/utilities/openapi/director.py +8 -1
  18. fastmcp/prompts/prompt.py +10 -8
  19. fastmcp/resources/resource.py +14 -11
  20. fastmcp/resources/template.py +12 -10
  21. fastmcp/server/auth/auth.py +7 -1
  22. fastmcp/server/auth/oauth_proxy.py +51 -11
  23. fastmcp/server/context.py +10 -10
  24. fastmcp/server/dependencies.py +18 -5
  25. fastmcp/server/server.py +7 -5
  26. fastmcp/settings.py +15 -1
  27. fastmcp/tools/tool.py +101 -85
  28. fastmcp/tools/tool_transform.py +1 -1
  29. fastmcp/utilities/mcp_server_config/v1/environments/uv.py +4 -39
  30. fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py +2 -2
  31. fastmcp/utilities/mcp_server_config/v1/schema.json +2 -1
  32. fastmcp/utilities/types.py +9 -5
  33. {fastmcp-2.12.1.dist-info → fastmcp-2.12.3.dist-info}/METADATA +2 -2
  34. {fastmcp-2.12.1.dist-info → fastmcp-2.12.3.dist-info}/RECORD +37 -36
  35. {fastmcp-2.12.1.dist-info → fastmcp-2.12.3.dist-info}/WHEEL +0 -0
  36. {fastmcp-2.12.1.dist-info → fastmcp-2.12.3.dist-info}/entry_points.txt +0 -0
  37. {fastmcp-2.12.1.dist-info → fastmcp-2.12.3.dist-info}/licenses/LICENSE +0 -0
fastmcp/tools/tool.py CHANGED
@@ -10,6 +10,7 @@ from typing import (
10
10
  Any,
11
11
  Generic,
12
12
  Literal,
13
+ TypeAlias,
13
14
  get_type_hints,
14
15
  )
15
16
 
@@ -55,6 +56,9 @@ class _UnserializableType:
55
56
  pass
56
57
 
57
58
 
59
+ ToolResultSerializerType: TypeAlias = Callable[[Any], str]
60
+
61
+
58
62
  def default_serializer(data: Any) -> str:
59
63
  return pydantic_core.to_json(data, fallback=str).decode()
60
64
 
@@ -70,12 +74,12 @@ class ToolResult:
70
74
  elif content is None:
71
75
  content = structured_content
72
76
 
73
- self.content = _convert_to_content(content)
77
+ self.content: list[ContentBlock] = _convert_to_content(result=content)
74
78
 
75
79
  if structured_content is not None:
76
80
  try:
77
81
  structured_content = pydantic_core.to_jsonable_python(
78
- structured_content
82
+ value=structured_content
79
83
  )
80
84
  except pydantic_core.PydanticSerializationError as e:
81
85
  logger.error(
@@ -112,7 +116,7 @@ class Tool(FastMCPComponent):
112
116
  Field(description="Additional annotations about the tool"),
113
117
  ] = None
114
118
  serializer: Annotated[
115
- Callable[[Any], str] | None,
119
+ ToolResultSerializerType | None,
116
120
  Field(description="Optional custom serializer for tool results"),
117
121
  ] = None
118
122
 
@@ -138,23 +142,25 @@ class Tool(FastMCPComponent):
138
142
  include_fastmcp_meta: bool | None = None,
139
143
  **overrides: Any,
140
144
  ) -> MCPTool:
145
+ """Convert the FastMCP tool to an MCP tool."""
146
+ title = None
147
+
141
148
  if self.title:
142
149
  title = self.title
143
150
  elif self.annotations and self.annotations.title:
144
151
  title = self.annotations.title
145
- else:
146
- title = None
147
-
148
- kwargs = {
149
- "name": self.name,
150
- "description": self.description,
151
- "inputSchema": self.parameters,
152
- "outputSchema": self.output_schema,
153
- "annotations": self.annotations,
154
- "title": title,
155
- "_meta": self.get_meta(include_fastmcp_meta=include_fastmcp_meta),
156
- }
157
- return MCPTool(**kwargs | overrides)
152
+
153
+ return MCPTool(
154
+ name=overrides.get("name", self.name),
155
+ title=overrides.get("title", title),
156
+ description=overrides.get("description", self.description),
157
+ inputSchema=overrides.get("inputSchema", self.parameters),
158
+ outputSchema=overrides.get("outputSchema", self.output_schema),
159
+ annotations=overrides.get("annotations", self.annotations),
160
+ _meta=overrides.get(
161
+ "_meta", self.get_meta(include_fastmcp_meta=include_fastmcp_meta)
162
+ ),
163
+ )
158
164
 
159
165
  @staticmethod
160
166
  def from_function(
@@ -166,7 +172,7 @@ class Tool(FastMCPComponent):
166
172
  annotations: ToolAnnotations | None = None,
167
173
  exclude_args: list[str] | None = None,
168
174
  output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet,
169
- serializer: Callable[[Any], str] | None = None,
175
+ serializer: ToolResultSerializerType | None = None,
170
176
  meta: dict[str, Any] | None = None,
171
177
  enabled: bool | None = None,
172
178
  ) -> FunctionTool:
@@ -208,7 +214,7 @@ class Tool(FastMCPComponent):
208
214
  tags: set[str] | None = None,
209
215
  annotations: ToolAnnotations | None | NotSetT = NotSet,
210
216
  output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet,
211
- serializer: Callable[[Any], str] | None = None,
217
+ serializer: ToolResultSerializerType | None = None,
212
218
  meta: dict[str, Any] | None | NotSetT = NotSet,
213
219
  transform_args: dict[str, ArgTransform] | None = None,
214
220
  enabled: bool | None = None,
@@ -246,7 +252,7 @@ class FunctionTool(Tool):
246
252
  annotations: ToolAnnotations | None = None,
247
253
  exclude_args: list[str] | None = None,
248
254
  output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet,
249
- serializer: Callable[[Any], str] | None = None,
255
+ serializer: ToolResultSerializerType | None = None,
250
256
  meta: dict[str, Any] | None = None,
251
257
  enabled: bool | None = None,
252
258
  ) -> FunctionTool:
@@ -315,27 +321,33 @@ class FunctionTool(Tool):
315
321
 
316
322
  unstructured_result = _convert_to_content(result, serializer=self.serializer)
317
323
 
318
- structured_output = None
319
- # First handle structured content based on output schema, if any
320
- if self.output_schema is not None:
321
- if self.output_schema.get("x-fastmcp-wrap-result"):
322
- # Schema says wrap - always wrap in result key
323
- structured_output = {"result": result}
324
- else:
325
- structured_output = result
326
- # If no output schema, try to serialize the result. If it is a dict, use
327
- # it as structured content. If it is not a dict, ignore it.
328
- if structured_output is None:
324
+ if self.output_schema is None:
325
+ # Do not produce a structured output for MCP Content Types
326
+ if isinstance(result, ContentBlock | Audio | Image | File) or (
327
+ isinstance(result, list | tuple)
328
+ and any(isinstance(item, ContentBlock) for item in result)
329
+ ):
330
+ return ToolResult(content=unstructured_result)
331
+
332
+ # Otherwise, try to serialize the result as a dict
329
333
  try:
330
- structured_output = pydantic_core.to_jsonable_python(result)
331
- if not isinstance(structured_output, dict):
332
- structured_output = None
333
- except Exception:
334
+ structured_content = pydantic_core.to_jsonable_python(result)
335
+ if isinstance(structured_content, dict):
336
+ return ToolResult(
337
+ content=unstructured_result,
338
+ structured_content=structured_content,
339
+ )
340
+
341
+ except pydantic_core.PydanticSerializationError:
334
342
  pass
335
343
 
344
+ return ToolResult(content=unstructured_result)
345
+
346
+ wrap_result = self.output_schema.get("x-fastmcp-wrap-result")
347
+
336
348
  return ToolResult(
337
349
  content=unstructured_result,
338
- structured_content=structured_output,
350
+ structured_content={"result": result} if wrap_result else result,
339
351
  )
340
352
 
341
353
 
@@ -476,65 +488,69 @@ class ParsedFunction:
476
488
  )
477
489
 
478
490
 
479
- def _convert_to_content(
480
- result: Any,
481
- serializer: Callable[[Any], str] | None = None,
482
- _process_as_single_item: bool = False,
483
- ) -> list[ContentBlock]:
484
- """Convert a result to a sequence of content objects."""
491
+ def _serialize_with_fallback(
492
+ result: Any, serializer: ToolResultSerializerType | None = None
493
+ ) -> str:
494
+ if serializer is not None:
495
+ try:
496
+ return serializer(result)
497
+ except Exception as e:
498
+ logger.warning(
499
+ "Error serializing tool result: %s",
500
+ e,
501
+ exc_info=True,
502
+ )
485
503
 
486
- if result is None:
487
- return []
504
+ return default_serializer(result)
488
505
 
489
- if isinstance(result, ContentBlock):
490
- return [result]
491
506
 
492
- if isinstance(result, Image):
493
- return [result.to_image_content()]
507
+ def _convert_to_single_content_block(
508
+ item: Any,
509
+ serializer: ToolResultSerializerType | None = None,
510
+ ) -> ContentBlock:
511
+ if isinstance(item, ContentBlock):
512
+ return item
494
513
 
495
- elif isinstance(result, Audio):
496
- return [result.to_audio_content()]
514
+ if isinstance(item, Image):
515
+ return item.to_image_content()
497
516
 
498
- elif isinstance(result, File):
499
- return [result.to_resource_content()]
517
+ if isinstance(item, Audio):
518
+ return item.to_audio_content()
500
519
 
501
- if isinstance(result, list | tuple) and not _process_as_single_item:
502
- # if the result is a list, then it could either be a list of MCP types,
503
- # or a "regular" list that the tool is returning, or a mix of both.
504
- #
505
- # so we extract all the MCP types / images and convert them as individual content elements,
506
- # and aggregate the rest as a single content element
520
+ if isinstance(item, File):
521
+ return item.to_resource_content()
507
522
 
508
- mcp_types = []
509
- other_content = []
523
+ if isinstance(item, str):
524
+ return TextContent(type="text", text=item)
510
525
 
511
- for item in result:
512
- if isinstance(item, ContentBlock | Image | Audio | File):
513
- mcp_types.append(_convert_to_content(item)[0])
514
- else:
515
- other_content.append(item)
526
+ return TextContent(type="text", text=_serialize_with_fallback(item, serializer))
516
527
 
517
- if other_content:
518
- other_content = _convert_to_content(
519
- other_content,
520
- serializer=serializer,
521
- _process_as_single_item=True,
522
- )
523
528
 
524
- return other_content + mcp_types
529
+ def _convert_to_content(
530
+ result: Any,
531
+ serializer: ToolResultSerializerType | None = None,
532
+ ) -> list[ContentBlock]:
533
+ """Convert a result to a sequence of content objects."""
525
534
 
526
- if not isinstance(result, str):
527
- if serializer is None:
528
- result = default_serializer(result)
529
- else:
530
- try:
531
- result = serializer(result)
532
- except Exception as e:
533
- logger.warning(
534
- "Error serializing tool result: %s",
535
- e,
536
- exc_info=True,
537
- )
538
- result = default_serializer(result)
535
+ if result is None:
536
+ return []
539
537
 
540
- return [TextContent(type="text", text=result)]
538
+ if not isinstance(result, (list | tuple)):
539
+ return [_convert_to_single_content_block(result, serializer)]
540
+
541
+ # If all items are ContentBlocks, return them as is
542
+ if all(isinstance(item, ContentBlock) for item in result):
543
+ return result
544
+
545
+ # If any item is a ContentBlock, convert non-ContentBlock items to TextContent
546
+ # without aggregating them
547
+ if any(isinstance(item, ContentBlock) for item in result):
548
+ return [
549
+ _convert_to_single_content_block(item, serializer)
550
+ if not isinstance(item, ContentBlock)
551
+ else item
552
+ for item in result
553
+ ]
554
+
555
+ # If none of the items are ContentBlocks, aggregate all items into a single TextContent
556
+ return [TextContent(type="text", text=_serialize_with_fallback(result, serializer))]
@@ -934,7 +934,7 @@ def apply_transformations_to_tools(
934
934
  tools: dict[str, Tool],
935
935
  transformations: dict[str, ToolTransformConfig],
936
936
  ) -> dict[str, Tool]:
937
- """Apply a list of transformations to a list of tools. Tools that do not have any transforamtions
937
+ """Apply a list of transformations to a list of tools. Tools that do not have any transformations
938
938
  are left unchanged.
939
939
  """
940
940
 
@@ -1,7 +1,5 @@
1
- import os
2
1
  import shutil
3
2
  import subprocess
4
- import sys
5
3
  from pathlib import Path
6
4
  from typing import Literal
7
5
 
@@ -59,7 +57,7 @@ class UVEnvironment(Environment):
59
57
  If no environment configuration is set, returns the command unchanged.
60
58
  """
61
59
  # If no environment setup is needed, return command as-is
62
- if not self._needs_setup():
60
+ if not self._must_run_with_uv():
63
61
  return command
64
62
 
65
63
  args = ["uv", "run"]
@@ -75,7 +73,7 @@ class UVEnvironment(Environment):
75
73
  # Always add dependencies, requirements, and editable packages
76
74
  # These work with --project to add additional packages on top of the project env
77
75
  if self.dependencies:
78
- for dep in self.dependencies:
76
+ for dep in sorted(set(self.dependencies)):
79
77
  args.extend(["--with", dep])
80
78
 
81
79
  # Add requirements file
@@ -92,31 +90,7 @@ class UVEnvironment(Environment):
92
90
 
93
91
  return args
94
92
 
95
- def run_with_uv(self, command: list[str]) -> None:
96
- """Execute a command using uv run with this environment configuration.
97
-
98
- Args:
99
- command: Command and arguments to execute (e.g., ["fastmcp", "run", "server.py"])
100
- """
101
- import subprocess
102
-
103
- # Build the full uv command
104
- cmd = self.build_command(command)
105
-
106
- # Set marker to prevent infinite loops when subprocess calls FastMCP again
107
- env = os.environ | {"FASTMCP_UV_SPAWNED": "1"}
108
-
109
- logger.debug(f"Running command: {' '.join(cmd)}")
110
-
111
- try:
112
- # Run without capturing output so it flows through naturally
113
- process = subprocess.run(cmd, check=True, env=env)
114
- sys.exit(process.returncode)
115
- except subprocess.CalledProcessError as e:
116
- logger.error(f"Command failed: {e}")
117
- sys.exit(e.returncode)
118
-
119
- def _needs_setup(self) -> bool:
93
+ def _must_run_with_uv(self) -> bool:
120
94
  """Check if this environment config requires uv to set up.
121
95
 
122
96
  Returns:
@@ -132,15 +106,6 @@ class UVEnvironment(Environment):
132
106
  ]
133
107
  )
134
108
 
135
- # Backward compatibility aliases
136
- def needs_uv(self) -> bool:
137
- """Deprecated: Use _needs_setup() internally or check if build_command modifies the command."""
138
- return self._needs_setup()
139
-
140
- def build_uv_run_command(self, command: list[str]) -> list[str]:
141
- """Deprecated: Use build_command() instead."""
142
- return self.build_command(command)
143
-
144
109
  async def prepare(self, output_dir: Path | None = None) -> None:
145
110
  """Prepare the Python environment using uv.
146
111
 
@@ -157,7 +122,7 @@ class UVEnvironment(Environment):
157
122
  )
158
123
 
159
124
  # Only prepare environment if there are actual settings to apply
160
- if not self._needs_setup():
125
+ if not self._must_run_with_uv():
161
126
  logger.debug("No environment settings configured, skipping preparation")
162
127
  return
163
128
 
@@ -26,7 +26,7 @@ logger = get_logger("cli.config")
26
26
  FASTMCP_JSON_SCHEMA = "https://gofastmcp.com/public/schemas/fastmcp.json/v1.json"
27
27
 
28
28
 
29
- # Type alias for source union (will expand with GitSource, etc in future)
29
+ # Type alias for source union (will expand with GitSource, etc. in future)
30
30
  SourceType: TypeAlias = FileSystemSource
31
31
 
32
32
  # Type alias for environment union (will expand with other environments in future)
@@ -36,7 +36,7 @@ EnvironmentType: TypeAlias = UVEnvironment
36
36
  class Deployment(BaseModel):
37
37
  """Configuration for server deployment and runtime settings."""
38
38
 
39
- transport: Literal["stdio", "http", "sse"] | None = Field(
39
+ transport: Literal["stdio", "http", "sse", "streamable-http"] | None = Field(
40
40
  default=None,
41
41
  description="Transport protocol to use",
42
42
  )
@@ -9,7 +9,8 @@
9
9
  "enum": [
10
10
  "stdio",
11
11
  "http",
12
- "sse"
12
+ "sse",
13
+ "streamable-http"
13
14
  ],
14
15
  "type": "string"
15
16
  },
@@ -31,6 +31,10 @@ NotSet = ...
31
31
  NotSetT: TypeAlias = EllipsisType
32
32
 
33
33
 
34
+ def get_fn_name(fn: Callable[..., Any]) -> str:
35
+ return fn.__name__ # ty: ignore[unresolved-attribute]
36
+
37
+
34
38
  class FastMCPBaseModel(BaseModel):
35
39
  """Base model for FastMCP models."""
36
40
 
@@ -80,11 +84,11 @@ def get_cached_typeadapter(cls: T) -> TypeAdapter[T]:
80
84
  # Handle both functions and methods
81
85
  if inspect.ismethod(cls):
82
86
  actual_func = cls.__func__
83
- code = actual_func.__code__
84
- globals_dict = actual_func.__globals__
85
- name = actual_func.__name__
86
- defaults = actual_func.__defaults__
87
- closure = actual_func.__closure__
87
+ code = actual_func.__code__ # ty: ignore[unresolved-attribute]
88
+ globals_dict = actual_func.__globals__ # ty: ignore[unresolved-attribute]
89
+ name = actual_func.__name__ # ty: ignore[unresolved-attribute]
90
+ defaults = actual_func.__defaults__ # ty: ignore[unresolved-attribute]
91
+ closure = actual_func.__closure__ # ty: ignore[unresolved-attribute]
88
92
  else:
89
93
  code = cls.__code__
90
94
  globals_dict = cls.__globals__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.12.1
3
+ Version: 2.12.3
4
4
  Summary: The fast, Pythonic way to build MCP servers and clients.
5
5
  Project-URL: Homepage, https://gofastmcp.com
6
6
  Project-URL: Repository, https://github.com/jlowin/fastmcp
@@ -278,7 +278,7 @@ async def main():
278
278
  tools = await client.list_tools()
279
279
  print(f"Available tools: {tools}")
280
280
  result = await client.call_tool("add", {"a": 5, "b": 3})
281
- print(f"Result: {result.text}")
281
+ print(f"Result: {result.content[0].text}")
282
282
 
283
283
  # Connect via SSE
284
284
  async with Client("http://localhost:8000/sse") as client:
@@ -2,30 +2,31 @@ fastmcp/__init__.py,sha256=KX2d8UjlyJdYwock62tYV7vJSRwyxzrjq-jnU6Gre_c,1544
2
2
  fastmcp/exceptions.py,sha256=-krEavxwddQau6T7MESCR4VjKNLfP9KHJrU1p3y72FU,744
3
3
  fastmcp/mcp_config.py,sha256=zbli5c8hcUfxOlqYFBJXbogpVlXwtnCuJjTg3oTfmtQ,11375
4
4
  fastmcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- fastmcp/settings.py,sha256=6m3rs7JQz8RN5rtFiRGCnb1K53Vt6588bF7zITRESK0,11982
5
+ fastmcp/settings.py,sha256=VBEkpJRMzhlcwWyQvRFxVWwcirUu4tKhgmcvd7Um-HQ,12449
6
6
  fastmcp/cli/__init__.py,sha256=Ii284TNoG5lxTP40ETMGhHEq3lQZWxu9m9JuU57kUpQ,87
7
- fastmcp/cli/claude.py,sha256=tGbJwLOW9BRfQ_VJ91Iz8HOiqKg0JKywzIJOijCHO78,4996
8
- fastmcp/cli/cli.py,sha256=sBwMOM_DHc90YOEWV94ikCjASBBKTbA1KmIElPVHBUg,28244
9
- fastmcp/cli/run.py,sha256=6-Cvo48mKh_VDdlavq7bDNUJ9wCkQOcRoOjqSb_Wgws,10100
10
- fastmcp/cli/install/__init__.py,sha256=cDEc0hhuf_xwGpI6ghpqlvlMdBMJUGHq_rs-tgmOJZ8,695
11
- fastmcp/cli/install/claude_code.py,sha256=XMm35e70BmFznYAPBYfuibG9G0bubq59nQiYNhTj57Y,8174
12
- fastmcp/cli/install/claude_desktop.py,sha256=zityBHHLZxTRf6t7JWgVIRznPNsyeqXBHqjM0pBFM1E,7289
13
- fastmcp/cli/install/cursor.py,sha256=jyauvEhpB-qouj08tcL-PCEWAkYgTAV_foQCqLn-k4g,11449
14
- fastmcp/cli/install/mcp_json.py,sha256=RlGtDuqflPXWeENL8SyuCEytLRm17lHyBNQeud9l4so,6317
7
+ fastmcp/cli/claude.py,sha256=Z2mNoOdfGNvPSZVhbS2n52Thu9fNCxtJwju1pnTaN7c,4546
8
+ fastmcp/cli/cli.py,sha256=s5uIEKGOhImfDZc74v2ZYYrN2WHNxRyy7ouo265sCcM,29041
9
+ fastmcp/cli/run.py,sha256=ImPCaEHgEHS_ZAumFI3QHJX93prMFsbVYVVs1joCqnc,6940
10
+ fastmcp/cli/install/__init__.py,sha256=FUrwjMVaxONgz1qO7suzJNz1xosRfR3TOHlr3Z77JXA,797
11
+ fastmcp/cli/install/claude_code.py,sha256=pIZXHJFv4lqj5V7Wr55fTjj9YDjBu0PBMBxPm_ww7Ow,7756
12
+ fastmcp/cli/install/claude_desktop.py,sha256=1skMjy07Z_4iQ1rMKO1L3Jl5hGsTIz8xdZTNG1tV2H0,6939
13
+ fastmcp/cli/install/cursor.py,sha256=eXJcI3u36eDDmLVeq49pK0R3cWA_iAtpYdO45tPDEgg,10749
14
+ fastmcp/cli/install/gemini_cli.py,sha256=MaDEvNvVUU4LJbjFmzqSfQsLvbrhluhm3nuz3vvwtp4,7805
15
+ fastmcp/cli/install/mcp_json.py,sha256=7tYslUjbPMwWt1UoARJjnDRRFZjH_l1UWd5hNWwKA5c,5939
15
16
  fastmcp/cli/install/shared.py,sha256=_1MNGCqf7BsAL6ntwA75wn86-0g-248ppQSAPQ8uTXk,5103
16
17
  fastmcp/client/__init__.py,sha256=J-RcLU2WcnYnstXWoW01itGtAg7DEjvCsWyqQKQljoo,663
17
- fastmcp/client/client.py,sha256=N1UZopFOy5NwbWY55goqRKlkwqEgbk2UaF13EncJ1Ps,35190
18
- fastmcp/client/elicitation.py,sha256=FKSJCQ9cZPFMC2V3e7VtrxNB9q22SoB5ou1lgjS8eCY,2445
18
+ fastmcp/client/client.py,sha256=xnu_tbE1UFz6crByEqbsWebQboQGsJQD9aFNOAn0dtg,35227
19
+ fastmcp/client/elicitation.py,sha256=VNWgeBe2KipLp9mCc-6AApmfYAU1OlH9_3JdskfW_Wc,2521
19
20
  fastmcp/client/logging.py,sha256=uIC9aWGKqgTbxhRqkMBlnYfYjtanC1fqyWbRu5FY6AY,1670
20
21
  fastmcp/client/messages.py,sha256=NIPjt-5js_DkI5BD4OVdTf6pz-nGjc2dtbgt-vAY234,4329
21
22
  fastmcp/client/oauth_callback.py,sha256=qxSMg1duv_uCYbbNaiFjl9esSlWeiiHtYBWBdQcX27w,10248
22
23
  fastmcp/client/progress.py,sha256=WjLLDbUKMsx8DK-fqO7AGsXb83ak-6BMrLvzzznGmcI,1043
23
24
  fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
24
25
  fastmcp/client/sampling.py,sha256=TXRj1Fs9lOk1wukhaHhPS__HGqpTieXSq2Rasj1F-e0,1819
25
- fastmcp/client/transports.py,sha256=7n0AnkCznQvQmck1luo3-cx1-IxVSSVihYOrgUmV8e8,38174
26
+ fastmcp/client/transports.py,sha256=RLOqBKO8cphsbPC8FRk6hgrM_2yH2WyT6o5xmXf3DVI,38183
26
27
  fastmcp/client/auth/__init__.py,sha256=4DNsfp4iaQeBcpds0JDdMn6Mmfud44stWLsret0sVKY,91
27
28
  fastmcp/client/auth/bearer.py,sha256=MFEFqcH6u_V86msYiOsEFKN5ks1V9BnBNiPsPLHUTqo,399
28
- fastmcp/client/auth/oauth.py,sha256=tZ3Q5p2jb1a6pkWXZif_6-b5sFvfPU23BPLd6_jI8rA,15810
29
+ fastmcp/client/auth/oauth.py,sha256=hG7PEFQdZEmNrrhghwvy372R4pl3QNHFL8lYs2JPtBw,15811
29
30
  fastmcp/contrib/README.md,sha256=rKknYSI1T192UvSszqwwDlQ2eYQpxywrNTLoj177SYU,878
30
31
  fastmcp/contrib/bulk_tool_caller/README.md,sha256=5aUUY1TSFKtz1pvTLSDqkUCkGkuqMfMZNsLeaNqEgAc,1960
31
32
  fastmcp/contrib/bulk_tool_caller/__init__.py,sha256=xvGSSaUXTQrc31erBoi1Gh7BikgOliETDiYVTP3rLxY,75
@@ -34,12 +35,12 @@ fastmcp/contrib/bulk_tool_caller/example.py,sha256=6og_8pCJN_CabworC5R82zPAwwwM-
34
35
  fastmcp/contrib/component_manager/README.md,sha256=sTan1D51jzkPNnCQTxwd5JXGzWVy4DtkUjrUfNH3-F0,4457
35
36
  fastmcp/contrib/component_manager/__init__.py,sha256=4bppVrCOSEepKmBRwVWN-ndu5BYAz1Kv2Z8yhjEUmlo,164
36
37
  fastmcp/contrib/component_manager/component_manager.py,sha256=4R1FPVYjCr-j7Mn6OcbHH-psl9-JTdd1hgNZHasC52Y,6412
37
- fastmcp/contrib/component_manager/component_service.py,sha256=dLIOtXvMpCAu8CGlrqAWb9pX0AhVGqkC4j0uxv6XnXs,8759
38
+ fastmcp/contrib/component_manager/component_service.py,sha256=QqJ4DgD8ppAEHopc_hn3Ir2HKs81wSyuCT7qFqW527E,8760
38
39
  fastmcp/contrib/component_manager/example.py,sha256=N16OIHmQuR-LNEv7bkrv2rGdMs862Nc3AKKEPfw-6rU,1587
39
- fastmcp/contrib/mcp_mixin/README.md,sha256=X6rzt_4vC_rmq9jbHmrVPqYLGVVlw9b4TVL4H_0SMmQ,4277
40
+ fastmcp/contrib/mcp_mixin/README.md,sha256=IPmAriefWNB54DnlBCcYWR9yQ2GQz3Us81OvcIxpXBk,4278
40
41
  fastmcp/contrib/mcp_mixin/__init__.py,sha256=aw9IQ1ssNjCgws4ZNt8bkdpossAAGVAwwjBpMp9O5ZQ,153
41
42
  fastmcp/contrib/mcp_mixin/example.py,sha256=GnunkXmtG5hLLTUsM8aW5ZURU52Z8vI4tNLl-fK7Dg0,1228
42
- fastmcp/contrib/mcp_mixin/mcp_mixin.py,sha256=sUSJ2o0sTsb061MyPN2xuYP0oI4W6YVQXupY3nnjD50,8687
43
+ fastmcp/contrib/mcp_mixin/mcp_mixin.py,sha256=q039j0OOwlflMLqpqEpniBf828LwIaeXkY7LPub3rRU,10171
43
44
  fastmcp/experimental/sampling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
45
  fastmcp/experimental/sampling/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
46
  fastmcp/experimental/sampling/handlers/base.py,sha256=mCPFj9ETc-Ro38R_pzx9rHVM2_EADCecScMkNWd6Tbs,714
@@ -51,32 +52,32 @@ fastmcp/experimental/server/openapi/routing.py,sha256=H_1RMaARucl8bfFT9-JJRDwrAf
51
52
  fastmcp/experimental/server/openapi/server.py,sha256=WQeUA3v69ZhrzN1-cbrDTC8EsaOXHwDSQT_NPgYrECk,16099
52
53
  fastmcp/experimental/utilities/openapi/README.md,sha256=pOXftamuVXxEMlOt-JAfpuvHeRGauC3l46ntD1WzM-A,8604
53
54
  fastmcp/experimental/utilities/openapi/__init__.py,sha256=4uba3nOrt8hAv1I91BWkg2hMo3O0VmYlSNG058xwmiA,1677
54
- fastmcp/experimental/utilities/openapi/director.py,sha256=0YnazKmfaSPkBRAz5aI6blFN9nzXJWru3fvU6llYltA,7859
55
+ fastmcp/experimental/utilities/openapi/director.py,sha256=zoYlIp4KESC8UlfKvooEtyzSO15P8T6YMZp5qCV6PfU,8078
55
56
  fastmcp/experimental/utilities/openapi/formatters.py,sha256=1RCd8DwPU8_4uF51pj8Qp3oSZkZmoxL5VUwxBzokAMg,15540
56
57
  fastmcp/experimental/utilities/openapi/json_schema_converter.py,sha256=W_40IPyuYnstcYtGf--eyTquecmwpvFYBK0W-XQ7OAw,12921
57
58
  fastmcp/experimental/utilities/openapi/models.py,sha256=tgqrHdTbiDfMjiaNVHW5ndbXJ5lg_sajK0S5u9JQL6A,2805
58
59
  fastmcp/experimental/utilities/openapi/parser.py,sha256=nVlvQ7RV7q4az_hrcE8WfGI5GqREKb6mZ5ANMgDED08,33232
59
60
  fastmcp/experimental/utilities/openapi/schemas.py,sha256=WZ1nQECX4McLIZ2Kmgr7VnlI1zGM8_hNofhzBboeEo0,21923
60
61
  fastmcp/prompts/__init__.py,sha256=An8uMBUh9Hrb7qqcn_5_Hent7IOeSh7EA2IUVsIrtHc,179
61
- fastmcp/prompts/prompt.py,sha256=lxlxQi9gylLW36-eVKUyH7PwndoxhA6ii8m4Cok6MEU,14158
62
+ fastmcp/prompts/prompt.py,sha256=Uo6NorQlGP1lvJh5-qK8jAvi4Mp4yDWkB5V4pzXMQYw,14235
62
63
  fastmcp/prompts/prompt_manager.py,sha256=mv3ge3vqNQNIPwVT8Tkr7IaBSflYBajpfxfTZLuHZiw,7807
63
64
  fastmcp/resources/__init__.py,sha256=y1iAuqx-GIrS1NqIYzKezIDiYyjNEzzHD35epHpMnXE,463
64
- fastmcp/resources/resource.py,sha256=IW2PToUgBOWDuZ1q8tiT7s0iSeh7a1mIFr56UyYbJ1E,6727
65
+ fastmcp/resources/resource.py,sha256=sWXqetS0X_u0bQOeMI-q9zVQvc29Qjz1hdxi7CjYmfE,6898
65
66
  fastmcp/resources/resource_manager.py,sha256=sDfMrAx1cl2sTaKrTYW3k6gxr_O0QmH18n9v10zR47s,20355
66
- fastmcp/resources/template.py,sha256=HXL_T1hUXMwv1h0962NTtszGY68R1TbumjJMvC0PjjU,11030
67
+ fastmcp/resources/template.py,sha256=KljJyfeO6Q702woIKKr5C9ODK4ImebY2PyFgYbQP5rY,11188
67
68
  fastmcp/resources/types.py,sha256=SiYNLnpXT-mHgNUrzqKUvXYUsY-V3gwJIrYdJfFwDDo,4868
68
69
  fastmcp/server/__init__.py,sha256=bMD4aQD4yJqLz7-mudoNsyeV8UgQfRAg3PRwPvwTEds,119
69
- fastmcp/server/context.py,sha256=caj-K-bbuFZINiugGw6Uz2P6fcn7jJ17dvTCAY37wRQ,24454
70
- fastmcp/server/dependencies.py,sha256=NDAQMAIgiWtLMkDS-oF8htoHpETilAZo1YawSDP5Lqg,3317
70
+ fastmcp/server/context.py,sha256=1FTJPBvxUeEiGF1wJC500FrIYjWd9fCql8nxI7vLVLQ,24496
71
+ fastmcp/server/dependencies.py,sha256=so60cBZc4QuiKP2Y4ajR_NPkIF5d_b5wp8U3-ZfZMEQ,3888
71
72
  fastmcp/server/elicitation.py,sha256=gmP17CzLQVpGzU00Ks31TWxdS-OLL5wTX_W5xRzs1Cc,8777
72
73
  fastmcp/server/http.py,sha256=dpSfE9VhilTjuz4BLh1MbdfHhMyDzWEi68GNjUZamTE,10665
73
74
  fastmcp/server/low_level.py,sha256=LNmc_nU_wx-fRG8OEHdLPKopZpovcrWlyAxJzKss3TA,1239
74
75
  fastmcp/server/openapi.py,sha256=-7-pKwQ1hT-UV9OnLlWrjbbXXRfZld8YJqa4Duybhtw,42102
75
76
  fastmcp/server/proxy.py,sha256=y9h-49PIBNRh03HI3HcrY_lL8AMbKv45fyr2mAz3Vyo,25734
76
- fastmcp/server/server.py,sha256=JVGKi1uBsF3f3kHMQT2o0lxY-E76bbCFSuzz98Ume_M,90333
77
+ fastmcp/server/server.py,sha256=QaqAzY4pzh424jibCmVSMvPMMv_2RRs12ea9mgh9VNA,90402
77
78
  fastmcp/server/auth/__init__.py,sha256=GwoyosVxuWCPzFHaCnj6iFp9fulnp124G2gQfsnzcgc,695
78
- fastmcp/server/auth/auth.py,sha256=373WvHAh-Vt6ktWa_xeW9Ci2WUB9KUwvhN848qNs6IE,12788
79
- fastmcp/server/auth/oauth_proxy.py,sha256=SxnO-K3P6UPR_uS5e63NYwWJ0V0ZY5UF9MGJX6UL4q0,40433
79
+ fastmcp/server/auth/auth.py,sha256=YLM04cwXHURaI1o3liPhAw-37YAnDOWHZTHfXfnoyEE,13053
80
+ fastmcp/server/auth/oauth_proxy.py,sha256=7fEozPgw0YJd57QQh4i6aWSwCnbrIg97p4WOVvNd3Ow,42264
80
81
  fastmcp/server/auth/redirect_validation.py,sha256=Jlhela9xpTbw4aWnQ04A5Z-TW0HYOC3f9BMsq3NXx1Q,2000
81
82
  fastmcp/server/auth/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
83
  fastmcp/server/auth/providers/azure.py,sha256=obQKR_M9XTjfZrqhzmfhRhCc4x4MPbF7uErDmWamSXQ,9940
@@ -94,9 +95,9 @@ fastmcp/server/middleware/rate_limiting.py,sha256=VTrCoQFmWCm0BxwOrNfG21CBFDDOKJ
94
95
  fastmcp/server/middleware/timing.py,sha256=lL_xc-ErLD5lplfvd5-HIyWEbZhgNBYkcQ74KFXAMkA,5591
95
96
  fastmcp/server/sampling/handler.py,sha256=yjLzvxlGllE-EY4bc6djsijEmwMT24PCpV6vJl-sPcI,580
96
97
  fastmcp/tools/__init__.py,sha256=vzqb-Y7Kf0d5T0aOsld-O-FA8kD7-4uFExChewFHEzY,201
97
- fastmcp/tools/tool.py,sha256=Q49E6L7Mx6v-VB9kru7CJVBM5_aF6V1Nti89scRv8Jc,19275
98
+ fastmcp/tools/tool.py,sha256=p_36dbaoqokSP0gVlfOq1v8J3ICGVOBVHW6mXwYwTMk,19825
98
99
  fastmcp/tools/tool_manager.py,sha256=xOm5XFbygUg2cW8jIiwhsgAdUA14wDMoUIvkWKL3LOU,9186
99
- fastmcp/tools/tool_transform.py,sha256=Mga202SjKhdMglhEXSPBi4dhq1bevfdsU5Rt21KVyZo,38447
100
+ fastmcp/tools/tool_transform.py,sha256=v5pgBddBacrryED_bSBOBe3jplInBE30W949_RxUzbA,38447
100
101
  fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
101
102
  fastmcp/utilities/auth.py,sha256=ZVHkNb4YBpLE1EmmFyhvFB2qfWDZdEYNH9TRI9jylOE,1140
102
103
  fastmcp/utilities/cli.py,sha256=NZbERkcatjKxgyE0sFT6g6tghhWkzz0QTI2u_LaQGXo,8662
@@ -110,19 +111,19 @@ fastmcp/utilities/logging.py,sha256=O_TsD5x8BPRRQ-xAa2CZlpKfRjipkpvdg6w6invBZVY,
110
111
  fastmcp/utilities/mcp_config.py,sha256=qATTXMGiYET-7PflOixQOgiw3aOizX-RlloRjAo7nwI,1796
111
112
  fastmcp/utilities/openapi.py,sha256=mfkY2XfWAmAOlKexArlrmDdD0Tkdqcn4TshsATaxB_o,63304
112
113
  fastmcp/utilities/tests.py,sha256=TRMIfcdSJWlHRA4mQSYu3OXlxnvqRYKhcJXEYG5BkYA,6403
113
- fastmcp/utilities/types.py,sha256=G60OPTub4ID2GQwxfIgR38PEyF7CaxLPZ-PfWkXberA,14462
114
+ fastmcp/utilities/types.py,sha256=dZ9dw5U1gAOJsERODSlVF1Ua6q7XBAQaD7SF2K_H38w,14751
114
115
  fastmcp/utilities/mcp_server_config/__init__.py,sha256=qbfd0c6aBpi0_SVgwt4IQCQ9siqqxmr9PWSYGiPDJqE,791
115
116
  fastmcp/utilities/mcp_server_config/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
- fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py,sha256=xP4yl04ZBmmoiDFDi10YRe9JZvTuFmDGAFogL3CC730,15311
117
- fastmcp/utilities/mcp_server_config/v1/schema.json,sha256=Vrm7vOWtVcDyT1aUPXlcy916JXXSpCOcVygD5SYLUQU,8469
117
+ fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py,sha256=NKfVQsjBS3-j0JAFkAvsCwDGyf-5uJTHesKxrPXnS_M,15331
118
+ fastmcp/utilities/mcp_server_config/v1/schema.json,sha256=uI7hQuF-sFDi4Zj5Quu5PeAPL6ZjDPifrt-pI0gKWTU,8504
118
119
  fastmcp/utilities/mcp_server_config/v1/environments/__init__.py,sha256=Tkv0dmJ6tKKotOBo-tho09QVdvEjy37iBsvBbEwH0EA,256
119
120
  fastmcp/utilities/mcp_server_config/v1/environments/base.py,sha256=FkrUsESEdW5akyn_FeR4tQB6Vlj7dO9VFcCj0YLCghQ,845
120
- fastmcp/utilities/mcp_server_config/v1/environments/uv.py,sha256=LZR9R5XjpIQZzbjdVeeNwMsO35T5cIKIweXTqy3bGIo,10977
121
+ fastmcp/utilities/mcp_server_config/v1/environments/uv.py,sha256=UzexA4kxuABtb2BZX8u6RYyrCd5xvW_7FiBjmgR47dc,9722
121
122
  fastmcp/utilities/mcp_server_config/v1/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
123
  fastmcp/utilities/mcp_server_config/v1/sources/base.py,sha256=KWunc5peDLFdSdLX8l3UI9SNxtN-KNq2FOXAZ7XD62c,980
123
124
  fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py,sha256=eFX47XNXz2oKHW8MZvx60dqyHkBxdg2FMOrHcyAS28g,8106
124
- fastmcp-2.12.1.dist-info/METADATA,sha256=qGL0ucEimvm8yVPb_m8A_9_uppLm04V98TvM691mYh8,17919
125
- fastmcp-2.12.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
126
- fastmcp-2.12.1.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
127
- fastmcp-2.12.1.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
128
- fastmcp-2.12.1.dist-info/RECORD,,
125
+ fastmcp-2.12.3.dist-info/METADATA,sha256=eci6FoLvgmyERUkIR6BuXZRd5SR4Obv1rvTMOdeMGpE,17930
126
+ fastmcp-2.12.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
127
+ fastmcp-2.12.3.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
128
+ fastmcp-2.12.3.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
129
+ fastmcp-2.12.3.dist-info/RECORD,,