MCP Chaos Rig
Un servidor MCP local que falla bajo demanda. Prueba tu cliente contra fallos de autenticación, herramientas que desaparecen, respuestas inestables y caducidad de tokens, todo desde una interfaz web.
Documentación
MCP Chaos Rig
Un servidor MCP local que falla a demanda. Prueba tu cliente contra fallos de autenticación, herramientas que desaparecen, respuestas inestables y expiración de tokens, todo desde una interfaz web.
El problema
Estás construyendo un cliente MCP. Necesitas probar flujos OAuth, renovación de tokens, descubrimiento de herramientas, manejo de errores y ciclo de vida de sesión. Los servidores de producción no fallan a voluntad. Necesitas un servidor que lo haga.
Qué hace Chaos Rig
Ejecuta un servidor MCP local donde controlas todo:
- Romper autenticación: forzar 401 y 500 a mitad de sesión, expirar tokens a demanda, rechazar tokens de refresco
- Romper herramientas: deshabilitar herramientas para provocar
tools/changed, cambiar versiones de esquema en vivo - Romper fiabilidad: añadir latencia aleatoria, hacer que las llamadas a herramientas fallen a tasas configurables
- Ver todo: el registro de solicitudes en vivo muestra llamadas JSON-RPC entrantes y respuestas SSE salientes, con cuerpos expandibles al hacer clic

Escenarios de prueba
| Escenario | Cómo probarlo |
|---|---|
| Flujo de consentimiento OAuth 2.1 | Usa la página de consentimiento interactiva: aprobar, rechazar, código inválido, estado manipulado |
| Autenticación de encabezado fijo | Cambia al modo Headers, configura pares clave-valor, verifica que el cliente los envía |
| Encabezados faltantes/incorrectos | Envía solicitudes con encabezados faltantes o no coincidentes — 401 con detalles |
| Rechazo de token a mitad de sesión | Alterna "Reject OAuth" a 401 o 500 mientras el cliente está conectado |
| Expiración y renovación de token | Establece un TTL corto para el token de acceso, observa cómo el cliente lo renueva |
| Rechazar tokens de refresco | Alterna "Reject refresh tokens" para forzar la re-autenticación |
| Cliente incorrecto refrescando | Habilita "Enforce refresh token ownership" — detecta clientes que pierden credenciales y se re-registran |
| Sin registro dinámico | Cambia a "Pre-registered client only" — /register 404s, solo tu client_id funciona |
| Credenciales de cliente rotadas | Cambia el client_id pre-registrado a mitad de sesión — el anterior ahora falla con invalid_client |
| Conflicto de descubrimiento de alcances | Establece diferentes alcances en metadatos vs encabezado WWW-Authenticate, prueba cuál confía el cliente |
| Herramienta desapareciendo | Deshabilita una herramienta en la pestaña Tools. Los clientes reciben tools/changed |
| Cambio de esquema de herramienta | Cambia echo o add entre esquemas v1 y v2 |
| Llamadas a herramientas inestables | Establece tasa de fallo 0-100%. Las llamadas fallidas devuelven isError: true |
| Respuestas lentas | Habilita el modo lento con rango de latencia configurable |
| Intercambio de código PKCE | La página de consentimiento OAuth ofrece opciones "Wrong Code" y "Wrong State" |
| Herramientas respaldadas por base de datos | Operaciones CRUD en una base de datos SQLite real de contactos |
Inicio rápido
npx mcp-chaos-rig
Panel de control en localhost:4100/ui, endpoint MCP en http://localhost:4100/mcp. Requiere Node 20+.
Si prefieres una instalación global:
npm install -g mcp-chaos-rig
mcp-chaos-rig
O ejecutar desde el código fuente:
git clone https://github.com/Typewise/mcp-chaos-rig.git
cd mcp-chaos-rig
npm install
npm run dev
Acceso remoto
Si tu entorno de producción necesita acceder a Chaos Rig, expónlo mediante un túnel (ngrok, Cloudflare Tunnel, etc.) y establece BASE_URL para que las redirecciones OAuth se resuelvan correctamente:
BASE_URL=https://your-tunnel.example.dev npx mcp-chaos-rig
El modo de autenticación comienza en Bearer, por lo que un rig orientado a túneles generalmente también quiere AUTH_MODE (none, bearer, headers, oauth). Para OAuth con credenciales pre-registradas, consulta Registro de cliente.
Estado de autenticación
Todo el estado está en memoria y se restablece al reiniciar, volviendo a lo que el entorno siembra (AUTH_MODE, OAUTH_CLIENT_MODE, STATIC_*) o a los valores predeterminados integrados. Bearer comienza con el token test-token-123 (válido hasta que se cambie). Los tokens OAuth expiran según TTL. Los tokens de refresco rastrean la propiedad por cliente cuando está habilitado. Después de reiniciar, haz un refresco con la propiedad desactivada para re-sembrar, luego actívala.
Pestañas del panel de control
Servidor
Configura el modo de autenticación, el modo lento (latencia aleatoria) y las herramientas inestables (% de tasa de fallo).
| Modo de autenticación | Comportamiento |
|---|---|
| None | Todas las solicitudes pasan |
| Bearer | Requiere Authorization: Bearer test-token-123 |
| Fixed Headers | Requiere pares de encabezados clave-valor configurados en cada solicitud |
| OAuth 2.1 | Flujo de autorización completo con página de consentimiento interactiva |
Los modos Bearer, Fixed Headers y OAuth admiten inyección de fallos: fuerza respuestas 401 o 500 para probar el manejo de errores. El modo comienza en Bearer a menos que AUTH_MODE indique lo contrario.
El modo OAuth añade controles para el registro de clientes, TTL del token de acceso, rechazo de tokens de refresco y aplicación de propiedad de tokens de refresco. Los endpoints OAuth se enumeran en una sección plegable.
Registro de cliente
| Modo | Comportamiento |
|---|---|
| Registro dinámico | Los clientes se registran en /oauth/register y obtienen credenciales nuevas (RFC 7591) |
| Solo cliente pre-registrado | Solo se acepta el client_id / client_secret configurado; el registro está desactivado |
El modo estático reproduce servidores de autorización que emiten credenciales fuera de banda (Google, Atlassian, la mayoría de IdPs empresariales):
registration_endpointdesaparece de los metadatos well-knownPOST /oauth/registeryPOST /registerdevuelven 404registration_not_supported- cualquier otro
client_idrecibeinvalid_clienten/authorizey/token - un
client_secretvacío lo convierte en un cliente público, por lo que el endpoint de token acepta el método de autenticaciónnone - las URIs de redirección deben coincidir exactamente con una configurada, excepto el puerto en hosts de loopback (RFC 8252)
La URI de redirección predeterminada incluida apunta a un cliente local. Probar contra un cliente desplegado significa registrar el callback de ese cliente en su lugar, o /authorize devuelve 400 invalid_request — la respuesta enumera las URIs registradas, ya que la relajación del puerto solo se aplica a hosts de loopback y los callbacks https:// deben coincidir exactamente.
Configura el cliente al arrancar para que un rig orientado a túneles comience listo:
AUTH_MODE=oauth \
OAUTH_CLIENT_MODE=static \
STATIC_CLIENT_ID=acme-client \
STATIC_CLIENT_SECRET=acme-secret \
STATIC_REDIRECT_URIS=https://platform-api.example.app/api/mcp/oauth/callback \
BASE_URL=https://your-tunnel.example.dev npx mcp-chaos-rig
AUTH_MODE es obligatorio aquí: por defecto es bearer, y los endpoints OAuth devuelven 404 hasta que esté oauth (none, bearer, headers, oauth; cualquier otra cosa falla al inicio). STATIC_REDIRECT_URIS está separado por comas. Un STATIC_CLIENT_SECRET= vacío arranca un cliente público. Todo sigue siendo editable desde la pestaña Server después.
Cambiar el client_id elimina el anterior, para que puedas probar la rotación de credenciales contra un cliente en vivo. También puedes configurarlo desde la API:
curl -X POST localhost:4100/api/oauth-client -H 'Content-Type: application/json' \
-d '{"mode":"static","clientId":"acme-client","clientSecret":"acme-secret","redirectUris":["http://localhost:3000/api/mcp/oauth/callback"]}'
Herramientas

