MCP

MCP Troubleshooting Guide

Comprehensive guide to debugging and fixing common Model Context Protocol issues. Find solutions to errors, connection problems, and implementation challenges.

Common Errors & Solutions

MCP error -32001: Request timed out

high severity

Symptoms:

  • Server fails to respond within timeout period
  • Long-running operations getting interrupted
  • Intermittent connection failures

Common Causes:

  • Server startup taking too long
  • Network connectivity issues
  • Resource-intensive operations blocking the server

Solutions:

Increase timeout duration:
// In claude_desktop_config.json
{
  "mcpServers": {
    "myserver": {
      "command": "node",
      "args": ["server.js"],
      "timeout": 30000 // Increase from default 10s to 30s
    }
  }
}
Optimize server startup:
// Defer heavy initialization
class MCPServer {
  constructor() {
    // Quick initialization only
    this.server = new Server({ name: 'myserver' });
  }
  
  async start() {
    // Heavy operations after server starts
    await this.loadDatabase();
    await this.initializeCache();
  }
}

MCP error -32000: Connection closed

high severity

Symptoms:

  • Server disconnects unexpectedly
  • Cannot establish initial connection
  • Connection drops during operation

Common Causes:

  • Server process crashed
  • Authentication failure
  • Protocol version mismatch

Solutions:

Check server logs:
// Enable detailed logging
const server = new Server({
  name: 'myserver',
  version: '1.0.0',
});

// Log to stderr (captured by host)
console.error('Server starting...');
server.onerror = (error) => {
  console.error('Server error:', error);
};
Verify protocol compatibility:
// package.json
{
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.5.0" // Use latest stable
  }
}

Headers Already Sent (SSE Transport)

medium severity

Symptoms:

  • Cannot set headers after streaming starts
  • Authentication failures with SSE
  • CORS errors in browser

Common Causes:

  • Trying to send headers after SSE stream initialized
  • Incorrect middleware ordering
  • Missing pre-flight handling

Solutions:

Set headers before SSE initialization:
app.get('/sse', (req, res) => {
  // Set all headers first
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Access-Control-Allow-Origin', '*');
  
  // Check auth before starting stream
  if (!isAuthenticated(req)) {
    res.status(401).end();
    return;
  }
  
  // Now safe to start SSE
  res.write('data: connected\n\n');
});

Working Directory Issues

medium severity

Symptoms:

  • File not found errors
  • Relative paths not working
  • Different behavior in development vs production

Common Causes:

  • Undefined working directory in claude_desktop_config.json
  • Relative path resolution differences
  • Environment-specific path issues

Solutions:

Always use absolute paths:
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Use absolute paths
const configPath = join(__dirname, 'config.json');
const dataDir = join(__dirname, '../data');
Set explicit working directory:
// claude_desktop_config.json
{
  "mcpServers": {
    "myserver": {
      "command": "node",
      "args": ["server.js"],
      "cwd": "/absolute/path/to/server"
    }
  }
}

Environment Variable Access

low severity

Symptoms:

  • Missing API keys or tokens
  • Configuration not loading
  • Different behavior across environments

Common Causes:

  • Limited environment variable inheritance
  • Security restrictions on variable access
  • Platform-specific variable handling

Solutions:

Explicitly pass environment variables:
// claude_desktop_config.json
{
  "mcpServers": {
    "myserver": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "API_KEY": "your-api-key",
        "DATABASE_URL": "postgresql://...",
        "NODE_ENV": "production"
      }
    }
  }
}

Debugging Steps

1

Enable Verbose Logging

Turn on detailed logging to see what's happening

Actions:

  • Add console.error() statements (not console.log())
  • Log server lifecycle events
  • Track request/response flow
  • Monitor resource usage

Example:

// Comprehensive logging setup
class MCPServer {
  constructor() {
    console.error('[INIT] Server initializing...');
    this.server = new Server({
      name: 'debug-server',
      version: '1.0.0'
    });
    
    this.server.onerror = (error) => {
      console.error('[ERROR]', error);
    };
    
    // Log all requests
    this.server.setRequestHandler('*', async (request, next) => {
      console.error('[REQUEST]', request.method, request.params);
      try {
        const result = await next();
        console.error('[RESPONSE]', result);
        return result;
      } catch (error) {
        console.error('[ERROR]', error);
        throw error;
      }
    });
  }
}
2

Use MCP Inspector

Test your server with the official debugging tool

Actions:

  • Install MCP Inspector globally
  • Connect to your server
  • Test each tool/resource individually
  • Verify request/response formats

Example:

# Install MCP Inspector
npm install -g @modelcontextprotocol/inspector

# Run your server
node server.js

# In another terminal, start inspector
mcp-inspector

# Connect to your server and test
3

Isolate the Problem

Narrow down where the issue occurs

Actions:

  • Test with minimal server implementation
  • Remove tools one by one
  • Check with different transport methods
  • Verify in different environments

Example:

// Minimal test server
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server({
  name: 'test-server',
  version: '1.0.0',
});

// Single test tool
server.setRequestHandler('tools/list', async () => ({
  tools: [{
    name: 'test',
    description: 'Test tool',
    inputSchema: { type: 'object' }
  }]
}));

server.setRequestHandler('tools/call', async (request) => ({
  content: [{ type: 'text', text: 'Test response' }]
}));

const transport = new StdioServerTransport();
await server.connect(transport);
4

Check External Dependencies

Verify all external services and dependencies

Actions:

  • Test API endpoints independently
  • Verify database connections
  • Check file system permissions
  • Validate network connectivity

Example:

// Test dependencies before server start
async function validateDependencies() {
  try {
    // Test database
    await db.query('SELECT 1');
    console.error('[OK] Database connected');
    
    // Test API
    const response = await fetch(API_ENDPOINT);
    if (!response.ok) throw new Error('API unavailable');
    console.error('[OK] API accessible');
    
    // Test file access
    await fs.access(CONFIG_PATH);
    console.error('[OK] Config file accessible');
    
  } catch (error) {
    console.error('[FAIL] Dependency check:', error);
    process.exit(1);
  }
}

Platform-Specific Issues

Windows

Path separator problems
Use path.join() or path.sep instead of hardcoded slashes
Process spawn errors
Use shell: true option or full executable paths
Permission issues
Run as administrator or check file permissions

macOS

Security warnings
Code sign your server or allow in System Preferences
Port access restrictions
Use ports above 1024 or grant specific permissions

Linux

Missing dependencies
Install required system packages (build-essential, etc.)
SELinux restrictions
Configure SELinux policies or use appropriate contexts

Quick Debugging Checklist

  • ✓ Check server logs in stderr (not stdout)
  • ✓ Verify MCP SDK version compatibility
  • ✓ Test with MCP Inspector tool
  • ✓ Use absolute paths for all file references
  • ✓ Explicitly pass required environment variables
  • ✓ Validate all external dependencies
  • ✓ Check transport-specific requirements