fastmcp 2.7.0__py3-none-any.whl → 2.7.1__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.
fastmcp/cli/cli.py CHANGED
@@ -1,4 +1,4 @@
1
- """FastmMCP CLI tools."""
1
+ """FastMCP CLI tools."""
2
2
 
3
3
  import importlib.metadata
4
4
  import importlib.util
@@ -32,6 +32,7 @@ from mcp.shared.memory import create_connected_server_and_client_session
32
32
  from pydantic import AnyUrl
33
33
  from typing_extensions import Unpack
34
34
 
35
+ from fastmcp.client.auth.bearer import BearerAuth
35
36
  from fastmcp.client.auth.oauth import OAuth
36
37
  from fastmcp.server.dependencies import get_http_headers
37
38
  from fastmcp.server.server import FastMCP
@@ -152,7 +153,7 @@ class WSTransport(ClientTransport):
152
153
  yield session
153
154
 
154
155
  def __repr__(self) -> str:
155
- return f"<WebSocket(url='{self.url}')>"
156
+ return f"<WebSocketTransport(url='{self.url}')>"
156
157
 
157
158
 
158
159
  class SSETransport(ClientTransport):
@@ -183,8 +184,7 @@ class SSETransport(ClientTransport):
183
184
  if auth == "oauth":
184
185
  auth = OAuth(self.url)
185
186
  elif isinstance(auth, str):
186
- self.headers["Authorization"] = auth
187
- auth = None
187
+ auth = BearerAuth(auth)
188
188
  self.auth = auth
189
189
 
190
190
  @contextlib.asynccontextmanager
@@ -221,7 +221,7 @@ class SSETransport(ClientTransport):
221
221
  yield session
222
222
 
223
223
  def __repr__(self) -> str:
224
- return f"<SSE(url='{self.url}')>"
224
+ return f"<SSETransport(url='{self.url}')>"
225
225
 
226
226
 
227
227
  class StreamableHttpTransport(ClientTransport):
@@ -252,8 +252,7 @@ class StreamableHttpTransport(ClientTransport):
252
252
  if auth == "oauth":
253
253
  auth = OAuth(self.url)
254
254
  elif isinstance(auth, str):
255
- self.headers["Authorization"] = auth
256
- auth = None
255
+ auth = BearerAuth(auth)
257
256
  self.auth = auth
258
257
 
259
258
  @contextlib.asynccontextmanager
@@ -291,7 +290,7 @@ class StreamableHttpTransport(ClientTransport):
291
290
  yield session
292
291
 
293
292
  def __repr__(self) -> str:
294
- return f"<StreamableHttp(url='{self.url}')>"
293
+ return f"<StreamableHttpTransport(url='{self.url}')>"
295
294
 
296
295
 
297
296
  class StdioTransport(ClientTransport):
@@ -683,7 +682,7 @@ class FastMCPTransport(ClientTransport):
683
682
  yield session
684
683
 
685
684
  def __repr__(self) -> str:
686
- return f"<FastMCP(server='{self.server.name}')>"
685
+ return f"<FastMCPTransport(server='{self.server.name}')>"
687
686
 
688
687
 
689
688
  class MCPConfigTransport(ClientTransport):
@@ -769,7 +768,7 @@ class MCPConfigTransport(ClientTransport):
769
768
  yield session
770
769
 
771
770
  def __repr__(self) -> str:
772
- return f"<MCPConfig(config='{self.config}')>"
771
+ return f"<MCPConfigTransport(config='{self.config}')>"
773
772
 
774
773
 
775
774
  @overload
fastmcp/prompts/prompt.py CHANGED
@@ -59,7 +59,7 @@ class PromptArgument(FastMCPBaseModel):
59
59
 
60
60
  name: str = Field(description="Name of the argument")
61
61
  description: str | None = Field(
62
- None, description="Description of what the argument does"
62
+ default=None, description="Description of what the argument does"
63
63
  )
