Files
modelcontextprotocol--pytho…/tests/docs_src/test_first_steps.py
T
wehub-resource-sync 49b9bb6724
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 12:10:27 +08:00

99 lines
4.1 KiB
Python

"""`docs/get-started/first-steps.md`: every claim the page makes, proved against the real SDK."""
import pytest
from inline_snapshot import snapshot
from mcp_types import (
PromptArgument,
PromptMessage,
TextContent,
TextResourceContents,
)
from docs_src.first_steps import tutorial001
from mcp import Client
from mcp.server import MCPServer
# See test_index.py for why this is a per-module mark and not a conftest hook.
pytestmark = [pytest.mark.anyio, pytest.mark.filterwarnings("error::mcp.MCPDeprecationWarning")]
async def test_each_decorator_registers_one_primitive() -> None:
"""tutorial001: name, description and schema all come from the decorated function."""
async with Client(tutorial001.mcp) as client:
(tool,) = (await client.list_tools()).tools
assert tool.name == "add"
assert tool.description == "Add two numbers."
assert tool.input_schema == snapshot(
{
"type": "object",
"properties": {
"a": {"title": "A", "type": "integer"},
"b": {"title": "B", "type": "integer"},
},
"required": ["a", "b"],
"title": "addArguments",
}
)
(template,) = (await client.list_resource_templates()).resource_templates
assert template.name == "greeting"
assert template.uri_template == "greeting://{name}"
assert template.description == "Greet someone by name."
(prompt,) = (await client.list_prompts()).prompts
assert prompt.name == "summarize"
assert prompt.description == "Summarize a piece of text in one sentence."
assert prompt.arguments == [PromptArgument(name="text", required=True)]
async def test_call_the_tool() -> None:
"""tutorial001: the Inspector walkthrough. `add` with 1 and 2 answers 3."""
async with Client(tutorial001.mcp) as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
assert not result.is_error
assert result.content == [TextContent(type="text", text="3")]
assert result.structured_content == {"result": 3}
async def test_templated_resource_is_a_template_not_a_resource() -> None:
"""tutorial001: a `{param}` in the URI means the concrete-resource list stays empty."""
async with Client(tutorial001.mcp) as client:
assert (await client.list_resources()).resources == []
async def test_read_the_resource_template() -> None:
"""tutorial001: supplying a `name` reads the template as a concrete resource."""
async with Client(tutorial001.mcp) as client:
result = await client.read_resource("greeting://World")
assert result.contents == [
TextResourceContents(uri="greeting://World", mime_type="text/plain", text="Hello, World!")
]
async def test_get_the_prompt() -> None:
"""tutorial001: the returned string becomes a single user message."""
async with Client(tutorial001.mcp) as client:
result = await client.get_prompt("summarize", {"text": "MCP is a protocol."})
rendered = "Summarize the following text in one sentence:\n\nMCP is a protocol."
assert result.messages == [PromptMessage(role="user", content=TextContent(type="text", text=rendered))]
async def test_the_three_primitive_capabilities_are_always_declared() -> None:
"""tutorial001: `MCPServer` always declares tools/resources/prompts; only `completions` follows your code.
An `MCPServer` with nothing registered declares the same three, which is why the
page ties registration to the *optional* capabilities only.
"""
async with Client(tutorial001.mcp) as client:
declared = client.server_capabilities
# The exact dictionary the page prints from `model_dump(exclude_none=True)`.
assert declared.model_dump(exclude_none=True) == snapshot(
{
"prompts": {"list_changed": True},
"resources": {"subscribe": True, "list_changed": True},
"tools": {"list_changed": True},
}
)
async with Client(MCPServer("Empty")) as client:
assert client.server_capabilities == declared