vanth
vanth
Ereignisgesteuerte Hintergrundjobs für Agenten.
Vanth ist ein lokaler Hintergrundjob-Daemon mit einer Model Context Protocol (MCP)-Schnittstelle.
Er führt abgekoppelte, nicht-interaktive Shell-Befehle aus, erfasst deren Ausgaben dauerhaft, parst optionale strukturierte AGENT_EVENT-Ereignisse in Fortschrittsbalken, Metrikreihen und Prüfpunkte und kann eine Codex- oder OpenCode-Sitzung wecken, wenn ein Job Aufmerksamkeit benötigt. Er ist für einen vertrauenswürdigen Benutzer auf einem Rechner konzipiert.
Beliebige Befehle: Downloads, Bild-/Audioverarbeitung, ETL, ML-Training – wenn es in einer Shell läuft, kann Vanth es abgekoppelt ausführen und verfolgen.
Dauerhaft: Jobs und Ereignisse leben in SQLite (
WAL, Busy-Timeout) und überstehen Daemon-, MCP- und Maschinenneustarts.Ereignisorientiert: Agenten
job_waitauf sinnvolle Ereignisse, anstatt Protokolle abzufragen.Aufmerksamkeitsweckung: Dauerhafte Zustellungen mit mindestens einmaliger Auslieferung setzen einen Codex-Thread oder eine OpenCode-Sitzung fort, wenn ein Job einen Menschen oder Agenten benötigt.
Terminal-Dashboard: Der native Go-Monitor
monitorrendert ein Live-Dashboard im W&B-LEET-Stil mit Jobs, Metriken und Diagrammen.
Nicht im Fokus für v1: Fernzugriff, TLS, Multi-User-Mandantenfähigkeit/RBAC, Kontingente, interaktive Standardeingabe und eine Weboberfläche.
Für Agenten: Starten Sie Arbeit mit job_start, dann job_wait für progress/checkpoint/completed-Ereignisse anstatt zu pollend; lassen Sie Jobs AGENT_EVENT-Zeilen (siehe unten) ausgeben, damit Fortschritt, Metriken und Prüfpunkte live im vanth-monitor-Dashboard erscheinen; und lassen Sie lange Jobs Sie über Weckziele fortsetzen, anstatt dass Sie selbst nach dem Rechten sehen.
Schnellstart
Installation (erfordert uv; läuft auf Python 3.11+):
uv tool install vanthDies installiert den MCP-Server vanth, den Daemon vanthd, das vanth-monitor und die Ops-CLI als eigenständige Werkzeuge (das Wheel bündelt den nativen Go-Monitor, daher wird keine Go-Toolchain benötigt).
Aus einem Quellcode-Checkout (Entwicklung):
git clone https://github.com/abhim-dv/vanth.git && cd vanth
uv syncStarten Sie den Daemon (halten Sie dieses Terminal offen):
uv run vanthdStarten Sie in einem zweiten Terminal einen verfolgten Job über den MCP-Server:
uv run vanthoder verwenden Sie die Werkzeuge direkt von einem MCP-Client aus (siehe MCP-Integration).
Überprüfen Sie, ob alles gesund ist:
job_doctor()Durchgängig: einen verfolgten Job ausführen
Sobald der MCP-Client verbunden ist, ist dies die gesamte Schleife:
job_start(
command="uv run python examples\\long_job.py",
name="demo run",
notify_on=["checkpoint", "failed", "completed"],
)
# -> job_<id>
job_wait(job_id="job_<id>", filters=["checkpoint"], timeout_seconds=120)
# -> returns the first checkpoint event + current status
job_wait(job_id="job_<id>", filters=["completed", "failed"], timeout_seconds=300)
# -> returns the terminal event + exit codeUnd in einem dritten Terminal sehen Sie live zu:
uv run vanth-monitorBefehlszeilen-Einstiegspunkte
Befehl | Zweck |
| MCP-Stdio-Server (Brücke zum Daemon); auch |
| Der Hintergrund-HTTP-Daemon |
| Live-Terminal-Dashboard (Go-Binärdatei, im Wheel gebündelt) |
| Zustellungsadapter: liest eine Wecknutzlast von stdin, leitet sie an Codex weiter |
Operations-CLI
uv run vanth status # is the daemon up? pid, schema, running jobs, deliveries
uv run vanth status --json # machine-readable version
uv run vanth doctor # full health report (same as job_doctor, human-readable)
uv run vanth restart # gracefully stop + start the daemon (jobs survive)
uv run vanth setup # register the MCP server in your clients' configs
uv run vanth setup --remove # unregister itvanth restart ist die zuverlässige Methode, um ein Code-/Versionsupdate zu übernehmen: Es sendet dem Daemon eine sanfte Herunterfahr-Anfrage über Loopback, wartet, bis der alte Prozess die Heimsperre vollständig freigegeben hat, und startet dann einen neuen Daemon. Laufende Jobs gehören zu abgekoppelten Ausführenden, daher laufen sie über den Neustart hinweg weiter.
Related MCP server: Background Process MCP
Funktionsweise
MCP client / HTTP client
|
v
vanthd (localhost HTTP daemon, bearer-token auth)
| | |
| | +---> wake adapters
| | (local_command / codex_thread / opencode_thread)
| |
| +----> jobs.sqlite (durable source of truth)
|
+----> vanth.runner (detached worker process)
|
+----> your command (own process group)
|
+----> stdout/stderr -> logs/ + AGENT_EVENT parsingEigentumsregeln:
der Ausführende besitzt den eigentlichen Befehl, sein Timeout und das Stream-Draining;
der Daemon besitzt Wartung, Zustellungsversand, API-Anfragen und Wiederherstellung;
SQLite ist die Quelle der Wahrheit über Prozessneustarts hinweg;
die MCP- und HTTP-Clients müssen niemals am Leben bleiben, damit Jobs fortgesetzt werden können.
Ein Job gilt erst dann als abgeschlossen, wenn beide Ausgabeströme das EOF erreicht haben und alle strukturierten Ereignisse persistiert wurden.
Job-Lebenszyklus
Ein Job durchläuft eine kleine Menge von Zuständen. Endzustände sind dauerhaft.
Zustand | Bedeutung |
| Arbeitslast gestartet; Ausführender streamt Ausgabe und sendet Heartbeats |
| Befehl mit Exit-Code 0 beendet, Ströme geleert, Ereignisse persistiert |
| Befehl mit Exit-Code ungleich 0 beendet |
| Befehl hat |
|
|
| Ausführender unerwartet gestorben (Absturz); niemals stillschweigend fallen gelassen |
Der Ausführende setzt timeout_seconds auch über Daemon-Neustarts hinweg durch. Bei der Wiederherstellung wird ein running-Job, dessen Ausführender verschwunden ist, als cancelled (wenn ein Stopp angefordert wurde) oder orphaned (wenn nicht) markiert – niemals als Zombie-running-Zeile belassen.
Installation des MCP-Servers
vanth ist der MCP-Stdio-Server. Er kommuniziert mit dem Daemon und startet ihn bei erster Verwendung automatisch, falls er noch nicht läuft.
Einmalige Einrichtung
Nach der Installation des Werkzeugs verbinden Sie es in einem einzigen Schritt mit den MCP-Clients auf Ihrem Rechner:
uv tool install vanth
vanth setupvanth setup erkennt Ihre installierten Clients (opencode, Codex und generische mcpServers-Clients wie Claude Code / Cursor), zeigt an, was gefunden wurde, sichert jede Konfiguration vor dem Bearbeiten (.vanth-setup-<ts>.bak) und fügt den Vanth-MCP-Eintrag ein oder aktualisiert ihn – dabei bleiben alle anderen Einstellungen und Kommentare unberührt.
vanth setup # detect + configure everything found (prompts)
vanth setup --yes # apply without prompting (scripts/CI)
vanth setup opencode codex # only specific clients
vanth setup --json # machine-readable result
vanth setup --remove # remove the Vanth MCP entries insteadKonfigurationen, die verwaltet werden:
Client | Datei | Abschnitt |
opencode |
|
|
Codex |
|
|
Claude Code / Cursor |
|
|
Manuell sehen die gleichen Einträge wie folgt aus:
opencode
Fügen Sie zu ~/.config/opencode/opencode.json hinzu:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"vanth": {
"type": "local",
"command": ["vanth"],
"enabled": true,
"timeout": 15000
}
}
}Verwenden Sie bei einem Quellcode-Checkout uv direkt anstelle eines nackten vanth:
{
"mcp": {
"vanth": {
"type": "local",
"command": ["uv", "run", "--directory", "/path/to/vanth", "vanth"],
"enabled": true,
"timeout": 15000
}
}
}Überprüfen Sie die Verbindung und die Werkzeuge:
opencode mcp listClaude-artige MCP-Clients (mcpServers)
Veröffentlichtes Wheel:
{
"mcpServers": {
"vanth": { "command": "vanth", "env": { "VANTH_HOME": "C:/Users/you/.vanth" } }
}
}Bei einem Quellcode-Checkout:
{
"mcpServers": {
"vanth": {
"command": "uv",
"args": ["--directory", "/path/to/vanth", "run", "vanth"],
"env": { "VANTH_HOME": "C:/Users/you/.vanth" }
}
}
}Konfiguration des Daemon-Heimverzeichnisses
Sowohl der MCP-Server als auch der Daemon lösen das gleiche Zustandsstammverzeichnis aus VANTH_HOME auf (Standard %USERPROFILE%\.vanth unter Windows, ~/.vanth unter Unix; AGENT_BG_HOME wird als Alias akzeptiert). Wenn beide gesetzt sind, müssen sie auf dasselbe Verzeichnis verweisen.
Instrumentierung von Jobs mit agent_event
Jedes Python-Skript kann strukturierte Ereignisse an stdout (oder stderr) ausgeben, die Vanth parst und der Monitor grafisch darstellt. Dies ist optional – einfache Skripte laufen und protokollieren weiterhin –, aber es macht aus einem Job ein erstklassiges verfolgtes Objekt.
from vanth.agent_events import agent_event, progress
# A checkpoint: something meaningful happened.
agent_event("checkpoint", "epoch complete", epoch=10, val_loss=0.42)
# A progress update: drives the progress bar and progress.* plots.
progress(10, 100, unit="epoch", stage="train", message="10/100 epochs")
# Arbitrary scalar metrics: become their own line plots.
agent_event("metric", _step=10, loss=0.42, acc=0.88, mbps=12.4)Hinweise:
Der Helfer gibt
AGENT_EVENT {json}mitflush=Trueaus (Flush ist wichtig);progress(current, total, unit=..., stage=...)berechnetpercentfür Sie;metric-Nutzlasten: numerische Felder werden zu Reihen;_step(falls vorhanden und numerisch) ist die x-Achse, andernfalls wird die Ereignis-Sequenznummer verwendet; Schlüssel, die mit_beginnen (außer_step), werden ignoriert; boolesche Werte sind keine Metriken; NaN/Infinity/Null-Werte werden übersprungen und im Warnungsabzeichen des Monitors gezählt;jedes andere Feld (z. B.
file,stage,phase) wird beibehalten und in der Ereignistabelle sichtbar.
Beispiel: ein verfolgter Downloader
# downloader.py
import os
from vanth.agent_events import agent_event, progress
files = ["a.bin", "b.bin", "c.bin"]
total = sum(os.path.getsize(f) for f in files)
done = 0
for f in files:
agent_event("checkpoint", f"starting {f}", file=f)
# ... download f ...
done += os.path.getsize(f)
progress(done, total, unit="bytes", stage="download",
message=f"{done}/{total} bytes")Beispiel: eine Bildverarbeitungs-Batch
from vanth.agent_events import agent_event, progress
images = list(find_images("input/"))
for i, img in enumerate(images, 1):
out = process(img) # resize, denoise, ...
agent_event("metric", _step=i, sharpness=out.sharpness, size_mb=out.size_mb)
progress(i, len(images), unit="images", stage="process", message=img.name)Zeitgestempeltes, abgestuftes Logging mit loguru
Vanth liefert einen loguru-Wrapper mit, der jeden Eintrag in eine strukturierte AGENT_EVENT-Logzeile umleitet, sodass Protokolle als zeitgestempelte, stufenbewusste Ereignisse in der Ereignistabelle erscheinen (mit dem Stufenabzeichen und genauen Zeitstempeln) anstelle von nacktem Text:
from vanth.agent_logger import logger, log_with_context
logger.info("training started", lr=8e-5, batch_size=8) # event type "log", level info
logger.warning("low disk", free_gb=2.5)
log_with_context("error", "failed to load checkpoint", path="best.pt")Jeder Aufruf gibt AGENT_EVENT {"type":"log","level":"info","message":"...","data":{...}} aus, was der Daemon als dauerhaftes Ereignis persistiert. data trägt zusätzlichen Kontext. Der Monitor zeigt diese in der Ereignistabelle zusammen mit metric/progress-Ereignissen an.
Werkzeugreferenz (alle 20 MCP-Werkzeuge)
Werkzeug | Zweck |
| Startet einen Befehl als abgekoppelten Job |
| Startet einen Job mit seinem ursprünglichen Befehl/Umgebung/Arbeitsverzeichnis/Zielen neu |
| Blockiert, bis ein passendes Ereignis (oder Timeout) eintritt – die bevorzugte Methode, um auf Jobs zu warten |
| Status, Befehl, Umgebung, Fortschritt, letztes Ereignis, Verknüpfungen, Tags eines Jobs |
| Letzte Jobs, filterbar nach |
| Agentenorientierte Zusammenfassungen, sortiert nach Aufmerksamkeitspriorität |
| Strukturierte Ereignisse eines Jobs (vorwärts über |
| Begrenzter stdout/stderr-Log-Auszug mit Byte-Offsets |
| Liest gespeicherte skalare Metrikreihen (Verlust, Genauigkeit, Fortschritt.Prozent, ...) |
| Vergleicht eine Metrik über mehrere Jobs hinweg (neuester/Mittelwert/Min/Max/Summe/Anzahl) |
| Ein Aufruf "Hat es funktioniert?" – Status, Laufzeit, Fortschritt, Metriken, Artefakte |
| Fügt einem Job ein Artefakt (Prüfpunkt, CSV, Ausgabe) hinzu |
| Listet Artefakte auf, die einem Job zugeordnet sind |
| Heruntersampelte Diagrammdatenansicht für beliebige Renderer |
| Weckzustellungen für einen Job, filterbar nach |
| Setzt manuell den Status einer Zustellung |
| Stellt eine fehlgeschlagene Zustellung erneut in die Warteschlange |
| Versuchs-/Leihverlauf einer Zustellung |
| Stoppt einen laufenden Job (beendet den Prozessbaum) |
| Daemon-Gesundheit, Schema, Tabellen, Binärverfügbarkeit |
| Trockenlauf oder echte Entfernung alter abgeschlossener Jobs |
job_start
job_start(
command="uv run python examples\\long_job.py",
name="training run",
cwd="F:\\git\\project", # optional
env={"CUDA_VISIBLE_DEVICES": "0"}, # optional
timeout_seconds=3600, # optional; None = no timeout
notify_on=["progress","checkpoint","failed","completed"],
origin_thread_id="019f...", # the agent thread that launched it
tags=["training","gpu"], # optional
wake_targets=[...] # optional, see below
)Gibt job_id, status, worker_pid und die Log-/Ereignispfade zurück.
job_status – sehen, was ein Job tut
job_status(job_id="job_...")Gibt Status, Befehl, Arbeitsverzeichnis, Umgebung, timeout_seconds, Notizen, Lauf (Autor, Hostname, Betriebssystem, Python-Version, CPU/GPU, Git-Repo/Branch/Commit), runtime_seconds, Fortschritt, letztes Ereignis, Thread-Verknüpfung, Tags und Exit-Code zurück. Dies ist der schnellste Weg für einen Agenten, um zu beantworten: "Was macht dieser Job?" – und spiegelt die Laufübersicht wider, die Sie für einen Lauf in W&B sehen würden.
Übergeben Sie notes="..." an job_start, um einen Lauf zu annotieren ("Was macht diesen Lauf besonders?"), was bei job_rerun erhalten bleibt und im Monitor angezeigt wird.
job_rerun – einen fehlgeschlagenen Job neu starten
job_rerun(job_id="job_...")Startet den Job mit seinem ursprünglichen Befehl, Arbeitsverzeichnis, Umgebung, Timeout, Namen, Tags, Ursprungs-Thread und Weckzielen neu – eine neue job_id wird zurückgegeben. Verwenden Sie es, um einen fehlgeschlagenen Download, eine fehlerhafte Verarbeitungs-Batch oder einen vorübergehenden Fehler zu wiederholen, ohne die Anfrage neu zu konstruieren.
job_list – nach Name oder Tag filtern
job_list(status=["running"], name="train", tags=["gpu"], limit=20)Filter: status (Liste), thread_id, name (Teilzeichenkette), tags (muss alle aufgelisteten Tags enthalten).
job_events – vorwärts oder neueste zuerst
job_events(job_id="job_...", since_event_id="evt_...", limit=20) # events after the cursor
job_events(job_id="job_...", reverse=true, limit=20) # the 20 newest events, newest firstreverse: true gibt die aktuellsten Ereignisse zurück (neueste zuerst) – ideal für "Was ist kürzlich passiert?" – und kann mit since_event_id kombiniert werden, um rückwärts zu blättern.
job_wait — das Herz der Agentennutzung
job_wait(job_id="job_...", filters=["checkpoint","failed","completed"], timeout_seconds=3600)wartet auf das erste Ereignis, das einem Filter entspricht, und gibt es mit dem aktuellen Status zurück;
übergebe
since_event_id, um nur auf Ereignisse zu warten, die neuer sind als eines, das du bereits gesehen hast;bei Zeitüberschreitung wird
result: "timeout"zurückgegeben; bei Daemon-Herunterfahren wirdresult: "shutdown"zurückgegeben.
job_view — was dem Benutzer angezeigt werden soll
job_view(thread_id="019f...", limit=20)Gibt kompakte Zusammenfassungen zurück, sortiert nach Aufmerksamkeitspriorität: laufende und fehlgeschlagene Jobs zuerst, dann Jobs mit ausstehenden/fehlgeschlagenen Zustellungen, dann alles andere. Jeder Eintrag enthält Status, Fortschritt, das letzte Ereignis, Thread-Verknüpfung, Tags und Zustellungsanzahlen.
job_stop — einen laufenden Job stoppen
job_stop(job_id="job_...", signal="terminate", kill_after_seconds=10)Beendet den Prozessbaum des Jobs. Zuerst wird ein sanftes signal (Standard terminate) gesendet; wenn der Job nicht innerhalb von kill_after_seconds beendet wurde, wird er gekillt. Der Job wird erst dann cancelled, wenn der Arbeitslastbaum tatsächlich beendet wurde; andernfalls bleibt er running und der Stopp ist wiederholbar.
job_mark_delivery / job_retry_delivery — manuelle Zustellungskontrolle
job_mark_delivery(delivery_id="del_...", status="delivered", error="optional reason")
job_retry_delivery(delivery_id="del_...") # requeue a failed deliveryjob_mark_delivery setzt den Status einer Zustellung manuell (z.B. nach Behebung eines Adapterproblems); job_retry_delivery stellt eine fehlgeschlagene Zustellung für den nächsten Versanddurchlauf erneut in die Warteschlange. job_delivery_attempts zeigt die Claim/Lease-Historie.
job_cleanup — alte terminale Jobs entfernen
job_cleanup(older_than_seconds=86400, dry_run=true) # preview
job_cleanup(older_than_seconds=86400, dry_run=false) # deleteEntfernt terminale Jobs, die älter als der Grenzwert sind: Logs, Ereignisspiegel, Spezifikationen, Zustellungen, Versuche, Wake-Ziele, Ereignisse, dann die Job-Zeile. Laufende Jobs werden nie ausgewählt. Der Trockenlauf ist vollständig schreibgeschützt. Die Bereinigung kann sicher wiederholt werden.
job_metrics_query — gespeicherte skalare Reihen lesen
job_metrics_query(job_id="job_...", metric="loss", from_ms=..., to_ms=..., limit=1000)Gibt die gespeicherten Reihen für einen Job zurück, gruppiert nach Metrikname. metric filtert auf eine einzelne Reihe (z.B. loss, acc, progress.percent); from_ms/to_ms filtern nach Ereigniszeitstempel (Epochen-Millisekunden). Punkte sind nach Ereignissequenz geordnet. Dies ist die Leseseite der Daten des Terminal-Monitors.
job_metric_compare — eine Metrik über Läufe hinweg vergleichen
job_metric_compare(job_ids=["job_a", "job_b"], metric="val_loss", aggregation="min")Vergleicht eine Metrik über Jobs hinweg (z.B. val_loss über Seeds oder Konfigurationen). aggregation ist latest, mean, min, max, sum oder count; das Ergebnis enthält den Wert pro Job plus die ersten/letzten Punkte. Dies ist das W&B-artige „Welcher Lauf hat gewonnen?"-Primitiv.
job_run_summary — hat es funktioniert?
job_run_summary(job_id="job_...")Ein Aufruf gibt Status, Name, Laufzeit, Exit-Code, aktuellsten Fortschritt, Notizen, eine Übersicht pro Metrik (aktuellster/erster/min/max/Anzahl) und angehängte Artefakte zurück – der schnellste Weg für einen Agenten, über einen abgeschlossenen Job zu berichten.
job_artifact_add / job_artifacts — Ausgaben anhängen
job_artifact_add(job_id="job_...", name="best.pt", uri="file:///...", kind="checkpoint",
size_bytes=..., sha256="...", meta={"epoch": 5})
job_artifacts(job_id="job_...")Hängt Artefakte (Checkpoints, CSVs, gerenderte Ausgaben) an einen Job an, sodass sie in job_run_summary aufgelistet und später abrufbar sind. meta ist frei formatiertes JSON.
job_dashboard — Diagrammdaten für jeden Renderer
job_dashboard(job_ids=["job_..."], limit=5000)Gibt die Jobliste plus jede gespeicherte Metrikreihe zurück, heruntergesampelt auf limit Punkte pro Reihe – dieselben Daten, die der Go-Terminal-Monitor diagrammiert, bereitgestellt über HTTP/MCP, sodass jeder Client (ein zukünftiges Web-/Cloud-Dashboard) sie rendern kann.
Wake-Ziele (einen Agenten wecken, wenn ein Job Aufmerksamkeit benötigt)
Wenn ein Job ein passendes Ereignis auslöst, erstellt der Daemon eine dauerhafte Zustellung und sendet sie über den Adapter. Die Zustellung erfolgt mindestens einmal; jede Nutzlast trägt eine delivery_id zur Deduplizierung.
local_command
Führt einen beliebigen Befehl aus und übergibt die Zustellungsnutzlast als JSON auf stdin:
{
"type": "local_command",
"events": ["checkpoint", "failed", "completed"],
"command": ["python", "deliver.py"]
}Exit 0 markiert die Zustellung als delivered; jeder andere Exit markiert sie als failed.
codex_thread
Setzt einen Codex-Thread über den lokalen App-Server fort:
{
"type": "codex_thread",
"thread_id": "019f...",
"events": ["checkpoint", "failed", "completed"],
"codex_command": ["C:\\codex\\codex.exe"]
}Protokoll: initialize -> thread/resume -> turn/start.
opencode_thread
Setzt eine OpenCode-Sitzung fort:
{
"type": "opencode_thread",
"thread_id": "ses_...",
"events": ["checkpoint", "failed", "completed"],
"cwd": "F:\\git\\project",
"opencode_command": ["opencode"], # override the binary
"attach": "http://127.0.0.1:4096", # submit via an opencode serve instance
"timeout_seconds": 120
}Das Standard-Timeout für OpenCode-Turns beträgt 30 Sekunden; erhöhe es für lange Turns.
Gemeinsame Zustellungsoptionen
{
"type": "codex_thread",
"thread_id": "019f...",
"events": ["checkpoint"],
"auto_dispatch": false, // leave the delivery pending for manual inspection
"max_attempts": 3, // default 1
"retry_delay_seconds": 5, // default 5
"timeout_seconds": 30 // adapter timeout; also sizes the delivery lease
}Mit auto_dispatch: false bleiben Zustellungen pending, bis ein Agent sie entweder manuell versendet oder das Ziel ändert.
Zustellungsoperationen
job_deliveries(job_id="job_...")
job_delivery_attempts(delivery_id="del_...")
job_retry_delivery(delivery_id="del_...") # requeue a failed delivery
job_mark_delivery(delivery_id="del_...", status="delivered")Die Versuchshistorie zeichnet den Claim-Token, Start-/Endzeiten, Status und ob der Versuch nach Ablauf eines Leases zurückgefordert wurde. Wenn der Daemon abstürzt, nachdem ein Adapter einen Wake akzeptiert hat, aber bevor Vanth den Erfolg aufzeichnet, wird die Zustellung zurückgefordert und erneut versucht – als reclaimed-Versuch angezeigt, anstatt als Exactly-Once-Zustellung beansprucht.
Den Daemon ausführen
Vordergrund (für Entwicklung oder Diagnose):
uv run vanthdOptionen für den Start bei der Anmeldung:
Windows: Der Daemon wird aus dem Benutzer-Startup-Ordner (
startup_commands.bat) zusammen mit anderen Startbefehlen gestartet; eine Taskplaner-Aktionsvorlage befindet sich ebenfalls indeploy/vanthd.cmd.Unix:
deploy/vanthd.serviceist ein systemd-Benutzerdienst.
Aktiviere nur einen Daemon pro VANTH_HOME. Ein zweiter Daemon für dasselbe Home beendet sich sofort (OS-Level-Sperre). Der Daemon bindet nur an Loopback (127.0.0.1 / ::1 / localhost); ein Nicht-Loopback-VANTH_DAEMON_HOST wird abgelehnt.
Sicherheit
Jeder Datenpfad erfordert
Authorization: Bearer <token>; der Token wird pro Home generiert und nie protokolliert.GET /healthist die einzige nicht authentifizierte Route (eine günstige Lebendigkeitssonde für Supervisoren).Beim Daemon-Start wird das Zustandsverzeichnis erneut auf den Eigentümer eingeschränkt: Unix
chmod 0700/0600; Windows deaktiviert die ACL-Vererbung und gewährt nur dem Eigentümer, SYSTEM und Administratoren übericaclsZugriff. Dies blockiert andere Konten (z.B. Sandbox/CI-Benutzer, die Leseberechtigung vom Benutzerprofil erben) daran, den Token oder die Umgebungs-/Spezifikationsdaten pro Job zu lesen.Unter Windows ist der Socket
SO_REUSEADDRdeaktiviert, sodass ein zweiter Daemon nicht zu einem Phantom-Listener auf demselben Port werden kann; ein fehlgeschlagenes Bind gibt die Home-Sperre frei und beendet sich sauber.
Der Go-Terminal-Monitor
Das native Go-Dashboard liest dasselbe Home schreibgeschützt und rendert Live-Diagramme, Fortschrittsbalken, die genaue Ereignistabelle und Log-Enden:
uv run vanth-monitorVon einem gebauten Wheel aus führt vanth-monitor die gebündelte native Binärdatei aus (kein Go-Toolchain erforderlich). Von einem Source-Checkout aus baut es den Monitor bei der ersten Verwendung und speichert ihn unter ~/.cache/vanth/ zwischen (erfordert go im PATH):
go build -o bin\vanth.exe ./cmd\vanth
bin\vanth.exe monitorTasten: up/down oder j/k wählen Jobs aus · enter fixiert die Reihe eines Jobs · e Ereignistabelle · l Log-Ende · +/- Diagramm zoomen · [/] schwenken · t zurück zum Live-Ende · ? Hilfe · q oder Ctrl+C beenden.
Konfigurationsreferenz
Umgebungsvariablen (Standardeinstellungen befinden sich in src/vanth/server.py, src/vanth/daemon.py, src/vanth/migrations.py):
Variable | Standard | Zweck |
|
| Zustandsstammverzeichnis (Alias: |
|
| Wo Clients den Daemon erreichen |
|
| Bind-Adresse (nur Loopback) |
|
| Bind-Port |
|
| HTTP-Anfragekörper-Obergrenze |
|
| HTTP-Antwort-Obergrenze |
|
| Einzelereignis-Nutzlast-Obergrenze |
|
| AGENT_EVENT-Zeilen-Obergrenze |
|
| Pro-Stream-Log-Obergrenze (Drain läuft weiter) |
|
| Strukturierte Ereignis-Obergrenze pro Job |
|
| Wartungsschleifen-Takt |
|
| Zusätzliche Lease-Zeit über Adapter-Timeout hinaus |
|
| Lebendigkeits-Herzschlag des Runners |
|
| Herzschlag-Veraltungsschwelle |
|
| Codex-Binärdatei |
|
| OpenCode-Binärdatei |
|
| Daemon-Log-Level |
|
| Rotierende Daemon-Log-Größe |
|
| Daemon-Log-Rotationsanzahl |
|
| SQLite-Schreibsperr-Wartezeit |
Betrieb
Zustandslayout
~/.vanth/
jobs.sqlite durable jobs (incl. env, notes, run-overview) / events / deliveries / targets / attempts / tombstones
token bearer token (owner-only permissions)
daemon.lock single-daemon OS lock
daemon.json discovery metadata (url, pid, started_at, schema) — written atomically, removed on graceful shutdown
logs/ daemon.log + per-job runner/stdout/stderr logs
events/ per-job JSONL event mirrors (monitor fallback source)
specs/ per-job launch specs (removed once the runner starts)
backups/ pre-migration SQLite backupsGesundheit, Bereitschaft und Diagnose
job_doctor()Meldet das Zustandsverzeichnis, Datenbanktabellen, Zustellungsanzahlen nach Status, Schema-Version, PRAGMA quick_check, veraltete Zustellungs-Leases, freien Speicherplatz, Token-Pfad und ob die Codex/OpenCode-Binärdateien aufgelöst werden. Es gibt niemals den Token preis.
Der HTTP-Daemon stellt außerdem bereit:
GET /health— günstige, nicht authentifizierte Lebendigkeitssonde für Supervisoren;GET /ready— authentifizierte Bereitschaft (Arztbericht; 503, wenn nicht in Ordnung).
Upgrades und Backups
Schemaänderungen sind geordnete SQLite-Migrationen. Vor der ersten Migration einer vorhandenen Datenbank wird ein zeitgestempeltes Backup unter backups/ über die SQLite-Backup-API geschrieben (niemals eine rohe Dateikopie, während WAL aktiv ist). Um manuell zu aktualisieren, kopiere zuerst das neueste backups/*.sqlite. Ein zukünftiges Datenbankschema wird abgelehnt, ohne die Dateien zu berühren.
HTTP-API (Äquivalent der MCP-Tools)
Authentifiziert mit Authorization: Bearer <token>.
Methode | Pfad | Zweck |
GET |
| Jobs auflisten ( |
POST |
| Einen Job starten |
POST |
| Einen Job mit seiner ursprünglichen Konfiguration erneut ausführen |
GET |
| Job-Status (enthält Befehl/Umgebung/Arbeitsverzeichnis) |
GET |
| Ereignisse ( |
GET |
| Metrikreihen ( |
GET |
| Ausführungszusammenfassung (Status, Laufzeit, Metriken, Artefakte) |
GET |
| Artefakte ( |
POST |
| Ein Artefakt hinzufügen |
GET |
| Metrik über Jobs hinweg vergleichen ( |
GET |
| Diagrammdaten ( |
GET |
| Log-Ende ( |
POST |
| Auf ein Ereignis warten |
POST |
| Einen Job stoppen |
GET |
| Agentenansicht ( |
GET |
| Zustellungen ( |
GET |
| Versuchshistorie |
POST |
| Eine Zustellung markieren |
POST |
| Eine Zustellung wiederholen |
POST |
| Bereinigung ( |
GET |
| Gesundheitsbericht |
GET |
| Nicht authentifizierte Lebendprüfung |
Tipps zur Agentennutzung
Warten, nicht abfragen. Verwenden Sie
job_wait(job_id, filters=[...], timeout_seconds=...)anstattjob_statusin einer Schleife. Der Daemon weckt den Wartenden sofort, sobald ein passendes Ereignis gespeichert wird.Übergeben Sie
since_event_idan den nächstenjob_wait, nachdem Sie ein Ereignis verarbeitet haben, damit Sie nie ein altes erneut verarbeiten.Taggen und Threaden Sie Ihre Jobs. Setzen Sie
origin_thread_id(den Agenten-Thread, der den Job gestartet hat) undtags; verwenden Siejob_view(thread_id=...)zur Zusammenfassung.Bevorzugen Sie
job_viewgegenüberjob_status, wenn Sie einem Benutzer eine Situation präsentieren – es ist bereits nach Aufmerksamkeitspriorität sortiert.Machen Sie Jobs selbsterklärend. Geben Sie
AGENT_EVENT progress/checkpoint/metric-Zeilen aus (siehe oben). Jobs, die still sind, funktionieren zwar auch, aber getrackte Jobs sind viel einfacher nachzuvollziehen.Verwenden Sie Weckziele für lange Jobs. Wenn ein Trainingslauf oder ein langer Download eine Entscheidung an einem Checkpoint benötigt, fügen Sie ein
codex_thread- oderopencode_thread-Ziel mitevents: ["checkpoint", "failed", "completed"]hinzu, damit der Agent fortgesetzt wird, anstatt abzufragen.Überprüfen Sie Zustellungsfehler.
job_delivery_attemptszeigt die Lease-/Claim-Historie;job_retry_deliverystellt einen fehlgeschlagenen nach Behebung der Ursache wieder in die Warteschlange.Setzen Sie ein sinnvolles
timeout_secondsbeijob_start, damit ein hängender Befehl in dentimeout-Zustand (terminal) übergeht, anstatt ewig zu laufen; der Runner erzwingt dies sogar über Daemon-Neustarts hinweg.Räumen Sie alte Zustände auf mit
job_cleanup(older_than_seconds=..., dry_run=false), damit der SQLite-Speicher und die Logdateien begrenzt bleiben.Führen Sie fehlgeschlagene Jobs erneut aus, bauen Sie sie nicht neu.
job_rerun(job_id=...)startet mit dem ursprünglichen Befehl, der Umgebung, dem Arbeitsverzeichnis und den Weckzielen neu – ideal, um einen vorübergehend fehlgeschlagenen Download oder Batch zu wiederholen.Fragen Sie „Was ist das für ein Job?“ mit
job_status. Es gibt jetzt den Befehl, das Arbeitsverzeichnis, die Umgebung und das Timeout zurück, sodass Sie einem Benutzer einen Job erklären können, ohne Logs zu lesen.Filtern Sie Listen nach Name/Tag.
job_list(name="train", tags=["gpu"])grenzt eine wachsende Jobliste ein, ohne alles durchzublättern.Verwenden Sie
reverse=truefür „Was ist kürzlich passiert?“.job_events(job_id, reverse=true, limit=20)gibt die neuesten Ereignisse zuerst zurück, und Sie können mitsince_event_idauf die älteste gesehene ID weiter zurückblättern.Ein Job überlebt den Daemon. Der Runner ist abgekoppelt; Jobs laufen über Daemon-/MCP-Neustarts hinweg weiter. Wenn ein Runner bei der Wiederherstellung fehlt, wird der Job als
orphanedmarkiert (niemals stillschweigend verworfen).
Beispiele
uv run python examples\long_job.py # emits progress + checkpointsexamples/long_job.py ist ein kleiner Referenzjob, der vanth.agent_events verwendet.
Starten Sie ihn über job_start und beobachten Sie ihn in vanth monitor.
Fehlerbehebung
Unauthorized(401): Das Bearer-Token in~/.vanth/tokenist das, was der Daemon erwartet. Stellen Sie sicher, dassVANTH_HOMEfür Daemon und Client gleich ist.Zweiter Daemon startet nicht:
another vanthd already owns this VANTH_HOME. Ein Daemon pro Home, wie vorgesehen.Job hängt in
runningund wird dannorphaned: Der Runner-Prozess ist gestorben. Überprüfen Sielogs/<job_id>.runner.logund die Heartbeat-Schwellenwerte.Keine Diagramme im Monitor: Der Job gibt keine
AGENT_EVENTmetric- oderprogress-Zeilen aus – fügen Sie sie hinzu (optional).OpenCode-Weck-Timeout: Erhöhen Sie
timeout_secondsim Weckziel über die erwartete Bearbeitungsdauer hinaus.Monitor zeigt nichts / leeren Zustand: Stellen Sie sicher, dass
VANTH_HOMEauf das Home des Daemons zeigt und dass dortjobs.sqliteexistiert.
Entwicklung
uv run pytest -q # Python suite (112 passed, 1 Linux-only skip)
uv run python -m compileall -q src tests examples
uv build # sdist + wheel; wheel bundles the Go monitor
go vet ./... && go test ./... # Go: config, state, monitorDer Wheel-Build führt einen Hatchling-Build-Hook (build-hooks/bundle_monitor.py) aus,
der den Go-Monitor für die Host-Plattform kompiliert und unter vanth/monitor-bin/
bündelt, sodass vanth-monitor zur Laufzeit keine Go-Toolchain benötigt. go muss
beim Bauen des Wheels im PATH sein; zum Installieren oder Ausführen wird es nicht
benötigt. Wheels sind plattformgetaggt (py3-none-<platform>), da sie das native
Binary enthalten.
Die Release-Gate-Automatisierung befindet sich in scripts/:
scripts/chaos_matrix.py– schwere synthetische Workloads und Kill-/Restart-Matrix;scripts/real_adapter_smoke.py– optionale Live-Codex/OpenCode-Weck-Smokes (setzen SieVANTH_SMOKE_CODEX_THREAD/VANTH_SMOKE_OPENCODE_SESSION);scripts/generate_go_fixture.py– generiert die deterministische Schema-v5- Konformitäts-Fixtur intestdata/neu;scripts/demo_jobs.py– startet Demo-Jobs (Trainingslauf, schnelle Aufgabe, fehlschlagende Aufgabe) für den Monitor.
Einschränkungen (v1)
Interaktives stdin und
job_sendsind nicht implementiert; Jobs laufen mit geschlossenem stdin (verwenden Sie nicht-interaktive Flags bei Befehlen).Die Zustellung erfolgt mindestens einmal; ein Absturz, nachdem ein Adapter einen Weckruf akzeptiert hat, aber bevor Vanth den Erfolg aufgezeichnet hat, ist eine dokumentierte, offengelegte Mehrdeutigkeit.
Fernzugriff, TLS, Mehrbenutzerrichtlinien, Kontingente, verteilte Worker und ein benutzerdefinierter Dienstmanager sind nicht im Umfang enthalten.
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 Servers
- AlicenseBqualityDmaintenanceEnables AI agents to launch, monitor, and manage long-running terminal processes with real-time log capture and search functionality. It features automatic log rotation and graceful process termination to ensure system stability.5445MIT
- Alicense-qualityDmaintenanceEnables LLMs to start, stop, and monitor long-running command-line processes in the background.3011MIT
- Flicense-qualityDmaintenanceEnables AI agents to efficiently manage and monitor background processes, with features like process startup, termination, log retrieval, and resource management.17
- Flicense-qualityBmaintenanceEnables AI agents to run commands, capture outputs, and manage background processes with filtering capabilities for debugging and monitoring.
Related MCP Connectors
Git-backed platform for skills, tools, and context for AI agents
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.
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/abhim-dv/vanth'
If you have feedback or need assistance with the MCP directory API, please join our Discord server