Debugging MCP
Aprende a depurar servidores MCP efectivamente. Herramientas, técnicas y soluciones para los problemas más comunes.
Guía de Debugging
Depurar servidores MCP puede ser desafiante debido a la naturaleza asíncrona del protocolo y la comunicación JSON-RPC. Esta guía te ayudará a identificar y resolver problemas comunes de forma eficiente.
1. Identificar
Usa logs y herramientas de inspección para identificar dónde ocurre el problema.
2. Aislar
Reduce el problema a su componente más simple para entender la causa raíz.
3. Resolver
Aplica la solución y verifica que el problema está resuelto completamente.
Herramientas de Debugging
Utiliza estas herramientas para inspeccionar, probar y depurar tus servidores MCP.
MCP Inspector
Herramienta interactiva oficial para inspeccionar y probar servidores MCP. Permite ver mensajes JSON-RPC en tiempo real.
Características:
- Inspección de mensajes JSON-RPC
- Prueba de recursos y herramientas
- Visualización de capacidades del servidor
- Debugging interactivo
Instalación:
npm install -g @modelcontextprotocol/inspectorUso:
mcp-inspector --server "python -m my_server"
Logs Verbosos
Habilita logging detallado en tu servidor para ver todos los mensajes y operaciones.
Características:
- Registro de todos los mensajes JSON-RPC
- Trazas de errores detalladas
- Timestamps y contexto
- Filtrado por nivel de log
Uso:
# Python
import logging
logging.basicConfig(level=logging.DEBUG)
# TypeScript
import { setLogLevel } from "@modelcontextprotocol/sdk";
setLogLevel("debug");Cliente de Prueba
Crea un cliente de prueba simple para validar que tu servidor responde correctamente.
Características:
- Prueba de métodos específicos
- Validación de respuestas
- Detección de errores temprana
- Automatización de tests
Uso:
# Ejemplo básico
from mcp.client import Client
client = Client("python -m my_server")
tools = await client.list_tools()
print(tools)Técnicas de Debugging
Mejores prácticas y técnicas para depurar servidores MCP de forma efectiva.
Logging Estratégico
Añade logs en puntos clave de tu código para rastrear el flujo de ejecución.
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)
raiseValidación de Entrada
Valida y sanitiza todos los parámetros antes de procesarlos.
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}")Manejo de Errores
Implementa manejo de errores robusto con mensajes claros.
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)}")Testing Incremental
Prueba cada componente por separado antes de integrar.
# 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)Troubleshooting Común
Problemas frecuentes y sus soluciones. Si encuentras un problema, revisa esta sección primero.
El servidor no se inicia
Síntomas:
- •Error al ejecutar el comando del servidor
- •Proceso termina inmediatamente
- •No hay respuesta del servidor
Soluciones:
- 1Verifica que el comando del servidor es correcto en la configuración
- 2Asegúrate de que todas las dependencias están instaladas
- 3Revisa los logs de error del sistema operativo
- 4Prueba ejecutar el servidor manualmente desde la terminal
Ejemplo de código:
# Verificar que el servidor funciona python -m my_server # O con Node.js node server.js
Herramientas no aparecen en el cliente
Síntomas:
- •El método tools/list retorna una lista vacía
- •Las herramientas no están disponibles en Claude Desktop
- •Error al listar herramientas
Soluciones:
- 1Verifica que el método list_tools() está implementado correctamente
- 2Asegúrate de que el servidor tiene la capacidad 'tools' habilitada
- 3Revisa que los nombres de las herramientas son válidos (sin espacios, caracteres especiales)
- 4Comprueba los logs del servidor para errores de serialización
Ejemplo de código:
# Python - Verificar implementación
@app.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="my_tool", # ✅ Nombre válido
description="...",
inputSchema={...}
)
]Errores de validación de parámetros
Síntomas:
- •Error 'Invalid params' al llamar herramientas
- •Los parámetros no coinciden con el esquema
- •Valores requeridos faltantes
Soluciones:
- 1Verifica que el inputSchema coincide con los parámetros esperados
- 2Asegúrate de que todos los campos 'required' están presentes
- 3Valida los tipos de datos (string, number, boolean, object, array)
- 4Usa JSON Schema válido para la validación
Ejemplo de código:
# Esquema correcto
inputSchema={
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
},
"required": ["name"] # ✅ Campos requeridos
}Timeout o conexión perdida
Síntomas:
- •El servidor deja de responder
- •Timeouts en las solicitudes
- •Conexión cerrada inesperadamente
Soluciones:
- 1Verifica que las operaciones asíncronas están manejadas correctamente
- 2Asegúrate de que no hay operaciones bloqueantes
- 3Implementa timeouts apropiados para operaciones largas
- 4Revisa el uso de memoria y recursos del servidor
Ejemplo de código:
# 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 resultErrores de serialización JSON
Síntomas:
- •Error al serializar respuestas
- •Tipos de datos no compatibles con JSON
- •Errores de encoding
Soluciones:
- 1Asegúrate de que todos los valores son serializables a JSON
- 2Convierte objetos complejos a dict/list antes de retornar
- 3Usa TextContent para respuestas de texto
- 4Maneja correctamente los caracteres especiales y encoding UTF-8
Ejemplo de código:
# Python - Serialización correcta
from mcp.types import TextContent
return [TextContent(
type="text",
text=str(result) # ✅ Convierte a string
)]Checklist de Debugging
Lista de verificación para depurar problemas en servidores MCP
Verificaciones Básicas
- El servidor se ejecuta sin errores
- Las dependencias están instaladas correctamente
- La configuración del cliente es correcta
- Los logs muestran actividad del servidor
- El protocolo JSON-RPC está funcionando
Verificaciones Avanzadas
- Los métodos están implementados correctamente
- Los esquemas JSON Schema son válidos
- Los tipos de datos coinciden con el esquema
- El manejo de errores es robusto
- Las operaciones asíncronas están bien manejadas
¿Necesitas más ayuda?
Explora más recursos, tutoriales y ejemplos para dominar MCP.