How to Test MCP Servers: Debug Handshakes, Tool Calls, and Response Times
How to Test MCP Servers: Debug Handshakes, Tool Calls, and Response Times
By Shekhar — Founder, AgenticMarket. Every testing method here comes from building AgenticMarket's server health monitoring system, which probes 800+ MCP endpoints every 60 seconds. Tested with MCP Inspector 0.6, Node.js 22, Python 3.12, VS Code 1.115.1, and Cursor 3.0.1. Last reviewed May 2026.
You built an MCP server. It runs in your terminal. You add it to your IDE config. Nothing happens — or worse, it works sometimes and fails silently other times.
The problem: you're testing at the wrong layer. Most developers test their MCP server by adding it to Cursor or VS Code and seeing if the tools show up. That conflates three separate systems — the server, the transport, and the IDE client — into one opaque pass/fail. When it fails, you have no idea which layer broke.
This guide separates MCP testing into the three layers that actually matter, with exact commands for each.
Quick win: run your endpoint through the MCP Playground first. It tests handshake, tool discovery, and response time in one shot — no config files, no IDE restart. Guest mode includes 4 free probes.
AgenticMarket installs MCP servers in ONE command. Works with Cursor, VS Code, Claude Desktop, and 10 other IDEs.
Try: npx agenticmarket install @agenticmarket/duckduckgo →The three layers of MCP server testing
Every MCP failure lives in one of these layers. Test them in order — skipping to layer 3 (IDE integration) before confirming layers 1 and 2 wastes hours.
| Layer | What it tests | Tools |
|---|---|---|
| 1. Handshake | Does the server respond to initialize and return capabilities? | curl, MCP Inspector, MCP Playground |
| 2. Tool discovery & execution | Does tools/list return valid schemas? Do tool calls return results? | MCP Inspector, manual JSON-RPC |
| 3. IDE integration | Does the IDE see the tools and does the agent call them? | IDE logs, developer tools |
If layer 1 fails, nothing else matters. If layer 1 passes but layer 2 fails, your server code has a bug. If layers 1 and 2 pass but layer 3 fails, your IDE config is wrong — not your server.
Layer 1 — Testing the MCP handshake
The handshake is the foundation. Your server must respond to the JSON-RPC initialize method with its protocol version and capabilities. If this fails, the IDE never discovers any tools.
Testing HTTP servers with curl
For remote MCP servers with a URL endpoint, send a raw initialize request:
bash# Send an MCP initialize handshake to your HTTP server # Replace the URL with your actual MCP endpoint curl -s -w "\n\nResponse time: %{time_total}s\n" \ -X POST https://your-server-url/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "test-client", "version": "1.0" } } }'
What a healthy response looks like:
json{ "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} }, "serverInfo": { "name": "your-server", "version": "1.0.0" } } }
What to check in the response:
protocolVersionmatches what you sent — a version mismatch causes-32601 method not founderrors downstreamcapabilities.toolsexists — if this field is missing, the server is telling clients it has no tools- Response time under 3 seconds — anything longer risks IDE timeout on first connection
If you get an HTML page instead of JSON, the URL is wrong. If you get a connection refused, the server is down. If you get valid JSON but no capabilities.tools, the server doesn't expose tools.
Testing stdio servers with MCP Inspector
Stdio servers don't have a URL — they run as local processes. You can't test them with curl. The MCP Inspector is the right tool:
bash# Test a Node.js stdio MCP server npx @modelcontextprotocol/inspector node path/to/your/server.js # Test a Python stdio MCP server npx @modelcontextprotocol/inspector python path/to/your/server.py # Test an npx-based server (like a published package) npx @modelcontextprotocol/inspector npx -y some-mcp-package
The Inspector opens a web UI at http://localhost:5173. The connection status and handshake result appear immediately. If the handshake fails here, your server has a fundamental issue — don't waste time with IDE configs.
Diagnosing handshake failures
| Symptom | Cause | Fix |
|---|---|---|
| Connection refused | Server not running or wrong port | Verify the server process is alive; check port binding |
| HTML response instead of JSON | URL points to web app, not MCP endpoint | Use the /mcp or /sse path, not the root |
| Timeout (no response) | Server blocked during initialization | Move heavy init to lazy loading (see our tools guide) |
{"error": {"code": -32600}} | Malformed JSON-RPC request | Check that your request body is valid JSON-RPC 2.0 |
-32000: Connection closed | Stdout contamination or PATH issue | Full -32000 debugging guide |
Layer 2 — Testing tool discovery and execution
The handshake passed. Now verify the server actually exposes tools and they work.
Listing tools via JSON-RPC
After a successful initialize, send a tools/list request:
bash# After initialize succeeds, request the tool list curl -s -X POST https://your-server-url/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }'
What to check:
- Each tool has a
name,description, andinputSchema - The
inputSchemahas"type": "object"at the root — anything else gets silently rejected by IDEs requiredfields are arrays of strings matching property keys- No duplicate tool names — duplicates cause silent conflicts in Cursor
Testing individual tool calls
Don't trust that tools work just because they're listed. Call one:
bash# Execute a specific tool — replace tool name and arguments curl -s -X POST https://your-server-url/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "your_tool_name", "arguments": { "param1": "test_value" } } }'
Common tool call failures that don't surface during handshake:
- Missing API keys — the server lists the tool but crashes when you call it because environment variables aren't set
- Schema mismatch — the tool expects
querybut the schema sayssearch_query - Timeout on execution — the tool takes 30 seconds to run, exceeding IDE limits
Validating JSON Schema correctness
I've seen servers list tools that Cursor silently drops because the JSON Schema is invalid. The MCP specification requires strict JSON Schema draft-07. Common violations:
json// WRONG — missing type: "object" at root { "inputSchema": { "query": { "type": "string" } } } // WRONG — using Python type names { "inputSchema": { "type": "object", "properties": { "count": { "type": "int" } } } } // CORRECT — valid JSON Schema { "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query" }, "count": { "type": "integer", "description": "Number of results" } }, "required": ["query"] } }
If you're using the official MCP Python SDK or TypeScript SDK, the schema is generated from your function signatures automatically. Raw implementations are where schema bugs hide.
Using MCP Inspector for interactive tool testing
The Inspector's web UI at localhost:5173 has a Tools tab where you can:
- See every tool's schema rendered as a form
- Fill in arguments and execute the tool
- See the raw JSON-RPC request and response
- Measure execution time per call
This is the fastest way to confirm a tool works end-to-end before touching any IDE config.
Layer 3 — Testing IDE integration
Layers 1 and 2 passed outside the IDE. Now test inside it.
Reading IDE logs
Every IDE has a way to see raw MCP communication. This is where you find the actual error when the tools panel shows nothing useful.
Cursor:
Help → Toggle Developer Tools → Console tab
— or —
Output panel (Ctrl+Shift+U) → select "MCP" from dropdown
Look for Starting new stdio process, Client closed for command, or error codes. A Connection closed immediately after starting is stdout contamination or a PATH issue.
VS Code:
Output panel (Ctrl+Shift+U) → select "MCP" from dropdown
— or —
Help → Toggle Developer Tools → Console → filter for "mcp"
Confirm the server shows a Start button in mcp.json and that you clicked it. VS Code doesn't auto-start servers on first save.
Claude Desktop:
bash# macOS — stream log entries live tail -f ~/Library/Logs/Claude/mcp*.log # Windows — read the latest log type %APPDATA%\Claude\logs\mcp*.log
Remember: Claude Desktop needs a full application quit, not just a window close, to reload config.
The isolation test
The single most useful test: run your server as the only MCP server in the IDE.
Disable every other server. Restart the IDE. Test your server alone.
If it works alone but fails with other servers loaded, you have one of:
- 40-tool limit in Cursor
- Tool name conflicts between servers
- Context window exhaustion from too many tool schemas
Profiling MCP server response times
Slow MCP servers cause timeout failures that look like connection errors. Measuring where the time goes is critical.
Timing each phase separately
bash# Time the handshake only time curl -s -o /dev/null -w "Handshake: %{time_total}s\n" \ -X POST https://your-server/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}' # Time tool discovery time curl -s -o /dev/null -w "Tool list: %{time_total}s\n" \ -X POST https://your-server/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' # Time a specific tool call time curl -s -o /dev/null -w "Tool call: %{time_total}s\n" \ -X POST https://your-server/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"your_tool","arguments":{"key":"value"}}}'
What healthy response times look like
| Phase | Good | Acceptable | Too slow |
|---|---|---|---|
Handshake (initialize) | < 500ms | 500ms–2s | > 2s |
Tool discovery (tools/list) | < 200ms | 200ms–1s | > 1s |
Tool execution (tools/call) | < 3s | 3s–10s | > 10s |
| Cold start (serverless) | < 3s | 3s–8s | > 8s |
IDE timeouts vary. Cursor is more aggressive than VS Code. Claude Desktop is the most lenient. If your handshake takes 4 seconds, it might work in Claude Desktop but fail in Cursor.
Diagnosing cold start issues on serverless platforms
If your MCP server runs on Vercel, Cloudflare Workers, or AWS Lambda:
bash# Test cold start: wait 5 minutes, then send two requests back-to-back sleep 300 && \ curl -s -w "Cold: %{time_total}s\n" -o /dev/null \ -X POST https://your-server/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}' && \ curl -s -w "Warm: %{time_total}s\n" -o /dev/null \ -X POST https://your-server/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'
If cold is 5x slower than warm, you need a keep-warm strategy. Options:
- Cron-based health ping every 5 minutes
- Edge runtime instead of serverless functions (faster cold starts)
- Self-hosted on a persistent server if latency is critical
Testing MCP servers you didn't build
When you install a third-party MCP server and it doesn't work, the debugging approach changes. You can't read the source code, but you can still isolate the failure layer.
Step 1: Test the endpoint directly
For servers installed through AgenticMarket:
bash# Check server health status agenticmarket list # Look for "active" vs "inactive" status
For any HTTP server:
bash# Minimal handshake test curl -s -X POST https://server-url/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'
Step 2: Use MCP Playground for visual debugging
The MCP Playground shows every step of the handshake visually — you can see exactly where the connection breaks. It also reports response times and tool schemas, making it easy to spot issues without reading logs.
Step 3: Check if the problem is the server or your config
If the server passes the Playground test but fails in your IDE, the problem is your IDE config. Check the usual suspects:
- Wrong config key name —
servers(VS Code) vsmcpServers(everyone else) - JSON syntax error — paste your config into jsonlint.com
- Wrong config file location — workspace vs global config
The complete MCP testing checklist
Use this checklist before filing a bug report or asking for help. It saves everyone time.
| # | Check | Command / Action | Pass criteria |
|---|---|---|---|
| 1 | Server process starts | node server.js or python server.py | No crash on startup |
| 2 | No stdout contamination | node server.js 2>/dev/null | head -c 200 | Output is JSON-RPC only |
| 3 | Handshake succeeds | curl initialize request | Valid JSON-RPC response with capabilities |
| 4 | Tools are listed | curl tools/list request | Array of tools with valid JSON Schema |
| 5 | Tool call works | curl tools/call request | Tool returns a result, not an error |
| 6 | Response time acceptable | curl with -w "%{time_total}s" | Handshake < 2s, tool call < 10s |
| 7 | Inspector shows tools | npx @modelcontextprotocol/inspector | Tools tab populated |
| 8 | IDE shows server | IDE MCP settings panel | Green dot or active status |
| 9 | IDE shows tools | Tools panel in chat | Tool names visible |
| 10 | Agent calls tools | Explicit prompt naming the tool | Tool call in chat response |
If checks 1–7 pass but 8–10 fail, the problem is IDE configuration — not your server. Start with the complete troubleshooting guide.
Common questions about MCP server testing {#faq}
How do I test if my MCP server is working without using an IDE?
Use the MCP Inspector for stdio servers (npx @modelcontextprotocol/inspector node server.js) or raw curl requests for HTTP servers. Both bypass the IDE entirely, so you can confirm the server works before adding IDE config complexity. The MCP Playground offers a browser-based alternative that requires no local setup.
Why does my MCP server work in the Inspector but not in Cursor?
If the Inspector shows tools but Cursor doesn't, the server is fine. Check: (1) the config key is mcpServers not servers, (2) the JSON has no syntax errors, (3) you haven't hit the 40-tool limit, and (4) the command path in your config matches what which node or which npx returns. Cursor uses a different shell environment than your terminal.
What does MCP error -32601 method not found actually mean?
It means the server received a JSON-RPC request for a method it doesn't implement. Usually a protocol version mismatch — the client sends tools/list but the server only knows an older method set, or the transport type is wrong (sending HTTP to an SSE-only endpoint). Send a raw initialize request and inspect the capabilities object to see what the server actually supports. See the full -32601 guide.
How do I test MCP server auth headers?
Include the auth header in your curl test to verify it works before adding it to IDE config:
bashcurl -s -X POST https://your-server/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-token-here" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'
A single extra space in the header value (Bearer token instead of Bearer token) causes silent auth failure. Copy the exact format from the server's documentation.
How often should I test my MCP server in production?
At minimum, run a handshake probe every 5 minutes. AgenticMarket probes every 60 seconds and tracks response time history — if your server is listed on AgenticMarket, you get this monitoring automatically. For self-hosted servers, a simple cron job with the curl commands above plus alerting on non-200 responses covers the basics.
Related troubleshooting:
- MCP Server Not Working? The Complete Troubleshooting Guide — for when the server won't connect at all
- MCP Server Connected But Agent Ignores Tools — for when tools are visible but never called
- MCP Server Not Showing Tools — for when the handshake succeeds but tools don't appear
Error-specific guides: MCP Error -32000 Connection Closed · MCP Error -32601 Method Not Found
IDE setup guides: VS Code · Cursor · Claude Desktop · Windsurf
Learn more: What is MCP? · What is an MCP Registry? · Browse Verified Servers · Explore Community Servers
Last updated May 2026. Tested with MCP Inspector 0.6, Node.js 22.4, Python 3.12, VS Code 1.115.1, Cursor 3.0.1, and Claude Desktop 0.10 on macOS 15 Sequoia and Windows 11. The MCP protocol is evolving — if a testing method here is outdated, open an issue and I'll update it.
What's your MCP debugging workflow? If you've found a testing approach I haven't covered, drop a comment — especially for Windsurf or JetBrains, where the debugging surface is still thin.
AgenticMarket