mcp-tester 0.7.0

Comprehensive MCP server testing tool - library and CLI
Documentation

MCP Tester

The Swiss Army knife for testing MCP servers. Validate protocol conformance, test tools, generate scenarios, and diagnose connection issues — all from a single binary.

$ mcp-tester test http://localhost:3000

  MCP Server Test Report
  ══════════════════════════════════════════════════════
  Server: my-server v1.0.0 | Protocol: 2025-11-25

  Core
    ✓ Initialize          Server responded with valid capabilities
    ✓ Protocol Version    Protocol version: 2025-11-25
    ✓ Server Info         my-server v1.0.0
    ✓ Capabilities        tools, resources, prompts

  Tools
    ✓ List                Found 5 tools
    ✓ Schema              All 5 tool schemas valid

  Resources
    ✓ List                Found 2 resources

  Summary: 7 passed, 0 failed, 0 warnings in 1.23s

Install

Option 1: Cargo (recommended for Rust developers)

# Standalone binary
cargo install mcp-tester

# Or as part of the full PMCP toolkit
cargo install cargo-pmcp

Option 2: Shell script (no Rust required)

Linux and macOS — downloads the pre-built binary for your platform:

curl -fsSL https://raw.githubusercontent.com/paiml/rust-mcp-sdk/main/install/install.sh | sh

Windows PowerShell:

irm https://raw.githubusercontent.com/paiml/rust-mcp-sdk/main/install/install.ps1 | iex

Pre-built binaries are available for Linux x86_64/ARM64, macOS Intel/Apple Silicon, and Windows x86_64.

Option 3: Via MCP (use from any MCP client)

The PMCP server at https://pmcp-server.us-east.true-mcp.com/mcp exposes testing tools you can call directly from Claude Desktop, ChatGPT, or any MCP client — no local install needed.

Quick Start: Check

The fastest way to validate an MCP server — one command, pass/fail answer:

# Test a local server
mcp-tester quick http://localhost:3000

# Test a remote server
mcp-tester quick https://my-server.example.com/mcp

# Test with OAuth
mcp-tester quick https://api.example.com/mcp \
  --oauth-issuer "https://auth.example.com" \
  --oauth-client-id "my-client-id"

# Via cargo-pmcp (auto-discovers server in your workspace)
cargo pmcp test check http://localhost:3000

Protocol Conformance

Validate any MCP server against the protocol spec (2025-11-25). Tests 5 domains: Core, Tools, Resources, Prompts, Tasks. Each domain reports independently — a server with no resources still passes.

# Full conformance check
mcp-tester conformance http://localhost:3000

# Strict mode (warnings → failures)
mcp-tester conformance http://localhost:3000 --strict

# Test specific domains only
mcp-tester conformance http://localhost:3000 --domain core,tools

# Via cargo-pmcp
cargo pmcp test conformance http://localhost:3000

Output includes a per-domain CI summary line:

Conformance: Core=PASS Tools=PASS Resources=SKIP Prompts=PASS Tasks=SKIP

App Validation

Validate MCP App metadata on a running server. Cross-references tools that declare ui.resourceUri against the resources they reference, validates MIME types, and (in strict modes) statically inspects the widget HTML for required protocol handler wiring.

# Default (permissive) — one summary Warning per widget
mcp-tester apps http://localhost:3000

# ChatGPT compatibility mode (no-op for widget HTML inspection)
mcp-tester apps http://localhost:3000 --mode chatgpt

# Claude Desktop / Claude.ai pre-deploy gate (strict static widget inspection)
mcp-tester apps http://localhost:3000 --mode claude-desktop

--mode claude-desktop statically inspects each widget HTML body for the @modelcontextprotocol/ext-apps import and the four required protocol handlers (onteardown, ontoolinput, ontoolcancelled, onerror) before connect(). This catches the silent-fail class where Claude Desktop tears down the MCP connection after a missing handler — see src/server/mcp_apps/GUIDE.md#handlers-before-connect.

