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/inspector

Uso:

mcp-inspector --server "python -m my_server"
Ver documentación

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)
        raise

Validació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:

  • 1
    Verifica que el comando del servidor es correcto en la configuración
  • 2
    Asegúrate de que todas las dependencias están instaladas
  • 3
    Revisa los logs de error del sistema operativo
  • 4
    Prueba 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:

  • 1
    Verifica que el método list_tools() está implementado correctamente
  • 2
    Asegúrate de que el servidor tiene la capacidad 'tools' habilitada
  • 3
    Revisa que los nombres de las herramientas son válidos (sin espacios, caracteres especiales)
  • 4
    Comprueba 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:

  • 1
    Verifica que el inputSchema coincide con los parámetros esperados
  • 2
    Asegúrate de que todos los campos 'required' están presentes
  • 3
    Valida los tipos de datos (string, number, boolean, object, array)
  • 4
    Usa 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:

  • 1
    Verifica que las operaciones asíncronas están manejadas correctamente
  • 2
    Asegúrate de que no hay operaciones bloqueantes
  • 3
    Implementa timeouts apropiados para operaciones largas
  • 4
    Revisa 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 result

Errores de serialización JSON

Síntomas:

  • Error al serializar respuestas
  • Tipos de datos no compatibles con JSON
  • Errores de encoding

Soluciones:

  • 1
    Asegúrate de que todos los valores son serializables a JSON
  • 2
    Convierte objetos complejos a dict/list antes de retornar
  • 3
    Usa TextContent para respuestas de texto
  • 4
    Maneja 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.