pytest for MCP servers — the testing framework for the Model Context Protocol
Project description
pytest-mcp-plugin
pytest for MCP servers — the testing framework for the Model Context Protocol.
pip install pytest-mcp-plugin
mcp-test demo # runs a bundled MCP server + tests in 5 seconds
Note on the name. This package is published on PyPI as
pytest-mcp-plugin. Themcp-testname on PyPI is reserved by Anthropic for their official MCP SDK, and PyPI's name-similarity policy blocks close variants likemcptest. The CLI binary is stillmcp-test, and the Python module is stillmcp_test.
Why
MCP (Model Context Protocol) is the standard interface every AI agent now uses to talk to tools, files, databases, and APIs. Thousands of teams are shipping MCP servers in 2026. Almost none of them are tested.
pytest-mcp-plugin fixes that. Write tests for your MCP tools, resources, and prompts
with the same developer experience you expect from pytest.
pytestplugin with auto-registered fixtures- stdio and HTTP/SSE transports
- Schema validation, snapshot testing, coverage reports
- Auth + policy assertions
- Drop-in GitHub Action
60-second tour
pip install pytest-mcp-plugin
mcp-test demo
That spins up a bundled MCP server and runs a real test suite against it — no setup, no API keys, no servers to write first.
🚀 mcp-test demo
server : python -m mcp_test._demo_server
workdir : /tmp/mcptest-demo-xxxx
test_demo.py::test_lists_tools PASSED
test_demo.py::test_echo PASSED
test_demo.py::test_add PASSED
test_demo.py::test_uppercase PASSED
test_demo.py::test_fail_returns_error PASSED
✅ Demo passed. Now write tests for your own MCP server:
mcp-test init
Test your own server
cd my-mcp-server/
mcp-test init
pytest --mcp-command "python my_server.py" -v
Or pin the command in your pyproject.toml:
[tool.mcp-test]
command = "python my_server.py"
timeout = 10
…and just run:
mcp-test run
Write tests
# tests/test_my_server.py
from mcp_test import assert_tool_ok, assert_tool_error, assert_tool_text_contains
def test_search_returns_results(mcp_client):
result = mcp_client.call_tool("search", query="machine learning")
assert_tool_ok(result)
assert len(result.content) > 0
def test_search_handles_empty_query(mcp_client):
result = mcp_client.call_tool("search", query="")
assert_tool_error(result)
def test_search_schema(mcp_client):
tools = mcp_client.list_tools()
search = tools.find("search")
assert search.required == ["query"]
assert search.properties["query"]["type"] == "string"
Use as a library
from mcp_test import MCPTestClient
with MCPTestClient.from_command("python my_server.py") as client:
tools = client.list_tools()
print(tools.names())
result = client.call_tool("echo", message="hello")
print(result.text())
Run on every PR (GitHub Action)
pytest-mcp-plugin ships as a composite action you can drop into any repo:
# .github/workflows/mcp-tests.yml
name: MCP Tests
on:
pull_request:
push:
branches: [main]
jobs:
mcp-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: yagna-1/mcp-test@v0.2.0
with:
command: "python my_server.py"
test-dir: "tests"
That's it. The action installs pytest-mcp-plugin, runs your suite against your MCP
server, and posts a JUnit XML report.
CLI reference
| Command | Description |
|---|---|
mcp-test demo |
Run the bundled demo server + tests (zero setup) |
mcp-test init |
Scaffold tests/ with example MCP tests |
mcp-test run -c "python server.py" |
Run pytest against your server |
mcp-test snapshot -c "..." |
Run snapshot tests (--update to refresh) |
mcp-test coverage -c "..." |
Print coverage report (tools/prompts/resources) |
mcp-test validate -c "..." |
Validate tool input schemas |
All commands accept --help for full options.
Fixtures
The pytest plugin auto-registers three fixtures:
| Fixture | Scope | Use for |
|---|---|---|
mcp_client |
session | Fast — one server process for the whole test run |
mcp_client_fresh |
function | Clean state per test |
sandboxed_client |
function | Fresh server with cwd=tmp_path and DATA_DIR=tmp_path |
snapshot |
function | Snapshot testing helper |
pytest --mcp-command "python my_server.py" --mcp-timeout 15
Spec-version markers
Mark tests by required MCP spec version; the plugin auto-skips tests against older servers.
import pytest
@pytest.mark.mcp_v3 # requires spec >= 2025-06-18
def test_uses_recent_feature(mcp_client):
...
Available markers: mcp_v2, mcp_v3, mcp_v4.
Assertion helpers
from mcp_test import (
assert_tool_ok,
assert_tool_error,
assert_tool_error_code,
assert_tool_text_contains,
assert_tool_text_equals,
assert_tool_content_count,
assert_policy_allows,
assert_policy_blocks,
assert_task_completes_within,
assert_task_cancelled,
assert_task_failed,
)
Architecture
pytest-mcp-plugin runs your MCP server as a subprocess and speaks JSON-RPC 2.0 over
stdio (or HTTP/SSE for the HTTP transport). A background message pump handles
response routing, notification dispatching, and concurrent request support —
so your tests just work.
Source modules:
mcp_test/
client.py # stdio JSON-RPC client
http_client.py # HTTP + SSE client
plugin.py # pytest plugin (fixtures, options, markers)
cli.py # mcp-test CLI
assertions.py # assert_tool_*, assert_policy_*, assert_task_*
schema_validator.py # JSON Schema validation for tool inputs
coverage.py # tools/prompts/resources coverage tracker
snapshot.py # snapshot testing
auth.py # OAuth / PKCE / RFC 9728 helpers
pagination.py # cursor pagination helpers
types.py # ToolResult, ToolSchema, MCPError, ...
_demo_server.py # bundled demo server (used by `mcp-test demo`)
Status
pytest-mcp-plugin is beta. The CLI surface and plugin API are stable; minor
internals (schema validator details, snapshot format) may still change.
Contributing
Bug reports, feature requests, and PRs welcome at github.com/yagna-1/mcp-test.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_mcp_plugin-0.2.0.tar.gz.
File metadata
- Download URL: pytest_mcp_plugin-0.2.0.tar.gz
- Upload date:
- Size: 53.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76712c1a059aa58adf96e4424aef3d8660a32433b2a49c45180500020c8eae87
|
|
| MD5 |
843397c2d3022110497a2f05f63ebe98
|
|
| BLAKE2b-256 |
4beae436fad24d53ddd24a11fe142013b51092e5ba5ec93b4d4d135c695ad517
|
File details
Details for the file pytest_mcp_plugin-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pytest_mcp_plugin-0.2.0-py3-none-any.whl
- Upload date:
- Size: 37.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ad6e6c598b7ad5ed7989a4aa25abcd31d0fb4350c37ab9e3f33d61836e454a0
|
|
| MD5 |
37032ca436dec6438aca436c0f307933
|
|
| BLAKE2b-256 |
63ab974d8a03f10524017bd3a342652e053b6bd2193080eb9f43d1f05fd8eeaa
|