fastmcp 2.0.0__py3-none-any.whl → 2.1.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.
@@ -6,7 +6,8 @@ from typing import TYPE_CHECKING, Any
6
6
  from mcp.shared.context import LifespanContextT
7
7
 
8
8
  from fastmcp.exceptions import ToolError
9
- from fastmcp.tools.base import Tool
9
+ from fastmcp.settings import DuplicateBehavior
10
+ from fastmcp.tools.tool import Tool
10
11
  from fastmcp.utilities.logging import get_logger
11
12
 
12
13
  if TYPE_CHECKING:
@@ -20,9 +21,9 @@ logger = get_logger(__name__)
20
21
  class ToolManager:
21
22
  """Manages FastMCP tools."""
22
23
 
23
- def __init__(self, warn_on_duplicate_tools: bool = True):
24
+ def __init__(self, duplicate_behavior: DuplicateBehavior = DuplicateBehavior.WARN):
24
25
  self._tools: dict[str, Tool] = {}
25
- self.warn_on_duplicate_tools = warn_on_duplicate_tools
26
+ self.duplicate_behavior = duplicate_behavior
26
27
 
27
28
  def get_tool(self, name: str) -> Tool | None:
28
29
  """Get tool by name."""
@@ -32,19 +33,30 @@ class ToolManager:
32
33
  """List all registered tools."""
33
34
  return list(self._tools.values())
34
35
 
