MCP Troubleshooting Guide: Fix Common Server Issues

MCP servers failing silently? Tools not appearing? This guide covers the most common problems and how to fix them fast.

Connection Issues

"Server failed to start"

Most common cause: the command path is wrong or the environment isn't set up correctly.

Check 1: Does the command work manually?

# Test your exact command from the config
cd /path/to/your/server
python -m your_server

# Or for Node servers
npx your-mcp-server

Check 2: Is Python/Node in PATH for the MCP host?

Claude Desktop and other clients may not inherit your shell's PATH. Use absolute paths:

// BAD - relies on PATH
{
  "command": "python",
  "args": ["-m", "my_server"]
}

// GOOD - explicit path
{
  "command": "/usr/local/bin/python3",
  "args": ["-m", "my_server"]
}

// Find your Python path with:
// which python3

"Connection closed unexpectedly"

The server started but crashed. Check for:

  1. Missing dependencies — Run pip install -e . or npm install
  2. Import errors — Test with python -c "from your_server import mcp"
  3. Missing environment variables — API keys, configs not set
// Pass env vars in config
{
  "command": "python",
  "args": ["-m", "my_server"],
  "env": {
    "OPENAI_API_KEY": "sk-...",
    "DEBUG": "true"
  }
}

Tools Not Showing Up

Server connects but tools are empty

Your server runs but Claude doesn't see the tools. Common causes:

1. Tools not registered properly

# FastMCP - make sure you're using the decorator
from fastmcp import FastMCP

mcp = FastMCP("my-server")

@mcp.tool()  # <-- This decorator is required!
def my_tool(arg: str) -> str:
    """Tool description here."""  # <-- Docstring required!
    return f"Result: {arg}"

# DON'T FORGET: Run with mcp.run()
if __name__ == "__main__":
    mcp.run()

2. Type hints missing

MCP uses type hints to generate the schema. No hints = no parameters:

# BAD - no type hints, tool won't have proper params
@mcp.tool()
def search(query):
    return results

# GOOD - explicit types
@mcp.tool()
def search(query: str, limit: int = 10) -> list[dict]:
    """Search for items.
    
    Args:
        query: The search query
        limit: Max results to return
    """
    return results

3. Server is stdio but config expects SSE (or vice versa)

// For stdio servers (most common)
{
  "mcpServers": {
    "my-server": {
      "command": "python",
      "args": ["-m", "my_server"]
    }
  }
}

// For SSE/HTTP servers
{
  "mcpServers": {
    "my-server": {
      "url": "http://localhost:3000/sse"
    }
  }
}

Timeout Errors

Tool execution timeouts

Tools taking too long? The client gives up after ~30-60 seconds typically.

Solutions:

  1. Add progress reporting — For long operations, report progress so the client knows you're alive
  2. Chunk the work — Break into smaller operations
  3. Return early, process async — Start the work and return a status/ID to check later
@mcp.tool()
async def long_operation(task: str) -> str:
    """Starts a long operation and returns immediately."""
    
    # Start background task
    task_id = start_background_task(task)
    
    # Return immediately
    return f"Started task {task_id}. Use check_status('{task_id}') to monitor."

@mcp.tool()
def check_status(task_id: str) -> dict:
    """Check status of a background task."""
    return get_task_status(task_id)

Startup timeouts

Server takes too long to initialize. Solutions:

  • Defer heavy initialization until first tool call
  • Load resources lazily
  • Add connection pooling instead of per-call connections

Config File Problems

Config file location

Different clients store configs in different places:

# Claude Desktop
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

# Cursor
~/.cursor/mcp.json

# Cline (VS Code extension)
Settings → Cline → MCP Servers

# OpenClaw
~/.openclaw/openclaw.json (under mcp.servers)

JSON syntax errors

Invalid JSON = config won't load. Common mistakes:

// WRONG - trailing comma
{
  "mcpServers": {
    "server1": { ... },  // <-- trailing comma breaks JSON
  }
}

// WRONG - comments in JSON
{
  // This breaks the config
  "mcpServers": { ... }
}

// Validate with:
cat config.json | python -m json.tool

Path escaping on Windows

// WRONG
{
  "command": "C:\Users\me\server.py"  // Single backslash
}

// RIGHT
{
  "command": "C:\\Users\\me\\server.py"  // Escaped
}
// OR
{
  "command": "C:/Users/me/server.py"  // Forward slashes work too
}

Debugging Techniques

1. Add logging to your server

import logging
import sys

# Log to stderr (stdout is for MCP protocol)
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    stream=sys.stderr
)
logger = logging.getLogger(__name__)

@mcp.tool()
def my_tool(arg: str) -> str:
    logger.debug(f"my_tool called with arg={arg}")
    try:
        result = do_something(arg)
        logger.debug(f"my_tool returning: {result}")
        return result
    except Exception as e:
        logger.error(f"my_tool failed: {e}", exc_info=True)
        raise

2. Test with MCP Inspector

The official MCP Inspector lets you test servers interactively:

# Install and run
npx @modelcontextprotocol/inspector

# Opens web UI at localhost:5173
# Connect to your server, test tools manually

3. Check client logs

# Claude Desktop logs
macOS: ~/Library/Logs/Claude/
Windows: %APPDATA%\Claude\logs\

# Look for MCP-related errors
grep -i "mcp" ~/Library/Logs/Claude/*.log

4. Test the protocol manually

# Start server and send test messages
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | python -m your_server

# Should get back a valid JSON response

Client-Specific Issues

Claude Desktop

  • Restart required — After config changes, fully quit and reopen Claude (Cmd/Ctrl+Q)
  • Server appears "disconnected" — Check the MCP server status in Claude settings
  • Can't find config — Enable Developer Mode in Claude settings first

Cursor

  • MCP not available — Ensure you're on Cursor version 0.43+
  • Config not loading — Check ~/.cursor/mcp.json exists and is valid JSON
  • Tools not appearing in Composer — Toggle Agent mode on

Cline

  • Settings location — VS Code Settings → Extensions → Cline → MCP Servers
  • Server startup issues — Check VS Code Output panel (Cline channel)

Still Stuck?

Common debugging checklist:

  1. ✓ Can you run the server command manually in terminal?
  2. ✓ Is the config file valid JSON? (Use a JSON validator)
  3. ✓ Are you using absolute paths for commands?
  4. ✓ Did you restart the client after config changes?
  5. ✓ Check client logs for error messages
  6. ✓ Test with MCP Inspector to isolate client vs server issues

Get updates in your inbox

Tutorials, updates, and best practices for Model Context Protocol.

No spam. Unsubscribe anytime.