approval-gate-mcp
approval-gate-mcp
Un servidor MCP que coloca una puerta de aprobación humana frente a un proceso autónomo de larga duración, además de las herramientas operativas que necesitas para convivir con él: estado, registros, reinicio, parámetros de recarga en caliente y un resumen de lo que ha hecho.
Construido con FastMCP. Funciona con cualquier cliente MCP.
El problema
Un proceso que actúa por sí solo es útil hasta que una de sus acciones tiene consecuencias. Las respuestas habituales son malas en ambos casos. Apágalo y pierdes todo lo que estaba haciendo bien. Déjalo correr y te enteras después.
La puerta es una tercera opción. El proceso sigue ejecutándose sin supervisión, pero cuando quiere realizar una acción que has marcado como trascendente, escribe una propuesta y continúa en lugar de actuar. Revisas las propuestas cuando puedas, en el cliente MCP que ya tengas abierto, y las apruebas o rechazas. El proceso recoge tu decisión en su siguiente ciclo.
Ninguno de los dos lados bloquea al otro. No hay ningún servicio intermedio. El contrato son dos archivos JSON.
process you
| |
|-- writes proposal ----> pending.json
| |
| list_pending_approvals
| approve(0) / reject(1)
| |
|<-- reads on next cycle -- approved.json
|
|-- acts, appends to records.jsonRelated MCP server: conduit-mcp
Herramientas
Puerta de aprobación
Herramienta | Qué hace |
| Cada propuesta pendiente de una decisión, con todos sus campos |
| Mueve una propuesta al archivo de aprobadas |
| Descarta una propuesta |
Control del proceso
Herramienta | Qué hace |
| En ejecución o no, PID, tiempo de actividad, CPU, memoria, disco, última línea de registro |
| Muestra las últimas líneas del archivo de registro |
| Reinicia mediante tu script de inicio, desacoplado para que sobreviva a la sesión SSH |
| Vía de escape para comprobaciones puntuales |
Registros
Herramienta | Qué hace |
| Totales, resueltos frente a abiertos, desglose por tipo, entradas recientes |
| Vista de tabla más amplia, además de los registros abiertos actualmente y su exposición |
Parámetros — registrados solo si PARAMS_SCHEMA apunta a tu manifiesto
Herramienta | Qué hace |
| Lo que este despliegue declara ajustable y lo que está sobrescrito en este momento |
| Escribe una sobrescritura, validada contra tu manifiesto |
| Elimina una sobrescritura, o todas ellas |
Cadena — registrados solo si EVM_RPC_URL, WALLET_ADDRESS y TOKEN_CONTRACT están todos configurados
Herramienta | Qué hace |
| Saldo ERC-20 y nativo de solo lectura para una dirección vigilada. No se firma nada. |
Instalación
git clone https://github.com/WillyV347/approval-gate-mcp
cd approval-gate-mcp
pip install -r requirements.txt
cp .env.example .env # then edit itPruébalo en el inspector antes de conectarlo a un cliente:
fastmcp dev server.pyLuego regístralo. Para un cliente que lee una configuración JSON:
{
"mcpServers": {
"approval-gate": {
"command": "python3",
"args": ["/absolute/path/to/approval-gate-mcp/server.py"],
"env": {
"VPS_HOST": "your.host.or.ip",
"VPS_USER": "your-ssh-user",
"PROCESS_DIR": "/srv/my-process",
"PROCESS_MATCH": "my_process.py",
"PARAMS_SCHEMA": "/absolute/path/to/params.schema.json"
}
}
}
}No hay valores predeterminados para VPS_HOST, VPS_USER ni PROCESS_DIR. El servidor se cierra con un mensaje claro si faltan. Una herramienta de supervisión que silenciosamente recurre a algún host fijado por su autor es un error, así que esta se niega a adivinar.
La autenticación es tu configuración SSH existente. El servidor invoca al binario ssh del sistema, por lo que los agentes, las claves de hardware y los administradores de contraseñas que exponen un agente funcionan sin cambios. Nunca lee una clave privada por sí mismo.
El contrato que implementa tu proceso
Necesitas tres cosas en el lado del proceso. Ninguna de ellas requiere una biblioteca.
1. Registros. Añade a un array JSON. Cuatro claves se interpretan si están presentes, y todo lo demás se transmite sin cambios:
[
{
"id": "job-1041",
"record_type": "reindex",
"resolved": true,
"outcome": "win",
"cost": 4.25,
"result": 11.80,
"label": "nightly reindex, shard 3"
}
]2. Propuestas. Cuando se ejecuta en modo de aprobación, escribe aquí en lugar de actuar:
{
"proposals": [
{
"id": "job-1042",
"label": "reindex shard 7",
"action": "reindex",
"cost": 6.00,
"created_at": "2026-08-18T22:14:07Z"
}
]
}Cada campo que incluyas se muestra. El servidor no tiene un esquema para las propuestas y no quiere tenerlo.
3. Consulta el archivo de aprobadas. En cada ciclo, lee approved.json, actúa sobre lo que hay y límpialo. A grandes rasgos:
approved = read_json(APPROVED_FILE) or {"proposals": []}
for proposal in approved["proposals"]:
execute(proposal)
write_json(APPROVED_FILE, {"proposals": []})El orden es deliberado en el lado del servidor. Una decisión elimina la propuesta de pending.json antes de escribir en approved.json, por lo que el modo de fallo de una decisión a medio completar es una propuesta descartada, nunca una acción duplicada.
Parámetros, y por qué no hay ninguno en este repositorio
La recarga en caliente solo es útil si el servidor sabe qué es ajustable, y codificar los parámetros de un despliegue en una herramienta compartida la hace de un solo propósito. Así que declaras los tuyos en un manifiesto y apuntas PARAMS_SCHEMA a él:
{
"poll_interval_seconds": { "type": "int", "description": "Seconds between work cycles" },
"max_concurrent_jobs": { "type": "int", "description": "Jobs in flight at once" },
"dry_run": { "type": "bool", "description": "Plan work but do not execute" },
"approval_mode": { "type": "bool", "description": "Queue proposals instead of acting" }
}Los tipos admitidos son int, float, bool, str, dict y list. set_param convierte y valida contra esto y rechaza cualquier cosa que no se pueda convertir. Sin un manifiesto, las herramientas de parámetros simplemente no se registran, lo cual es mejor que exponer una ruta de escritura sin nada contra lo que verificarla.
params.schema.json está en gitignore, porque tu ajuste es tuyo. params.schema.example.json se incluye como punto de partida.
Haz que tu proceso lea el archivo de sobrescrituras al inicio, y en cada ciclo si quieres que los cambios se apliquen sin reiniciar:
overrides = read_json(PARAMS_FILE) or {}
poll_interval = overrides.get("poll_interval_seconds", POLL_INTERVAL_DEFAULT)Sesión de ejemplo
> is it running?
Process RUNNING
PID: 31882
Uptime: 14h 22m (51720s)
CPU: 0.6%
Memory: 84.3 MB
Disk: 212M
Last log: 2026-08-18 22:03:11 cycle complete, 2 proposals queued
> anything waiting on me?
2 proposal(s) awaiting approval
--- Proposal #0 ------------------------------
id: job-1042
label: reindex shard 7
action: reindex
cost: 6.00
created_at: 2026-08-18T22:14:07Z
--- Proposal #1 ------------------------------
id: job-1043
label: reindex shard 12
action: reindex
cost: 6.00
created_at: 2026-08-18T22:14:07Z
Use approve(index) or reject(index) to decide.
> approve 0, reject 1
Approved and queued for execution: reindex shard 7
Rejected and removed: reindex shard 12La salida anterior es ilustrativa.
Notas sobre seguridad
run_commandejecuta comandos de shell arbitrarios en el host remoto. Existe porque la alternativa es abrir una terminal de todos modos, pero es la herramienta más peligrosa aquí. Limita el usuario SSH a lo que realmente necesita en lugar de ejecutar todo como root.wallet_balancees de solo lectura y nunca toca una clave. Si no lo configuras, no existe.Nada en este repositorio almacena una credencial. Las URL RPC llevan claves de proveedor en la ruta, así que mantén
EVM_RPC_URLen el entorno y fuera de tus archivos de configuración.StrictHostKeyCheckingestá configurado enaccept-new: los hosts desconocidos se consideran de confianza en la primera conexión, las claves de host cambiadas aún fallan. Configúralo enyesy rellena previamenteknown_hostssi quieres el comportamiento más estricto.
Licencia
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Self-hosted MCP server: 26 deterministic dev, security, and EVM tools.
A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server that enforces governance on agentic decisions with auditable evidence records, providing tools for understanding, calibrating confidence, and navigating handoffs based on policy.-
- AlicenseNot gradedqualityCmaintenanceA governance-layer MCP server that gates AI writes to systems of record, requiring human signatures and providing a tamper-evident audit trail. It offers read, propose, approve, commit, and audit tools, with demo and Xero backends.69 npmMIT
- AlicenseNot gradedqualityCmaintenanceMCP server that provides human-in-the-loop approval for risky AI agent actions, with durable state and audit logs.MIT
- AlicenseNot gradedqualityAmaintenanceMCP server that adds a trust layer to AI agent memory, enforcing independent review and tamper-evident audit chains for any memory store. It provides tools to search, get, propose, and promote memories under governance rules.37 PyPIMIT