35
- def add_tool(
36
+ def add_tool_from_fn(
36
37
  self,
37
38
  fn: Callable[..., Any],
38
39
  name: str | None = None,
39
40
  description: str | None = None,
41
+ tags: set[str] | None = None,
40
42
  ) -> Tool:
41
43
  """Add a tool to the server."""
42
- tool = Tool.from_function(fn, name=name, description=description)
44
+ tool = Tool.from_function(fn, name=name, description=description, tags=tags)
45
+ return self.add_tool(tool)
46
+
47
+ def add_tool(self, tool: Tool) -> Tool:
48
+ """Register a tool with the server."""
43
49
  existing = self._tools.get(tool.name)
44
50
  if existing:
45
- if self.warn_on_duplicate_tools:
51
+ if self.duplicate_behavior == DuplicateBehavior.WARN:
46
52
  logger.warning(f"Tool already exists: {tool.name}")
47
- return existing
53
+ self._tools[tool.name] = tool
54
+ elif self.duplicate_behavior == DuplicateBehavior.REPLACE:
55
+ self._tools[tool.name] = tool
56
+ elif self.duplicate_behavior == DuplicateBehavior.ERROR:
57
+ raise ValueError(f"Tool already exists: {tool.name}")
58
+ elif self.duplicate_behavior == DuplicateBehavior.IGNORE:
59
+ pass
48
60
  self._tools[tool.name] = tool
49
61
  return tool
50
62
 
@@ -78,13 +90,7 @@ class ToolManager:
78
90
  for name, tool in tool_manager._tools.items():
79
91
  prefixed_name = f"{prefix}{name}" if prefix else name
80
92
 
81
- # Create a shallow copy of the tool with the prefixed name
82
- copied_tool = Tool.from_function(
83
- tool.fn,
84
- name=prefixed_name,
85
- description=tool.description,
86
- )
87
-
93
+ new_tool = tool.copy(updates=dict(name=prefixed_name))
88
94
  # Store the copied tool
89
- self._tools[prefixed_name] = copied_tool
90
- logger.debug(f"Imported tool: {name} as {prefixed_name}")
95
+ self.add_tool(new_tool)
96
+ logger.debug(f'Imported tool "{name}" as "{prefixed_name}"')
@@ -2,9 +2,21 @@
2
2
 
3
3
  import base64
4
4
  from pathlib import Path
5
+ from typing import TypeVar
5
6
 
6
7
  from mcp.types import ImageContent
7
8
 
9
+ T = TypeVar("T")
10
+
11
+
12
+ def _convert_set_defaults(maybe_set: set[T] | list[T] | None) -> set[T]:
13
+ """Convert a set or list to a set, defaulting to an empty set if None."""
14
+ if maybe_set is None:
15
+ return set()
16
+ if isinstance(maybe_set, set):
17
+ return maybe_set
18
+ return set(maybe_set)
19
+
8
20
 
9
21
  class Image:
10
22
  """Helper class for returning images from tools."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: An ergonomic MCP interface
5
5
  Author: Jeremiah Lowin
6
6
  License: Apache-2.0
@@ -0,0 +1,39 @@
1
+ fastmcp/__init__.py,sha256=2bwhjiyLJisyobp1O9tVYMjriHZAx_f4bIKJYOL-Rpk,399
2
+ fastmcp/exceptions.py,sha256=q9djUDmpwmGEWcHI8q4UzJBtf7s7UtgL--OB7OaGzyQ,435
3
+ fastmcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ fastmcp/settings.py,sha256=r5LT5yAZmwS1Lppro_fzdrCUJ0otnAmgtjsNgDdQIvs,1980
5
+ fastmcp/cli/__init__.py,sha256=Ii284TNoG5lxTP40ETMGhHEq3lQZWxu9m9JuU57kUpQ,87
6
+ fastmcp/cli/claude.py,sha256=IAlcZ4qZKBBj09jZUMEx7EANZE_IR3vcu7zOBJmMOuU,4567
7
+ fastmcp/cli/cli.py,sha256=L1git_8u-OvVCSEtwztHhmJ6WwlFhlvK4gEIAWgrMMM,13933
8
+ fastmcp/client/__init__.py,sha256=BXO9NUhntZ5GnUACfaRCzDJ5IzxqFJs8qKG-CRMSco4,490
9
+ fastmcp/client/base.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
10
+ fastmcp/client/client.py,sha256=OMJ1FzrlcRRYKQg3DFxiQpaNDo4uYK3Acs23rxPyE-g,7941
11
+ fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
12
+ fastmcp/client/sampling.py,sha256=WdRhIZbWv54rXYI8lWHv0thXmGCloZYPFpwJK9El_sQ,1613
13
+ fastmcp/client/transports.py,sha256=gA_aGjgPY2q_PqaURkes_vUKtuUicViTHYEe4TAkDmU,13864
14
+ fastmcp/prompts/__init__.py,sha256=wTtTHaYiH-IArcumPSxM1-8V2EGzClVVIP76vwcWsFQ,108
15
+ fastmcp/prompts/prompt.py,sha256=br_o7eaLg9j04jqCKxRwnrzkcNxe7rtsScB2qUSh_a8,6445
16
+ fastmcp/prompts/prompt_manager.py,sha256=1kWgdTH7WE36F5j-B7cP3q81XxguXiOxpNIi9FANUIg,3461
17
+ fastmcp/resources/__init__.py,sha256=ImyPi5xICGW8nN634fP82PzU0SsKCPeJXU-WopVOu6Y,467
18
+ fastmcp/resources/resource.py,sha256=MrfRdLA2FEglvRJP7KgduG7na_qgkBo-_iXTzRbil6c,2038
19
+ fastmcp/resources/resource_manager.py,sha256=AsK3hxorGbWC04fWGTH0QMqQvOLJDauWdckZiA-DC1E,7849
20
+ fastmcp/resources/template.py,sha256=Fpjb51_ktWFpS1aQ5CFCt1SFuPe6S7CPuyzQCz7c3Mg,3742
21
+ fastmcp/resources/types.py,sha256=tigil7z-SUJMakGXzDLIGSqTepPrAsRpwqwtBA4yoUY,6168
22
+ fastmcp/server/__init__.py,sha256=pdkghG11VLMZiluQ-4_rl2JK1LMWmV003m9dDRUN8W4,92
23
+ fastmcp/server/context.py,sha256=SPYr3KUBG9MmKRh6Y6tfzPNgdxR5TmPGfnVwcEMqwMM,7115
24
+ fastmcp/server/openapi.py,sha256=J7HrAlRziaB2a6pwB0wStbjRJ1E5Lf818yMqD762s5U,22693
25
+ fastmcp/server/proxy.py,sha256=YKSPG2uwmUwHxw9brHmKD-i8noxq0FG4Loln7WGflgc,8019
26
+ fastmcp/server/server.py,sha256=B9swucn_1H5Z8Gd_JMG8fvcF8hb5r4C3Kpp7bXoY9LI,26328
27
+ fastmcp/tools/__init__.py,sha256=ocw-SFTtN6vQ8fgnlF8iNAOflRmh79xS1xdO0Bc3QPE,96
28
+ fastmcp/tools/tool.py,sha256=_BN0ZIMP0NKkRD_9_t_eNWHP6xRfEoSSl-9ZI3V337k,3753
29
+ fastmcp/tools/tool_manager.py,sha256=oUT8ExxIKKpJnFxCUDwThRxdK7WADD40e6yjGBYDPmI,3498
30
+ fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
31
+ fastmcp/utilities/func_metadata.py,sha256=ODD9ds7bGXED27rx4MiMim1EBPnjNHIcXabJhynVKBA,7739
32
+ fastmcp/utilities/logging.py,sha256=1ipiOXzgWUp3Vih_JtEiLX7aAFmrUDZNr4KrZbofZTM,818
33
+ fastmcp/utilities/openapi.py,sha256=yl83QsOcLZc00vScdL2LpEopzVCv32gDpC5da9NGkTM,30351
34
+ fastmcp/utilities/types.py,sha256=m2rPYMzO-ZFvvZ46N-1-Xqyw693K7yq9Z2xR4pVELyk,2091
35
+ fastmcp-2.1.0.dist-info/METADATA,sha256=hNrhsqF-IhAt5ExONGcyXbgFTCRV8aVqzVtJl0hTeeA,26270
36
+ fastmcp-2.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
37
+ fastmcp-2.1.0.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
38
+ fastmcp-2.1.0.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
39
+ fastmcp-2.1.0.dist-info/RECORD,,
@@ -1,39 +0,0 @@
1
- fastmcp/__init__.py,sha256=2bwhjiyLJisyobp1O9tVYMjriHZAx_f4bIKJYOL-Rpk,399
2
- fastmcp/exceptions.py,sha256=q9djUDmpwmGEWcHI8q4UzJBtf7s7UtgL--OB7OaGzyQ,435
3
- fastmcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- fastmcp/settings.py,sha256=jpmSeDMcak_2ozVm0xkm4aUeGBGcShEvBWz3HtORkCg,1763
5
- fastmcp/cli/__init__.py,sha256=Ii284TNoG5lxTP40ETMGhHEq3lQZWxu9m9JuU57kUpQ,87
6
- fastmcp/cli/claude.py,sha256=IAlcZ4qZKBBj09jZUMEx7EANZE_IR3vcu7zOBJmMOuU,4567
7
- fastmcp/cli/cli.py,sha256=0k1zyTNFPjTe8zdqMhUY8MGAfJIPPoz-Zwylf3uhSCk,13925
8
- fastmcp/client/__init__.py,sha256=BXO9NUhntZ5GnUACfaRCzDJ5IzxqFJs8qKG-CRMSco4,490
9
- fastmcp/client/base.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
10
- fastmcp/client/client.py,sha256=hiCc7PAPzHhhLW-L5yQhVMn390nthQESh_PyH7k_gck,6650
11
- fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
12
- fastmcp/client/sampling.py,sha256=WdRhIZbWv54rXYI8lWHv0thXmGCloZYPFpwJK9El_sQ,1613
13
- fastmcp/client/transports.py,sha256=gA_aGjgPY2q_PqaURkes_vUKtuUicViTHYEe4TAkDmU,13864
14
- fastmcp/prompts/__init__.py,sha256=23GNQg1AYPGnz0AfNa0IK7NCpzDOr-arHze-ldWvAg4,106
15
- fastmcp/prompts/base.py,sha256=sPkax0-LZu8EJ__aiD8ZWhCK4Af9j6NPJilH7ZwG_7E,5718
16
- fastmcp/prompts/prompt_manager.py,sha256=lKo6WWeWnAmCpkzXzAMf2jUttwrXKlElPEEKudaAgww,2574
17
- fastmcp/resources/__init__.py,sha256=e4S369jBoJt07ez9_ZaJefzGfz4kr9nGwG4KPMzMHc8,464
18
- fastmcp/resources/base.py,sha256=UFl1SalsiRsicCUw_ItTUl4BnSW4WeV-aMIr0BI7spY,1355
19
- fastmcp/resources/resource_manager.py,sha256=zgEKSbNKDmlsnbnckd76IXFDvEmwxh0AtW2_uAQ8Ij0,5889
20
- fastmcp/resources/templates.py,sha256=EocMjazS0TT7Ef9JO0_QtAjgpFjzH5OQzs1Md17DIic,2961
21
- fastmcp/resources/types.py,sha256=-53oBf9C0wyaHq_Dqos6B1CR_MF0Crv6sFFn0uq2zzM,6186
22
- fastmcp/server/__init__.py,sha256=pdkghG11VLMZiluQ-4_rl2JK1LMWmV003m9dDRUN8W4,92
23
- fastmcp/server/context.py,sha256=SPYr3KUBG9MmKRh6Y6tfzPNgdxR5TmPGfnVwcEMqwMM,7115
24
- fastmcp/server/openapi.py,sha256=6b10nnaaZxGoSyPxQyqLDX7NmcHMlbPms1zQudnbets,22268
25
- fastmcp/server/proxy.py,sha256=Ry3fmIwd6eiOd1rjzgLFMKGIjq-uvLDVdiqpS1G4Wfw,8018
26
- fastmcp/server/server.py,sha256=Qh_pCNKQLFqjEbl9DMMvBMUD5cuktQoQSNjPDF1jrkc,23937
27
- fastmcp/tools/__init__.py,sha256=ZboxhyMJDl87Svjov8YwNYwNZi55P9VhmpTjBZLesnk,96
28
- fastmcp/tools/base.py,sha256=DvHEWuQxBfp8e_FRWS8_oBSq7JL7m2Gm9gkaivk-eb8,3033
29
- fastmcp/tools/tool_manager.py,sha256=zDWeuWAev1uyWO95GkXbRx9sXfJ3Iom7CyVHz0bs5GY,3051
30
- fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
31
- fastmcp/utilities/func_metadata.py,sha256=ODD9ds7bGXED27rx4MiMim1EBPnjNHIcXabJhynVKBA,7739
32
- fastmcp/utilities/logging.py,sha256=1ipiOXzgWUp3Vih_JtEiLX7aAFmrUDZNr4KrZbofZTM,818
33
- fastmcp/utilities/openapi.py,sha256=yl83QsOcLZc00vScdL2LpEopzVCv32gDpC5da9NGkTM,30351
34
- fastmcp/utilities/types.py,sha256=rsNHw-O0IfZrCPkSQbmM-hJ2We8lnqra834HbtD2Clo,1760
35
- fastmcp-2.0.0.dist-info/METADATA,sha256=0-fdfOLJbdvUw-mXCW1Ol_dP4CMyh7-YneErxG3-vdI,26270
36
- fastmcp-2.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
37
- fastmcp-2.0.0.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
38
- fastmcp-2.0.0.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
39
- fastmcp-2.0.0.dist-info/RECORD,,