fastmcp 2.1.1__py3-none-any.whl → 2.1.2__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/prompts/prompt.py +0 -8
- fastmcp/prompts/prompt_manager.py +3 -1
- fastmcp/resources/resource.py +1 -9
- fastmcp/resources/resource_manager.py +5 -4
- fastmcp/resources/template.py +0 -8
- fastmcp/tools/tool.py +0 -8
- fastmcp/tools/tool_manager.py +4 -1
- fastmcp/utilities/logging.py +14 -6
- fastmcp/utilities/openapi.py +0 -87
- {fastmcp-2.1.1.dist-info → fastmcp-2.1.2.dist-info}/METADATA +15 -3
- {fastmcp-2.1.1.dist-info → fastmcp-2.1.2.dist-info}/RECORD +14 -14
- {fastmcp-2.1.1.dist-info → fastmcp-2.1.2.dist-info}/WHEEL +0 -0
- {fastmcp-2.1.1.dist-info → fastmcp-2.1.2.dist-info}/entry_points.txt +0 -0
- {fastmcp-2.1.1.dist-info → fastmcp-2.1.2.dist-info}/licenses/LICENSE +0 -0
fastmcp/prompts/prompt.py
CHANGED
|
@@ -8,7 +8,6 @@ from typing import Annotated, Any, Literal
|
|
|
8
8
|
import pydantic_core
|
|
9
9
|
from mcp.types import EmbeddedResource, ImageContent, TextContent
|
|
10
10
|
from pydantic import BaseModel, BeforeValidator, Field, TypeAdapter, validate_call
|
|
11
|
-
from typing_extensions import Self
|
|
12
11
|
|
|
13
12
|
from fastmcp.utilities.types import _convert_set_defaults
|
|
14
13
|
|
|
@@ -163,13 +162,6 @@ class Prompt(BaseModel):
|
|
|
163
162
|
except Exception as e:
|
|
164
163
|
raise ValueError(f"Error rendering prompt {self.name}: {e}")
|
|
165
164
|
|
|
166
|
-
def copy(self, updates: dict[str, Any] | None = None) -> Self:
|
|
167
|
-
"""Copy the prompt with optional updates."""
|
|
168
|
-
data = self.model_dump()
|
|
169
|
-
if updates:
|
|
170
|
-
data.update(updates)
|
|
171
|
-
return type(self)(**data)
|
|
172
|
-
|
|
173
165
|
def __eq__(self, other: object) -> bool:
|
|
174
166
|
if not isinstance(other, Prompt):
|
|
175
167
|
return False
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Prompt management functionality."""
|
|
2
2
|
|
|
3
|
+
import copy
|
|
3
4
|
from collections.abc import Awaitable, Callable
|
|
4
5
|
from typing import Any
|
|
5
6
|
|
|
@@ -84,7 +85,8 @@ class PromptManager:
|
|
|
84
85
|
# Create prefixed name
|
|
85
86
|
prefixed_name = f"{prefix}{name}" if prefix else name
|
|
86
87
|
|
|
87
|
-
new_prompt =
|
|
88
|
+
new_prompt = copy.copy(prompt)
|
|
89
|
+
new_prompt.name = prefixed_name
|
|
88
90
|
|
|
89
91
|
# Store the prompt with the prefixed name
|
|
90
92
|
self.add_prompt(new_prompt)
|
fastmcp/resources/resource.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Base classes and interfaces for FastMCP resources."""
|
|
2
2
|
|
|
3
3
|
import abc
|
|
4
|
-
from typing import Annotated
|
|
4
|
+
from typing import Annotated
|
|
5
5
|
|
|
6
6
|
from pydantic import (
|
|
7
7
|
AnyUrl,
|
|
@@ -13,7 +13,6 @@ from pydantic import (
|
|
|
13
13
|
ValidationInfo,
|
|
14
14
|
field_validator,
|
|
15
15
|
)
|
|
16
|
-
from typing_extensions import Self
|
|
17
16
|
|
|
18
17
|
from fastmcp.utilities.types import _convert_set_defaults
|
|
19
18
|
|
|
@@ -54,13 +53,6 @@ class Resource(BaseModel, abc.ABC):
|
|
|
54
53
|
"""Read the resource content."""
|
|
55
54
|
pass
|
|
56
55
|
|
|
57
|
-
def copy(self, updates: dict[str, Any] | None = None) -> Self:
|
|
58
|
-
"""Copy the resource with optional updates."""
|
|
59
|
-
data = self.model_dump()
|
|
60
|
-
if updates:
|
|
61
|
-
data.update(updates)
|
|
62
|
-
return type(self)(**data)
|
|
63
|
-
|
|
64
56
|
def __eq__(self, other: object) -> bool:
|
|
65
57
|
if not isinstance(other, Resource):
|
|
66
58
|
return False
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Resource manager functionality."""
|
|
2
2
|
|
|
3
|
+
import copy
|
|
3
4
|
import inspect
|
|
4
5
|
import re
|
|
5
6
|
from collections.abc import Callable
|
|
@@ -238,7 +239,8 @@ class ResourceManager:
|
|
|
238
239
|
# Create prefixed URI and copy the resource with the new URI
|
|
239
240
|
prefixed_uri = f"{prefix}{uri}" if prefix else uri
|
|
240
241
|
|
|
241
|
-
new_resource =
|
|
242
|
+
new_resource = copy.copy(resource)
|
|
243
|
+
new_resource.uri = AnyUrl(prefixed_uri)
|
|
242
244
|
|
|
243
245
|
# Store directly in resources dictionary
|
|
244
246
|
self.add_resource(new_resource)
|
|
@@ -266,9 +268,8 @@ class ResourceManager:
|
|
|
266
268
|
f"{prefix}{uri_template}" if prefix else uri_template
|
|
267
269
|
)
|
|
268
270
|
|
|
269
|
-
new_template =
|
|
270
|
-
|
|
271
|
-
)
|
|
271
|
+
new_template = copy.copy(template)
|
|
272
|
+
new_template.uri_template = prefixed_uri_template
|
|
272
273
|
|
|
273
274
|
# Store directly in templates dictionary
|
|
274
275
|
self.add_template(new_template)
|
fastmcp/resources/template.py
CHANGED
|
@@ -8,7 +8,6 @@ from collections.abc import Callable
|
|
|
8
8
|
from typing import Annotated, Any
|
|
9
9
|
|
|
10
10
|
from pydantic import BaseModel, BeforeValidator, Field, TypeAdapter, validate_call
|
|
11
|
-
from typing_extensions import Self
|
|
12
11
|
|
|
13
12
|
from fastmcp.resources.types import FunctionResource, Resource
|
|
14
13
|
from fastmcp.utilities.types import _convert_set_defaults
|
|
@@ -92,13 +91,6 @@ class ResourceTemplate(BaseModel):
|
|
|
92
91
|
except Exception as e:
|
|
93
92
|
raise ValueError(f"Error creating resource from template: {e}")
|
|
94
93
|
|
|
95
|
-
def copy(self, updates: dict[str, Any] | None = None) -> Self:
|
|
96
|
-
"""Copy the resource template with optional updates."""
|
|
97
|
-
data = self.model_dump()
|
|
98
|
-
if updates:
|
|
99
|
-
data.update(updates)
|
|
100
|
-
return type(self)(**data)
|
|
101
|
-
|
|
102
94
|
def __eq__(self, other: object) -> bool:
|
|
103
95
|
if not isinstance(other, ResourceTemplate):
|
|
104
96
|
return False
|
fastmcp/tools/tool.py
CHANGED
|
@@ -5,7 +5,6 @@ from collections.abc import Callable
|
|
|
5
5
|
from typing import TYPE_CHECKING, Annotated, Any
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel, BeforeValidator, Field
|
|
8
|
-
from typing_extensions import Self
|
|
9
8
|
|
|
10
9
|
from fastmcp.exceptions import ToolError
|
|
11
10
|
from fastmcp.utilities.func_metadata import FuncMetadata, func_metadata
|
|
@@ -102,13 +101,6 @@ class Tool(BaseModel):
|
|
|
102
101
|
except Exception as e:
|
|
103
102
|
raise ToolError(f"Error executing tool {self.name}: {e}") from e
|
|
104
103
|
|
|
105
|
-
def copy(self, updates: dict[str, Any] | None = None) -> Self:
|
|
106
|
-
"""Copy the tool with optional updates."""
|
|
107
|
-
data = self.model_dump()
|
|
108
|
-
if updates:
|
|
109
|
-
data.update(updates)
|
|
110
|
-
return type(self)(**data)
|
|
111
|
-
|
|
112
104
|
def __eq__(self, other: object) -> bool:
|
|
113
105
|
if not isinstance(other, Tool):
|
|
114
106
|
return False
|
fastmcp/tools/tool_manager.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations as _annotations
|
|
2
2
|
|
|
3
|
+
import copy
|
|
3
4
|
from collections.abc import Callable
|
|
4
5
|
from typing import TYPE_CHECKING, Any
|
|
5
6
|
|
|
@@ -90,7 +91,9 @@ class ToolManager:
|
|
|
90
91
|
for name, tool in tool_manager._tools.items():
|
|
91
92
|
prefixed_name = f"{prefix}{name}" if prefix else name
|
|
92
93
|
|
|
93
|
-
new_tool =
|
|
94
|
+
new_tool = copy.copy(tool)
|
|
95
|
+
new_tool.name = prefixed_name
|
|
96
|
+
|
|
94
97
|
# Store the copied tool
|
|
95
98
|
self.add_tool(new_tool)
|
|
96
99
|
logger.debug(f'Imported tool "{name}" as "{prefixed_name}"')
|
fastmcp/utilities/logging.py
CHANGED
|
@@ -20,15 +20,23 @@ def get_logger(name: str) -> logging.Logger:
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def configure_logging(
|
|
23
|
-
level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO",
|
|
23
|
+
level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] | int = "INFO",
|
|
24
24
|
) -> None:
|
|
25
25
|
"""Configure logging for FastMCP.
|
|
26
26
|
|
|
27
27
|
Args:
|
|
28
28
|
level: the log level to use
|
|
29
29
|
"""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
# Only configure the FastMCP logger namespace
|
|
31
|
+
handler = RichHandler(console=Console(stderr=True), rich_tracebacks=True)
|
|
32
|
+
formatter = logging.Formatter("%(message)s")
|
|
33
|
+
handler.setFormatter(formatter)
|
|
34
|
+
|
|
35
|
+
fastmcp_logger = logging.getLogger("FastMCP")
|
|
36
|
+
fastmcp_logger.setLevel(level)
|
|
37
|
+
|
|
38
|
+
# Remove any existing handlers to avoid duplicates on reconfiguration
|
|
39
|
+
for hdlr in fastmcp_logger.handlers[:]:
|
|
40
|
+
fastmcp_logger.removeHandler(hdlr)
|
|
41
|
+
|
|
42
|
+
fastmcp_logger.addHandler(handler)
|
fastmcp/utilities/openapi.py
CHANGED
|
@@ -150,93 +150,6 @@ def _resolve_ref(
|
|
|
150
150
|
return item
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
def _extract_schema_as_dict(
|
|
154
|
-
schema_obj: Schema | Reference, openapi: OpenAPI
|
|
155
|
-
) -> JsonSchema:
|
|
156
|
-
"""Resolves a schema/reference and returns it as a dictionary."""
|
|
157
|
-
resolved_schema = _resolve_ref(schema_obj, openapi)
|
|
158
|
-
if isinstance(resolved_schema, Schema):
|
|
159
|
-
# Using exclude_none=True might be better than exclude_unset sometimes
|
|
160
|
-
return resolved_schema.model_dump(mode="json", by_alias=True, exclude_none=True)
|
|
161
|
-
elif isinstance(resolved_schema, dict):
|
|
162
|
-
logger.warning(
|
|
163
|
-
"Resolved schema reference resulted in a dict, not a Schema model."
|
|
164
|
-
)
|
|
165
|
-
return resolved_schema
|
|
166
|
-
else:
|
|
167
|
-
ref_str = getattr(schema_obj, "ref", "unknown")
|
|
168
|
-
logger.warning(
|
|
169
|
-
f"Expected Schema after resolving ref '{ref_str}', got {type(resolved_schema)}. Returning empty dict."
|
|
170
|
-
)
|
|
171
|
-
return {}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def _convert_to_parameter_location(param_in: str) -> ParameterLocation:
|
|
175
|
-
"""Convert string parameter location to our ParameterLocation type."""
|
|
176
|
-
if param_in == "path":
|
|
177
|
-
return "path"
|
|
178
|
-
elif param_in == "query":
|
|
179
|
-
return "query"
|
|
180
|
-
elif param_in == "header":
|
|
181
|
-
return "header"
|
|
182
|
-
elif param_in == "cookie":
|
|
183
|
-
return "cookie"
|
|
184
|
-
else:
|
|
185
|
-
logger.warning(f"Unknown parameter location: {param_in}, defaulting to 'query'")
|
|
186
|
-
return "query"
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def _extract_responses(
|
|
190
|
-
operation_responses: dict[str, Response | Reference] | None,
|
|
191
|
-
openapi: OpenAPI,
|
|
192
|
-
) -> dict[str, ResponseInfo]:
|
|
193
|
-
"""Extracts and resolves response information for an operation."""
|
|
194
|
-
extracted_responses: dict[str, ResponseInfo] = {}
|
|
195
|
-
if not operation_responses:
|
|
196
|
-
return extracted_responses
|
|
197
|
-
|
|
198
|
-
for status_code, resp_or_ref in operation_responses.items():
|
|
199
|
-
try:
|
|
200
|
-
response = cast(Response, _resolve_ref(resp_or_ref, openapi))
|
|
201
|
-
if not isinstance(response, Response):
|
|
202
|
-
ref_str = getattr(resp_or_ref, "ref", "unknown")
|
|
203
|
-
logger.warning(
|
|
204
|
-
f"Expected Response after resolving ref '{ref_str}' for status code {status_code}, got {type(response)}. Skipping."
|
|
205
|
-
)
|
|
206
|
-
continue
|
|
207
|
-
|
|
208
|
-
content_schemas: dict[str, JsonSchema] = {}
|
|
209
|
-
if response.content:
|
|
210
|
-
for media_type_str, media_type_obj in response.content.items():
|
|
211
|
-
if (
|
|
212
|
-
isinstance(media_type_obj, MediaType)
|
|
213
|
-
and media_type_obj.media_type_schema
|
|
214
|
-
):
|
|
215
|
-
try:
|
|
216
|
-
schema_dict = _extract_schema_as_dict(
|
|
217
|
-
media_type_obj.media_type_schema, openapi
|
|
218
|
-
)
|
|
219
|
-
content_schemas[media_type_str] = schema_dict
|
|
220
|
-
except ValueError as schema_err:
|
|
221
|
-
logger.error(
|
|
222
|
-
f"Failed to extract schema for media type '{media_type_str}' in response {status_code}: {schema_err}"
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
resp_info = ResponseInfo(
|
|
226
|
-
description=response.description, content_schema=content_schemas
|
|
227
|
-
)
|
|
228
|
-
extracted_responses[str(status_code)] = resp_info
|
|
229
|
-
|
|
230
|
-
except (ValidationError, ValueError, AttributeError) as e:
|
|
231
|
-
ref_name = getattr(resp_or_ref, "ref", "unknown")
|
|
232
|
-
logger.error(
|
|
233
|
-
f"Failed to extract response for status code {status_code} (ref: '{ref_name}'): {e}",
|
|
234
|
-
exc_info=False,
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
return extracted_responses
|
|
238
|
-
|
|
239
|
-
|
|
240
153
|
# --- Main Parsing Function ---
|
|
241
154
|
# (No changes needed in the main loop logic, only in the helpers it calls)
|
|
242
155
|
def parse_openapi_to_http_routes(openapi_dict: dict[str, Any]) -> list[HTTPRoute]:
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: The fast, Pythonic way to build MCP servers.
|
|
5
|
+
Project-URL: Homepage, https://gofastmcp.com
|
|
6
|
+
Project-URL: Repository, https://github.com/jlowin/fastmcp
|
|
7
|
+
Project-URL: Documentation, https://gofastmcp.com
|
|
5
8
|
Author: Jeremiah Lowin
|
|
6
|
-
License: Apache-2.0
|
|
9
|
+
License-Expression: Apache-2.0
|
|
7
10
|
License-File: LICENSE
|
|
11
|
+
Keywords: agent,fastmcp,llm,mcp,mcp client,mcp server,model context protocol
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Typing :: Typed
|
|
8
19
|
Requires-Python: >=3.10
|
|
9
20
|
Requires-Dist: dotenv>=0.9.9
|
|
10
21
|
Requires-Dist: fastapi>=0.115.12
|
|
@@ -26,6 +37,7 @@ Description-Content-Type: text/markdown
|
|
|
26
37
|
[](https://github.com/jlowin/fastmcp/actions/workflows/run-tests.yml)
|
|
27
38
|
[](https://github.com/jlowin/fastmcp/blob/main/LICENSE)
|
|
28
39
|
|
|
40
|
+
<a href="https://trendshift.io/repositories/13266" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13266" alt="jlowin%2Ffastmcp | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
|
29
41
|
</div>
|
|
30
42
|
|
|
31
43
|
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a new, standardized way to provide context and tools to your LLMs, and FastMCP makes building MCP servers and clients simple and intuitive. Create tools, expose resources, define prompts, and connect components with clean, Pythonic code.
|
|
@@ -787,4 +799,4 @@ We use `ruff` via `pre-commit`.
|
|
|
787
799
|
|
|
788
800
|
Please open an issue or discussion for questions or suggestions!
|
|
789
801
|
|
|
790
|
-
</details>
|
|
802
|
+
</details>
|
|
@@ -12,12 +12,12 @@ fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
|
|
|
12
12
|
fastmcp/client/sampling.py,sha256=WdRhIZbWv54rXYI8lWHv0thXmGCloZYPFpwJK9El_sQ,1613
|
|
13
13
|
fastmcp/client/transports.py,sha256=WVChsDV1UF0I3reiefsT3dipIh-P_K262TXpucwH-YY,14602
|
|
14
14
|
fastmcp/prompts/__init__.py,sha256=LtPAv2JKIu54AwUd3iwv-HUd4DPcwgEqy6itEd3BH_E,194
|
|
15
|
-
fastmcp/prompts/prompt.py,sha256=
|
|
16
|
-
fastmcp/prompts/prompt_manager.py,sha256=
|
|
15
|
+
fastmcp/prompts/prompt.py,sha256=TCjIn0RyYsKDKjBYMuzSvmZPzigw4Y05EOvM0u_WBuk,5992
|
|
16
|
+
fastmcp/prompts/prompt_manager.py,sha256=fX8Ckha0byC2VEgwRoM8_w8orNAkcdxEZRCd6oRtvo4,3533
|
|
17
17
|
fastmcp/resources/__init__.py,sha256=t0x1j8lc74rjUKtXe9H5Gs4fpQt82K4NgBK6Y7A0xTg,467
|
|
18
|
-
fastmcp/resources/resource.py,sha256=
|
|
19
|
-
fastmcp/resources/resource_manager.py,sha256=
|
|
20
|
-
fastmcp/resources/template.py,sha256=
|
|
18
|
+
fastmcp/resources/resource.py,sha256=qTAj6v_NrOhI_Hd1Mc6VfsmgSNFAxsBdCJTF9W-nU_s,1755
|
|
19
|
+
fastmcp/resources/resource_manager.py,sha256=Ei1QthTUgjvSXIN-qXQeBd7aQiBNNsv0SY_lMtV9tfw,10997
|
|
20
|
+
fastmcp/resources/template.py,sha256=_4JaMeYqtQYs1IO-lgBehaHJqp16G1pQ1Qe1f9YYoNg,3455
|
|
21
21
|
fastmcp/resources/types.py,sha256=tigil7z-SUJMakGXzDLIGSqTepPrAsRpwqwtBA4yoUY,6168
|
|
22
22
|
fastmcp/server/__init__.py,sha256=pdkghG11VLMZiluQ-4_rl2JK1LMWmV003m9dDRUN8W4,92
|
|
23
23
|
fastmcp/server/context.py,sha256=s1885AZRipKB3VltfaO3VEtMxGefKs8fdZByj-4tbNI,7120
|
|
@@ -25,16 +25,16 @@ fastmcp/server/openapi.py,sha256=J7HrAlRziaB2a6pwB0wStbjRJ1E5Lf818yMqD762s5U,226
|
|
|
25
25
|
fastmcp/server/proxy.py,sha256=gYcoQFDIBraqWMOpWSsZLqefKjL_v0v74juLW1SU1AU,8058
|
|
26
26
|
fastmcp/server/server.py,sha256=ryN7o7G1gNFE1NsAuZVc3WpcmsBtcKOo-mXACN5NCoc,28814
|
|
27
27
|
fastmcp/tools/__init__.py,sha256=ocw-SFTtN6vQ8fgnlF8iNAOflRmh79xS1xdO0Bc3QPE,96
|
|
28
|
-
fastmcp/tools/tool.py,sha256=
|
|
29
|
-
fastmcp/tools/tool_manager.py,sha256=
|
|
28
|
+
fastmcp/tools/tool.py,sha256=pD3xOtryldu6lYsM5cOHnS05tJq9EwmQaoNUCZzLcoY,3598
|
|
29
|
+
fastmcp/tools/tool_manager.py,sha256=p-L1KK8ecwP2psoyrcaSwHmeUKQZf-2pLPv6S_qgIcM,3525
|
|
30
30
|
fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
|
|
31
31
|
fastmcp/utilities/decorators.py,sha256=AjhjsetQZF4YOPV5MTZmIxO21iFp_4fDIS3O2_KNCEg,2990
|
|
32
32
|
fastmcp/utilities/func_metadata.py,sha256=uh-u3gAjLD4kCcGf0ZkZZwBTTl-84JuANZTnDqP5ztI,7841
|
|
33
|
-
fastmcp/utilities/logging.py,sha256=
|
|
34
|
-
fastmcp/utilities/openapi.py,sha256=
|
|
33
|
+
fastmcp/utilities/logging.py,sha256=zav8pnFxG_fvGJHUV2XpobmT9WVrmv1mlQBSCz-CPx4,1159
|
|
34
|
+
fastmcp/utilities/openapi.py,sha256=PrH3usbTblaVC6jIH1UGiPEfgB2sSCLj33zA5dH7o_s,45193
|
|
35
35
|
fastmcp/utilities/types.py,sha256=m2rPYMzO-ZFvvZ46N-1-Xqyw693K7yq9Z2xR4pVELyk,2091
|
|
36
|
-
fastmcp-2.1.
|
|
37
|
-
fastmcp-2.1.
|
|
38
|
-
fastmcp-2.1.
|
|
39
|
-
fastmcp-2.1.
|
|
40
|
-
fastmcp-2.1.
|
|
36
|
+
fastmcp-2.1.2.dist-info/METADATA,sha256=I3ePFWEbVbqKFh3UG6bnScng4t5WEhpbq3YNR-VET34,27467
|
|
37
|
+
fastmcp-2.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
38
|
+
fastmcp-2.1.2.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
|
|
39
|
+
fastmcp-2.1.2.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
40
|
+
fastmcp-2.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|