Skip to main content

mcp-evals

Behavioral evaluation and description linting for Model Context Protocol (MCP) servers.

License: MIT Python 3.11+ CI

Status: v0.4 — stdio + HTTP JSON-RPC discovery, description lint (including name-description-mismatch), and mock/OpenAI-compatible tool-selection evals.

60-second try

docker compose run --rm run-example   # mock eval, no API key
docker compose run --rm lint-example  # live stdio lint
docker compose run --rm test          # pytest

Why this vs alternatives

Approach Strength Gap
mcp-evals Lint + YAML evals + mock CI runner Not a full agent harness
MCP Inspector Interactive debugging No CI lint/eval suite
Protocol conformance tests JSON-RPC correctness Do not test tool selection
Hand-written LLM mocks Full control Drift from real descriptions

Problem

Protocol conformance tests verify JSON-RPC correctness. They do not verify whether an LLM agent selects the right tool, passes sensible arguments, or completes the task. Tool descriptions are now load-bearing API design, and there is no standard way to test them.

mcp-evals fills the behavioral layer: lint tool descriptions, define eval cases in YAML, and (next) measure tool-selection accuracy in CI.

Key features (v0.4)

  • Description linter — missing descriptions, undocumented required params, overlapping tools, ambiguous verbs, name-description-mismatch
  • Live discover — handshake a stdio or HTTP JSON-RPC MCP server (or load a catalog fixture)
  • Eval runnermcp-evals run with --model mock (CI), --live SERVER.yaml, or an OpenAI-compatible endpoint
  • CLI + Docker + GitHub Action — lint and optional eval in CI without a cloud key (mock selector)

Architecture

┌─────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  CLI        │────▶│  Linter / Runner │────▶│  Models (Pydantic)│
│  mcp-evals  │     │  spec_loader     │     │  EvalSuite, etc.  │
└─────────────┘     └──────────────────┘     └─────────────────┘
                            │
                    (next) MCP client + LLM
Component Technology Why
Language Python 3.11+ MCP SDK ecosystem, pytest integration
CLI Click Mature, composable commands
Schemas Pydantic v2 Strict validation, good errors
Logging structlog Structured, JSON-capable
Config pydantic-settings Env-based, typed
Tests pytest + ruff + mypy Standard Python OSS stack

Installation

pip install mcp-tool-evals
# or from source:
pip install -e ".[dev]"

Local development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
mcp-evals health
mcp-evals lint examples/tools.yaml
mcp-evals discover examples/server.yaml
mcp-evals lint --live examples/server.yaml
mcp-evals validate-spec examples/eval-suite.yaml
mcp-evals run examples/eval-suite.yaml --catalog examples/tools.yaml --model mock
pytest tests/ -v

Docker

# Health check
docker compose run --rm dev

# Run tests
docker compose run --rm test

# Lint a live stdio server (this example passes)
docker compose run --rm lint-example

# Discover tools from the example calc server
docker compose run --rm discover-example

# Mock eval run (no API key)
docker compose run --rm run-example

Configuration

Copy .env.example to .env:

Variable Default Description
MCP_EVALS_LOG_LEVEL INFO Log level
MCP_EVALS_LOG_JSON false JSON log output
MCP_EVALS_DEFAULT_MODEL gpt-4o-mini Model for eval runs (future)
MCP_EVALS_PASS_THRESHOLD 0.8 Minimum selection accuracy

Usage

Lint tool descriptions

mcp-evals lint examples/tools.yaml
mcp-evals lint --live examples/server.yaml
mcp-evals discover examples/server.yaml
mcp-evals lint examples/tools.yaml --format json
mcp-evals lint examples/tools.yaml --fail-on-warning

Run behavioral evals

mcp-evals run examples/eval-suite.yaml --catalog examples/tools.yaml --model mock
mcp-evals run examples/eval-suite.yaml --catalog examples/tools.yaml \
  --model llama3.2 --base-url http://localhost:11434/v1 --pass-threshold 0.8
# or discover tools from a live server that matches the suite:
# mcp-evals run suite.yaml --live server.yaml --model mock

Validate eval suite

mcp-evals validate-spec examples/eval-suite.yaml

Health check

mcp-evals health

Example eval suite

See examples/eval-suite.yaml:

name: document-server-behavior
cases:
  - id: search-by-keyword
    request: Find documents about quarterly revenue
    expected_tool:
      name: search_documents
      arguments:
        query: quarterly revenue

Running tests

pytest tests/ -v
ruff check src tests
mypy src

Development workflow

  1. Add linter rules in src/mcp_evals/linter/
  2. Add runner logic in src/mcp_evals/runner/
  3. Add tests in tests/
  4. Update examples in examples/

Roadmap

  • MCP client: stdio discover + lint --live
  • LLM eval runner (mock + OpenAI-compatible)
  • HTTP JSON-RPC MCP transport
  • name-description-mismatch linter rule
  • Streamable HTTP/SSE MCP transport
  • GitHub Action PR comments and accuracy deltas

Known limitations (v0.4)

  • Streamable HTTP/SSE MCP is not implemented — HTTP is JSON-RPC POST only
  • Mock selector does not fill tool arguments (accuracy is tool-name only)
  • Live Ollama/OpenAI evals need a reachable --base-url; CI uses --model mock
  • examples/tools.yaml is intentionally dirty so mcp-evals lint can show findings

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Release files for mcp-tool-evals 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-tool-evals 0.4.0
File Size Uploaded
mcp_tool_evals-0.4.0.tar.gz 25.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-tool-evals 0.4.0
File Interpreter ABI Platform
mcp_tool_evals-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size:46.6 kB

Release files / mcp_tool_evals-0.4.0.tar.gz

Download URL mcp_tool_evals-0.4.0.tar.gz
Size 25.7 kB
Tags Source
SHA-256 checksum
How to use checksums
089e0628bbf2cd169eb2e265aaca7fe755a3831f73735c8b8e4f1c8cc2f751d4
BLAKE2b-256 checksum
How to use checksums
2c3cd1117ebb53bfdbbfc2e5d5ff76129460124daa48a208eb6f66786975abcd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / mcp_tool_evals-0.4.0-py3-none-any.whl

Download URL mcp_tool_evals-0.4.0-py3-none-any.whl
Size 21.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad7a574e9d4f6c6d8b460ab62fa15af4671adf4c497fdb5d0526423d750a3e0c
BLAKE2b-256 checksum
How to use checksums
a996f2b9e8730549e683e9e692ea047c57f94945894e9158723bc7ea31e25fd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

This release

0.4.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page