Completely drop RootModel from types module (#1910)
This commit is contained in:
parent
f4672c5084
commit
5fdd48a0d3
3 changed files with 640 additions and 800 deletions
|
|
@ -19,7 +19,7 @@ from starlette.routing import Route
|
|||
from mcp import ClientSession, types
|
||||
from mcp.client.streamable_http import streamable_http_client
|
||||
from mcp.shared.session import RequestResponder
|
||||
from mcp.types import ClientNotification, RootsListChangedNotification
|
||||
from mcp.types import RootsListChangedNotification
|
||||
from tests.test_helpers import wait_for_server
|
||||
|
||||
|
||||
|
|
@ -135,9 +135,7 @@ async def test_non_compliant_notification_response(non_sdk_server: None, non_sdk
|
|||
await session.initialize()
|
||||
|
||||
# The test server returns a 204 instead of the expected 202
|
||||
await session.send_notification(
|
||||
ClientNotification(RootsListChangedNotification(method="notifications/roots/list_changed"))
|
||||
)
|
||||
await session.send_notification(RootsListChangedNotification(method="notifications/roots/list_changed"))
|
||||
|
||||
if returned_exception: # pragma: no cover
|
||||
pytest.fail(f"Server encountered an exception: {returned_exception}")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from unittest.mock import patch
|
|||
|
||||
import anyio
|
||||
import pytest
|
||||
from pydantic import TypeAdapter
|
||||
|
||||
from mcp.shared.message import SessionMessage
|
||||
from mcp.shared.session import BaseSession, RequestId, SendResultT
|
||||
|
|
@ -23,20 +24,23 @@ async def test_send_request_stream_cleanup():
|
|||
) -> None: # pragma: no cover
|
||||
pass
|
||||
|
||||
@property
|
||||
def _receive_request_adapter(self) -> TypeAdapter[Any]:
|
||||
return TypeAdapter(object) # pragma: no cover
|
||||
|
||||
@property
|
||||
def _receive_notification_adapter(self) -> TypeAdapter[Any]:
|
||||
return TypeAdapter(object) # pragma: no cover
|
||||
|
||||
# Create streams
|
||||
write_stream_send, write_stream_receive = anyio.create_memory_object_stream[SessionMessage](1)
|
||||
read_stream_send, read_stream_receive = anyio.create_memory_object_stream[SessionMessage](1)
|
||||
|
||||
# Create the session
|
||||
session = TestSession(
|
||||
read_stream_receive,
|
||||
write_stream_send,
|
||||
object, # Request type doesn't matter for this test
|
||||
object, # Notification type doesn't matter for this test
|
||||
)
|
||||
session = TestSession(read_stream_receive, write_stream_send)
|
||||
|
||||
# Create a test request
|
||||
request = ClientRequest(PingRequest())
|
||||
request = PingRequest()
|
||||
|
||||
# Patch the _write_stream.send method to raise an exception
|
||||
async def mock_send(*args: Any, **kwargs: Any):
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ from mcp.shared.version import SUPPORTED_PROTOCOL_VERSIONS
|
|||
from mcp.types import (
|
||||
LATEST_PROTOCOL_VERSION,
|
||||
CallToolResult,
|
||||
ClientNotification,
|
||||
ClientRequest,
|
||||
Implementation,
|
||||
InitializedNotification,
|
||||
InitializeRequest,
|
||||
|
|
@ -22,8 +20,9 @@ from mcp.types import (
|
|||
JSONRPCRequest,
|
||||
JSONRPCResponse,
|
||||
ServerCapabilities,
|
||||
ServerResult,
|
||||
TextContent,
|
||||
client_notification_adapter,
|
||||
client_request_adapter,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -41,24 +40,22 @@ async def test_client_session_initialize():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
assert isinstance(request, InitializeRequest)
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(
|
||||
logging=None,
|
||||
resources=None,
|
||||
tools=None,
|
||||
experimental=None,
|
||||
prompts=None,
|
||||
),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
instructions="The server instructions.",
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(
|
||||
logging=None,
|
||||
resources=None,
|
||||
tools=None,
|
||||
experimental=None,
|
||||
prompts=None,
|
||||
),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
instructions="The server instructions.",
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -74,7 +71,7 @@ async def test_client_session_initialize():
|
|||
session_notification = await client_to_server_receive.receive()
|
||||
jsonrpc_notification = session_notification.message
|
||||
assert isinstance(jsonrpc_notification, JSONRPCNotification)
|
||||
initialized_notification = ClientNotification.model_validate(
|
||||
initialized_notification = client_notification_adapter.validate_python(
|
||||
jsonrpc_notification.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
|
||||
|
|
@ -109,7 +106,7 @@ async def test_client_session_initialize():
|
|||
|
||||
# Check that the client sent the initialized notification
|
||||
assert initialized_notification
|
||||
assert isinstance(initialized_notification.root, InitializedNotification)
|
||||
assert isinstance(initialized_notification, InitializedNotification)
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
|
|
@ -126,18 +123,16 @@ async def test_client_session_custom_client_info():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
received_client_info = request.root.params.client_info
|
||||
assert isinstance(request, InitializeRequest)
|
||||
received_client_info = request.params.client_info
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -185,18 +180,16 @@ async def test_client_session_default_client_info():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
received_client_info = request.root.params.client_info
|
||||
assert isinstance(request, InitializeRequest)
|
||||
received_client_info = request.params.client_info
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -238,21 +231,19 @@ async def test_client_session_version_negotiation_success():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
assert isinstance(request, InitializeRequest)
|
||||
|
||||
# Verify client sent the latest protocol version
|
||||
assert request.root.params.protocol_version == LATEST_PROTOCOL_VERSION
|
||||
assert request.params.protocol_version == LATEST_PROTOCOL_VERSION
|
||||
|
||||
# Server responds with a supported older version
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version="2024-11-05",
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version="2024-11-05",
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -295,18 +286,16 @@ async def test_client_session_version_negotiation_failure():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
assert isinstance(request, InitializeRequest)
|
||||
|
||||
# Server responds with an unsupported version
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version="2020-01-01", # Unsupported old version
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version="2020-01-01", # Unsupported old version
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -349,18 +338,16 @@ async def test_client_capabilities_default():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
received_capabilities = request.root.params.capabilities
|
||||
assert isinstance(request, InitializeRequest)
|
||||
received_capabilities = request.params.capabilities
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -422,18 +409,16 @@ async def test_client_capabilities_with_custom_callbacks():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
received_capabilities = request.root.params.capabilities
|
||||
assert isinstance(request, InitializeRequest)
|
||||
received_capabilities = request.params.capabilities
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -503,18 +488,16 @@ async def test_client_capabilities_with_sampling_tools():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
received_capabilities = request.root.params.capabilities
|
||||
assert isinstance(request, InitializeRequest)
|
||||
received_capabilities = request.params.capabilities
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -572,17 +555,15 @@ async def test_get_server_capabilities():
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
assert isinstance(request, InitializeRequest)
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=expected_capabilities,
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=expected_capabilities,
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
async with server_to_client_send:
|
||||
|
|
@ -639,17 +620,15 @@ async def test_client_tool_call_with_meta(meta: dict[str, Any] | None):
|
|||
session_message = await client_to_server_receive.receive()
|
||||
jsonrpc_request = session_message.message
|
||||
assert isinstance(jsonrpc_request, JSONRPCRequest)
|
||||
request = ClientRequest.model_validate(
|
||||
request = client_request_adapter.validate_python(
|
||||
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
|
||||
)
|
||||
assert isinstance(request.root, InitializeRequest)
|
||||
assert isinstance(request, InitializeRequest)
|
||||
|
||||
result = ServerResult(
|
||||
InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
result = InitializeResult(
|
||||
protocol_version=LATEST_PROTOCOL_VERSION,
|
||||
capabilities=ServerCapabilities(),
|
||||
server_info=Implementation(name="mock-server", version="0.1.0"),
|
||||
)
|
||||
|
||||
# Answer initialization request
|
||||
|
|
@ -678,9 +657,7 @@ async def test_client_tool_call_with_meta(meta: dict[str, Any] | None):
|
|||
assert "_meta" in jsonrpc_request.params
|
||||
assert jsonrpc_request.params["_meta"] == meta
|
||||
|
||||
result = ServerResult(
|
||||
CallToolResult(content=[TextContent(type="text", text="Called successfully")], is_error=False)
|
||||
)
|
||||
result = CallToolResult(content=[TextContent(type="text", text="Called successfully")], is_error=False)
|
||||
|
||||
# Send the tools/call result
|
||||
await server_to_client_send.send(
|
||||
|
|
|
|||
Loading…
Reference in a new issue