Source-scan mode: --widgets-dir <path>

Two scan surfaces are supported:

Scan mode When to use What it scans
Bundle scan (default) CI against a deployed server Each widget HTML body fetched via resources/read
Source scan (--widgets-dir <path>) Local pre-deploy validation <path>/*.html source files on disk

Why both: Bundle scan validates what the server actually serves to clients (the post-Vite-singlefile bytes). Source scan is faster and higher-confidence pre-deploy because source files have unmangled identifiers and intact import statements — minifiers cannot defeat patterns that match against the unminified import { App } from '@modelcontextprotocol/ext-apps'.

The validator's regex set is minification-resistant in both modes (see Plan 78-06 — gap closure for cost-coach minified-bundle false positives). The four SDK-presence signals — [ext-apps] log prefix, ui/initialize method literal, ui/notifications/tool-result method literal, and the legacy @modelcontextprotocol/ext-apps import literal — survive Vite singlefile minification because they are protocol-level strings the SDK exposes by name.

Example:

# Source-scan local widget files (pre-deploy)
cargo pmcp test apps --mode claude-desktop --widgets-dir ./widget "http://informational"

# Bundle-scan against a deployed server (CI)
cargo pmcp test apps --mode claude-desktop https://my-server.example.com/mcp

Same validator, same verdict shape, two ingestion paths.

Generate Test Scenarios

Auto-generate test scenarios from your server's capabilities. The generator discovers all tools, analyzes their JSON schemas, and creates YAML scenario files with smart placeholder values:

# Generate from a running server
mcp-tester generate-scenario http://localhost:3000 -o tests/my-server.yaml \
  --all-tools --with-resources --with-prompts

# Via cargo-pmcp
cargo pmcp test generate --server my-server --port 3000

This produces editable YAML like:

name: my-server Test Scenario
timeout: 60
steps:
  - name: Test tool search
    operation:
      type: tool_call
      tool: search
      arguments:
        query: "TODO: query"    # ← fill in real test data
    assertions:
      - type: success
      - type: exists
        path: results

Run Test Scenarios

Execute generated or hand-written scenarios against your server:

# Run a single scenario
mcp-tester scenario http://localhost:3000 tests/my-server.yaml --detailed

# Run all scenarios in a directory
cargo pmcp test run --server my-server --scenarios tests/

All Commands

Command Description
test Full test suite — protocol, tools, resources, prompts
quick Fast connectivity and protocol check
conformance MCP protocol conformance validation (19 scenarios across 5 domains)
tools Discover tools and validate schemas
resources Test resource discovery and reading
prompts Validate prompt templates and arguments
apps Validate MCP App metadata (standard, ChatGPT, Claude Desktop modes)
generate-scenario Auto-generate test scenarios from server capabilities
scenario Run YAML/JSON test scenarios
diagnose Layer-by-layer connection diagnostics
compare Compare two servers side-by-side
health Health check endpoint

Key Features

  • Multi-transport: HTTP, HTTPS, WebSocket, stdio — auto-detected or forced with --transport
  • OAuth 2.0: Interactive browser-based PKCE flow with token caching (--oauth-* flags)
  • Schema validation: Warns about missing properties, empty schemas, incomplete metadata
  • MCP App validation: Checks _meta, ui.resourceUri, resource cross-refs, ChatGPT keys
  • CI/CD ready: --format json for machine-readable output, deterministic exit codes
  • Multiple output formats: pretty (default), json, minimal, verbose

CI/CD Integration

# GitHub Actions
- name: Test MCP Server
  run: |
    curl -fsSL https://raw.githubusercontent.com/paiml/rust-mcp-sdk/main/install/install.sh | sh
    mcp-tester test ${{ env.SERVER_URL }} --format json > results.json
# Any CI — exit code tells you pass/fail
mcp-tester test "$SERVER_URL" --format minimal

Documentation

License

MIT — See LICENSE in the repository root.