Skip to content

Commit 7e64c91

Browse files
committed
Merge branch 'main' of https://github.com/modelcontextprotocol/python-sdk into feat/tasks
2 parents 35f3de2 + 9c8f763 commit 7e64c91

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/mcp/client/session.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import anyio.lowlevel
99
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
10-
from jsonschema import SchemaError, ValidationError, validate
1110
from pydantic import AnyUrl, BaseModel, TypeAdapter
1211
from typing_extensions import deprecated
1312

@@ -451,6 +450,8 @@ async def _validate_tool_result(self, name: str, result: types.CallToolResult) -
451450
logger.warning(f"Tool {name} not listed by server, cannot validate any structured content")
452451

453452
if output_schema is not None:
453+
from jsonschema import SchemaError, ValidationError, validate
454+
454455
if result.structuredContent is None:
455456
raise RuntimeError(
456457
f"Tool {name} has an output schema but did not return structured content"

tests/client/test_output_schema_validation.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,27 @@ def bypass_server_output_validation():
1919
This simulates a malicious or non-compliant server that doesn't validate
2020
its outputs, allowing us to test client-side validation.
2121
"""
22-
# Patch jsonschema.validate in the server module to disable all validation
23-
with patch("mcp.server.lowlevel.server.jsonschema.validate"):
24-
# The mock will simply return None (do nothing) for all validation calls
22+
import jsonschema
23+
24+
# Save the original validate function
25+
original_validate = jsonschema.validate
26+
27+
# Create a mock that tracks which module is calling it
28+
def selective_mock(instance: Any = None, schema: Any = None, *args: Any, **kwargs: Any) -> None:
29+
import inspect
30+
31+
# Check the call stack to see where this is being called from
32+
for frame_info in inspect.stack():
33+
# If called from the server module, skip validation
34+
# TODO: fix this as it's a rather gross workaround and will eventually break
35+
# Normalize path separators for cross-platform compatibility
36+
normalized_path = frame_info.filename.replace("\\", "/")
37+
if "mcp/server/lowlevel/server.py" in normalized_path:
38+
return None
39+
# Otherwise, use the real validation (for client-side)
40+
return original_validate(instance=instance, schema=schema, *args, **kwargs)
41+
42+
with patch("jsonschema.validate", selective_mock):
2543
yield
2644

2745

0 commit comments

Comments
 (0)