fastmcp 2.2.8__py3-none-any.whl → 2.2.9__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/server/server.py +15 -1
- fastmcp/tools/tool.py +3 -1
- fastmcp/utilities/types.py +7 -4
- {fastmcp-2.2.8.dist-info → fastmcp-2.2.9.dist-info}/METADATA +1 -1
- {fastmcp-2.2.8.dist-info → fastmcp-2.2.9.dist-info}/RECORD +8 -8
- {fastmcp-2.2.8.dist-info → fastmcp-2.2.9.dist-info}/WHEEL +0 -0
- {fastmcp-2.2.8.dist-info → fastmcp-2.2.9.dist-info}/entry_points.txt +0 -0
- {fastmcp-2.2.8.dist-info → fastmcp-2.2.9.dist-info}/licenses/LICENSE +0 -0
fastmcp/server/server.py
CHANGED
|
@@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Any, Generic, Literal
|
|
|
14
14
|
|
|
15
15
|
import anyio
|
|
16
16
|
import httpx
|
|
17
|
+
import pydantic
|
|
17
18
|
import uvicorn
|
|
18
19
|
from mcp.server.auth.middleware.auth_context import AuthContextMiddleware
|
|
19
20
|
from mcp.server.auth.middleware.bearer_auth import (
|
|
@@ -39,7 +40,7 @@ from mcp.types import Prompt as MCPPrompt
|
|
|
39
40
|
from mcp.types import Resource as MCPResource
|
|
40
41
|
from mcp.types import ResourceTemplate as MCPResourceTemplate
|
|
41
42
|
from mcp.types import Tool as MCPTool
|
|
42
|
-
from pydantic
|
|
43
|
+
from pydantic import AnyUrl
|
|
43
44
|
from starlette.applications import Starlette
|
|
44
45
|
from starlette.middleware import Middleware
|
|
45
46
|
from starlette.middleware.authentication import AuthenticationMiddleware
|
|
@@ -88,6 +89,8 @@ class MountedServer:
|
|
|
88
89
|
if prompt_separator is None:
|
|
89
90
|
prompt_separator = "_"
|
|
90
91
|
|
|
92
|
+
_validate_resource_prefix(f"{prefix}{resource_separator}")
|
|
93
|
+
|
|
91
94
|
self.server = server
|
|
92
95
|
self.prefix = prefix
|
|
93
96
|
self.tool_separator = tool_separator
|
|
@@ -1074,6 +1077,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|
|
1074
1077
|
|
|
1075
1078
|
# Import resources and templates from the mounted server
|
|
1076
1079
|
resource_prefix = f"{prefix}{resource_separator}"
|
|
1080
|
+
_validate_resource_prefix(resource_prefix)
|
|
1077
1081
|
for key, resource in (await server.get_resources()).items():
|
|
1078
1082
|
self._resource_manager.add_resource(resource, key=f"{resource_prefix}{key}")
|
|
1079
1083
|
for key, template in (await server.get_resource_templates()).items():
|
|
@@ -1131,3 +1135,13 @@ class FastMCP(Generic[LifespanResultT]):
|
|
|
1131
1135
|
from fastmcp.server.proxy import FastMCPProxy
|
|
1132
1136
|
|
|
1133
1137
|
return FastMCPProxy(client=client, **settings)
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
def _validate_resource_prefix(prefix: str) -> None:
|
|
1141
|
+
valid_resource = "resource://path/to/resource"
|
|
1142
|
+
try:
|
|
1143
|
+
AnyUrl(f"{prefix}{valid_resource}")
|
|
1144
|
+
except pydantic.ValidationError as e:
|
|
1145
|
+
raise ValueError(
|
|
1146
|
+
f"Resource prefix or separator would result in an invalid resource URI: {e}"
|
|
1147
|
+
)
|
fastmcp/tools/tool.py
CHANGED
|
@@ -127,7 +127,9 @@ class Tool(BaseModel):
|
|
|
127
127
|
except json.JSONDecodeError:
|
|
128
128
|
pass
|
|
129
129
|
|
|
130
|
-
type_adapter = get_cached_typeadapter(
|
|
130
|
+
type_adapter = get_cached_typeadapter(
|
|
131
|
+
self.fn, config=frozenset([("coerce_numbers_to_str", True)])
|
|
132
|
+
)
|
|
131
133
|
result = type_adapter.validate_python(parsed_args | injected_args)
|
|
132
134
|
if inspect.isawaitable(result):
|
|
133
135
|
result = await result
|
fastmcp/utilities/types.py
CHANGED
|
@@ -6,23 +6,26 @@ from collections.abc import Callable
|
|
|
6
6
|
from functools import lru_cache
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from types import UnionType
|
|
9
|
-
from typing import Annotated, TypeVar, Union, get_args, get_origin
|
|
9
|
+
from typing import Annotated, Any, TypeVar, Union, get_args, get_origin
|
|
10
10
|
|
|
11
11
|
from mcp.types import ImageContent
|
|
12
|
-
from pydantic import TypeAdapter
|
|
12
|
+
from pydantic import ConfigDict, TypeAdapter
|
|
13
13
|
|
|
14
14
|
T = TypeVar("T")
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@lru_cache(maxsize=5000)
|
|
18
|
-
def get_cached_typeadapter(
|
|
18
|
+
def get_cached_typeadapter(
|
|
19
|
+
cls: T, config: frozenset[tuple[str, Any]] | None = None
|
|
20
|
+
) -> TypeAdapter[T]:
|
|
19
21
|
"""
|
|
20
22
|
TypeAdapters are heavy objects, and in an application context we'd typically
|
|
21
23
|
create them once in a global scope and reuse them as often as possible.
|
|
22
24
|
However, this isn't feasible for user-generated functions. Instead, we use a
|
|
23
25
|
cache to minimize the cost of creating them as much as possible.
|
|
24
26
|
"""
|
|
25
|
-
|
|
27
|
+
config_dict = dict(config or {})
|
|
28
|
+
return TypeAdapter(cls, config=ConfigDict(**config_dict))
|
|
26
29
|
|
|
27
30
|
|
|
28
31
|
def issubclass_safe(cls: type, base: type) -> bool:
|
|
@@ -33,9 +33,9 @@ fastmcp/server/__init__.py,sha256=pdkghG11VLMZiluQ-4_rl2JK1LMWmV003m9dDRUN8W4,92
|
|
|
33
33
|
fastmcp/server/context.py,sha256=X8mBdF7SPwH_x8qG4oDoZBPZO9ibYFLjZu_pZoQvafg,7858
|
|
34
34
|
fastmcp/server/openapi.py,sha256=1Yhep4zwHhZPlfNIo2Y3sIxfwHNJRdzw3Kc4DZrEW3Q,23950
|
|
35
35
|
fastmcp/server/proxy.py,sha256=f7V1X9lDUanHS_iTzEf7Nt0WwkDOXDiJ3-XrMWdq3tw,9969
|
|
36
|
-
fastmcp/server/server.py,sha256=
|
|
36
|
+
fastmcp/server/server.py,sha256=kXcnO_TzJuoColFjSBER8M5IaA4k9Cvwkrd5LUYKgRQ,43588
|
|
37
37
|
fastmcp/tools/__init__.py,sha256=ocw-SFTtN6vQ8fgnlF8iNAOflRmh79xS1xdO0Bc3QPE,96
|
|
38
|
-
fastmcp/tools/tool.py,sha256=
|
|
38
|
+
fastmcp/tools/tool.py,sha256=qglTiW2K5EVpn-0Ctl29VPfubuwfKIt9_NVX9HzMSqg,7390
|
|
39
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
|
|
@@ -43,9 +43,9 @@ fastmcp/utilities/http.py,sha256=EzOe38e2oC0SjAnLmcf__1AjEtF19px8ZIVxPLt3Cr0,991
|
|
|
43
43
|
fastmcp/utilities/json_schema.py,sha256=mSakhP8bENxhLFMwHJSxJAFllNeByIBDjVohwlpac6w,2026
|
|
44
44
|
fastmcp/utilities/logging.py,sha256=zav8pnFxG_fvGJHUV2XpobmT9WVrmv1mlQBSCz-CPx4,1159
|
|
45
45
|
fastmcp/utilities/openapi.py,sha256=Er3G1MyFwiWVxZXicXtD2j-BvttHEDTi1dgkq1KiBQc,51073
|
|
46
|
-
fastmcp/utilities/types.py,sha256=
|
|
47
|
-
fastmcp-2.2.
|
|
48
|
-
fastmcp-2.2.
|
|
49
|
-
fastmcp-2.2.
|
|
50
|
-
fastmcp-2.2.
|
|
51
|
-
fastmcp-2.2.
|
|
46
|
+
fastmcp/utilities/types.py,sha256=LVNfzDGRNglNo5BUpFVWJhfK672saznxxju0tLrwy8Q,4544
|
|
47
|
+
fastmcp-2.2.9.dist-info/METADATA,sha256=UE27Qphn0YxHdfX9Jz4q8YZmImSvxouxt8mDWdeouVc,16279
|
|
48
|
+
fastmcp-2.2.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
49
|
+
fastmcp-2.2.9.dist-info/entry_points.txt,sha256=ff8bMtKX1JvXyurMibAacMSKbJEPmac9ffAKU9mLnM8,44
|
|
50
|
+
fastmcp-2.2.9.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
51
|
+
fastmcp-2.2.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|