
mcp-server-attestation v0.2.0
Endurecimiento de la cadena de suministro de Capa 2 para servidores MCP — manifiestos de herramientas firmados con Ed25519, atestación de spawn en tiempo de ejecución, saneador de argumentos con denegación por defecto. Protege contra el envenenamiento del marketplace + CVE-2025-69256 + CVE-2025-61591.
Parte del StudioMeyer MCP Stack — Hecho en Mallorca 🌴 · ⭐ si lo usas
mcp-server-attestation
Endurecimiento de la cadena de suministro de capa 2 para servidores del Model Context Protocol. Manifiestos de herramientas firmados con Ed25519, atestación de spawn en tiempo de ejecución, saneador de argumentos de denegación por defecto.Respuesta directa a:
- Envenenamiento del marketplace de OX Security, abril de 2026 — 9 de 11 registros MCP aceptaron servidores maliciosos. La posición publicada de Anthropic: "comportamiento esperado".
- CVE-2025-69256 — RCE en Serverless Framework MCP mediante inyección de comandos en
child_process.exec(). - CVE-2025-61591 — RCE en Cursor MCP a través de un servidor malicioso instalado por OAuth con secuestro de spawn.
Este paquete proporciona lo que Anthropic decidió no ofrecer: verificación criptográfica de qué herramientas puede exponer un servidor y qué llamadas de spawn puede realizar. Es una dependencia de sustitución directa, no un reemplazo del runtime.
Una nota de nuestra parte
Llevamos dos años construyendo herramientas y sistemas para nosotros mismos. Que este repositorio sea pequeño y tenga pocas estrellas no se debe a que sea nuevo. Se debe a que hace poco que decidimos compartir lo que hemos construido. No es un experimento reciente, es una historia larga con un commit reciente.
Nos encanta construir cosas y compartirlas. No nos gustan las tácticas de redes sociales, los trucos de crecimiento ni perseguir estrellas y seguidores. Por eso este repositorio es pequeño. El código es real, se usa y las incidencias se responden. Juzga por ti mismo.
Si te resulta útil, compartirlo, probarlo y dar tu opinión nos ayuda. Si podría ser mejor, una incidencia es más útil. Si construyes algo con él, cuéntanoslo en [email protected]. Eso de verdad nos alegra el día.
Desde un pequeño estudio en Palma de Mallorca.
Paquetes (npm workspaces)
| Paquete | Propósito |
|---|---|
mcp-server-attestation (packages/lib) | Librería: firma/verificación Ed25519, esquema de manifiesto, saneador, atestador de spawn, almacén de confianza TOFU. |
mcp-attest-cli (packages/cli) | CLI mcp-attest: keygen, sign, verify, inspect, fingerprint, check-pin. |
mcp-attest-demo (packages/demo-server) | Servidor MCP de referencia (stdio, spec 2025-06-18) que expone 5 herramientas que demuestran la librería. |
Instalación
npm install mcp-server-attestation
# CLI:
npm install -g mcp-attest-cli
# Reference MCP server:
npx mcp-attest-demo
Node 20+. Sin dependencias criptográficas externas: usa primitivas Ed25519 de node:crypto.
Inicio rápido del servidor en cinco líneas
import { verifyManifestStrict, attestSpawnStrict, type SignedManifest } from "mcp-server-attestation";
import signed from "./signed/manifest.json" assert { type: "json" };
// 1. At startup: prove the manifest you ship is the manifest you signed.
verifyManifestStrict(signed);
// 2. Before every child_process.spawn:
attestSpawnStrict(signed as SignedManifest, { command, args });
Esa es toda la integración. Dos llamadas a funciones, sin SaaS, sin daemon.
Si prefieres volver a verificar la firma en cada spawn (defensa en profundidad contra que un manifiesto no verificado o sustituido llegue a la compuerta), usa en su lugar la única llamada a prueba de fallos: verifica y luego atesta:
import { attestSpawnVerified, type SignedManifest } from "mcp-server-attestation";
attestSpawnVerified(signed as SignedManifest, { command, args });
Herramientas (servidor de referencia mcp-attest-demo)
| # | Nombre | readOnlyHint | destructiveHint |
|---|---|---|---|
| 1 | attest_verify_manifest | true | false |
| 2 | attest_inspect_spawn | true | false |
| 3 | attest_generate_manifest_template | true | false |
| 4 | attest_sign_manifest | false | false |
| 5 | attest_keygen | false | false |
Las anotaciones son honestas: attest_sign_manifest y attest_keygen escriben archivos en el disco, por lo que no son de solo lectura, pero no destruyen datos existentes, por lo que destructiveHint se mantiene en false. Consulta docs/THREAT-MODEL.md para ver la tabla de capacidades por herramienta.
CLI
mcp-attest keygen --out-dir ./keys --name prod
mcp-attest sign --manifest manifest.json --private-key keys/prod.key --out signed.json
mcp-attest verify --signed signed.json --pin # TOFU pin
mcp-attest verify --signed signed.json --sigstore # opt-in Rekor cross-ref
mcp-attest inspect --signed signed.json --command /usr/bin/echo --arg "hello"
mcp-attest fingerprint --public-key keys/prod.pub
mcp-attest check-pin --server my-server --signed signed.json
verify sale con código 2 ante una firma incorrecta y con código 3 ante una discrepancia de pin.
Compatibilidad con la especificación MCP
| Versión de la especificación | Estado |
|---|---|
| 2024-11-05 | analizable en el manifiesto, no es objetivo del servidor de referencia |
| 2025-03-26 | analizable en el manifiesto, no es objetivo del servidor de referencia |
| 2025-06-18 | objetivo completo |
La librería es agnóstica al transporte. El servidor de referencia es solo stdio.
Modelo de seguridad
- Trust-on-First-Use es el comportamiento por defecto. La primera vez que verificas un servidor, su clave pública se fija en
~/.mcp-attest/trust.json(anulación:MCP_ATTEST_TRUST_FILE). Las verificaciones posteriores rechazan cualquier clave nueva para el mismo nombre de servidor conTRUST_PIN_MISMATCH. Esto bloquea el vector de actualización maliciosa al estilo Cursor. - Sin lista de claves de confianza incluida. Este paquete no actúa como guardián. Si quieres una garantía más sólida, activa
--sigstorepara contrastar la huella de la clave pública con el registro de transparencia Rekor de Sigstore. - Saneador de argumentos de denegación por defecto.
shellSafeStringbloquea todos los metacaracteres ASCII de shell, NUL, CR, LF, VT, FF, NEL, caracteres de ancho cero, BOM, anulaciones RTL/LTR, aisladores Trojan-Source y confundibles latinos de ancho completo. El comportamiento de lista de permitidos requiere los tipos de regla explícitosregex/enum/prefix/literal. - Reglas
regexseguras frente a ReDoS. El patrón de una reglaregexestá firmado por el autor, pero el valor del argumento lo controla el atacante. El saneador detecta estáticamente los patrones propensos a retroceso (cuantificadores anidados sin límite como(a+)+) y se niega a ejecutarlos, por lo que un único argumento manipulado no puede congelar la ruta crítica del spawn. Las reglasregextambién llevan un límite de entradamaxLength(4096 por defecto). - Reglas
prefixseguras frente a traversal. Las reglasprefixrechazan los componentes de ruta..por defecto (denyTraversal: true, incluida la forma codificada%2e%2e), por lo que/safe/../../etc/passwdse bloquea aunque cumplaprefix: "/safe/". - Verificar y luego atestar.
attestSpawnVerifiedcomprueba la firma del manifiesto antes de atestar el spawn en una única llamada a prueba de fallos: úsala en lugar deattestSpawnStricta menos que hayas sacado la verificación Ed25519 por spawn de un bucle realmente crítico. - JSON canónico es la superficie firmada. La reserialización no puede cambiar los bytes firmados.
Lo que este paquete NO hace (fuera del alcance):
- Hacer sandbox o contenerizar el proceso del servidor.
- Endurecimiento del flujo OAuth (build separado de
mcp-oauth-shield). - Control de tráfico de salida de red.
- Parcheo automático de servidores existentes.
Pruebas
npm install
npm run typecheck
npm test
El corpus de pruebas incluye fixtures de reproducción de CVE (packages/lib/tests/fixtures/cve-2025-69256-payloads.json, cve-2025-61591-payloads.json). La compilación es una comprobación de regresión: todos los payloads deben bloquearse.
Distribución
- Publicación en npm mediante GitHub Actions OIDC con
--provenance. - Servidor de referencia enviado a mcp.so y FastMCP Directory.
- Librería publicada por separado como
mcp-server-attestation.
Acerca de StudioMeyer
StudioMeyer es un estudio de diseño e IA con sede en Palma de Mallorca que trabaja con clientes de todo el mundo. Creamos sitios web personalizados e infraestructura de IA para pequeñas y medianas empresas. Stack de producción sobre Claude Agent SDK, MCP y n8n, con Sentry, Langfuse y LangGraph para la observabilidad y una capa de protección propia.
Licencia
MIT, Copyright 2026 Matthias Meyer (StudioMeyer). Consulta LICENSE.