Debugging MCP
Learn to debug MCP servers effectively. Tools, techniques and solutions for the most common problems.
Debugging Guide
Debugging MCP servers can be challenging due to the asynchronous nature of the protocol and JSON-RPC communication. This guide will help you identify and resolve common problems efficiently.
1. Identify
Use logs and inspection tools to identify where the problem occurs.
2. Isolate
Reduce the problem to its simplest component to understand the root cause.
3. Resolve
Apply the solution and verify that the problem is completely resolved.
Debugging Tools
Use these tools to inspect, test and debug your MCP servers.
MCP Inspector
Official interactive tool to inspect and test MCP servers. Allows viewing JSON-RPC messages in real time.
Features:
- JSON-RPC message inspection
- Resource and tool testing
- Server capabilities visualization
- Interactive debugging
Installation:
npm install -g @modelcontextprotocol/inspectorUsage:
mcp-inspector --server "python -m my_server"
Verbose Logs
Enable detailed logging in your server to see all messages and operations.
Features:
- Logging of all JSON-RPC messages
- Detailed error traces
- Timestamps and context
- Filtering by log level
Usage:
# Python
import logging
logging.basicConfig(level=logging.DEBUG)
# TypeScript
import { setLogLevel } from "@modelcontextprotocol/sdk";
setLogLevel("debug");Test Client
Create a simple test client to validate that your server responds correctly.
Features:
- Testing specific methods
- Response validation
- Early error detection
- Test automation
Usage:
# Basic example
from mcp.client import Client
client = Client("python -m my_server")
tools = await client.list_tools()
print(tools)Debugging Techniques
Best practices and techniques to debug MCP servers effectively.
Strategic Logging
Add logs at key points in your code to track execution flow.
import logging
logger = logging.getLogger(__name__)
@app.call_tool()
async def call_tool(name: str, arguments: dict):
logger.debug(f"Llamando herramienta: {name}")
logger.debug(f"Argumentos: {arguments}")
try:
result = await execute_tool(name, arguments)
logger.info(f"Herramienta ejecutada exitosamente")
return result
except Exception as e:
logger.error(f"Error ejecutando herramienta: {e}", exc_info=True)
raiseInput Validation
Validate and sanitize all parameters before processing them.
def validate_tool_args(arguments: dict, schema: dict):
"""Valida argumentos contra un esquema"""
required = schema.get("required", [])
for field in required:
if field not in arguments:
raise ValueError(f"Campo requerido faltante: {field}")
# Validar tipos
for field, value in arguments.items():
expected_type = schema["properties"][field]["type"]
if not isinstance(value, type_map[expected_type]):
raise TypeError(f"{field} debe ser {expected_type}")Error Handling
Implement robust error handling with clear messages.
from mcp.types import ErrorCode
@app.call_tool()
async def call_tool(name: str, arguments: dict):
try:
if name not in available_tools:
raise ValueError(f"Herramienta desconocida: {name}")
return await execute_tool(name, arguments)
except ValueError as e:
# Error de validación
raise ValueError(f"Error de validación: {str(e)}")
except Exception as e:
# Error inesperado
logger.exception(f"Error inesperado: {e}")
raise RuntimeError(f"Error ejecutando herramienta: {str(e)}")Incremental Testing
Test each component separately before integrating.
# Prueba unitaria de una herramienta
def test_read_file():
result = read_file("/path/to/file.txt")
assert result is not None
assert isinstance(result, str)
# Prueba de integración
async def test_list_tools():
tools = await list_tools()
assert len(tools) > 0
assert all(tool.name for tool in tools)Common Troubleshooting
Frequent problems and their solutions. If you encounter a problem, check this section first.
Server does not start
Symptoms:
- •Error executing server command
- •Process terminates immediately
- •No response from server
Solutions:
- 1Verify that the server command is correct in the configuration
- 2Make sure all dependencies are installed
- 3Check operating system error logs
- 4Try running the server manually from the terminal
Code example:
# Verificar que el servidor funciona python -m my_server # O con Node.js node server.js
Tools do not appear in client
Symptoms:
- •tools/list method returns empty list
- •Tools are not available in Claude Desktop
- •Error listing tools
Solutions:
- 1Verify that list_tools() method is implemented correctly
- 2Make sure the server has 'tools' capability enabled
- 3Check that tool names are valid (no spaces, special characters)
- 4Check server logs for serialization errors
Code example:
# Python - Verificar implementación
@app.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="my_tool", # ✅ Nombre válido
description="...",
inputSchema={...}
)
]Parameter validation errors
Symptoms:
- •Error 'Invalid params' when calling tools
- •Parameters do not match schema
- •Missing required values
Solutions:
- 1Verify that inputSchema matches expected parameters
- 2Make sure all 'required' fields are present
- 3Validate data types (string, number, boolean, object, array)
- 4Use valid JSON Schema for validation
Code example:
# Esquema correcto
inputSchema={
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
},
"required": ["name"] # ✅ Campos requeridos
}Timeout or lost connection
Symptoms:
- •Server stops responding
- •Request timeouts
- •Connection closed unexpectedly
Solutions:
- 1Verify that asynchronous operations are handled correctly
- 2Make sure there are no blocking operations
- 3Implement appropriate timeouts for long operations
- 4Check server memory and resource usage
Code example:
# Python - Operación asÃncrona correcta
@app.call_tool()
async def call_tool(name: str, arguments: dict):
# ✅ Usa async/await para operaciones I/O
result = await some_async_operation()
return resultJSON serialization errors
Symptoms:
- •Error serializing responses
- •Data types not compatible with JSON
- •Encoding errors
Solutions:
- 1Make sure all values are JSON serializable
- 2Convert complex objects to dict/list before returning
- 3Use TextContent for text responses
- 4Handle special characters and UTF-8 encoding correctly
Code example:
# Python - Serialización correcta
from mcp.types import TextContent
return [TextContent(
type="text",
text=str(result) # ✅ Convierte a string
)]Debugging Checklist
Checklist for debugging problems in MCP servers
Basic Checks
- Server runs without errors
- Dependencies are installed correctly
- Client configuration is correct
- Logs show server activity
- JSON-RPC protocol is working
Advanced Checks
- Methods are implemented correctly
- JSON Schema schemas are valid
- Data types match the schema
- Error handling is robust
- Asynchronous operations are well handled
Need more help?
Explore more resources, tutorials and examples to master MCP.