approval-gate-mcp
approval-gate-mcp
Ein MCP-Server, der ein menschliches Genehmigungs-Gate vor einen langlaufenden autonomen Prozess schaltet, plus die betrieblichen Werkzeuge, die man braucht, um tatsächlich mit einem zu leben: Status, Logs, Neustart, Hot-Reload-Parameter und eine Zusammenfassung dessen, was er getan hat.
Erstellt mit FastMCP. Funktioniert mit jedem MCP-Client.
Das Problem
Ein Prozess, der eigenständig handelt, ist nützlich – bis eine seiner Aktionen folgenreich ist. Die üblichen Antworten sind beide schlecht. Schaltet man ihn ab, verliert man alles, was er gut gemacht hat. Lässt man ihn laufen, erfährt man es hinterher.
Das Tor ist eine dritte Option. Der Prozess läuft unbeaufsichtigt weiter, aber wenn er eine Aktion ausführen will, die du als folgenreich markiert hast, schreibt er einen Vorschlag und macht stattdessen weiter. Du prüfst Vorschläge, wann immer du dazu kommst, in welchem MCP-Client auch immer du gerade offen hast, und genehmigst oder lehnst ab. Der Prozess nimmt deine Entscheidung im nächsten Zyklus auf.
Keine Seite blockiert die andere. Es gibt keinen Dienst dazwischen. Der Vertrag besteht aus zwei JSON-Dateien.
process you
| |
|-- writes proposal ----> pending.json
| |
| list_pending_approvals
| approve(0) / reject(1)
| |
|<-- reads on next cycle -- approved.json
|
|-- acts, appends to records.jsonWerkzeuge
Genehmigungs-Gate
Tool | Was es tut |
| Jeden Vorschlag, der auf eine Entscheidung wartet, mit allen Feldern |
| Verschiebt einen Vorschlag in die Datei der Genehmigten |
| Verwirft einen Vorschlag |
Prozesssteuerung
Tool | Was es tut |
| Läuft oder nicht, PID, Laufzeit, CPU, Speicher, Festplatte, letzte Logzeile |
| Das Ende der Logdatei anzeigen |
| Neustart über dein Startskript, abgekoppelt, sodass es die SSH-Sitzung überlebt |
| Notausgang für einmalige Prüfungen |
Datensätze
Tool | Was es tut |
| Summen, erledigt gegenüber offen, Aufschlüsselung nach Typ, letzte Einträge |
| Breitere Tabellenansicht plus aktuell offene Datensätze und deren Risiko |
Parameter – nur registriert, wenn PARAMS_SCHEMA auf dein Manifest zeigt
Tool | Was es tut |
| Was diese Bereitstellung als einstellbar deklariert und was gerade überschrieben ist |
| Schreibt eine Überschreibung, validiert gegen dein Manifest |
| Entfernt eine Überschreibung oder alle |
Blockchain – nur registriert, wenn EVM_RPC_URL, WALLET_ADDRESS und TOKEN_CONTRACT gesetzt sind
Tool | Was es tut |
| Schreibgeschützter ERC-20- und nativer Kontostand für eine Überwachungsadresse. Es wird nichts signiert |
Installation
git clone https://github.com/WillyV347/approval-gate-mcp
cd approval-gate-mcp
pip install -r requirements.txt
cp .env.example .env # then edit itProbiere es im Inspector aus, bevor du es in einen Client einbindest:
fastmcp dev server.pyDann registriere es. Für einen Client, der eine JSON-Konfiguration liest:
{
"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"
}
}
}
}Es gibt keine Standardwerte für VPS_HOST, VPS_USER oder PROCESS_DIR. Der Server beendet sich mit einer klaren Meldung, wenn sie fehlen. Ein Überwachungswerkzeug, das stillschweigend auf einen vom Autor eingebauten Host zurückfällt, ist ein Fehler, also weigert sich dieses, zu raten.
Die Authentifizierung erfolgt über deine bestehende SSH-Einrichtung. Der Server ruft die System-ssh-Binärdatei auf, sodass Agenten, Hardware-Schlüssel und Passwortmanager, die einen Agenten bereitstellen, unverändert funktionieren. Er liest selbst nie einen privaten Schlüssel.
Den Vertrag, den dein Prozess implementiert
Du brauchst drei Dinge auf der Prozessseite. Keines davon erfordert eine Bibliothek.
1. Datensätze. An ein JSON-Array anhängen. Vier Schlüssel werden interpretiert, wenn sie vorhanden sind, und alles andere wird unverändert durchgereicht:
[
{
"id": "job-1041",
"record_type": "reindex",
"resolved": true,
"outcome": "win",
"cost": 4.25,
"result": 11.80,
"label": "nightly reindex, shard 3"
}
]2. Vorschläge. Wenn du im Genehmigungsmodus läufst, schreibe hierhin, anstatt zu handeln:
{
"proposals": [
{
"id": "job-1042",
"label": "reindex shard 7",
"action": "reindex",
"cost": 6.00,
"created_at": "2026-08-18T22:14:07Z"
}
]
}Jedes Feld, das du aufnimmst, wird angezeigt. Der Server hat kein Schema für Vorschläge und will auch keins.
3. Die Datei für Genehmigte abfragen. Lies bei jedem Zyklus approved.json, reagiere auf das, was da ist, und leere sie. Ungefähr:
approved = read_json(APPROVED_FILE) or {"proposals": []}
for proposal in approved["proposals"]:
execute(proposal)
write_json(APPROVED_FILE, {"proposals": []})Die Reihenfolge ist serverseitig beabsichtigt. Eine Entscheidung entfernt den Vorschlag aus pending.json, bevor in approved.json geschrieben wird. Der Fehlermodus einer halb abgeschlossenen Entscheidung ist also ein verworfener Vorschlag, niemals eine doppelte Aktion.
Parameter und warum es in diesem Repository keine gibt
Hot-Reload ist nur nützlich, wenn der Server weiß, was einstellbar ist. Und die Parameter einer einzelnen Bereitstellung in ein gemeinsames Werkzeug zu codieren, macht es zu einem Einzweck-Werkzeug. Du deklarierst deine also in einem Manifest und weist PARAMS_SCHEMA darauf:
{
"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" }
}Unterstützte Typen sind int, float, bool, str, dict und list. set_param wandelt um und validiert dagegen und lehnt alles ab, was sich nicht konvertieren lässt. Ohne Manifest werden die Parameterwerkzeuge einfach nicht registriert, was besser ist, als einen Schreibpfad ohne Prüfung bereitzustellen.
params.schema.json ist in der .gitignore eingetragen, denn deine Abstimmung ist deine Sache. params.schema.example.json wird als Ausgangspunkt mitgeliefert.
Lass deinen Prozess die Überschreibungsdatei beim Start lesen und bei jedem Zyklus, wenn du willst, dass Änderungen ohne Neustart greifen:
overrides = read_json(PARAMS_FILE) or {}
poll_interval = overrides.get("poll_interval_seconds", POLL_INTERVAL_DEFAULT)Beispielsitzung
> 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 12Die Ausgabe oben ist illustrativ.
Hinweise zur Sicherheit
run_commandführt beliebige Shell-Befehle auf dem entfernten Host aus. Es existiert, weil die Alternative sowieso das Öffnen eines Terminals ist, aber es ist das gefährlichste Werkzeug hier. Beschränke den SSH-Benutzer auf das, was er tatsächlich braucht, anstatt alles als Root auszuführen.wallet_balanceist schreibgeschützt und berührt nie einen Schlüssel. Wenn du es nicht konfigurierst, existiert es nicht.Nichts in diesem Repository speichert Anmeldedaten. RPC-URLs tragen Anbieterschlüssel im Pfad. Bewahre
EVM_RPC_URLalso in der Umgebung und außerhalb deiner Konfigurationsdateien auf.StrictHostKeyCheckingist aufaccept-newgesetzt: Unbekannte Hosts werden bei der ersten Verbindung vertraut, geänderte Hostschlüssel schlagen weiterhin fehl. Setze es aufyesund befüllleknown_hostsvorab, wenn du das strengere Verhalten willst.
Lizenz
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.
A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready
A paid remote MCP for hosted MCP server, built to return verdicts, receipts, usage logs, and audit-r
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/WillyV347/approval-gate-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server