|
| 1 | +# Getting Started with MCPChecker |
| 2 | + |
| 3 | +> **Get started with MCPChecker in 5 minutes** |
| 4 | +
|
| 5 | +A minimal, batteries-included example showing how to test an HTTP MCP server with MCPChecker. |
| 6 | + |
| 7 | +**What you get:** |
| 8 | +- ✅ Working HTTP MCP server (FastMCP official quickstart example) |
| 9 | +- ✅ MCPChecker test for the `add` tool |
| 10 | +- ✅ One command to run everything |
| 11 | +- ✅ Perfect starting point to test your own MCP servers |
| 12 | + |
| 13 | +## Why MCPChecker? |
| 14 | + |
| 15 | +You've built an MCP server with tools. It works. But: |
| 16 | +- **Is your tool description clear enough for an LLM to discover it?** |
| 17 | +- **Can an AI agent actually use your tool correctly?** |
| 18 | +- **Does your tool handle edge cases properly?** |
| 19 | + |
| 20 | +MCPChecker helps you test these questions automatically by: |
| 21 | +1. Running real AI agents (like Claude Code) against your tools |
| 22 | +2. Verifying agents can discover and use your tools correctly |
| 23 | +3. Testing edge cases and error handling |
| 24 | +4. Ensuring tool descriptions are clear and actionable |
| 25 | + |
| 26 | +Think of it as integration testing for AI tool use. |
| 27 | + |
| 28 | +## What's Included |
| 29 | + |
| 30 | +- **HTTP MCP Server** (`server/server.py`) - Simple FastMCP server with: |
| 31 | + - `add` tool - Adds two numbers (taken from the official Python-SDK [Quickstart](https://github.com/modelcontextprotocol/python-sdk?tab=readme-ov-file#quickstart)) |
| 32 | +- **MCPChecker Tests** (`evals/`) - Test task for the `add` tool |
| 33 | + |
| 34 | +The server uses **streamable HTTP transport** with `mcp.run(transport="streamable-http")`. |
| 35 | + |
| 36 | +## Quick Start |
| 37 | + |
| 38 | +### 0. Configure the Judge LLM |
| 39 | + |
| 40 | +MCPChecker uses an LLM to verify test results. Set these environment variables before running tests, for instance with OpenAI: |
| 41 | + |
| 42 | +```bash |
| 43 | +export JUDGE_BASE_URL="https://api.openai.com/v1" |
| 44 | +export JUDGE_API_KEY="sk-your-key-here" |
| 45 | +export JUDGE_MODEL_NAME="gpt-4o-mini" |
| 46 | +``` |
| 47 | + |
| 48 | +The judge LLM evaluates whether the agent completed tasks correctly by analyzing the agent's output. |
| 49 | + |
| 50 | +### 1. Install Prerequisites |
| 51 | + |
| 52 | +**Install uv** (Python package manager): |
| 53 | +```bash |
| 54 | +curl -LsSf https://astral.sh/uv/install.sh | sh |
| 55 | +``` |
| 56 | + |
| 57 | +**Install mcpchecker** - Download from [releases](https://github.com/mcpchecker/mcpchecker/releases): |
| 58 | + |
| 59 | +```bash |
| 60 | +# Linux (amd64) |
| 61 | +curl -L -o mcpchecker https://github.com/mcpchecker/mcpchecker/releases/latest/download/mcpchecker-linux-amd64 |
| 62 | +chmod +x mcpchecker |
| 63 | +sudo mv mcpchecker /usr/local/bin/ |
| 64 | + |
| 65 | +# macOS (arm64 - Apple Silicon) |
| 66 | +curl -L -o mcpchecker https://github.com/mcpchecker/mcpchecker/releases/latest/download/mcpchecker-darwin-arm64 |
| 67 | +chmod +x mcpchecker |
| 68 | +sudo mv mcpchecker /usr/local/bin/ |
| 69 | +``` |
| 70 | + |
| 71 | +### 2. Start the MCP Server |
| 72 | + |
| 73 | +In one terminal, start the HTTP server: |
| 74 | + |
| 75 | +```bash |
| 76 | +cd server |
| 77 | +PORT=8000 ./server.py |
| 78 | +``` |
| 79 | + |
| 80 | +The server will start on `http://localhost:8000/mcp` using streamable HTTP transport. |
| 81 | + |
| 82 | +**Note**: The `PORT` environment variable tells FastMCP which port to use. |
| 83 | + |
| 84 | +### 3. Run the Tests |
| 85 | + |
| 86 | +**Option A: Manual** (two terminals) |
| 87 | + |
| 88 | +In another terminal, run mcpchecker: |
| 89 | + |
| 90 | +```bash |
| 91 | +cd evals |
| 92 | +mcpchecker eval eval.yaml |
| 93 | +``` |
| 94 | + |
| 95 | +You should see: |
| 96 | +``` |
| 97 | + Task: add-test |
| 98 | + Path: /../getting-started/evals/tasks/add.yaml |
| 99 | + Difficulty: easy |
| 100 | + Task Status: PASSED |
| 101 | + Assertions: PASSED (3/3) |
| 102 | +``` |
| 103 | + |
| 104 | +## Understanding the Test Files |
| 105 | + |
| 106 | +This quickstart includes a complete evaluation setup. Let's look at what gets tested and how it's defined: |
| 107 | + |
| 108 | +### The Main Eval Configuration (`evals/eval.yaml`) |
| 109 | + |
| 110 | +```yaml |
| 111 | +kind: Eval |
| 112 | +metadata: |
| 113 | + name: "demo-server-test" |
| 114 | + |
| 115 | +config: |
| 116 | + # Use Claude Code as the AI agent |
| 117 | + agent: |
| 118 | + type: "builtin.claude-code" |
| 119 | + |
| 120 | + # MCP server configuration |
| 121 | + mcpConfigFile: mcp-config.yaml |
| 122 | + |
| 123 | + # LLM judge configuration |
| 124 | + llmJudge: |
| 125 | + env: |
| 126 | + baseUrlKey: JUDGE_BASE_URL |
| 127 | + apiKeyKey: JUDGE_API_KEY |
| 128 | + modelNameKey: JUDGE_MODEL_NAME |
| 129 | + |
| 130 | + # Test tasks |
| 131 | + taskSets: |
| 132 | + - path: tasks/add.yaml |
| 133 | + assertions: |
| 134 | + toolsUsed: |
| 135 | + - server: demo-server |
| 136 | + tool: add |
| 137 | + minToolCalls: 1 |
| 138 | + maxToolCalls: 5 |
| 139 | +``` |
| 140 | +
|
| 141 | +**What this does:** |
| 142 | +- Configures **Claude Code** as the agent that will attempt the tasks |
| 143 | +- Points to **mcp-config.yaml** to connect to your MCP server |
| 144 | +- Defines the **judge LLM** settings (using your environment variables) |
| 145 | +- Loads tasks from **tasks/add.yaml** and asserts the `add` tool must be used |
| 146 | + |
| 147 | +### The Task Definition (`evals/tasks/add.yaml`) |
| 148 | + |
| 149 | +```yaml |
| 150 | +kind: Task |
| 151 | +apiVersion: mcpchecker/v1alpha2 |
| 152 | +metadata: |
| 153 | + name: "add-test" |
| 154 | + difficulty: easy |
| 155 | +
|
| 156 | +spec: |
| 157 | + verify: |
| 158 | + - llmJudge: |
| 159 | + contains: "8" |
| 160 | +
|
| 161 | + prompt: |
| 162 | + inline: | |
| 163 | + I need to know what 5 + 3 equals. Can you help me figure this out? |
| 164 | +``` |
| 165 | + |
| 166 | +**What this tests:** |
| 167 | +- **Natural language prompt**: No mention of tools - agent must discover the `add` tool |
| 168 | +- **Verification**: Judge LLM checks that the result contains "8" |
| 169 | +- **Tool discovery**: Can the agent find and use the right tool from a simple question? |
| 170 | + |
| 171 | +This tests whether the agent can: |
| 172 | +1. **Discover** the `add` tool from its description |
| 173 | +2. **Understand** when to use it based on the natural language prompt |
| 174 | +3. **Call it correctly** with the right parameters (a=5, b=3) |
| 175 | + |
| 176 | +### The MCP Server Config (`evals/mcp-config.yaml`) |
| 177 | + |
| 178 | +```yaml |
| 179 | +mcpServers: |
| 180 | + demo-server: |
| 181 | + type: http |
| 182 | + url: http://localhost:8000/mcp |
| 183 | + enableAllTools: true |
| 184 | +``` |
| 185 | + |
| 186 | +**What this does:** |
| 187 | +- Defines a server named **demo-server** |
| 188 | +- Connects via **HTTP** to `http://localhost:8000/mcp` |
| 189 | +- **Enables all tools** exposed by the server |
| 190 | + |
| 191 | +## Expected Output |
| 192 | + |
| 193 | +When tests pass, you'll see: |
| 194 | + |
| 195 | +``` |
| 196 | +✅ add-test: PASSED |
| 197 | + Tool calls: |
| 198 | + - demo-server.add(a=5, b=3) → 8 |
| 199 | + Verifications: |
| 200 | + - Result contains "8" ✓ |
| 201 | +``` |
| 202 | + |
| 203 | +The output also generates a JSON file (`demo-server-test-out.json`) with detailed results including: |
| 204 | +- Complete agent conversation transcript |
| 205 | +- All tool calls made |
| 206 | +- Verification results |
| 207 | +- Timing information |
| 208 | + |
| 209 | +## Project Structure |
| 210 | + |
| 211 | +``` |
| 212 | +getting-started/ |
| 213 | +├── server/ |
| 214 | +│ └── server.py # HTTP MCP server (FastMCP quickstart example) |
| 215 | +└── evals/ |
| 216 | + ├── eval.yaml # Main test configuration |
| 217 | + ├── mcp-config.yaml # MCP server connection config |
| 218 | + └── tasks/ |
| 219 | + └── add.yaml # Test for add tool |
| 220 | +``` |
| 221 | +
|
| 222 | +## How It Works |
| 223 | +
|
| 224 | +``` |
| 225 | +┌─────────────────────┐ |
| 226 | +│ Your MCP Server │ |
| 227 | +│ (port 8000) │◄──────┐ |
| 228 | +│ │ │ |
| 229 | +│ Tools: │ │ HTTP |
| 230 | +│ - add(a, b) │ │ |
| 231 | +└─────────────────────┘ │ |
| 232 | + │ |
| 233 | + ┌─────────┴──────────────────────────┐ |
| 234 | + │ MCPChecker Test Runner │ |
| 235 | + │ │ |
| 236 | + │ ┌──────────────┐ ┌────────────┐ │ |
| 237 | + │ │ Agent │ │ Judge LLM │ │ |
| 238 | + │ │ (Claude Code)│─►│ (verifies) │ │ |
| 239 | + │ │ uses tools │ │ results │ │ |
| 240 | + │ └──────────────┘ └────────────┘ │ |
| 241 | + └────────────────────────────────────┘ |
| 242 | + │ |
| 243 | + ▼ |
| 244 | + Results: ✅/❌ |
| 245 | +``` |
| 246 | +
|
| 247 | +**Step by step:** |
| 248 | +1. **Server runs** on `http://localhost:8000/mcp` (Streamable HTTP transport) |
| 249 | +2. **MCPChecker connects** to the server via HTTP |
| 250 | +3. **Claude Code agent** receives task prompts (e.g., "What is 5 + 3?") |
| 251 | +4. **Agent discovers and calls tools** to complete tasks |
| 252 | +5. **Judge LLM verifies** results match expected values |
| 253 | +6. **Results saved** to JSON file with full transcript |
0 commit comments