Skip to content

Commit 41af509

Browse files
committed
Add test to verify request ID preservation
This test ensures that the server properly preserves and returns the same request ID in responses, which is a fundamental part of the JSON-RPC protocol. The test initializes the server, sends requests with custom IDs, and verifies that these IDs are correctly returned. Github-Issue:#192
1 parent f10665d commit 41af509

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

tests/issues/test_192_request_id.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import anyio
2+
import pytest
3+
4+
from mcp.server.lowlevel import NotificationOptions, Server
5+
from mcp.server.models import InitializationOptions
6+
from mcp.types import (
7+
LATEST_PROTOCOL_VERSION,
8+
ClientCapabilities,
9+
Implementation,
10+
InitializeRequestParams,
11+
JSONRPCMessage,
12+
JSONRPCNotification,
13+
JSONRPCRequest,
14+
NotificationParams,
15+
)
16+
17+
18+
@pytest.mark.anyio
19+
async def test_request_id_match() -> None:
20+
"""Test that the server preserves request IDs in responses."""
21+
server = Server("test")
22+
custom_request_id = "test-123"
23+
24+
# Create memory streams for communication
25+
client_writer, client_reader = anyio.create_memory_object_stream(1)
26+
server_writer, server_reader = anyio.create_memory_object_stream(1)
27+
28+
# Server task to process the request
29+
async def run_server():
30+
async with client_reader, server_writer:
31+
await server.run(
32+
client_reader,
33+
server_writer,
34+
InitializationOptions(
35+
server_name="test",
36+
server_version="1.0.0",
37+
capabilities=server.get_capabilities(
38+
notification_options=NotificationOptions(),
39+
experimental_capabilities={},
40+
),
41+
),
42+
raise_exceptions=True,
43+
)
44+
45+
# Start server task
46+
async with anyio.create_task_group() as tg:
47+
tg.start_soon(run_server)
48+
49+
# Send initialize request
50+
init_req = JSONRPCRequest(
51+
id="init-1",
52+
method="initialize",
53+
params=InitializeRequestParams(
54+
protocolVersion=LATEST_PROTOCOL_VERSION,
55+
capabilities=ClientCapabilities(),
56+
clientInfo=Implementation(name="test-client", version="1.0.0"),
57+
).model_dump(by_alias=True, exclude_none=True),
58+
jsonrpc="2.0",
59+
)
60+
61+
await client_writer.send(JSONRPCMessage(root=init_req))
62+
await server_reader.receive() # Get init response but don't need to check it
63+
64+
# Send initialized notification
65+
initialized_notification = JSONRPCNotification(
66+
method="notifications/initialized",
67+
params=NotificationParams().model_dump(by_alias=True, exclude_none=True),
68+
jsonrpc="2.0",
69+
)
70+
await client_writer.send(JSONRPCMessage(root=initialized_notification))
71+
72+
# Send ping request with custom ID
73+
ping_request = JSONRPCRequest(
74+
id=custom_request_id, method="ping", params={}, jsonrpc="2.0"
75+
)
76+
77+
await client_writer.send(JSONRPCMessage(root=ping_request))
78+
79+
# Read response
80+
response = await server_reader.receive()
81+
82+
# Verify response ID matches request ID
83+
assert (
84+
response.root.id == custom_request_id
85+
), "Response ID should match request ID"
86+
87+
# Cancel server task
88+
tg.cancel_scope.cancel()

0 commit comments

Comments
 (0)