64
64
  required: bool = Field(
65
65
  default=False, description="Whether the argument is required"
@@ -71,13 +71,13 @@ class Prompt(FastMCPBaseModel, ABC):
71
71
 
72
72
  name: str = Field(description="Name of the prompt")
73
73
  description: str | None = Field(
74
- None, description="Description of what the prompt does"
74
+ default=None, description="Description of what the prompt does"
75
75
  )
76
76
  tags: Annotated[set[str], BeforeValidator(_convert_set_defaults)] = Field(
77
77
  default_factory=set, description="Tags for the prompt"
78
78
  )
79
79
  arguments: list[PromptArgument] | None = Field(
80
- None, description="Arguments that can be passed to the prompt"
80
+ default=None, description="Arguments that can be passed to the prompt"
81
81
  )
82
82
 
83
83
  def __eq__(self, other: object) -> bool:
@@ -38,9 +38,9 @@ class Resource(FastMCPBaseModel, abc.ABC):
38
38
  uri: Annotated[AnyUrl, UrlConstraints(host_required=False)] = Field(
39
39
  default=..., description="URI of the resource"
40
40
  )
41
- name: str | None = Field(description="Name of the resource", default=None)
41
+ name: str | None = Field(default=None, description="Name of the resource")
42
42
  description: str | None = Field(
43
- description="Description of the resource", default=None
43
+ default=None, description="Description of the resource"
44
44
  )
45
45
  tags: Annotated[set[str], BeforeValidator(_convert_set_defaults)] = Field(
46
46
  default_factory=set, description="Tags for the resource"
@@ -67,6 +67,7 @@ def get_http_headers(include_all: bool = False) -> dict[str, str]:
67
67
  "te",
68
68
  "keep-alive",
69
69
  "expect",
70
+ "accept",
70
71
  # Proxy-related headers
71
72
  "proxy-authenticate",
72
73
  "proxy-authorization",
fastmcp/server/http.py CHANGED
@@ -13,6 +13,7 @@ from mcp.server.auth.middleware.bearer_auth import (
13
13
  from mcp.server.auth.routes import create_auth_routes
14
14
  from mcp.server.lowlevel.server import LifespanResultT
15
15
  from mcp.server.sse import SseServerTransport
16
+ from mcp.server.streamable_http import EventStore
16
17
  from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
17
18
  from starlette.applications import Starlette
18
19
  from starlette.middleware import Middleware
@@ -241,7 +242,7 @@ def create_sse_app(
241
242
  def create_streamable_http_app(
242
243
  server: FastMCP[LifespanResultT],
243
244
  streamable_http_path: str,
244
- event_store: None = None,
245
+ event_store: EventStore | None = None,
245
246
  auth: OAuthProvider | None = None,
246
247
  json_response: bool = False,
247
248
  stateless_http: bool = False,
fastmcp/server/server.py CHANGED
@@ -41,6 +41,7 @@ from starlette.requests import Request
41
41
  from starlette.responses import Response
42
42
  from starlette.routing import BaseRoute, Route
43
43
 
44
+ import fastmcp
44
45
  import fastmcp.server
45
46
  import fastmcp.settings
46
47
  from fastmcp.exceptions import NotFoundError
@@ -131,6 +132,8 @@ class FastMCP(Generic[LifespanResultT]):
131
132
  tools: list[Tool | Callable[..., Any]] | None = None,
132
133
  **settings: Any,
133
134
  ):
135
+ if cache_expiration_seconds is not None:
136
+ settings["cache_expiration_seconds"] = cache_expiration_seconds
134
137
  self.settings = fastmcp.settings.ServerSettings(**settings)
135
138
 
136
139
  # If mask_error_details is provided, override the settings value
@@ -148,7 +151,9 @@ class FastMCP(Generic[LifespanResultT]):
148
151
  self.tags: set[str] = tags or set()
149
152
  self.dependencies = dependencies
150
153
  self._cache = TimedCache(
151
- expiration=datetime.timedelta(seconds=cache_expiration_seconds or 0)
154
+ expiration=datetime.timedelta(
155
+ seconds=self.settings.cache_expiration_seconds
156
+ )
152
157
  )
153
158
  self._mounted_servers: dict[str, MountedServer] = {}
154
159
  self._additional_http_routes: list[BaseRoute] = []
@@ -490,11 +495,7 @@ class FastMCP(Generic[LifespanResultT]):
490
495
  with the Context type annotation. See the @tool decorator for examples.
491
496
 
492
497
  Args:
493
- fn: The function to register as a tool
494
- name: Optional name for the tool (defaults to function name)
495
- description: Optional description of what the tool does
496
- tags: Optional set of tags for categorizing the tool
497
- annotations: Optional annotations about the tool's behavior
498
+ tool: The Tool instance to register
498
499
  """
499
500
  self._tool_manager.add_tool(tool)
500
501
  self._cache.clear()
@@ -864,7 +865,7 @@ class FastMCP(Generic[LifespanResultT]):
864
865
 
865
866
  This decorator supports multiple calling patterns:
866
867
  - @server.prompt (without parentheses)
867
- - @server.prompt (with empty parentheses)
868
+ - @server.prompt() (with empty parentheses)
868
869
  - @server.prompt("custom_name") (with name as first argument)
869
870
  - @server.prompt(name="custom_name") (with name as keyword argument)
870
871
  - server.prompt(function, name="custom_name") (direct function call)
@@ -886,7 +887,7 @@ class FastMCP(Generic[LifespanResultT]):
886
887
  }
887
888
  ]
888
889
 
889
- @server.prompt
890
+ @server.prompt()
890
891
  def analyze_with_context(table_name: str, ctx: Context) -> list[Message]:
891
892
  ctx.info(f"Analyzing table {table_name}")
892
893
  schema = read_table_schema(table_name)
fastmcp/settings.py CHANGED
@@ -170,7 +170,7 @@ class ServerSettings(BaseSettings):
170
170
  ),
171
171
  ] = []
172
172
 
173
- # cache settings (for checking mounted servers)
173
+ # cache settings (for getting attributes from servers, used to avoid repeated calls)
174
174
  cache_expiration_seconds: float = 0
175
175
 
176
176
  # StreamableHTTP settings
fastmcp/tools/tool.py CHANGED
@@ -45,14 +45,14 @@ class Tool(FastMCPBaseModel, ABC):
45
45
  default_factory=set, description="Tags for the tool"
46
46
  )
47
47
  annotations: ToolAnnotations | None = Field(
48
- None, description="Additional annotations about the tool"
48
+ default=None, description="Additional annotations about the tool"
49
49
  )
50
50
  exclude_args: list[str] | None = Field(
51
- None,
51
+ default=None,
52
52
  description="Arguments to exclude from the tool schema, such as State, Memory, or Credential",
53
53
  )
54
54
  serializer: Callable[[Any], str] | None = Field(
55
- None, description="Optional custom serializer for tool results"
55
+ default=None, description="Optional custom serializer for tool results"
56
56
  )
57
57
 
58
58
  def to_mcp_tool(self, **overrides: Any) -> MCPTool:
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Literal
3
+ from typing import TYPE_CHECKING, Annotated, Any, Literal
4
4
  from urllib.parse import urlparse
5
5
 
6
6
  from pydantic import AnyUrl, Field
@@ -56,6 +56,12 @@ class RemoteMCPServer(FastMCPBaseModel):
56
56
  url: str
57
57
  headers: dict[str, str] = Field(default_factory=dict)
58
58
  transport: Literal["streamable-http", "sse", "http"] | None = None
59
+ auth: Annotated[
60
+ str | Literal["oauth"] | None,
61
+ Field(
62
+ description='Either a string representing a Bearer token or the literal "oauth" to use OAuth authentication.'
63
+ ),
64
+ ] = None
59
65
 
60
66
  def to_transport(self) -> StreamableHttpTransport | SSETransport:
61
67
  from fastmcp.client.transports import SSETransport, StreamableHttpTransport
@@ -66,9 +72,11 @@ class RemoteMCPServer(FastMCPBaseModel):
66
72
  transport = self.transport
67
73
 
68
74
  if transport == "sse":
69
- return SSETransport(self.url, headers=self.headers)
75
+ return SSETransport(self.url, headers=self.headers, auth=self.auth)
70
76
  else:
71
- return StreamableHttpTransport(self.url, headers=self.headers)
77
+ return StreamableHttpTransport(
78
+ self.url, headers=self.headers, auth=self.auth
79
+ )
72
80
 
73
81
 
74
82
  class MCPConfig(FastMCPBaseModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.7.0
3
+ Version: 2.7.1
4
4
  Summary: The fast, Pythonic way to build MCP servers.
5
5
  Project-URL: Homepage, https://gofastmcp.com
6
6
  Project-URL: Repository, https://github.com/jlowin/fastmcp
@@ -1,10 +1,10 @@
1
1
  fastmcp/__init__.py,sha256=yTAqLZORsPqbr7AE0ayw6zIYBeMlxQlI-3HE2WqbvHk,435
2
2
  fastmcp/exceptions.py,sha256=YvaKqOT3w0boXF9ylIoaSIzW9XiQ1qLFG1LZq6B60H8,680
3
3
  fastmcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- fastmcp/settings.py,sha256=DbFdWx4EVHhJZF6e2GB0pBMCSjc425kXIVY8mqfOVX8,6175
4
+ fastmcp/settings.py,sha256=aZHD42Mz1SkhbgGAInYPXL7Aba3snpRsySYnPocIftk,6212
5
5
  fastmcp/cli/__init__.py,sha256=Ii284TNoG5lxTP40ETMGhHEq3lQZWxu9m9JuU57kUpQ,87
6
6
  fastmcp/cli/claude.py,sha256=IAlcZ4qZKBBj09jZUMEx7EANZE_IR3vcu7zOBJmMOuU,4567
7
- fastmcp/cli/cli.py,sha256=zoHJ8DjUBLISVb4VHaVP-fCJP4Y8zG6-UhhNqSvczqY,12667
7
+ fastmcp/cli/cli.py,sha256=Nxkl_9kdHP6ufaT9nN9_w23JebkUKn76Sd3XB6UnvH4,12666
8
8
  fastmcp/cli/run.py,sha256=sGH7M3Yi8HGju4sPypKGk3P2cdZq1n3l-_CpJmdGvDc,6277
9
9
  fastmcp/client/__init__.py,sha256=kd2hhSuD8rZuF87c9zlPJP_icJ-Rx3exyNoK0EzfOtE,617
10
10
  fastmcp/client/client.py,sha256=vQk0l6htoD6CyO0le8q23iYd5hX1l8NIbxchedbWqgE,24872
@@ -13,7 +13,7 @@ fastmcp/client/oauth_callback.py,sha256=ODAnVX-ettL82RuI5KpfkKf8iDtYMDue3Tnab5sj
13
13
  fastmcp/client/progress.py,sha256=WjLLDbUKMsx8DK-fqO7AGsXb83ak-6BMrLvzzznGmcI,1043
14
14
  fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
15
15
  fastmcp/client/sampling.py,sha256=UlDHxnd6k_HoU8RA3ob0g8-e6haJBc9u27N_v291QoI,1698
16
- fastmcp/client/transports.py,sha256=Pi4g2B9lKbgvey-7lTLkjsSVxE2DoT2yMq82D7xktK0,32091
16
+ fastmcp/client/transports.py,sha256=2lKuqIznxZd9irJ-Cb8bBeVi32xa_YfouW2Y5kAAIWU,32112
17
17
  fastmcp/client/auth/__init__.py,sha256=4DNsfp4iaQeBcpds0JDdMn6Mmfud44stWLsret0sVKY,91
18
18
  fastmcp/client/auth/bearer.py,sha256=MFEFqcH6u_V86msYiOsEFKN5ks1V9BnBNiPsPLHUTqo,399
19
19
  fastmcp/client/auth/oauth.py,sha256=LJHCB-34EC-sL9GC97XFQkyanK8Cc5skAp6GkH0tKzE,14709
@@ -27,20 +27,20 @@ fastmcp/contrib/mcp_mixin/__init__.py,sha256=aw9IQ1ssNjCgws4ZNt8bkdpossAAGVAwwjB
27
27
  fastmcp/contrib/mcp_mixin/example.py,sha256=GnunkXmtG5hLLTUsM8aW5ZURU52Z8vI4tNLl-fK7Dg0,1228
28
28
  fastmcp/contrib/mcp_mixin/mcp_mixin.py,sha256=3e0wHlKI9OF12t-SbpRTL-TWjBBLw7T8ATjCdoDtX6k,8173
29
29
  fastmcp/prompts/__init__.py,sha256=An8uMBUh9Hrb7qqcn_5_Hent7IOeSh7EA2IUVsIrtHc,179
30
- fastmcp/prompts/prompt.py,sha256=FMvDO3491LJkdPSorKKwr_2KtDJx_C54iYDbGtBzH5M,9474
30
+ fastmcp/prompts/prompt.py,sha256=tQdbY9vuIoza8NZp8SoaZ1s3GJ13sBGz8jlZOtdb8f0,9498
31
31
  fastmcp/prompts/prompt_manager.py,sha256=zAxlMzNHt8z5tD6lHl60aETvCBq6FNfE_1I4p5juKRE,4161
32
32
  fastmcp/resources/__init__.py,sha256=y1iAuqx-GIrS1NqIYzKezIDiYyjNEzzHD35epHpMnXE,463
33
- fastmcp/resources/resource.py,sha256=pvyeuUJvBGyudvxEKiBsof8B5X1EfYpCNwC4wO3-rZA,5139
33
+ fastmcp/resources/resource.py,sha256=xENm0LLw01cxFbEip68bYanDlm4YFqJy2lckKQwSIeo,5139
34
34
  fastmcp/resources/resource_manager.py,sha256=AZO05oYJ6DmFst7hWedT6Jx7WfhISodw4K-HdQpY5iI,11761
35
35
  fastmcp/resources/template.py,sha256=EDoPOMFRwCNHugEtmlcuTuWx2O1qe5_nUOLrGNYvsXM,8749
36
36
  fastmcp/resources/types.py,sha256=SiYNLnpXT-mHgNUrzqKUvXYUsY-V3gwJIrYdJfFwDDo,4868
37
37
  fastmcp/server/__init__.py,sha256=bMD4aQD4yJqLz7-mudoNsyeV8UgQfRAg3PRwPvwTEds,119
38
38
  fastmcp/server/context.py,sha256=7r-gxMiCgDpd9AStTk0hwfme540H7S1dEcU0bjoerxU,10169
39
- fastmcp/server/dependencies.py,sha256=DfN40fz4UkmdzvVg3QesuHKUVJ07iQU5ookkWawAoH4,2336
40
- fastmcp/server/http.py,sha256=RbUnqqKsiThOGZwJH-BIzC5_V1EXQh9tBlN4S-JJhbY,11624
39
+ fastmcp/server/dependencies.py,sha256=iKJdz1XsVJcrfHo_reXj9ZSldw-HeAwsp9S6lAgfGA8,2358
40
+ fastmcp/server/http.py,sha256=2v4_N9piolv4z8Nbkn8K0TtHOZzs683mUNA81uGdDdY,11687
41
41
  fastmcp/server/openapi.py,sha256=heLQA3B57nCOLNsbOYLVFbZGI8XQaVeXL6ST5L55vuo,38596
42
42
  fastmcp/server/proxy.py,sha256=EVup0L4gGMnxkG2SJHE09ugKvfhPyJ_3AnkhAS-Dc3E,9562
43
- fastmcp/server/server.py,sha256=pupGTlXcbindBILxYQoFYqQomQcDMK5QS04vTngYIdk,65399
43
+ fastmcp/server/server.py,sha256=hSLnp-zn2HP3DIGiYN-HhYaf7vrTDq4LzV2mQhvXjPE,65301
44
44
  fastmcp/server/auth/__init__.py,sha256=doHCLwOIElvH1NrTdpeP9JKfnNf3MDYPSpQfdsQ-uI0,84
45
45
  fastmcp/server/auth/auth.py,sha256=kz02HGwXYU0N0clURZDjFNWdKSpTYmgmCnGJN-jSG3Y,1640
46
46
  fastmcp/server/auth/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -48,7 +48,7 @@ fastmcp/server/auth/providers/bearer.py,sha256=3pTKL3tEU7FlCD5yI81LTa2n0dBsM7GRp
48
48
  fastmcp/server/auth/providers/bearer_env.py,sha256=MXsr4rjRm8DDmbdNd7IEXT6naCq48fkC1LlpoFAjt7c,1971
49
49
  fastmcp/server/auth/providers/in_memory.py,sha256=sCRJambxXFZLg_EbJ5ma-aUZvtxuuKbGy7lTxIbzVb0,13772
50
50
  fastmcp/tools/__init__.py,sha256=G-XFAr0RhVFj_crAZFaWZDUqcBPCTCyzAndpKXtpIFc,126
51
- fastmcp/tools/tool.py,sha256=J5VDyQE85IyZPXEq8x0n1V2qdNJ5zVlgB7FkzxJwW9E,9994
51
+ fastmcp/tools/tool.py,sha256=bQASYcig9y82Qczk9RHQEOlwU0h5MfNB9UqhsQLIgpo,10018
52
52
  fastmcp/tools/tool_manager.py,sha256=C3mB0lgQU-vmcrUltqck-Yx7zrnIHXthHijS-dJliU8,4724
53
53
  fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
54
54
  fastmcp/utilities/cache.py,sha256=aV3oZ-ZhMgLSM9iAotlUlEy5jFvGXrVo0Y5Bj4PBtqY,707
@@ -56,12 +56,12 @@ fastmcp/utilities/exceptions.py,sha256=Aax9K0larjzrrgJBS6o_PQwoIrvBvVwck2suZvgaf
56
56
  fastmcp/utilities/http.py,sha256=1ns1ymBS-WSxbZjGP6JYjSO52Wa_ls4j4WbnXiupoa4,245
57
57
  fastmcp/utilities/json_schema.py,sha256=m65XU9lPq7pCxJ9vvCeGRl0HOFr6ArezvYpMBR6-gAg,3777
58
58
  fastmcp/utilities/logging.py,sha256=B1WNO-ZWFjd9wiFSh13YtW1hAKaNmbpscDZleIAhr-g,1317
59
- fastmcp/utilities/mcp_config.py,sha256=Htux1dKyDaeK6-gT_fZwpJ_yj0MxUjGfPFAY3Dnnxsk,2233
59
+ fastmcp/utilities/mcp_config.py,sha256=8mDEMctTrB_BmtsD-ASjieELHB0eqGfiYksxYIp4vms,2527
60
60
  fastmcp/utilities/openapi.py,sha256=ctceiGb4jYgzZGSseMb-yZccEEXf41P-dhB3ae9lGdk,38992
61
61
  fastmcp/utilities/tests.py,sha256=4Vuua6nVgbE5uQspEK0fk4tBuJ0rO4GTBmnyD0kXJPA,3930
62
62
  fastmcp/utilities/types.py,sha256=HX1y4JrDC3sZA2ENRqsyxMyLQepr5-JiS9StXhIX8TE,4548
63
- fastmcp-2.7.0.dist-info/METADATA,sha256=kXjE9Y1-qt0-OP2PVR2b1Gjdp6QKb68olWBNxM5xQmc,17687
64
- fastmcp-2.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
65
- fastmcp-2.7.0.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
66
- fastmcp-2.7.0.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
67
- fastmcp-2.7.0.dist-info/RECORD,,
63
+ fastmcp-2.7.1.dist-info/METADATA,sha256=jB0fcE8mHVupX27jlehFf55wurmm4mvUp9i3PIfvU7s,17687
64
+ fastmcp-2.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
65
+ fastmcp-2.7.1.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
66
+ fastmcp-2.7.1.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
67
+ fastmcp-2.7.1.dist-info/RECORD,,