Skip to content

Commit 09608a8

Browse files
committed
Add request context tests and pre-commit config
1 parent 6316738 commit 09608a8

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

.pre-commit-config.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
fail_fast: true
2+
3+
repos:
4+
- repo: https://github.com/pre-commit/mirrors-prettier
5+
rev: v3.1.0
6+
hooks:
7+
- id: prettier
8+
types_or: [yaml, json5]
9+
10+
- repo: https://github.com/astral-sh/ruff-pre-commit
11+
rev: v0.8.1
12+
hooks:
13+
- id: ruff-format
14+
- id: ruff
15+
args: [--fix, --exit-non-zero-on-fix]

tests/server/test_request_context.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""Test request context handling in the server."""
2+
3+
import io
4+
import logging
5+
6+
import anyio
7+
import pytest
8+
9+
from mcp.server import Server
10+
from mcp.server.models import InitializationOptions
11+
from mcp.server.stdio import stdio_server
12+
from mcp.types import (
13+
LATEST_PROTOCOL_VERSION,
14+
CallToolRequest,
15+
CallToolRequestParams,
16+
ClientCapabilities,
17+
ClientRequest,
18+
Implementation,
19+
InitializeRequest,
20+
InitializeRequestParams,
21+
JSONRPCMessage,
22+
JSONRPCRequest,
23+
RequestParams,
24+
ServerCapabilities,
25+
TextContent,
26+
ToolsCapability,
27+
)
28+
29+
logger = logging.getLogger()
30+
logger.setLevel(logging.DEBUG)
31+
32+
33+
@pytest.mark.anyio
34+
async def test_request_meta_simple():
35+
"""Test request_meta availability in server.request_context"""
36+
server = Server("test_server")
37+
38+
# Add a tool handler to verify request context
39+
tool_called = False
40+
captured_meta = None
41+
42+
@server.call_tool()
43+
async def handle_tool_call(name: str, args: dict | None = None):
44+
nonlocal captured_meta, tool_called
45+
# Capture the meta from request context
46+
logger.info(server.request_context)
47+
captured_meta = server.request_context.meta
48+
tool_called = True
49+
return [TextContent(type="text", text="test")]
50+
51+
# Initialize server with tool capabilities
52+
init_request = InitializeRequest(
53+
method="initialize",
54+
params=InitializeRequestParams(
55+
protocolVersion=LATEST_PROTOCOL_VERSION,
56+
capabilities=ClientCapabilities(),
57+
clientInfo=Implementation(name="test", version="1.0"),
58+
),
59+
)
60+
61+
init_msg = JSONRPCMessage(
62+
root=JSONRPCRequest(
63+
jsonrpc="2.0",
64+
id=1,
65+
**init_request.model_dump(by_alias=True, exclude_none=True),
66+
)
67+
)
68+
69+
# Send initialized notification
70+
init_notify = JSONRPCMessage(
71+
root=dict(jsonrpc="2.0", method="notifications/initialized")
72+
)
73+
74+
# Send tool call request with _meta
75+
call_request = ClientRequest(
76+
root=CallToolRequest(
77+
method="tools/call",
78+
params=CallToolRequestParams(
79+
name="test", arguments={}, _meta=RequestParams.Meta(progressToken=123)
80+
),
81+
)
82+
)
83+
84+
call_msg = JSONRPCMessage(
85+
root=JSONRPCRequest(
86+
jsonrpc="2.0",
87+
id=2,
88+
**call_request.model_dump(by_alias=True, exclude_none=True),
89+
)
90+
)
91+
92+
stdin = io.StringIO()
93+
stdout = io.StringIO()
94+
stdin.write(init_msg.model_dump_json(by_alias=True, exclude_none=True) + "\n")
95+
stdin.write(init_notify.model_dump_json(by_alias=True, exclude_none=True) + "\n")
96+
stdin.write(call_msg.model_dump_json(by_alias=True, exclude_none=True) + "\n")
97+
stdin.seek(0)
98+
99+
async with stdio_server(
100+
stdin=anyio.AsyncFile(stdin), stdout=anyio.AsyncFile(stdout)
101+
) as (read_stream, write_stream):
102+
await server.run(
103+
read_stream,
104+
write_stream,
105+
InitializationOptions(
106+
server_name="test",
107+
server_version="1.0",
108+
capabilities=ServerCapabilities(tools=ToolsCapability()),
109+
),
110+
raise_exceptions=True,
111+
)
112+
113+
assert tool_called
114+
assert captured_meta is not None
115+
assert captured_meta.progressToken == 123

0 commit comments

Comments
 (0)