fastmcp 2.2.6__py3-none-any.whl → 2.2.7__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/client/client.py +243 -41
- fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +1 -3
- fastmcp/prompts/prompt.py +8 -4
- fastmcp/resources/template.py +5 -2
- fastmcp/resources/types.py +4 -7
- fastmcp/server/context.py +12 -1
- fastmcp/server/openapi.py +28 -5
- fastmcp/server/proxy.py +3 -2
- fastmcp/server/server.py +243 -18
- fastmcp/settings.py +7 -0
- fastmcp/tools/tool.py +24 -22
- fastmcp/tools/tool_manager.py +16 -3
- fastmcp/utilities/http.py +44 -0
- fastmcp/utilities/openapi.py +147 -36
- fastmcp/utilities/types.py +29 -1
- {fastmcp-2.2.6.dist-info → fastmcp-2.2.7.dist-info}/METADATA +3 -3
- {fastmcp-2.2.6.dist-info → fastmcp-2.2.7.dist-info}/RECORD +20 -19
- {fastmcp-2.2.6.dist-info → fastmcp-2.2.7.dist-info}/WHEEL +0 -0
- {fastmcp-2.2.6.dist-info → fastmcp-2.2.7.dist-info}/entry_points.txt +0 -0
- {fastmcp-2.2.6.dist-info → fastmcp-2.2.7.dist-info}/licenses/LICENSE +0 -0
fastmcp/utilities/openapi.py
CHANGED
|
@@ -1001,53 +1001,153 @@ def format_description_with_responses(
|
|
|
1001
1001
|
responses: dict[
|
|
1002
1002
|
str, Any
|
|
1003
1003
|
], # Changed from specific ResponseInfo type to avoid circular imports
|
|
1004
|
+
parameters: list[openapi.ParameterInfo] | None = None, # Add parameters parameter
|
|
1005
|
+
request_body: openapi.RequestBodyInfo | None = None, # Add request_body parameter
|
|
1004
1006
|
) -> str:
|
|
1005
|
-
"""
|
|
1006
|
-
|
|
1007
|
-
|
|
1007
|
+
"""
|
|
1008
|
+
Formats the base description string with response, parameter, and request body information.
|
|
1009
|
+
|
|
1010
|
+
Args:
|
|
1011
|
+
base_description (str): The initial description to be formatted.
|
|
1012
|
+
responses (dict[str, Any]): A dictionary of response information, keyed by status code.
|
|
1013
|
+
parameters (list[openapi.ParameterInfo] | None, optional): A list of parameter information,
|
|
1014
|
+
including path and query parameters. Each parameter includes details such as name,
|
|
1015
|
+
location, whether it is required, and a description.
|
|
1016
|
+
request_body (openapi.RequestBodyInfo | None, optional): Information about the request body,
|
|
1017
|
+
including its description, whether it is required, and its content schema.
|
|
1008
1018
|
|
|
1019
|
+
Returns:
|
|
1020
|
+
str: The formatted description string with additional details about responses, parameters,
|
|
1021
|
+
and the request body.
|
|
1022
|
+
"""
|
|
1009
1023
|
desc_parts = [base_description]
|
|
1010
|
-
response_section = "\n\n**Responses:**"
|
|
1011
|
-
added_response_section = False
|
|
1012
1024
|
|
|
1013
|
-
#
|
|
1014
|
-
|
|
1015
|
-
|
|
1025
|
+
# Add parameter information
|
|
1026
|
+
if parameters:
|
|
1027
|
+
# Process path parameters
|
|
1028
|
+
path_params = [p for p in parameters if p.location == "path"]
|
|
1029
|
+
if path_params:
|
|
1030
|
+
param_section = "\n\n**Path Parameters:**"
|
|
1031
|
+
desc_parts.append(param_section)
|
|
1032
|
+
for param in path_params:
|
|
1033
|
+
required_marker = " (Required)" if param.required else ""
|
|
1034
|
+
param_desc = f"\n- **{param.name}**{required_marker}: {param.description or 'No description.'}"
|
|
1035
|
+
desc_parts.append(param_desc)
|
|
1036
|
+
|
|
1037
|
+
# Process query parameters
|
|
1038
|
+
query_params = [p for p in parameters if p.location == "query"]
|
|
1039
|
+
if query_params:
|
|
1040
|
+
param_section = "\n\n**Query Parameters:**"
|
|
1041
|
+
desc_parts.append(param_section)
|
|
1042
|
+
for param in query_params:
|
|
1043
|
+
required_marker = " (Required)" if param.required else ""
|
|
1044
|
+
param_desc = f"\n- **{param.name}**{required_marker}: {param.description or 'No description.'}"
|
|
1045
|
+
desc_parts.append(param_desc)
|
|
1046
|
+
|
|
1047
|
+
# Add request body information if present
|
|
1048
|
+
if request_body and request_body.description:
|
|
1049
|
+
req_body_section = "\n\n**Request Body:**"
|
|
1050
|
+
desc_parts.append(req_body_section)
|
|
1051
|
+
required_marker = " (Required)" if request_body.required else ""
|
|
1052
|
+
desc_parts.append(f"\n{request_body.description}{required_marker}")
|
|
1053
|
+
|
|
1054
|
+
# Add request body property descriptions if available
|
|
1055
|
+
if request_body.content_schema:
|
|
1056
|
+
media_type = (
|
|
1057
|
+
"application/json"
|
|
1058
|
+
if "application/json" in request_body.content_schema
|
|
1059
|
+
else next(iter(request_body.content_schema), None)
|
|
1060
|
+
)
|
|
1061
|
+
if media_type:
|
|
1062
|
+
schema = request_body.content_schema.get(media_type, {})
|
|
1063
|
+
if isinstance(schema, dict) and "properties" in schema:
|
|
1064
|
+
desc_parts.append("\n\n**Request Properties:**")
|
|
1065
|
+
for prop_name, prop_schema in schema["properties"].items():
|
|
1066
|
+
if (
|
|
1067
|
+
isinstance(prop_schema, dict)
|
|
1068
|
+
and "description" in prop_schema
|
|
1069
|
+
):
|
|
1070
|
+
required = prop_name in schema.get("required", [])
|
|
1071
|
+
req_mark = " (Required)" if required else ""
|
|
1072
|
+
desc_parts.append(
|
|
1073
|
+
f"\n- **{prop_name}**{req_mark}: {prop_schema['description']}"
|
|
1074
|
+
)
|
|
1016
1075
|
|
|
1017
|
-
#
|
|
1018
|
-
|
|
1076
|
+
# Add response information
|
|
1077
|
+
if responses:
|
|
1078
|
+
response_section = "\n\n**Responses:**"
|
|
1079
|
+
added_response_section = False
|
|
1019
1080
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
added_response_section = True
|
|
1081
|
+
# Determine success codes (common ones)
|
|
1082
|
+
success_codes = {"200", "201", "202", "204"} # As strings
|
|
1083
|
+
success_status = next((s for s in success_codes if s in responses), None)
|
|
1024
1084
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
f"\n- **{status_code}**{status_marker}: {resp_info.description or 'No description.'}"
|
|
1028
|
-
)
|
|
1085
|
+
# Process all responses
|
|
1086
|
+
responses_to_process = responses.items()
|
|
1029
1087
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1088
|
+
for status_code, resp_info in sorted(responses_to_process):
|
|
1089
|
+
if not added_response_section:
|
|
1090
|
+
desc_parts.append(response_section)
|
|
1091
|
+
added_response_section = True
|
|
1092
|
+
|
|
1093
|
+
status_marker = " (Success)" if status_code == success_status else ""
|
|
1094
|
+
desc_parts.append(
|
|
1095
|
+
f"\n- **{status_code}**{status_marker}: {resp_info.description or 'No description.'}"
|
|
1037
1096
|
)
|
|
1038
1097
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1098
|
+
# Process content schemas for this response
|
|
1099
|
+
if resp_info.content_schema:
|
|
1100
|
+
# Prioritize json, then take first available
|
|
1101
|
+
media_type = (
|
|
1102
|
+
"application/json"
|
|
1103
|
+
if "application/json" in resp_info.content_schema
|
|
1104
|
+
else next(iter(resp_info.content_schema), None)
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
if media_type:
|
|
1108
|
+
schema = resp_info.content_schema.get(media_type)
|
|
1109
|
+
desc_parts.append(f" - Content-Type: `{media_type}`")
|
|
1110
|
+
|
|
1111
|
+
# Add response property descriptions
|
|
1112
|
+
if isinstance(schema, dict):
|
|
1113
|
+
# Handle array responses
|
|
1114
|
+
if schema.get("type") == "array" and "items" in schema:
|
|
1115
|
+
items_schema = schema["items"]
|
|
1116
|
+
if (
|
|
1117
|
+
isinstance(items_schema, dict)
|
|
1118
|
+
and "properties" in items_schema
|
|
1119
|
+
):
|
|
1120
|
+
desc_parts.append("\n - **Response Item Properties:**")
|
|
1121
|
+
for prop_name, prop_schema in items_schema[
|
|
1122
|
+
"properties"
|
|
1123
|
+
].items():
|
|
1124
|
+
if (
|
|
1125
|
+
isinstance(prop_schema, dict)
|
|
1126
|
+
and "description" in prop_schema
|
|
1127
|
+
):
|
|
1128
|
+
desc_parts.append(
|
|
1129
|
+
f"\n - **{prop_name}**: {prop_schema['description']}"
|
|
1130
|
+
)
|
|
1131
|
+
# Handle object responses
|
|
1132
|
+
elif "properties" in schema:
|
|
1133
|
+
desc_parts.append("\n - **Response Properties:**")
|
|
1134
|
+
for prop_name, prop_schema in schema["properties"].items():
|
|
1135
|
+
if (
|
|
1136
|
+
isinstance(prop_schema, dict)
|
|
1137
|
+
and "description" in prop_schema
|
|
1138
|
+
):
|
|
1139
|
+
desc_parts.append(
|
|
1140
|
+
f"\n - **{prop_name}**: {prop_schema['description']}"
|
|
1141
|
+
)
|
|
1042
1142
|
|
|
1043
|
-
if schema:
|
|
1044
1143
|
# Generate Example
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1144
|
+
if schema:
|
|
1145
|
+
example = generate_example_from_schema(schema)
|
|
1146
|
+
if example != "unknown_type" and example is not None:
|
|
1147
|
+
desc_parts.append("\n - **Example:**")
|
|
1148
|
+
desc_parts.append(
|
|
1149
|
+
format_json_for_description(example, indent=2)
|
|
1150
|
+
)
|
|
1051
1151
|
|
|
1052
1152
|
return "\n".join(desc_parts)
|
|
1053
1153
|
|
|
@@ -1069,7 +1169,15 @@ def _combine_schemas(route: openapi.HTTPRoute) -> dict[str, Any]:
|
|
|
1069
1169
|
for param in route.parameters:
|
|
1070
1170
|
if param.required:
|
|
1071
1171
|
required.append(param.name)
|
|
1072
|
-
|
|
1172
|
+
|
|
1173
|
+
# Copy the schema and add description if available
|
|
1174
|
+
param_schema = param.schema_.copy() if isinstance(param.schema_, dict) else {}
|
|
1175
|
+
|
|
1176
|
+
# Add parameter description to schema if available and not already present
|
|
1177
|
+
if param.description and not param_schema.get("description"):
|
|
1178
|
+
param_schema["description"] = param.description
|
|
1179
|
+
|
|
1180
|
+
properties[param.name] = param_schema
|
|
1073
1181
|
|
|
1074
1182
|
# Add request body if it exists
|
|
1075
1183
|
if route.request_body and route.request_body.content_schema:
|
|
@@ -1077,8 +1185,11 @@ def _combine_schemas(route: openapi.HTTPRoute) -> dict[str, Any]:
|
|
|
1077
1185
|
content_type = next(iter(route.request_body.content_schema))
|
|
1078
1186
|
body_schema = route.request_body.content_schema[content_type]
|
|
1079
1187
|
body_props = body_schema.get("properties", {})
|
|
1188
|
+
|
|
1189
|
+
# Add request body properties
|
|
1080
1190
|
for prop_name, prop_schema in body_props.items():
|
|
1081
1191
|
properties[prop_name] = prop_schema
|
|
1192
|
+
|
|
1082
1193
|
if route.request_body.required:
|
|
1083
1194
|
required.extend(body_schema.get("required", []))
|
|
1084
1195
|
|
fastmcp/utilities/types.py
CHANGED
|
@@ -2,13 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
import base64
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from
|
|
5
|
+
from types import UnionType
|
|
6
|
+
from typing import Annotated, TypeVar, Union, get_args, get_origin
|
|
6
7
|
|
|
7
8
|
from mcp.types import ImageContent
|
|
8
9
|
|
|
9
10
|
T = TypeVar("T")
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
def issubclass_safe(cls: type, base: type) -> bool:
|
|
14
|
+
"""Check if cls is a subclass of base, even if cls is a type variable."""
|
|
15
|
+
try:
|
|
16
|
+
if origin := get_origin(cls):
|
|
17
|
+
return issubclass_safe(origin, base)
|
|
18
|
+
return issubclass(cls, base)
|
|
19
|
+
except TypeError:
|
|
20
|
+
return False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def is_class_member_of_type(cls: type, base: type) -> bool:
|
|
24
|
+
"""Check if cls is a member of base, even if cls is a type variable."""
|
|
25
|
+
origin = get_origin(cls)
|
|
26
|
+
# Handle both types of unions: UnionType (from types module, used with | syntax)
|
|
27
|
+
# and typing.Union (used with Union[] syntax)
|
|
28
|
+
if origin is UnionType or origin == Union:
|
|
29
|
+
return any(is_class_member_of_type(arg, base) for arg in get_args(cls))
|
|
30
|
+
elif origin is Annotated:
|
|
31
|
+
# For Annotated[T, ...], check if T is a member of base
|
|
32
|
+
args = get_args(cls)
|
|
33
|
+
if args:
|
|
34
|
+
return is_class_member_of_type(args[0], base)
|
|
35
|
+
return False
|
|
36
|
+
else:
|
|
37
|
+
return issubclass_safe(cls, base)
|
|
38
|
+
|
|
39
|
+
|
|
12
40
|
def _convert_set_defaults(maybe_set: set[T] | list[T] | None) -> set[T]:
|
|
13
41
|
"""Convert a set or list to a set, defaulting to an empty set if None."""
|
|
14
42
|
if maybe_set is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.7
|
|
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
|
|
@@ -19,7 +19,7 @@ Classifier: Typing :: Typed
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Requires-Dist: exceptiongroup>=1.2.2
|
|
21
21
|
Requires-Dist: httpx>=0.28.1
|
|
22
|
-
Requires-Dist: mcp<2.0.0,>=1.
|
|
22
|
+
Requires-Dist: mcp<2.0.0,>=1.7.1
|
|
23
23
|
Requires-Dist: openapi-pydantic>=0.5.1
|
|
24
24
|
Requires-Dist: python-dotenv>=1.1.0
|
|
25
25
|
Requires-Dist: rich>=13.9.4
|
|
@@ -789,7 +789,7 @@ Contributions make the open-source community vibrant! We welcome improvements an
|
|
|
789
789
|
|
|
790
790
|
Run the test suite:
|
|
791
791
|
```bash
|
|
792
|
-
uv run pytest -vv
|
|
792
|
+
uv run --frozen pytest -vv
|
|
793
793
|
```
|
|
794
794
|
|
|
795
795
|
#### Formatting & Linting
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
fastmcp/__init__.py,sha256=e-wu5UQpgduOauB-H8lzbnxv_H9K90fCJVnc1qgaAhM,413
|
|
2
2
|
fastmcp/exceptions.py,sha256=QKVHbftoZp4YZQ2NxA-t1SjztqspFdX95YTFOAmr5EE,640
|
|
3
3
|
fastmcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
fastmcp/settings.py,sha256=
|
|
4
|
+
fastmcp/settings.py,sha256=Ix_VrAegM27wpPViCJvC04dmPm2QsBgtbxcZXHGQOhM,2213
|
|
5
5
|
fastmcp/cli/__init__.py,sha256=Ii284TNoG5lxTP40ETMGhHEq3lQZWxu9m9JuU57kUpQ,87
|
|
6
6
|
fastmcp/cli/claude.py,sha256=IAlcZ4qZKBBj09jZUMEx7EANZE_IR3vcu7zOBJmMOuU,4567
|
|
7
7
|
fastmcp/cli/cli.py,sha256=wsFIYTv48_nr0mcW8vjI1l7_thr4cOrRxzo9g-qr2l8,15726
|
|
8
8
|
fastmcp/client/__init__.py,sha256=BXO9NUhntZ5GnUACfaRCzDJ5IzxqFJs8qKG-CRMSco4,490
|
|
9
9
|
fastmcp/client/base.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
fastmcp/client/client.py,sha256=
|
|
10
|
+
fastmcp/client/client.py,sha256=hzf7YZDKkRimkhsvl2c3GpN_0WVnteJnyPn_JP_jW1A,15333
|
|
11
11
|
fastmcp/client/logging.py,sha256=Q8jYcZj4KA15Yiz3RP8tBXj8sd9IxL3VThF_Y0O4Upc,356
|
|
12
12
|
fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
|
|
13
13
|
fastmcp/client/sampling.py,sha256=UlDHxnd6k_HoU8RA3ob0g8-e6haJBc9u27N_v291QoI,1698
|
|
@@ -15,36 +15,37 @@ fastmcp/client/transports.py,sha256=FMMniyxnaaHyWeFHXXP_ayOpb4jtCoyjaiqLobgYb_M,
|
|
|
15
15
|
fastmcp/contrib/README.md,sha256=rKknYSI1T192UvSszqwwDlQ2eYQpxywrNTLoj177SYU,878
|
|
16
16
|
fastmcp/contrib/bulk_tool_caller/README.md,sha256=5aUUY1TSFKtz1pvTLSDqkUCkGkuqMfMZNsLeaNqEgAc,1960
|
|
17
17
|
fastmcp/contrib/bulk_tool_caller/__init__.py,sha256=xvGSSaUXTQrc31erBoi1Gh7BikgOliETDiYVTP3rLxY,75
|
|
18
|
-
fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py,sha256=
|
|
18
|
+
fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py,sha256=2NcrGS59qvHo1lfbRaT8NSWfCxN66knciLxFvnGwCLY,4165
|
|
19
19
|
fastmcp/contrib/bulk_tool_caller/example.py,sha256=3RdsU2KrRwYZHEdVAmHOGJsO3ZJBxSaqz8BTznkPg7Y,321
|
|
20
20
|
fastmcp/contrib/mcp_mixin/README.md,sha256=9DDTJXWkA3yv1fp5V58gofmARPQ2xWDhblYGvUhKpDQ,1689
|
|
21
21
|
fastmcp/contrib/mcp_mixin/__init__.py,sha256=aw9IQ1ssNjCgws4ZNt8bkdpossAAGVAwwjBpMp9O5ZQ,153
|
|
22
22
|
fastmcp/contrib/mcp_mixin/example.py,sha256=GnunkXmtG5hLLTUsM8aW5ZURU52Z8vI4tNLl-fK7Dg0,1228
|
|
23
23
|
fastmcp/contrib/mcp_mixin/mcp_mixin.py,sha256=cfIRbnSxsVzglTD-auyTE0izVQeHP7Oz18qzYoBZJgg,7899
|
|
24
24
|
fastmcp/prompts/__init__.py,sha256=LtPAv2JKIu54AwUd3iwv-HUd4DPcwgEqy6itEd3BH_E,194
|
|
25
|
-
fastmcp/prompts/prompt.py,sha256=
|
|
25
|
+
fastmcp/prompts/prompt.py,sha256=0RWTlsE3xxRq1falPkZhKosb9Ugo6cVqzLR6wxQ5ebU,8087
|
|
26
26
|
fastmcp/prompts/prompt_manager.py,sha256=4CInlSWASjHUfGu2i0ig2ZICzHHxCMFGTXhuXgYdukQ,3237
|
|
27
27
|
fastmcp/resources/__init__.py,sha256=t0x1j8lc74rjUKtXe9H5Gs4fpQt82K4NgBK6Y7A0xTg,467
|
|
28
28
|
fastmcp/resources/resource.py,sha256=GGG0XugoIMbgAJRMVxsBcZLbt19W3COy8PyTh_uoWjs,2705
|
|
29
29
|
fastmcp/resources/resource_manager.py,sha256=yfQNCEUooZiQ8LNslnAzjQp4Vh-y1YOlFyGEQZ0BtAg,9586
|
|
30
|
-
fastmcp/resources/template.py,sha256=
|
|
31
|
-
fastmcp/resources/types.py,sha256=
|
|
30
|
+
fastmcp/resources/template.py,sha256=0g_3Yif9XYrZW3SpbrdoHVJ13Uk7ZJBXcXo_WsAhfl0,7322
|
|
31
|
+
fastmcp/resources/types.py,sha256=ht0Jzo-CQwmmJ1XIz2VaCDETsUcGbAiN81wm1uxDSmk,7559
|
|
32
32
|
fastmcp/server/__init__.py,sha256=pdkghG11VLMZiluQ-4_rl2JK1LMWmV003m9dDRUN8W4,92
|
|
33
|
-
fastmcp/server/context.py,sha256=
|
|
34
|
-
fastmcp/server/openapi.py,sha256=
|
|
35
|
-
fastmcp/server/proxy.py,sha256=
|
|
36
|
-
fastmcp/server/server.py,sha256=
|
|
33
|
+
fastmcp/server/context.py,sha256=X8mBdF7SPwH_x8qG4oDoZBPZO9ibYFLjZu_pZoQvafg,7858
|
|
34
|
+
fastmcp/server/openapi.py,sha256=XN6xI3qz6YYN42gToO3nBp2a7sEkbFVegeUfOPyCJh0,24221
|
|
35
|
+
fastmcp/server/proxy.py,sha256=296gGXkmhaBaQzn0WYNZay4mFbjEhRX_QLB0my1W3IU,10169
|
|
36
|
+
fastmcp/server/server.py,sha256=fksGETa-kPWXIfH4Cj55uyd088kbKRadJVMiwHymTOA,42947
|
|
37
37
|
fastmcp/tools/__init__.py,sha256=ocw-SFTtN6vQ8fgnlF8iNAOflRmh79xS1xdO0Bc3QPE,96
|
|
38
|
-
fastmcp/tools/tool.py,sha256=
|
|
39
|
-
fastmcp/tools/tool_manager.py,sha256=
|
|
38
|
+
fastmcp/tools/tool.py,sha256=J1tSgXiyv6tkugYetW3QwHJ5oDOxdrg5UaRYf_RngEI,6759
|
|
39
|
+
fastmcp/tools/tool_manager.py,sha256=whi3oYfTqUXC0vXWvSvGBaUqwo1YKZxSI-clRAKKnWQ,3606
|
|
40
40
|
fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
|
|
41
41
|
fastmcp/utilities/decorators.py,sha256=AjhjsetQZF4YOPV5MTZmIxO21iFp_4fDIS3O2_KNCEg,2990
|
|
42
42
|
fastmcp/utilities/func_metadata.py,sha256=iYXnx7MILOSL8mUQ6Rtq_6U7qA08OkoEN2APY802hJg,8141
|
|
43
|
+
fastmcp/utilities/http.py,sha256=EzOe38e2oC0SjAnLmcf__1AjEtF19px8ZIVxPLt3Cr0,991
|
|
43
44
|
fastmcp/utilities/logging.py,sha256=zav8pnFxG_fvGJHUV2XpobmT9WVrmv1mlQBSCz-CPx4,1159
|
|
44
|
-
fastmcp/utilities/openapi.py,sha256=
|
|
45
|
-
fastmcp/utilities/types.py,sha256=
|
|
46
|
-
fastmcp-2.2.
|
|
47
|
-
fastmcp-2.2.
|
|
48
|
-
fastmcp-2.2.
|
|
49
|
-
fastmcp-2.2.
|
|
50
|
-
fastmcp-2.2.
|
|
45
|
+
fastmcp/utilities/openapi.py,sha256=Er3G1MyFwiWVxZXicXtD2j-BvttHEDTi1dgkq1KiBQc,51073
|
|
46
|
+
fastmcp/utilities/types.py,sha256=ZcPRtm_4U7Veh1vmW0uGj0TN66FWROwyzKEIcYE_758,3167
|
|
47
|
+
fastmcp-2.2.7.dist-info/METADATA,sha256=rIbdMviw7gLEA-QGO-3jk50CewCTyev1FQEC04JNzoY,27776
|
|
48
|
+
fastmcp-2.2.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
49
|
+
fastmcp-2.2.7.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
|
|
50
|
+
fastmcp-2.2.7.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
51
|
+
fastmcp-2.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|