Activa/desactiva herramientas. Deshabilitar envía tools/changed a los clientes conectados. Algunas herramientas (echo, add) admiten cambio de versión.
Herramientas disponibles:
echo: devuelve tu mensaje (v2 añade opciones de formato)add: suma dos números (v2 acepta un array)get-time: hora actual del servidor como ISO 8601random-number: entero aleatorio en un rangoreverse: invierte una cadenatypeEcho: hace eco de un parámetro opcional por cada primitivo de JSON Schema, para verificar que un cliente recorre todos los tiposdispute-charge: presenta una disputa de facturación, devuelve un recibo JSONlist-contacts,get-contact-by-id,get-contact-by-email,search-contacts,create-contact,update-contact,delete-contact: CRUD SQLite
Tres herramientas de esquema grande comienzan deshabilitadas, para probar cómo un cliente maneja entradas amplias: submit-customs-declaration (todos los campos obligatorios), create-product-listing (25 obligatorios, 25 opcionales), search-properties (50 filtros opcionales).
Contactos

Ver y restablecer la base de datos SQLite que respalda las herramientas de contacto. Comienza con tres registros semilla.
Registro

Registro de solicitudes en vivo que muestra solicitudes entrantes y respuestas SSE salientes. Muestra marca de tiempo, fuente (mcp/auth/sse), método, estado, método JSON-RPC, nombre de herramienta y argumentos. Haz clic en cualquier línea de cuerpo o argumentos truncados para expandirla. Mantiene las últimas 200 entradas.
Página de consentimiento OAuth

Cuando el modo de autenticación es OAuth, el endpoint de autorización muestra una página de consentimiento interactiva:
| Botón | Resultado |
|---|---|
| Approve | Redirige con código de autorización válido |
| Decline | Redirige con error=access_denied |
| Wrong Code | Redirige con código inválido (el intercambio de token falla) |
| Wrong State | Redirige con parámetro de estado manipulado |