Skip to content

Commit d9d6bfe

Browse files
authored
Merge branch 'main' into fix/sse-server-message-path
2 parents dfdf077 + 697b6e8 commit d9d6bfe

File tree

6 files changed

+13
-23
lines changed

6 files changed

+13
-23
lines changed

src/mcp/server/fastmcp/prompts/base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Base classes for FastMCP prompts."""
22

33
import inspect
4-
import json
54
from collections.abc import Awaitable, Callable, Sequence
65
from typing import Any, Literal
76

@@ -155,7 +154,9 @@ async def render(self, arguments: dict[str, Any] | None = None) -> list[Message]
155154
content = TextContent(type="text", text=msg)
156155
messages.append(UserMessage(content=content))
157156
else:
158-
content = json.dumps(pydantic_core.to_jsonable_python(msg))
157+
content = pydantic_core.to_json(
158+
msg, fallback=str, indent=2
159+
).decode()
159160
messages.append(Message(role="user", content=content))
160161
except Exception:
161162
raise ValueError(

src/mcp/server/fastmcp/resources/types.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import anyio
1010
import anyio.to_thread
1111
import httpx
12-
import pydantic.json
12+
import pydantic
1313
import pydantic_core
1414
from pydantic import Field, ValidationInfo
1515

@@ -59,15 +59,12 @@ async def read(self) -> str | bytes:
5959
)
6060
if isinstance(result, Resource):
6161
return await result.read()
62-
if isinstance(result, bytes):
62+
elif isinstance(result, bytes):
6363
return result
64-
if isinstance(result, str):
64+
elif isinstance(result, str):
6565
return result
66-
try:
67-
return json.dumps(pydantic_core.to_jsonable_python(result))
68-
except (TypeError, pydantic_core.PydanticSerializationError):
69-
# If JSON serialization fails, try str()
70-
return str(result)
66+
else:
67+
return pydantic_core.to_json(result, fallback=str, indent=2).decode()
7168
except Exception as e:
7269
raise ValueError(f"Error reading resource {self.uri}: {e}")
7370

src/mcp/server/fastmcp/server.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations as _annotations
44

55
import inspect
6-
import json
76
import re
87
from collections.abc import AsyncIterator, Callable, Iterable, Sequence
98
from contextlib import (
@@ -582,10 +581,7 @@ def _convert_to_content(
582581
return list(chain.from_iterable(_convert_to_content(item) for item in result)) # type: ignore[reportUnknownVariableType]
583582

584583
if not isinstance(result, str):
585-
try:
586-
result = json.dumps(pydantic_core.to_jsonable_python(result))
587-
except Exception:
588-
result = str(result)
584+
result = pydantic_core.to_json(result, fallback=str, indent=2).decode()
589585

590586
return [TextContent(type="text", text=result)]
591587

tests/server/fastmcp/resources/test_function_resources.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class MyModel(BaseModel):
100100
fn=lambda: MyModel(name="test"),
101101
)
102102
content = await resource.read()
103-
assert content == '{"name": "test"}'
103+
assert content == '{\n "name": "test"\n}'
104104

105105
@pytest.mark.anyio
106106
async def test_custom_type_conversion(self):

tests/server/fastmcp/resources/test_resource_template.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,4 @@ def get_data(value: str) -> CustomData:
185185

186186
assert isinstance(resource, FunctionResource)
187187
content = await resource.read()
188-
assert content == "hello"
188+
assert content == '"hello"'

tests/server/fastmcp/servers/test_file_server.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,13 @@ async def test_read_resource_file(mcp: FastMCP):
114114

115115
@pytest.mark.anyio
116116
async def test_delete_file(mcp: FastMCP, test_dir: Path):
117-
await mcp.call_tool(
118-
"delete_file", arguments={"path": str(test_dir / "example.py")}
119-
)
117+
await mcp.call_tool("delete_file", arguments={"path": str(test_dir / "example.py")})
120118
assert not (test_dir / "example.py").exists()
121119

122120

123121
@pytest.mark.anyio
124122
async def test_delete_file_and_check_resources(mcp: FastMCP, test_dir: Path):
125-
await mcp.call_tool(
126-
"delete_file", arguments={"path": str(test_dir / "example.py")}
127-
)
123+
await mcp.call_tool("delete_file", arguments={"path": str(test_dir / "example.py")})
128124
res_iter = await mcp.read_resource("file://test_dir/example.py")
129125
res_list = list(res_iter)
130126
assert len(res_list) == 1

0 commit comments

Comments
 (0)