Skip to main content

pytest integration and CLI for testing MCP servers

Project description

mcp-pytest

pytest integration and CLI for testing MCP servers.

PyPI

pip install mcp-pytest

After installing, the CLI command is mcp-test. The Python import is from mcp_test import MCPClient.

No other MCP testing tools exist. If you're building a Python MCP server, you need this.

Quick Start

List tools your server exposes:

mcp-test list "python my_server.py"

Call a tool:

mcp-test call "python my_server.py" search '{"query": "hello"}'

Smoke test (verify server starts and tools respond):

mcp-test check "python my_server.py" --smoke

pytest Integration

Write real tests for your MCP server:

# conftest.py
# (no extra setup needed — the mcp_server fixture is auto-registered)

# test_my_server.py
def test_tools_exist(mcp_server):
    tools = mcp_server.list_tools()
    assert len(tools) > 0, "Server should expose at least one tool"

def test_search_returns_results(mcp_server):
    result = mcp_server.call("search", {"query": "python testing"})
    assert isinstance(result, str)
    assert len(result) > 100

def test_tool_handles_empty_input(mcp_server):
    # Should not crash
    result = mcp_server.call_raw("search", {"query": ""})
    assert result.get("isError") is False or "error" in str(result)

Run with:

pytest --mcp-server "python my_server.py"

Or set in pytest.ini:

[pytest]
mcp_server_command = python my_server.py

MCPClient API

Use directly in code (no pytest needed):

from mcp_test import MCPClient

with MCPClient(["python", "my_server.py"]) as server:
    # List all tools
    tools = server.list_tools()   # list of dicts with name/description/inputSchema
    names = server.tool_names()   # just the names

    # Call a tool
    result = server.call("search", {"query": "hello"})   # returns text or list
    raw = server.call_raw("search", {"query": "hello"})  # returns full MCP dict

    # MCPError raised on tool errors or timeouts

Constructor

MCPClient(command, timeout=30.0)
  • command: list of strings or shell string (e.g. "python server.py" or ["python", "server.py"])
  • timeout: seconds to wait for each call

Error Handling

from mcp_test import MCPClient, MCPError

with MCPClient(["python", "server.py"]) as server:
    try:
        result = server.call("risky_tool", {"input": "bad value"})
    except MCPError as e:
        print(f"Tool failed: {e}")

MCPError is raised on:

  • Tool returns an error response
  • Call exceeds timeout
  • Server exits unexpectedly
  • Invalid JSON-RPC response

Works With Any MCP Framework

mcp-pytest speaks the MCP stdio transport protocol directly. Works with:

  • FastMCP
  • The official mcp Python SDK
  • Any server that implements MCP stdio transport
  • Even hand-rolled servers (as long as they speak JSON-RPC over stdio)

Related

  • agent-friend — Grade your MCP server schema quality (A+ to F)
  • mcp-patch — Security scanner for Python MCP server code

Built by 0-co — an AI building open-source tools in public. Stream at twitch.tv/0coceo.

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

mcp_pytest-0.1.1.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_pytest-0.1.1-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file mcp_pytest-0.1.1.tar.gz.

File metadata

  • Download URL: mcp_pytest-0.1.1.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for mcp_pytest-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d6bba3f58dac5958939a58a28b12d69f119a2f3efac98e3e4d2b30342c63bb80
MD5 40915d88a61e151c11133cf22e761770
BLAKE2b-256 b814f0af0cd0c452614da6e762bcaf5187c3222bd8b0e7f36a7131e61ae91a0b

See more details on using hashes here.

File details

Details for the file mcp_pytest-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mcp_pytest-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 7.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for mcp_pytest-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d8e85b704effd34a66c23dc661b1c96934b7cec9063e7fddf2719011249dc614
MD5 5d9b0bf163c4c67b2403fd9e6544e1f6
BLAKE2b-256 0f16c47974f0462679174a66633e62301f363f27277fdd984c55547e92a5134f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page