← Back to Blog
tutorialdebuggingtroubleshooting

Debugging MCP Tools: Logs, Traces, and Common Pitfalls

Debug MCP servers effectively — stdio logging, structured errors, common mistakes, and diagnostic strategies.

·3 min read·xapable

Debugging MCP Tools: Logs, Traces, and Common Pitfalls

MCP servers run on stdio — no console to watch. Debugging requires different strategies. This guide covers them all.

The Stdio Challenge

MCP servers communicate via stdin/stdout with the client. console.log() goes to stdout and breaks the protocol.

Rule #1: Log to stderr

<span class="hljs-comment">// ❌ WRONG — breaks MCP protocol</span>
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;User requested weather for London&quot;</span>);

<span class="hljs-comment">// ✅ RIGHT — goes to stderr, visible in logs</span>
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">&quot;User requested weather for London&quot;</span>);

All MCP clients capture stderr for debugging. Use it.

Structured Logging

Go beyond console.error:

<span class="hljs-keyword">function</span> <span class="hljs-title function_">log</span>(<span class="hljs-params">level, message, data = {}</span>) {
  <span class="hljs-keyword">const</span> entry = {
    <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>().<span class="hljs-title function_">toISOString</span>(),
    level,
    message,
    ...data
  };
  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(entry));
}

<span class="hljs-comment">// Usage</span>
<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;info&quot;</span>, <span class="hljs-string">&quot;Tool called&quot;</span>, {
  <span class="hljs-attr">tool</span>: <span class="hljs-string">&quot;get_weather&quot;</span>,
  <span class="hljs-attr">args</span>: { <span class="hljs-attr">city</span>: <span class="hljs-string">&quot;London&quot;</span> }
});
<span class="hljs-comment">// → {&quot;timestamp&quot;:&quot;2026-07-07T10:00:00Z&quot;,&quot;level&quot;:&quot;info&quot;,&quot;message&quot;:&quot;Tool called&quot;,&quot;tool&quot;:&quot;get_weather&quot;,&quot;args&quot;:{&quot;city&quot;:&quot;London&quot;}}</span>

Viewing Logs

Claude Desktop

Help → Developer → MCP Logs

Cursor

Settings → MCP → Click server → View Logs

Windsurf

~/.windsurf/logs/mcp.log

Manual (any client)

Since the server runs as a child process, redirect stderr:

node index.js 2&gt; debug.log

Common Pitfalls & Fixes

1. "Tool not found"

Symptom: Agent says it can't find your tool.

Diagnosis:

<span class="hljs-comment">// Add diagnostic logging to tools/list</span>
server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">&quot;tools/list&quot;</span>, <span class="hljs-title function_">async</span> () =&gt; {
  <span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;debug&quot;</span>, <span class="hljs-string">&quot;tools/list called&quot;</span>, { <span class="hljs-attr">toolCount</span>: <span class="hljs-variable constant_">TOOLS</span>.<span class="hljs-property">length</span> });
  <span class="hljs-keyword">return</span> { <span class="hljs-attr">tools</span>: <span class="hljs-variable constant_">TOOLS</span> };
});

Fix: Check that tools/list returns the correct structure and tools/call handles the tool name.

2. "Connection closed unexpectedly"

Symptom: Client disconnects after startup.

Diagnosis: The server likely crashed.

process.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;uncaughtException&quot;</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
  <span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;fatal&quot;</span>, <span class="hljs-string">&quot;Uncaught exception&quot;</span>, { <span class="hljs-attr">error</span>: err.<span class="hljs-property">message</span>, <span class="hljs-attr">stack</span>: err.<span class="hljs-property">stack</span> });
  process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>);
});

process.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;unhandledRejection&quot;</span>, <span class="hljs-function">(<span class="hljs-params">reason</span>) =&gt;</span> {
  <span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;fatal&quot;</span>, <span class="hljs-string">&quot;Unhandled rejection&quot;</span>, { <span class="hljs-attr">reason</span>: <span class="hljs-title class_">String</span>(reason) });
  process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>);
});

3. Empty Response

Symptom: Tool runs but agent sees no output.

Diagnosis: Check the response format.

<span class="hljs-comment">// ❌ Wrong — missing content wrapper</span>
<span class="hljs-keyword">return</span> { <span class="hljs-attr">text</span>: <span class="hljs-string">&quot;Hello&quot;</span> };

<span class="hljs-comment">// ✅ Correct</span>
<span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">&quot;text&quot;</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">&quot;Hello&quot;</span> }] };

4. Schema Mismatch

Symptom: Agent passes wrong argument types.

Diagnosis: Validate your inputSchema.

<span class="hljs-comment">// Add validation in tools/call</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">validateArgs</span>(<span class="hljs-params">schema, args</span>) {
  <span class="hljs-keyword">if</span> (schema.<span class="hljs-property">required</span>) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> field <span class="hljs-keyword">of</span> schema.<span class="hljs-property">required</span>) {
      <span class="hljs-keyword">if</span> (!(field <span class="hljs-keyword">in</span> args)) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">`Missing required field: <span class="hljs-subst">${field}</span>`</span>);
      }
    }
  }
}

Debugging Checklist

When your tool doesn't work:

  1. console.error for all logging (not console.log)
  2. ✅ Server starts without errors (node index.js in terminal)
  3. tools/list returns valid JSON
  4. tools/call handles the tool name
  5. ✅ Response follows { content: [{ type, text }] } format
  6. ✅ Error messages are clear and structured
  7. ✅ Environment variables are set correctly
  8. ✅ Check client-specific logs

Interactive Debugging

For deep issues, use Node.js inspector:

node --inspect index.js

Then open chrome://inspect in Chrome. Set breakpoints in your tool handlers.

Debug Mode Flag

Add a debug mode to your server:

<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">DEBUG</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">MCP_DEBUG</span> === <span class="hljs-string">&quot;true&quot;</span>;

<span class="hljs-keyword">function</span> <span class="hljs-title function_">debug</span>(<span class="hljs-params">...args</span>) {
  <span class="hljs-keyword">if</span> (<span class="hljs-variable constant_">DEBUG</span>) <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">&quot;[DEBUG]&quot;</span>, ...args);
}

<span class="hljs-comment">// In tools/call:</span>
<span class="hljs-title function_">debug</span>(<span class="hljs-string">&quot;Handling tool:&quot;</span>, name, <span class="hljs-string">&quot;with args:&quot;</span>, args);

Enable with: MCP_DEBUG=true in your client config env vars.

Debugging MCP tools takes practice, but with stderr logging and structured error handling, you'll catch issues fast.

#MCP #Tutorial #Debugging #mcpm #DevTools