|
9 | 9 | from mcp.server.lowlevel import NotificationOptions |
10 | 10 | from mcp.server.models import InitializationOptions |
11 | 11 | from mcp.server.session import ServerSession |
| 12 | +from mcp.shared.exceptions import McpError |
12 | 13 | from mcp.shared.message import SessionMessage |
13 | 14 | from mcp.shared.session import RequestResponder |
14 | 15 | from mcp.types import ( |
@@ -393,6 +394,56 @@ async def test_create_message_tool_result_validation(): |
393 | 394 | ) |
394 | 395 |
|
395 | 396 |
|
| 397 | +@pytest.mark.anyio |
| 398 | +async def test_create_message_without_tools_capability(): |
| 399 | + """Test that create_message raises McpError when tools are provided without capability.""" |
| 400 | + server_to_client_send, server_to_client_receive = anyio.create_memory_object_stream[SessionMessage](1) |
| 401 | + client_to_server_send, client_to_server_receive = anyio.create_memory_object_stream[SessionMessage | Exception](1) |
| 402 | + |
| 403 | + async with ( |
| 404 | + client_to_server_send, |
| 405 | + client_to_server_receive, |
| 406 | + server_to_client_send, |
| 407 | + server_to_client_receive, |
| 408 | + ): |
| 409 | + async with ServerSession( |
| 410 | + client_to_server_receive, |
| 411 | + server_to_client_send, |
| 412 | + InitializationOptions( |
| 413 | + server_name="test", |
| 414 | + server_version="0.1.0", |
| 415 | + capabilities=ServerCapabilities(), |
| 416 | + ), |
| 417 | + ) as session: |
| 418 | + # Set up client params WITHOUT sampling.tools capability |
| 419 | + session._client_params = types.InitializeRequestParams( |
| 420 | + protocolVersion=types.LATEST_PROTOCOL_VERSION, |
| 421 | + capabilities=types.ClientCapabilities(sampling=types.SamplingCapability()), |
| 422 | + clientInfo=types.Implementation(name="test", version="1.0"), |
| 423 | + ) |
| 424 | + |
| 425 | + tool = types.Tool(name="test_tool", inputSchema={"type": "object"}) |
| 426 | + text = types.TextContent(type="text", text="hello") |
| 427 | + |
| 428 | + # Should raise McpError when tools are provided but client lacks capability |
| 429 | + with pytest.raises(McpError) as exc_info: |
| 430 | + await session.create_message( |
| 431 | + messages=[types.SamplingMessage(role="user", content=text)], |
| 432 | + max_tokens=100, |
| 433 | + tools=[tool], |
| 434 | + ) |
| 435 | + assert "does not support sampling tools capability" in exc_info.value.error.message |
| 436 | + |
| 437 | + # Should also raise McpError when tool_choice is provided |
| 438 | + with pytest.raises(McpError) as exc_info: |
| 439 | + await session.create_message( |
| 440 | + messages=[types.SamplingMessage(role="user", content=text)], |
| 441 | + max_tokens=100, |
| 442 | + tool_choice=types.ToolChoice(mode="auto"), |
| 443 | + ) |
| 444 | + assert "does not support sampling tools capability" in exc_info.value.error.message |
| 445 | + |
| 446 | + |
396 | 447 | @pytest.mark.anyio |
397 | 448 | async def test_other_requests_blocked_before_initialization(): |
398 | 449 | """Test that non-ping requests are still blocked before initialization.""" |
|
0 commit comments