Las dos formas en que fallan los servidores MCP y una capa de protección para evitarlo
Los servidores MCP fallan debido a tokens demasiado amplios y herramientas que no tienen en cuenta las tareas específicas. Los tokens con alcance definido, las verificaciones de audiencia, los errores sanitizados y los límites en las herramientas constituyen una capa de protección.
Fuentes: MCP Servers Fail in Two Ways, and Both Are Preventable. Here’s the Guardrail Layer.
La mayoría de los servidores MCP no fallan por un cierre inesperado. Fallan al otorgar más confianza de la que la tarea requiere, en dos aspectos: los permisos que asignan y la interfaz que exponen. Un modelo más inteligente no solucionará eso. Sin embargo, una capa de protección situada entre el agente y la herramienta sí lo hará, y las secciones siguientes muestran qué contiene dicha capa, junto con código.
Una limpieza que nadie solicitó
Un usuario le pide a un agente que copie una base de datos de producción a un entorno de preproducción. Al procesar la solicitud, el agente decide que sería conveniente realizar una limpieza y elimina primero algunos datos de prueba antiguos. Nadie lo había solicitado. Si el servidor MCP reenvía las credenciales del propio usuario, y ese usuario tiene derechos de administrador, la eliminación se lleva a cabo y la base de datos de producción desaparece.
AWS menciona exactamente este escenario en sus directrices de gobernanza para MCP al explicar por qué no se pueden omitir los tokens de alcance.
El servidor es un límite de confianza
Por lo general, la gente describe un servidor MCP de la misma manera en que describe cualquier herramienta de integración: algo que conecta a un agente con un sistema, con un puñado de herramientas expuestas y el trabajo completado. En realidad, es el único lugar donde la decisión del modelo de actuar se convierte en un efecto secundario real, utilizando infraestructura real y credenciales reales. Todos los pasos anteriores son solo razonamiento. El servidor es el punto en el que el razonamiento tiene consecuencias.
Por lo tanto, el servidor es un límite de confianza, ya sea que esté diseñado así o no. Si observamos los servidores en producción desde esa perspectiva, sus errores se dividen en dos grupos.
Categoría de fallos uno: demasiados permisos
La situación con la base de datos representa el caso general. Las directrices de gobernanza de AWS indican la solución: cada llamada posterior debe incluir un token diseñado específicamente y generado para esa llamada, y nunca las credenciales que iniciaron al agente. También se añade que se debe validar la afirmación de audiencia del token, lo que impide que un token creado para un servidor MCP sea reutilizado en otro.
Pocos equipos implementan esto desde el principio, ya que requiere más configuración que simplemente reenviar el token del llamante. Sin embargo, esto marca la diferencia entre una llamada a una herramienta que falla de forma segura y una que llega realmente a producción.
Clase de fallo dos: una interfaz deficiente
El segundo grupo es más sutil. No ocurre ningún incidente dramático. La fiabilidad simplemente se va desgastando, y resulta difícil rastrear su deterioro. La guía de desarrollo de Azure MCP de Microsoft identifica el hábito subyacente: los servidores se diseñan como APIs REST, con cada operación expuesta como una herramienta separada, cuando el diseño debería basarse en lo que el agente desea lograr. Su ilustración explica bien este punto. En lugar de cuatro herramientas llamadas create_ticket, add_comment, assign_ticket y notify_user, una sola herramienta llamada file_support_request realiza internamente las cuatro acciones.
La guía señala dos síntomas adicionales de ese hábito. Las descripciones pueden prometer cosas que la herramienta no cumple, por lo que el agente confía en texto que el código nunca respeta. Además, los mensajes de error pueden ser inútiles (“Error”) o demasiado reveladores: rastros de pila, rutas de archivos internos, o una confirmación de que existe un usuario específico en su base de datos, lo cual por sí solo permite ataques de enumeración.
Una asimetría en hacia dónde se dirige la sospecha
Considere cuánto trabajo de ingeniería se invierte en la respuesta final de un agente: validación de salida estructurada, medidas de seguridad, intentos repetidos y pasos de verificación. La salida del modelo se considera sospechosa, y con razón.
Ahora considere la capa de llamada a herramientas que se encuentra debajo de esa respuesta. El token del que realiza la llamada pasa directamente. La lista de herramientas se expande sin que nadie verifique si el modelo aún puede razonar sobre ellas. La descripción de una herramienta se acepta tal como está escrita, y nunca hay pruebas que muestren a un agente utilizando la herramienta correctamente. Se invierte mucho esfuerzo en dudar de lo que dice el modelo, pero casi ninguno en dudar de lo que hace.
Esta sospecha desequilibrada es el verdadero defecto en ambos grupos. Ni una lógica de permisos más inteligente ni nombres de herramientas mejores por sí solos podrán solucionarlo. Lo que se necesita es una capa que verifique cada llamada a herramientas, y no solo cada respuesta del modelo, antes de extender la confianza en ella.
Construyendo la capa
La unidad aquí es la llamada a herramientas. No deje que una solicitud sin procesar llegue al backend. Envuélvala primero.
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional
@dataclass
class ScopedToken:
audience: str # which MCP server this token is valid for
permissions: list[str] # e.g. ["read", "create"] - never assume "all"
issued_at: datetime
expires_at: datetime
source_user: str # who originally triggered this, for audit
Cada campo en ese contenedor existe para que la capa siguiente pueda determinar hasta qué punto confiar en la llamada. Ahora vienen los controles.
Delimita el token antes de que se ejecute la herramienta
No reutilices las credenciales con las que llegó el llamante para una acción posterior. Emite un token más restringido que abarque únicamente lo que la herramienta va a realizar.
def issue_scoped_token(user_token: ScopedToken, tool_name: str,
required_permissions: list[str]) -> ScopedToken:
# Never grant more than the tool declares it needs
granted = [p for p in required_permissions if p in user_token.permissions]
if set(required_permissions) - set(granted):
raise PermissionError(
f"{tool_name} requires {required_permissions}, "
f"caller only has {user_token.permissions}"
)
return ScopedToken(
audience=tool_name,
permissions=granted,
issued_at=datetime.utcnow(),
expires_at=datetime.utcnow() + timedelta(minutes=5),
source_user=user_token.source_user,
)
Este es el elemento que permite que el escenario de la base de datos falle de manera segura. Una solicitud con permisos solo para leer y crear simplemente no puede realizar una eliminación, independientemente de lo que decida el modelo.
Verifique al público en cada llamada
Un token emitido para una herramienta debe ser rechazado por todas las demás herramientas.
def enforce_audience(token: ScopedToken, expected_tool: str) -> None:
if token.audience != expected_tool:
raise PermissionError(
f"Token issued for '{token.audience}' cannot be used on '{expected_tool}'"
)
Diseñe la herramienta según la tarea
Esto aplica el patrón file_support_request de las directrices de Azure:
def file_support_request(customer_email: str, issue_type: str, description: str) -> dict:
ticket = create_ticket(issue_type, description)
add_comment(ticket.id, f"Filed by {customer_email}")
assign_ticket(ticket.id, team=route_by_type(issue_type))
notify_user(customer_email, ticket.id)
return {
"ticket_id": ticket.id,
"status": "open",
"assigned_team": ticket.team,
}
Una sola llamada transmite una única intención clara, por lo que el agente nunca tiene que manejar por sí mismo el orden correcto de cuatro operaciones.
Sanitizar los errores antes de que los vea el agente
Registrar todos los detalles en el servidor y proporcionarle al agente solo lo necesario para recuperarse.
def safe_error(internal_message: str, request_id: str) -> dict:
# internal_message goes to your logs, never to the model
log.error(internal_message, extra={"request_id": request_id})
return {
"content": [{
"type": "text",
"text": f"Unable to complete the request. Request ID: {request_id}. "
f"Try again or contact support."
}],
"isError": True,
}
Límite en la cantidad de herramientas por servidor
Conozca el límite antes de que lo haga la producción. La guía de Microsoft indica un número: más de 10 a 15 herramientas en un servidor, distribuidas por dominio, y no se debe seguir aumentando la cantidad en un mismo servidor.
MAX_TOOLS_PER_SERVER = 15
def register_tool(server, tool):
if len(server.tools) >= MAX_TOOLS_PER_SERVER:
raise ValueError(
f"{server.name} already has {len(server.tools)} tools. "
f"Split into a domain-specific server instead of adding more."
)
server.tools.append(tool)
Tres verificaciones rápidas en un servidor existente
Ninguna de estas requiere una reconstrucción.
Revise el alcance de los tokens, no solo su presencia. Obtenga diez llamadas recientes a la herramienta y compare los permisos que cada token tenía con los que necesitaba la herramienta. Si suelen diferir, se están utilizando tokens más amplios de lo necesario, y probablemente ese sea el estado actual.
Haga los cálculos de tokens para conocer el número real de herramientas que utiliza. La guía de AWS estima entre 5,000 y 10,000 tokens por llamada solo para las descripciones, una vez que un servidor cuenta con más de 20 herramientas. Cuente las herramientas que tiene. Un servidor que supera ampliamente esa cifra, sin filtrado ni división, sufre de sobrecarga de contexto que ningún cambio en el modelo podrá solucionar.
Pruebe una prueba a nivel de agente que probablemente aún no se ha realizado. Utilice las tres herramientas más utilizadas y, con un agente real y no una prueba de unidad, verifique si selecciona la adecuada a partir de una solicitud cotidiana en lenguaje natural. La guía de Microsoft describe esto como la capa que casi todos omiten. Superar las pruebas de unidad y protocolo sin realizar esta prueba deja sin saber si las herramientas funcionan.
Cómo encaja con el resto
Nada de esto sustituye el trabajo existente en materia de fiabilidad, sino que funciona junto a él. Los tokens con alcance definido siguen el mismo principio que la validación de entrada en cualquier límite de confianza. Un límite en la cantidad de herramientas y un diseño centrado en tareas reflejan la disciplina del versionado de APIs y el diseño de interfaces, pero aplicada a una superficie que lee un modelo y no un desarrollador humano. Cada servidor MCP es otro lugar donde el sistema decide hasta qué punto confiar en quien lo llama, por lo que merece la misma atención que el resto.
Los equipos adoptan MCP porque permite a los agentes tener un mayor alcance: una ruta estándar hacia sistemas reales en lugar de cien integraciones personalizadas. El problema es que un modelo realiza una llamada con alcance deficiente con la misma fidelidad que una con alcance adecuado, ya que no percibe la diferencia. Solo la capa de controles lo hace.
Los fallos de permisos y los fallos de la interfaz parecen no estar relacionados: uno se refiere al acceso y el otro al diseño. Ambos surgen de una suposición no verificada, a saber, que una llamada a una herramienta ha ganado una confianza que en realidad nadie le ha otorgado. La mayoría de los sistemas de IA dirigen su sospecha hacia el lado de la salida. El lado de las llamadas a herramientas también merece esa atención.
Esto deja una pregunta para cada servidor MCP en uso: ¿qué impide actualmente que un agente actúe ante una llamada que contiene una confianza excesiva, y se activaría una alerta si ya la tuviera?
Respuestas rápidas
¿Qué es el alcance de los tokens MCP? Significa asignar a cada llamada a una herramienta su propio token específico para ese fin, en lugar de reenviar las credenciales originales del solicitante. La guía de gobernanza de AWS lo recomienda para evitar que una acción errónea o no intencionada tenga éxito simplemente porque las credenciales subyacentes lo permitieran.
¿Cuántas herramientas debería exponer un servidor MCP? La guía de Azure sugiere entre 10 y 15 como regla general, después de lo cual el servidor debería dividirse por dominio. Además, los agentes eligen la herramienta adecuada de forma notablemente menos frecuente, y la guía de AWS indica que el costo de una lista larga de herramientas asciende a 5,000 a 10,000 tokens por llamada solo para las descripciones, cuando hay más de 20 herramientas.
¿En qué difiere el diseño de herramientas orientado a tareas del diseño de API de sistema? El diseño de API de sistema convierte cada operación de backend en una herramienta propia, imitando una API REST. El diseño orientado a tareas ofrece lo que el usuario intenta lograr como una sola herramienta que gestiona los pasos internamente. El ejemplo de Microsoft es una herramienta única llamada file_support_request en lugar de cuatro operaciones de gestión de tickets.
¿Por qué sanitizar los mensajes de error de MCP? Las trazas de pila, las rutas internas o las indicaciones de que existe un registro determinado proporcionan a los atacantes detalles que no deberían obtener, lo cual representa al menos una debilidad por enumeración. Un enfoque más seguro consiste en escribir todos los detalles en los registros del lado del servidor y devolver al agente solo lo que necesita para recuperarse, junto con un ID de correlación.
¿Los tests unitarios detectan estos problemas? No. Los tests unitarios solo cubren la lógica de una herramienta, mientras que las pruebas de protocolo verifican el cumplimiento de MCP, pero ninguno demuestra que un agente pueda encontrar, seleccionar y utilizar correctamente la herramienta en una situación real. Para ello se necesita una tercera capa de pruebas impulsada por un agente real, algo que la mayoría de los equipos omiten.
Leer más
- Construir o comprar infraestructura MCP: Una guía de decisión para equipos de SaaS — Comparar un servidor MCP interno con una plataforma gestionada: carga de trabajo real, autenticación, niveles de control, limitaciones de adaptación, una ruta híbrida y cinco preguntas que deben resolverse primero.
- WebMCP, MCP a nivel de servicio o uso simple en el navegador: Donde encajan las herramientas de agente — Un análisis crítico de WebMCP: herramientas de página frente a MCP a nivel de servicio y agentes de navegador comunes, abordando sesiones, OAuth CIMD, descubrimiento, estado local y propiedad.