fastmcp 2.9.0__py3-none-any.whl → 2.9.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/client/client.py +2 -2
- fastmcp/client/logging.py +1 -2
- fastmcp/client/messages.py +126 -0
- fastmcp/prompts/prompt.py +18 -2
- fastmcp/prompts/prompt_manager.py +2 -2
- fastmcp/resources/resource.py +16 -0
- fastmcp/resources/resource_manager.py +4 -4
- fastmcp/resources/template.py +17 -1
- fastmcp/server/auth/providers/bearer.py +38 -11
- fastmcp/server/context.py +72 -8
- fastmcp/server/low_level.py +35 -0
- fastmcp/server/server.py +134 -46
- fastmcp/tools/tool.py +16 -0
- fastmcp/tools/tool_manager.py +2 -2
- fastmcp/tools/tool_transform.py +42 -16
- fastmcp/utilities/openapi.py +70 -2
- {fastmcp-2.9.0.dist-info → fastmcp-2.9.2.dist-info}/METADATA +2 -2
- {fastmcp-2.9.0.dist-info → fastmcp-2.9.2.dist-info}/RECORD +21 -19
- {fastmcp-2.9.0.dist-info → fastmcp-2.9.2.dist-info}/WHEEL +0 -0
- {fastmcp-2.9.0.dist-info → fastmcp-2.9.2.dist-info}/entry_points.txt +0 -0
- {fastmcp-2.9.0.dist-info → fastmcp-2.9.2.dist-info}/licenses/LICENSE +0 -0
fastmcp/utilities/openapi.py
CHANGED
|
@@ -274,6 +274,12 @@ class OpenAPIParser(
|
|
|
274
274
|
result = {}
|
|
275
275
|
|
|
276
276
|
return _replace_ref_with_defs(result)
|
|
277
|
+
except ValueError as e:
|
|
278
|
+
# Re-raise ValueError for external reference errors and other validation issues
|
|
279
|
+
if "External or non-local reference not supported" in str(e):
|
|
280
|
+
raise
|
|
281
|
+
logger.error(f"Failed to extract schema as dict: {e}", exc_info=False)
|
|
282
|
+
return {}
|
|
277
283
|
except Exception as e:
|
|
278
284
|
logger.error(f"Failed to extract schema as dict: {e}", exc_info=False)
|
|
279
285
|
return {}
|
|
@@ -302,11 +308,17 @@ class OpenAPIParser(
|
|
|
302
308
|
|
|
303
309
|
# Extract parameter info - handle both 3.0 and 3.1 parameter models
|
|
304
310
|
param_in = parameter.param_in # Both use param_in
|
|
305
|
-
|
|
311
|
+
# Handle enum or string parameter locations
|
|
312
|
+
from enum import Enum
|
|
313
|
+
|
|
314
|
+
param_in_str = (
|
|
315
|
+
param_in.value if isinstance(param_in, Enum) else param_in
|
|
316
|
+
)
|
|
317
|
+
param_location = self._convert_to_parameter_location(param_in_str)
|
|
306
318
|
param_schema_obj = parameter.param_schema # Both use param_schema
|
|
307
319
|
|
|
308
320
|
# Skip duplicate parameters (same name and location)
|
|
309
|
-
param_key = (parameter.name,
|
|
321
|
+
param_key = (parameter.name, param_in_str)
|
|
310
322
|
if param_key in seen_params:
|
|
311
323
|
continue
|
|
312
324
|
seen_params[param_key] = True
|
|
@@ -400,12 +412,30 @@ class OpenAPIParser(
|
|
|
400
412
|
request_body_info.content_schema[media_type_str] = (
|
|
401
413
|
schema_dict
|
|
402
414
|
)
|
|
415
|
+
except ValueError as e:
|
|
416
|
+
# Re-raise ValueError for external reference errors
|
|
417
|
+
if "External or non-local reference not supported" in str(
|
|
418
|
+
e
|
|
419
|
+
):
|
|
420
|
+
raise
|
|
421
|
+
logger.error(
|
|
422
|
+
f"Failed to extract schema for media type '{media_type_str}': {e}"
|
|
423
|
+
)
|
|
403
424
|
except Exception as e:
|
|
404
425
|
logger.error(
|
|
405
426
|
f"Failed to extract schema for media type '{media_type_str}': {e}"
|
|
406
427
|
)
|
|
407
428
|
|
|
408
429
|
return request_body_info
|
|
430
|
+
except ValueError as e:
|
|
431
|
+
# Re-raise ValueError for external reference errors
|
|
432
|
+
if "External or non-local reference not supported" in str(e):
|
|
433
|
+
raise
|
|
434
|
+
ref_name = getattr(request_body_or_ref, "ref", "unknown")
|
|
435
|
+
logger.error(
|
|
436
|
+
f"Failed to extract request body '{ref_name}': {e}", exc_info=False
|
|
437
|
+
)
|
|
438
|
+
return None
|
|
409
439
|
except Exception as e:
|
|
410
440
|
ref_name = getattr(request_body_or_ref, "ref", "unknown")
|
|
411
441
|
logger.error(
|
|
@@ -449,6 +479,17 @@ class OpenAPIParser(
|
|
|
449
479
|
media_type_obj.media_type_schema
|
|
450
480
|
)
|
|
451
481
|
resp_info.content_schema[media_type_str] = schema_dict
|
|
482
|
+
except ValueError as e:
|
|
483
|
+
# Re-raise ValueError for external reference errors
|
|
484
|
+
if (
|
|
485
|
+
"External or non-local reference not supported"
|
|
486
|
+
in str(e)
|
|
487
|
+
):
|
|
488
|
+
raise
|
|
489
|
+
logger.error(
|
|
490
|
+
f"Failed to extract schema for media type '{media_type_str}' "
|
|
491
|
+
f"in response {status_code}: {e}"
|
|
492
|
+
)
|
|
452
493
|
except Exception as e:
|
|
453
494
|
logger.error(
|
|
454
495
|
f"Failed to extract schema for media type '{media_type_str}' "
|
|
@@ -456,6 +497,16 @@ class OpenAPIParser(
|
|
|
456
497
|
)
|
|
457
498
|
|
|
458
499
|
extracted_responses[str(status_code)] = resp_info
|
|
500
|
+
except ValueError as e:
|
|
501
|
+
# Re-raise ValueError for external reference errors
|
|
502
|
+
if "External or non-local reference not supported" in str(e):
|
|
503
|
+
raise
|
|
504
|
+
ref_name = getattr(resp_or_ref, "ref", "unknown")
|
|
505
|
+
logger.error(
|
|
506
|
+
f"Failed to extract response for status code {status_code} "
|
|
507
|
+
f"from reference '{ref_name}': {e}",
|
|
508
|
+
exc_info=False,
|
|
509
|
+
)
|
|
459
510
|
except Exception as e:
|
|
460
511
|
ref_name = getattr(resp_or_ref, "ref", "unknown")
|
|
461
512
|
logger.error(
|
|
@@ -556,6 +607,17 @@ class OpenAPIParser(
|
|
|
556
607
|
logger.info(
|
|
557
608
|
f"Successfully extracted route: {method_upper} {path_str}"
|
|
558
609
|
)
|
|
610
|
+
except ValueError as op_error:
|
|
611
|
+
# Re-raise ValueError for external reference errors
|
|
612
|
+
if "External or non-local reference not supported" in str(
|
|
613
|
+
op_error
|
|
614
|
+
):
|
|
615
|
+
raise
|
|
616
|
+
op_id = getattr(operation, "operationId", "unknown")
|
|
617
|
+
logger.error(
|
|
618
|
+
f"Failed to process operation {method_upper} {path_str} (ID: {op_id}): {op_error}",
|
|
619
|
+
exc_info=True,
|
|
620
|
+
)
|
|
559
621
|
except Exception as op_error:
|
|
560
622
|
op_id = getattr(operation, "operationId", "unknown")
|
|
561
623
|
logger.error(
|
|
@@ -901,6 +963,12 @@ def _replace_ref_with_defs(
|
|
|
901
963
|
if ref_path.startswith("#/components/schemas/"):
|
|
902
964
|
schema_name = ref_path.split("/")[-1]
|
|
903
965
|
schema["$ref"] = f"#/$defs/{schema_name}"
|
|
966
|
+
elif not ref_path.startswith("#/"):
|
|
967
|
+
raise ValueError(
|
|
968
|
+
f"External or non-local reference not supported: {ref_path}. "
|
|
969
|
+
f"FastMCP only supports local schema references starting with '#/'. "
|
|
970
|
+
f"Please include all schema definitions within the OpenAPI document."
|
|
971
|
+
)
|
|
904
972
|
elif properties := schema.get("properties"):
|
|
905
973
|
if "$ref" in properties:
|
|
906
974
|
schema["properties"] = _replace_ref_with_defs(properties)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.2
|
|
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
|
|
@@ -20,7 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Requires-Dist: authlib>=1.5.2
|
|
21
21
|
Requires-Dist: exceptiongroup>=1.2.2
|
|
22
22
|
Requires-Dist: httpx>=0.28.1
|
|
23
|
-
Requires-Dist: mcp<
|
|
23
|
+
Requires-Dist: mcp<1.10.0,>=1.9.4
|
|
24
24
|
Requires-Dist: openapi-pydantic>=0.5.1
|
|
25
25
|
Requires-Dist: python-dotenv>=1.1.0
|
|
26
26
|
Requires-Dist: rich>=13.9.4
|
|
@@ -7,8 +7,9 @@ fastmcp/cli/claude.py,sha256=IAlcZ4qZKBBj09jZUMEx7EANZE_IR3vcu7zOBJmMOuU,4567
|
|
|
7
7
|
fastmcp/cli/cli.py,sha256=598s1S-KdqIB85mwqvXJaBVen6xYY65ek4v-q3lmY4k,15933
|
|
8
8
|
fastmcp/cli/run.py,sha256=Pw3vH5wKRHfbmHRn0saIbC4l450KPOzeQbzPFqG4AbY,6208
|
|
9
9
|
fastmcp/client/__init__.py,sha256=kd2hhSuD8rZuF87c9zlPJP_icJ-Rx3exyNoK0EzfOtE,617
|
|
10
|
-
fastmcp/client/client.py,sha256=
|
|
11
|
-
fastmcp/client/logging.py,sha256=
|
|
10
|
+
fastmcp/client/client.py,sha256=BmWALAw1PgJGm3Gokpsc0vSamqYES2jM2egEo6q4JHk,25664
|
|
11
|
+
fastmcp/client/logging.py,sha256=7GJ-BLFW16_IOJPlGTNEWPP0P-yqqRpmsLdiKrlVsw8,757
|
|
12
|
+
fastmcp/client/messages.py,sha256=NIPjt-5js_DkI5BD4OVdTf6pz-nGjc2dtbgt-vAY234,4329
|
|
12
13
|
fastmcp/client/oauth_callback.py,sha256=ODAnVX-ettL82RuI5KpfkKf8iDtYMDue3Tnab5sjQtM,10071
|
|
13
14
|
fastmcp/client/progress.py,sha256=WjLLDbUKMsx8DK-fqO7AGsXb83ak-6BMrLvzzznGmcI,1043
|
|
14
15
|
fastmcp/client/roots.py,sha256=IxI_bHwHTmg6c2H-s1av1ZgrRnNDieHtYwdGFbzXT5c,2471
|
|
@@ -27,24 +28,25 @@ fastmcp/contrib/mcp_mixin/__init__.py,sha256=aw9IQ1ssNjCgws4ZNt8bkdpossAAGVAwwjB
|
|
|
27
28
|
fastmcp/contrib/mcp_mixin/example.py,sha256=GnunkXmtG5hLLTUsM8aW5ZURU52Z8vI4tNLl-fK7Dg0,1228
|
|
28
29
|
fastmcp/contrib/mcp_mixin/mcp_mixin.py,sha256=sUSJ2o0sTsb061MyPN2xuYP0oI4W6YVQXupY3nnjD50,8687
|
|
29
30
|
fastmcp/prompts/__init__.py,sha256=An8uMBUh9Hrb7qqcn_5_Hent7IOeSh7EA2IUVsIrtHc,179
|
|
30
|
-
fastmcp/prompts/prompt.py,sha256=
|
|
31
|
-
fastmcp/prompts/prompt_manager.py,sha256=
|
|
31
|
+
fastmcp/prompts/prompt.py,sha256=dtJgKPXL8Yj_rRPy9Oy_6ZQn3IaX2tqieqQ0vIk7xiU,13725
|
|
32
|
+
fastmcp/prompts/prompt_manager.py,sha256=Pt9cg_c9FR2EA0ITIHJT5Utihkd383JzhqhT-y2VnKo,7677
|
|
32
33
|
fastmcp/resources/__init__.py,sha256=y1iAuqx-GIrS1NqIYzKezIDiYyjNEzzHD35epHpMnXE,463
|
|
33
|
-
fastmcp/resources/resource.py,sha256=
|
|
34
|
-
fastmcp/resources/resource_manager.py,sha256=
|
|
35
|
-
fastmcp/resources/template.py,sha256=
|
|
34
|
+
fastmcp/resources/resource.py,sha256=aiM0T61-P_GcLboIhWC16VPceWomDY4CTHIcIoAUqOY,5896
|
|
35
|
+
fastmcp/resources/resource_manager.py,sha256=zjhso9ZP0EK_beTpUz_amqJ7XSABqU8mqPSk-JturOE,19777
|
|
36
|
+
fastmcp/resources/template.py,sha256=hf5cPEz3aSky1wPjGSEz9npnJNcMcfOZxYhG-v99FXs,10195
|
|
36
37
|
fastmcp/resources/types.py,sha256=SiYNLnpXT-mHgNUrzqKUvXYUsY-V3gwJIrYdJfFwDDo,4868
|
|
37
38
|
fastmcp/server/__init__.py,sha256=bMD4aQD4yJqLz7-mudoNsyeV8UgQfRAg3PRwPvwTEds,119
|
|
38
|
-
fastmcp/server/context.py,sha256=
|
|
39
|
+
fastmcp/server/context.py,sha256=425vsDfoiTJ5wVbRdq_eqYr_RkrNqSwFH8YJpENWewY,14525
|
|
39
40
|
fastmcp/server/dependencies.py,sha256=iKJdz1XsVJcrfHo_reXj9ZSldw-HeAwsp9S6lAgfGA8,2358
|
|
40
41
|
fastmcp/server/http.py,sha256=gwovXTVKd7UR_mrbMP3WI3eaxFKvZcxwjm3RwKxL6wU,12055
|
|
42
|
+
fastmcp/server/low_level.py,sha256=yPusWSidyEzDbrB9kBfXkARBc4pc523KFqYxLuR64Ww,1184
|
|
41
43
|
fastmcp/server/openapi.py,sha256=rF8umkOQGLejDVH7Ef36QdMmjv6zwPB5tmkgmQscM7A,39539
|
|
42
44
|
fastmcp/server/proxy.py,sha256=nz8DSDMd3LWDgtI2a3l3-EYn2i45wvgxx7zdLMs8C84,14944
|
|
43
|
-
fastmcp/server/server.py,sha256=
|
|
45
|
+
fastmcp/server/server.py,sha256=6ds3Z5ruJn5tth0Cg7hP-U1i27AVS9uDoiq00vpCvXI,78824
|
|
44
46
|
fastmcp/server/auth/__init__.py,sha256=doHCLwOIElvH1NrTdpeP9JKfnNf3MDYPSpQfdsQ-uI0,84
|
|
45
47
|
fastmcp/server/auth/auth.py,sha256=kz02HGwXYU0N0clURZDjFNWdKSpTYmgmCnGJN-jSG3Y,1640
|
|
46
48
|
fastmcp/server/auth/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
fastmcp/server/auth/providers/bearer.py,sha256=
|
|
49
|
+
fastmcp/server/auth/providers/bearer.py,sha256=lRtElzrFw23ZXD_eukqCtGNBxKQhKLwO9v-UE-HT3yU,15232
|
|
48
50
|
fastmcp/server/auth/providers/bearer_env.py,sha256=zHbJmzT6RhEW9tGG-_aRACQ_t0GwXCvKEAnKQLCO9mY,1892
|
|
49
51
|
fastmcp/server/auth/providers/in_memory.py,sha256=_8hRo6KZEVqsSSMNxpseJH48LZEywF4uZ687XuOmqYw,13772
|
|
50
52
|
fastmcp/server/middleware/__init__.py,sha256=sKrgbpTlaVdzg_bL8ZI5SGf7EceVqqFUcUr9rvt1r08,112
|
|
@@ -54,9 +56,9 @@ fastmcp/server/middleware/middleware.py,sha256=v6nKcphMhCxwDvbtffPYHHl-WYr9V09cz
|
|
|
54
56
|
fastmcp/server/middleware/rate_limiting.py,sha256=VTrCoQFmWCm0BxwOrNfG21CBFDDOKJT7IiSEjpJgmPA,7921
|
|
55
57
|
fastmcp/server/middleware/timing.py,sha256=lL_xc-ErLD5lplfvd5-HIyWEbZhgNBYkcQ74KFXAMkA,5591
|
|
56
58
|
fastmcp/tools/__init__.py,sha256=vzqb-Y7Kf0d5T0aOsld-O-FA8kD7-4uFExChewFHEzY,201
|
|
57
|
-
fastmcp/tools/tool.py,sha256=
|
|
58
|
-
fastmcp/tools/tool_manager.py,sha256=
|
|
59
|
-
fastmcp/tools/tool_transform.py,sha256=
|
|
59
|
+
fastmcp/tools/tool.py,sha256=sG102iHn7iM58sGXFJ8CIfjUHRyEhh2fxnzgcrZBBSc,11734
|
|
60
|
+
fastmcp/tools/tool_manager.py,sha256=TGO17cs9A2CGVnNk6RViu9dgPN8xYQE0x1c8JBfIbgc,7780
|
|
61
|
+
fastmcp/tools/tool_transform.py,sha256=pXuYLdRjiutPlil88wssUSiqnit7hHz_51ELY_6EU6E,28001
|
|
60
62
|
fastmcp/utilities/__init__.py,sha256=-imJ8S-rXmbXMWeDamldP-dHDqAPg_wwmPVz-LNX14E,31
|
|
61
63
|
fastmcp/utilities/cache.py,sha256=aV3oZ-ZhMgLSM9iAotlUlEy5jFvGXrVo0Y5Bj4PBtqY,707
|
|
62
64
|
fastmcp/utilities/components.py,sha256=JhXTFWQ2lUe5h2eDVKQLVWnVfvQ77iCbBxE4CYQEuTs,2382
|
|
@@ -66,11 +68,11 @@ fastmcp/utilities/inspect.py,sha256=XNA0dfYM5G-FVbJaVJO8loSUUCNypyLA-QjqTOneJyU,
|
|
|
66
68
|
fastmcp/utilities/json_schema.py,sha256=K0QH5UazBD_tweBi-TguWYjUu5Lgp9wcM-wT42Fet5w,5022
|
|
67
69
|
fastmcp/utilities/logging.py,sha256=B1WNO-ZWFjd9wiFSh13YtW1hAKaNmbpscDZleIAhr-g,1317
|
|
68
70
|
fastmcp/utilities/mcp_config.py,sha256=ryjAfJUPquDSoKdSymPH4M2B0WvuM3pWUGI3cOgAX80,2782
|
|
69
|
-
fastmcp/utilities/openapi.py,sha256=
|
|
71
|
+
fastmcp/utilities/openapi.py,sha256=llB7T0x3QI0VlPNiL0Qh1L5RkmJLc8EO0TyA0GC70N4,42578
|
|
70
72
|
fastmcp/utilities/tests.py,sha256=O9hRSjnyaYQqu1RJ-CFBw1cIjezlwSQtS-Ea_iqO4sY,3899
|
|
71
73
|
fastmcp/utilities/types.py,sha256=XfTwZU1MhBfMCPU5SDNu3z8-D_yaLbw_PfoXCZOm530,9589
|
|
72
|
-
fastmcp-2.9.
|
|
73
|
-
fastmcp-2.9.
|
|
74
|
-
fastmcp-2.9.
|
|
75
|
-
fastmcp-2.9.
|
|
76
|
-
fastmcp-2.9.
|
|
74
|
+
fastmcp-2.9.2.dist-info/METADATA,sha256=BRqDiaXqeDy1b2XRGYczSsqxufU4I8XNMKNHhSDqcPk,17763
|
|
75
|
+
fastmcp-2.9.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
76
|
+
fastmcp-2.9.2.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
|
|
77
|
+
fastmcp-2.9.2.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
78
|
+
fastmcp-2.9.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|