-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_mcp_stdio_contract.py
More file actions
78 lines (69 loc) · 3.08 KB
/
Copy pathtest_mcp_stdio_contract.py
File metadata and controls
78 lines (69 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import json
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
BENCH_PYTHON = ROOT.parent / ".venv-bench" / "bin" / "python"
SERVER_SCRIPT = ROOT / "examples" / "run_zcp_mcp_stdio_server.py"
def test_official_mcp_client_can_talk_to_zcp_stdio_server() -> None:
if not BENCH_PYTHON.exists():
return
script = f"""
import asyncio
import json
from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client
async def main():
async with stdio_client(
StdioServerParameters(
command={json.dumps(str(BENCH_PYTHON))},
args={[str(SERVER_SCRIPT)]!r},
cwd={json.dumps(str(ROOT))},
)
) as (read_stream, write_stream):
async with ClientSession(read_stream, write_stream) as session:
await session.initialize()
tools = await session.list_tools()
tool = await session.call_tool("weather.get_current", {{"city": "Hangzhou"}})
resources = await session.list_resources()
templates = await session.list_resource_templates()
resource = await session.read_resource("weather://cities")
prompts = await session.list_prompts()
prompt = await session.get_prompt("weather.summary", {{"city": "Hangzhou"}})
completion = await session.complete(
{{"type": "ref/prompt", "name": "weather.summary"}},
{{"name": "city", "value": "Ha"}},
)
tool_payload = tool.structured_content
if tool_payload is None and tool.content:
tool_payload = {{"text": tool.content[0].text}}
print(json.dumps({{
"tool_names": [item.name for item in tools.tools],
"tool_content": tool_payload,
"resource_uris": [item.uri for item in resources.resources],
"template_uris": [item.uri_template for item in templates.resource_templates],
"resource_text": resource.contents[0].text,
"prompt_names": [item.name for item in prompts.prompts],
"prompt_content": prompt.messages[0].content.text,
"completion_values": completion.completion.values,
}}, ensure_ascii=False))
asyncio.run(main())
"""
completed = subprocess.run(
[str(BENCH_PYTHON), "-c", script],
cwd=ROOT,
capture_output=True,
text=True,
check=True,
)
payload = json.loads(completed.stdout.strip())
assert "weather.get_current" in payload["tool_names"]
if "city" in payload["tool_content"]:
assert payload["tool_content"]["city"] == "Hangzhou"
else:
assert "Hangzhou" in payload["tool_content"]["text"]
assert "weather://cities" in payload["resource_uris"]
assert "weather://city/{name}" in payload["template_uris"]
assert "Hangzhou" in payload["resource_text"]
assert "weather.summary" in payload["prompt_names"]
assert payload["prompt_content"] == "Summarize weather for Hangzhou"
assert payload["completion_values"] == ["Hangzhou"]