protect-mcp
Puerta de enlace
Documentación
protect-mcp
Puerta de políticas Cedar de cierre por fallo más recibos firmados para llamadas a herramientas de agentes de IA.
protect-mcp es una puerta que se sitúa delante de las llamadas a herramientas de un agente de IA. Evalúa cada llamada contra una política de Cedar (el mismo lenguaje que AWS usa para IAM), bloquea lo que infringe las reglas antes de que se ejecute, y firma un recibo Ed25519 verificable sin conexión de cada decisión. Se ejecuta localmente, no envía telemetría de tus decisiones a ningún lugar, y tiene licencia MIT.
Por qué es diferente
- Cierre por fallo por defecto. Ante cualquier error de política, un motor faltante o un fallo de evaluación, la decisión es DENEGAR. La puerta nunca permite silenciosamente. Existe un modo de observación para despliegue en sombra, pero incluso allí una llamada que sería bloqueada se marca como
would_deny: true, por lo que un fallo nunca es silencioso. - Demuestra su propia contención.
serve --enforceydoctorejecutan una autoprueba de arranque y se niegan a armar la puerta a menos que puedan demostrar que una acción conocida como prohibida es realmente denegada. Una puerta que no puede demostrar que deniega no se inicia. - Cada decisión es un recibo que cualquiera puede verificar. Las decisiones están firmadas con Ed25519 y son verificables sin conexión con
@veritasacta/verify. No se requiere confianza en el proveedor: las matemáticas no importan quién lo ejecute.
Inicio rápido: instalar hasta la primera prueba útil
# 1. Generate an Ed25519 keypair, config template, and sample policy.
npx protect-mcp init
# 2. Wrap any MCP server in shadow mode. Nothing is blocked yet; calls are logged.
npx protect-mcp wrap -- node your-mcp-server.js
# 3. Inspect the local-only dashboard: tool inventory, risk, approvals, receipts.
npx protect-mcp dashboard --open
# 4. Draft a reviewable policy from observed calls.
npx protect-mcp recommend --write
# 5. When reviewed, restart the wrapper in enforce mode with that policy.
npx protect-mcp --policy protect-mcp.recommended.json --enforce -- node your-mcp-server.js
Para Claude Desktop, ejecuta primero un parche de configuración en seco y luego aplícalo:
npx protect-mcp wrap --claude-desktop
npx protect-mcp wrap --claude-desktop --write
npx protect-mcp dashboard --open
El panel se vincula a 127.0.0.1, lee solo archivos locales de registros/recibos y no sube nada. Usa npx protect-mcp connect solo si deseas explícitamente un panel ScopeBlind alojado.
La puerta como servidor MCP
Si prefieres llamar a la puerta como herramientas en lugar de conectar los ganchos de Claude Code, ejecútala como servidor MCP:
npx protect-mcp mcp
Habla MCP sobre stdio y expone cuatro herramientas de solo lectura, todo el bucle:
evaluate_action: decide una llamada de herramienta propuesta contra una política Cedar en línea, con cierre por fallo (cualquier error de política es DENEGAR). Devuelve{ allowed, decision, reason, policy_digest }.sign_decision: convierte una decisión en un recibo firmado con Ed25519 (una denegación firma ungateway_restraint, un permiso undecision_receipt). Devuelve el recibo y su clave pública; genera una clave efímera si no proporcionas una.verify_receipt: verifica un recibo firmado sin conexión contra una clave pública. Devuelve{ valid, error, type, kid, issuer }.self_test: demuéstralo, sin entradas. Una acción conocida como prohibida es denegada, luego un recibo firmado hace un viaje de ida y vuelta y una copia manipulada falla.
Apunta cualquier host MCP a ella, por ejemplo Claude Desktop:
{
"mcpServers": {
"protect-mcp": { "command": "npx", "args": ["-y", "protect-mcp", "mcp"] }
}
}
Los recibos son compatibles a nivel de bytes con los que la puerta firma en tiempo de ejecución, por lo que un recibo acuñado aquí se verifica con @veritasacta/verify y el verificador del navegador de la misma manera.
Panel de acciones local
protect-mcp dashboard es la vista del operador para pasar de la visibilidad a la aplicación:
- Inventario de herramientas: cada herramienta observada, recuento de llamadas, riesgo alto/medio/bajo, y si la política activa tiene una regla exacta, un comodín de respaldo o ninguna regla.
- Cobertura de políticas: ediciones locales de políticas con un clic para
Require approval,BlockoObserve. Reinicia el envoltorio después de revisar los cambios. - Cola de aprobación de acciones exactas: la herramienta exacta, acción, destino, vista previa del payload redactado, hash del payload, base de la política y captura de razón antes de que un humano apruebe, deniegue, edite o tome el control.
- Cadena de recibos: ids de solicitud correlacionados con hashes de recibos firmados, para que un revisor de auditoría pueda ver qué decisiones tienen prueba criptográfica.
- Exportación de auditoría: descarga el paquete de auditoría verificable sin conexión cuando existen recibos firmados. Si solo existen registros locales sin firmar, el panel explica que la firma debe habilitarse primero.
Para aprobaciones de respaldo en escritorio en vivo, inicia el panel con el endpoint de aprobación de la puerta de enlace local y el nonce impreso por el envoltorio:
npx protect-mcp dashboard --open \
--approval-endpoint http://127.0.0.1:9876 \
--approval-nonce "$PROTECT_MCP_APPROVAL_NONCE"
Approve reenvía a la puerta de enlace local en vivo cuando esos indicadores están presentes. Deny, Edit y Take over se registran localmente como registros de resolución de aprobación; úsalos como instrucción del operador y vuelve a ejecutar la herramienta cuando sea necesario.
MVP de límite de pago: anclaje de resúmenes, no subida de datos
Los recibos autofirmados locales siguen siendo gratuitos y verificables sin conexión. El límite de pago es evidencia independiente de que ScopeBlind vio un resumen de recibo en un momento, bajo una identidad de organización, sin recibir el prompt sin procesar, el payload de la herramienta, la salida, la clave privada o el recibo sin procesar.
# Create or refresh a local org identity and public-key directory.
npx protect-mcp registry init --org "Meridian Global Macro" --billing-account acct_meridian
# Local preview: writes a digest registry and shareable static verifier page.
npx protect-mcp registry anchor
# Hosted mode: uploads receipt digests only for independent anchoring.
SCOPEBLIND_TOKEN=... npx protect-mcp registry anchor \
--hosted \
--endpoint https://api.scopeblind.com \
--verifier-base https://legate.scopeblind.com
La vista previa local está deliberadamente etiquetada como local-preview-not-independent. El modo alojado ancla solo hashes de recibos, ids de solicitud, claves públicas de la organización y metadatos de facturación. No sube recibos sin procesar ni contexto sensible.
Demo asesina: de sombra a política a prueba
protect-mcp killer-demo genera un paquete completo de ventas/demo de tres minutos:
npx protect-mcp killer-demo --dir ./scopeblind-demo
Crea actividad simulada de sistema de archivos, GitHub, correo electrónico y PMS; muestra llamadas riesgosas en modo sombra; aplica un paquete de políticas; requiere aprobación para una reserva sensible de PMS; ejecuta a través de la puerta de enlace; escribe un recibo firmado; demuestra que el recibo original se verifica; demuestra que un recibo manipulado falla; y crea un paquete de divulgación selectiva que oculta el contexto sensible mientras muestra la prueba mínima.
Abre primero el DEMO-RUNBOOK.md generado. Luego ejecuta el comando de panel impreso para guiar a un cliente a través de la secuencia exacta.
Divulgación selectiva v0
Los recibos en modo compromiso pueden llevar un committed_fields_root en lugar de exponer cada campo en texto claro. Más tarde, el titular puede divulgar solo campos seleccionados:
npx protect-mcp verify-disclosure \
--receipt ./receipts/selective-disclosure.receipt.json \
--disclosure ./receipts/selective-disclosure.tool-only.json
El verificador comprueba el hash del recibo padre, la firma Ed25519, la raíz del compromiso y la prueba de Merkle de cada campo divulgado. Luego explica qué campos fueron divulgados y qué campos comprometidos permanecen ocultos. Esto es divulgación de compromiso con sal, no conocimiento cero completo, pero hace concreto el reclamo de privacidad: los auditores pueden verificar hechos seleccionados sin recibir el payload completo de la herramienta ni el contexto sensible del escritorio.
Probar una afirmación sobre el registro (atestaciones ciegas a la posición)
Puedes probar una AFIRMACIÓN sobre tu registro sin revelarlo. Acuña una atestación firmada y ciega a la posición sobre todo el registro que divulga solo categorías por decisión (un resumen de recibo, el veredicto, etiquetas de capacidad), nunca tus entradas, salidas o datos de la herramienta:
# "No action reached the network across the record":
npx protect-mcp claim --no net.egress
# other predicates:
# --only fs.read,fs.write all actions were confined to these capabilities
# --no-verdict blocked no action was blocked
# --count blocked how many were blocked
Cualquiera la verifica sin conexión, viendo solo las categorías, nunca el contenido:
npx protect-mcp verify-claim claim-<id>.json
El verificador recalcula una raíz de Merkle sobre el conjunto divulgado y recalcula el predicado de forma independiente, por lo que el emisor no puede mentir sobre la afirmación dada la divulgación. Agrega --anchor para registrar el resumen de la afirmación en el registro de transparencia público y de solo añadidura de ScopeBlind, para que una contraparte que no confíe en ti pueda confirmar que el conjunto divulgado está completo y no fue recortado silenciosamente (solo se envía el hash; el registro permanece local):
npx protect-mcp claim --no net.egress --anchor
Esta es una atestación responsable y ciega a la posición, no conocimiento cero completo: revela la forma, no el contenido.
Pruébalo en 60 segundos (sin agente requerido)
Mira el video de dos minutos en legate.scopeblind.com/record, luego reprodúcelo contra tu propia copia:
npx protect-mcp sample # seed a labeled sample record (8 decisions: 1 blocked, 2 payments)
npx protect-mcp record # open it: signatures verified in your browser
npx protect-mcp claim --payment-under 100 --anchor --output payments-under-100.json
npx protect-mcp verify-claim payments-under-100.json
npx protect-mcp anchor-record
Coloca el demo-tampered.jsonl generado en la página de registro para ver cómo se detecta una edición posterior a la firma. sample se niega a tocar un registro existente, así que ejecútalo en una carpeta vacía. Cuando estés listo para lo real, conecta la puerta a continuación y los mismos comandos se ejecutan contra el propio registro de tu agente.
Inicio rápido de gancho de Claude Code
# Generate hook config and a sample Cedar policy.
npx protect-mcp init-hooks
# Serve the Claude Code hook gate in enforce mode. It runs a restraint self-test
# first and refuses to start if it cannot prove it denies a forbidden vector.
npx protect-mcp serve --enforce --cedar ./cedar
Evaluación de una sola vez, como la llama un gancho PreToolUse. El código de salida 2 significa denegar (la herramienta está bloqueada); el código 0 significa permitir:
npx protect-mcp evaluate --cedar ./cedar --tool Bash --input '{"command":"rm"}'
echo $? # 2 -> denied, fail-closed
npx protect-mcp evaluate --cedar ./cedar --tool Read --input '{"path":"README.md"}'
echo $? # 0 -> allowed
Una política faltante o no cargable deniega (salida 2) a menos que pases explícitamente --fail-on-missing-policy false.
Ganchos de Claude Code
protect-mcp init-hooks escribe un .claude/settings.json por ti. Para conectar la puerta manualmente, los dos verbos que necesitas son evaluate (PreToolUse, bloquea en salida 2) y sign (PostToolUse, registra un recibo). Fija la versión para que una sesión de Claude Code siempre ejecute la puerta que probaste:
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "npx protect-mcp@0.9.1 evaluate --cedar ./cedar --tool \"$TOOL_NAME\" --input \"$TOOL_INPUT\""
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "npx protect-mcp@0.9.1 sign --tool \"$TOOL_NAME\" --receipts ./receipts --key ./keys/gateway.json"
}
]
}
]
}
}
evaluate sale con 2 en denegación para que Claude Code bloquee la llamada a la herramienta, y con 0 en permiso. sign es de mejor esfuerzo: agrega un recibo firmado con Ed25519 cuando hay una clave configurada, y si no hay firmante disponible registra una línea honesta sin firmar ("signed": false) en lugar de fallar la herramienta.
Úsalo en otros agentes (Codex, Cursor, Gemini, Hermes)
La misma puerta de cierre por fallo se ejecuta como gancho de herramienta en cualquier agente que los soporte. Agrega --format <host> para que el verbo lea el payload del gancho de ese host desde stdin y deniegue en su contrato:
# the PreToolUse / before-tool command for each host
npx -y protect-mcp@latest evaluate --format codex --cedar ./cedar # OpenAI Codex
npx -y protect-mcp@latest evaluate --format gemini --cedar ./cedar # Gemini CLI BeforeTool
npx -y protect-mcp@latest evaluate --format cursor --cedar ./cedar # Cursor beforeShellExecution
npx -y protect-mcp@latest evaluate --format hermes --cedar ./cedar # Hermes pre_tool_call
Empareja cada uno con sign --format <host> en el evento posterior a la herramienta para recibos. El caso importante es Hermes, que ignora los códigos de salida de los ganchos y lee el veredicto desde stdout, por lo que --format hermes deniega mediante {"decision":"block"} en lugar de salida 2 (una salida 2 cruda fallaría abiertamente allí). Sin --format, los verbos leen los indicadores --tool/--input exactamente como en la sección de Claude Code anterior.
Escribir una política
Las políticas de Cedar viven en un directorio al que apuntas con --cedar. Una regla forbid deniega, una regla permit permite. Para coincidir con un valor en la entrada de la herramienta, usa el modismo .contains():
// Allow read-only tools.
permit(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"Read"
);
// Deny dangerous shell commands by matching the command against a list.
forbid(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"Bash"
) when {
["rm", "dd", "mkfs"].contains(context.command)
};
// Block destructive tools outright.
forbid(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"delete_file"
);
Peligro: NO escribas
context.command in ["rm", "dd"]para coincidir una cadena contra una lista.ines para jerarquías de entidades, no para pertenencia a cadenas. Cedar trata la expresión como un error de tipo y descarta silenciosamente toda la reglaforbid, lo que (bajo una puerta de apertura por fallo) deja unpermitresidual en pie. Este es el defecto exacto detrás del aviso a continuación. Usa[...].contains(context.command)en su lugar. Desde 0.7.0 la puerta deniega en ese error en lugar de permitir, y una prueba de alambre de CI falla la compilación si el patrón se reintroduce en una política enviada. Ver GHSA-hm46-7j72-rpv9.
Paquetes de políticas iniciales
La mayoría de los equipos no deberían escribir Cedar desde cero el primer día. Instala un paquete inicial, ejecuta en modo sombra, inspecciona los recibos y luego ajusta o aplica:
npx protect-mcp policy-packs list
npx protect-mcp policy-packs show secrets-safe
npx protect-mcp policy-packs install filesystem-safe --dir ./cedar
npx protect-mcp policy-packs install all --dir ./cedar
npx protect-mcp serve --cedar ./cedar
Paquetes integrados:
filesystem-safe: acciones destructivas de archivos y lecturas de rutas similares a secretos.git-safe: push forzados, resets duros, limpieza destructiva, eliminación de repositorios.email-safe: permitir borradores, bloquear envíos no supervisados.database-safe: postura de base de datos orientada a lectura, bloquear SQL de escritura/administración.cloud-spend-safe: creación obvia de gastos en la nube y destrucción de infraestructura.secrets-safe: exfiltración común de secretos de archivos, entorno, shell y nube.finance-mandate-safe: violaciones de listas restringidas y concentración en flujos de reserva.
Verificar un recibo
Los recibos están firmados y son verificables sin conexión por cualquiera con la clave pública. Sin red, sin proveedor, sin confianza en ScopeBlind:
npx @veritasacta/verify ./receipts/receipts.jsonl --format jsonl
# Exit 0 = valid, non-zero = tampered or malformed
npx protect-mcp bundle --output audit.json exporta un paquete de auditoría autocontenido y verificable sin conexión de tus recibos más la clave pública de firma.
Seguridad
protect-mcp 0.7.0 falla cerrado por diseño. Ante cualquier error de evaluación de política, un motor faltante o una política que falló en la evaluación, la decisión es DENEGAR, no permitir. serve --enforce y doctor ejecutan una autoprueba de arranque que demuestra que la puerta deniega un vector conocido como prohibido antes de que se confíe en ella, y se niegan a armar si no puede.
Versiones afectadas: 0.5.x y 0.6.x. Esas líneas fallan abiertas (devuelven PERMITIR en error de evaluación) y no evalúan Cedar correctamente contra el motor fijado, por lo que una regla forbid podría no bloquear. Actualiza a >= 0.7.0.
Detalles y remediación: GHSA-hm46-7j72-rpv9. Para reportar una vulnerabilidad, consulta SECURITY.md.
Comandos
| Comando | Descripción |
|---|---|
serve | Inicia el servidor de enganche HTTP para Claude Code (puerto 9377). --enforce ejecuta primero la autocomprobación de restricción; --cedar <dir> y --policy <path> seleccionan la política. |
init | Genera un par de claves Ed25519 (keys/gateway.json), una plantilla de configuración y una política de ejemplo. |
sample | Siembra un registro de muestra claramente etiquetado (8 decisiones: una llamada bloqueada, dos pagos; kid sample-demo) más una copia alterada, para que record, claim, verify-claim y anchor-record sean reproducibles desde cero antes de conectar un agente. Se niega a tocar un registro existente; --force lo anula. |
policy | Ver y cambiar la política Cedar desde la terminal: policy list (permitir / prohibir / denegar por defecto por herramienta, con la frecuencia con la que la puerta lo permitió o denegó), policy show, policy allow <tool>, policy deny <tool>, policy path. Un serve en ejecución se recarga en caliente con el cambio. |
wrap | Imprime un comando MCP protegido o parchea los servidores MCP de Claude Desktop. Simulación por defecto; usa --write para actualizar la configuración de Claude Desktop. |
dashboard | Inicia un panel solo local en 127.0.0.1 que muestra inventario de herramientas, riesgo, cobertura de políticas, aprobaciones de acciones exactas, cadenas de recibos y exportación de auditoría. |
recommend | Redacta una política JSON revisable a partir de llamadas locales observadas. Simulación por defecto; usa --write para crear protect-mcp.recommended.json. |
registry | Crea una identidad de organización, ancla resúmenes de recibos y escribe una página verificadora estática. El modo alojado sube solo los resúmenes. |
record | Abre un visor local y buscable sobre tus recibos (--live transmite mientras el agente se ejecuta): firmas Ed25519 verificadas en tu navegador contra tu clave de puerta de enlace, etiquetas de capacidad, un árbol de procedencia y exportación firmada con un clic. Todo local, nada se sube. |
claim | Acuña una atestación firmada y ciega a la posición de un predicado sobre el registro (--no <cap> incl. --no payment, --only <c1,c2>, --no-verdict <verdict>, --count <verdict>, --payment-under <cap>), revelando solo categorías de decisión. Agrega --anchor para registrar el resumen de la reclamación en el registro de transparencia público; las claves inscritas se anclan como una organización nombrada. |
anchor-record | Marca el punto de control de la raíz de Merkle del registro + recuento + rango de tiempo en el registro público (amigable con latidos: se omite cuando no cambia). Una reclamación posterior cuyo compromiso coincida con un punto de control anclado es demostrablemente sobre el registro completo a partir de ese punto de control. |
verify-claim | Verifica un paquete de reclamaciones sin conexión: firma, raíz de Merkle recalculada, predicado recalculado independientemente y el sidecar de anclaje cuando esté presente (vincula el sobre anclado a esta reclamación exacta, luego confirma que el registro público lo contiene). --check-anchor requiere el anclaje; --offline omite el salto de registro. |
killer-demo | Genera un paquete de demostración completo de modo sombra a política a aprobación a recibo firmado. |
verify-disclosure | Verifica un paquete scopeblind.selective_disclosure.v0 y explica los campos revelados versus los ocultos. |
policy-packs | Lista, inspecciona e instala paquetes de políticas Cedar de inicio. |
evaluate | Evalúa una llamada de herramienta contra una política Cedar (puerta PreToolUse). Salida 2 = denegar (fallo cerrado), salida 0 = permitir. |
sign | Firma una llamada de herramienta en un recibo (PostToolUse). Mejor esfuerzo: registra una línea honesta sin firmar si no hay clave. |
simulate | Simula una política contra un registro de decisiones grabado para ver qué habría bloqueado. |
demo | Inicia un servidor de demostración integrado envuelto con la puerta, para ver recibos al instante. |
doctor | Verifica tu configuración (claves, políticas, motor Cedar, verificador) y ejecuta la autocomprobación de restricción. |
bundle | Exporta un paquete de auditoría verificable sin conexión de recibos más la clave pública. |
report | Genera un informe de cumplimiento (Markdown o JSON) a partir del registro de decisiones y los recibos. |
Ejecuta npx protect-mcp --help para la referencia completa de banderas.
Enlaces
- Protocolo (IETF): draft-farley-acta-signed-receipts
- CHANGELOG
- npm
- scopeblind.com
Licencia MIT. Construido por ScopeBlind.
