Skip to main content
Glama

vanth

에이전트를 위한 이벤트 기반 백그라운드 작업.

Vanth는 Model Context Protocol (MCP) 인터페이스를 갖춘 로컬호스트 백그라운드 작업 데몬입니다. 분리된 비대화형 셸 명령을 실행하고, 출력을 지속적으로 캡처하며, 선택적 AGENT_EVENT 구조화 이벤트를 진행률 표시줄, 메트릭 시리즈, 체크포인트로 파싱하고, 작업이 주의를 필요로 할 때 Codex 또는 OpenCode 세션을 깨울 수 있습니다. 하나의 신뢰할 수 있는 사용자와 하나의 머신을 위해 설계되었습니다.

  • 모든 명령: 다운로드, 이미지/오디오 처리, ETL, ML 학습 — 셸에서 실행된다면 Vanth는 분리하여 실행하고 추적할 수 있습니다.

  • 내구성: 작업과 이벤트는 SQLite (WAL, busy-timeout)에 저장되며 데몬, MCP, 머신 재시작에도 유지됩니다.

  • 이벤트 우선: 에이전트는 로그를 폴링하는 대신 의미 있는 이벤트를 job_wait합니다.

  • 주의 시 깨우기: 내구성 있는 최소 한 번 전달로 작업이 사람이나 에이전트를 필요로 할 때 Codex 스레드 또는 OpenCode 세션을 재개합니다.

  • 터미널 대시보드: 네이티브 Go monitor가 작업, 메트릭, 플롯의 실시간 W&B-LEET 스타일 대시보드를 렌더링합니다.

v1 범위 밖: 원격 네트워크 액세스, TLS, 다중 사용자 테넌시/RBAC, 할당량, 대화형 stdin, 웹 UI.

에이전트를 위한: job_start로 작업을 시작하고, 폴링 대신 progress/checkpoint/completed 이벤트를 job_wait하세요. 작업이 AGENT_EVENT 줄(아래 참조)을 방출하도록 하여 진행률, 메트릭, 체크포인트가 vanth-monitor 대시보드에 실시간으로 나타나게 하고, 긴 작업은 당신이 확인하는 대신 깨우기 대상을 통해 당신을 재개하도록 하세요.


Quick start

설치 (uv 필요; Python 3.11+에서 실행):

uv tool install vanth

이것은 vanth MCP 서버, vanthd 데몬, vanth-monitor, 그리고 ops CLI를 독립형 도구로 설치합니다 (휠은 네이티브 Go 모니터를 번들로 포함하므로 Go 툴체인이 필요하지 않습니다).

소스 체크아웃에서 (개발):

git clone https://github.com/abhim-dv/vanth.git && cd vanth
uv sync

데몬 시작 (이 터미널을 열어 두세요):

uv run vanthd

두 번째 터미널에서 MCP 서버를 통해 추적되는 작업을 시작하세요:

uv run vanth

또는 MCP 클라이언트에서 직접 도구를 사용하세요 (MCP 통합 참조).

모든 것이 정상인지 확인하세요:

job_doctor()

End-to-end: run a tracked job

MCP 클라이언트가 연결되면, 전체 루프는 다음과 같습니다:

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 code

그리고 세 번째 터미널에서 실시간으로 확인하세요:

uv run vanth-monitor

Command-line entry points

Command

Purpose

uv run vanth

MCP stdio 서버 (데몬에 대한 브리지); 또한 status / doctor / restart 하위 명령

uv run vanthd

백그라운드 HTTP 데몬

uv run vanth-monitor

실시간 터미널 대시보드 (Go 바이너리, 휠에 번들됨)

uv run vanth-codex-notify

전달 어댑터: stdin에서 깨우기 페이로드를 읽어 Codex로 전송

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 it

vanth restart는 코드/버전 업데이트를 적용하는 신뢰할 수 있는 방법입니다: 데몬에 루프백을 통해 정상 종료를 보내고, 이전 프로세스가 홈 잠금을 완전히 해제할 때까지 기다린 후, 새 데몬을 시작합니다. 진행 중인 작업은 분리된 러너가 소유하므로 재시작 중에도 계속됩니다.


Related MCP server: Background Process MCP

How it works

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 parsing

소유권 규칙:

  • 러너는 실제 명령, 타임아웃, 스트림 드레이닝을 소유합니다;

  • 데몬은 유지보수, 전달 디스패치, API 요청, 복구를 소유합니다;

  • SQLite는 프로세스 재시작 전반에 걸쳐 진실의 원천입니다;

  • MCP 및 HTTP 클라이언트는 작업이 계속되기 위해 살아 있을 필요가 없습니다.

작업은 두 출력 스트림이 모두 EOF에 도달하고 모든 구조화된 이벤트가 영구 저장될 때까지 종료된 것으로 간주되지 않습니다.

Job lifecycle

작업은 소수의 상태를 거칩니다. 종료 상태는 영구적입니다.

State

Meaning

running

워크로드 실행됨; 러너가 출력을 스트리밍하고 하트비트를 보내는 중

completed

명령이 0으로 종료됨, 스트림 드레이닝 완료, 이벤트 영구 저장됨

failed

명령이 0이 아닌 값으로 종료됨

timeout

명령이 timeout_seconds를 초과함; 러너가 종료시킴

cancelled

job_stop이 발행되었고 프로세스 트리가 실제로 종료됨

orphaned

러너가 예기치 않게 사망함 (크래시); 절대 조용히 삭제되지 않음

러너는 데몬 재시작에도 timeout_seconds를 적용합니다. 복구 시, 러너가 사라진 running 작업은 (중지가 요청된 경우) cancelled로 표시되거나 (그렇지 않은 경우) orphaned로 표시됩니다 — 절대 좀비 running 행으로 남지 않습니다.


Installing the MCP server

vanth는 MCP stdio 서버입니다. 데몬과 통신하며, 아직 실행 중이 아닌 경우 첫 사용 시 자동으로 시작합니다.

One-shot setup

도구를 설치한 후, 한 단계로 머신의 MCP 클라이언트에 연결하세요:

uv tool install vanth
vanth setup

vanth setup은 설치된 클라이언트(opencode, Codex, 그리고 Claude Code / Cursor와 같은 일반 mcpServers 스타일 클라이언트)를 감지하고, 찾은 내용을 표시하며, 각 구성을 건드리기 전에 백업하고 (.vanth-setup-<ts>.bak), Vanth MCP 항목을 업서트(upsert)합니다 — 다른 모든 설정과 주석은 그대로 둡니다.

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 instead

관리하는 구성:

클라이언트

파일

섹션

opencode

~/.config/opencode/opencode.json

mcp.vanth

Codex

~/.codex/config.toml

[mcp_servers.vanth]

Claude Code / Cursor

~/.claude.json

mcpServers.vanth

수동으로 동일한 항목은 다음과 같습니다:

opencode

~/.config/opencode/opencode.json에 추가:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "vanth": {
      "type": "local",
      "command": ["vanth"],
      "enabled": true,
      "timeout": 15000
    }
  }
}

소스 체크아웃에서는 vanth 대신 uv를 직접 사용하세요:

{
  "mcp": {
    "vanth": {
      "type": "local",
      "command": ["uv", "run", "--directory", "/path/to/vanth", "vanth"],
      "enabled": true,
      "timeout": 15000
    }
  }
}

연결 및 도구 확인:

opencode mcp list

Claude-style MCP clients (mcpServers)

게시된 휠:

{
  "mcpServers": {
    "vanth": { "command": "vanth", "env": { "VANTH_HOME": "C:/Users/you/.vanth" } }
  }
}

소스 체크아웃에서:

{
  "mcpServers": {
    "vanth": {
      "command": "uv",
      "args": ["--directory", "/path/to/vanth", "run", "vanth"],
      "env": { "VANTH_HOME": "C:/Users/you/.vanth" }
    }
  }
}

Configuring the daemon home

MCP 서버와 데몬 모두 VANTH_HOME에서 동일한 상태 루트를 확인합니다 (Windows에서는 기본값 %USERPROFILE%\.vanth, Unix에서는 ~/.vanth; AGENT_BG_HOME이 별칭으로 허용됩니다). 둘 다 설정된 경우 동일한 디렉터리로 확인되어야 합니다.


Instrumenting jobs with agent_event

모든 Python 스크립트는 Vanth가 파싱하고 모니터가 차트로 표시하는 구조화된 이벤트를 stdout(또는 stderr)으로 방출할 수 있습니다. 이는 선택 사항입니다 — 일반 스크립트도 여전히 실행되고 로그를 남깁니다 — 하지만 이것이 작업을 일급 추적 객체로 만드는 것입니다.

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)

참고:

  • 헬퍼는 flush=TrueAGENT_EVENT {json}을 출력합니다 (flush가 중요합니다);

  • progress(current, total, unit=..., stage=...)percent를 계산해 줍니다;

  • metric 페이로드: 숫자 필드는 시리즈가 됩니다; _step (존재하고 숫자인 경우)이 x축이 되고, 그렇지 않으면 이벤트 시퀀스 번호가 사용됩니다; _step 이외에 _로 시작하는 키는 무시됩니다; 부울은 메트릭이 아닙니다; NaN/Infinity/null 값은 건너뛰고 모니터의 경고 배지에 집계됩니다;

  • 다른 모든 필드 (예: file, stage, phase)는 보존되며 정확한 이벤트 테이블에서 볼 수 있습니다.

Example: a tracked 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")

Example: an image-processing 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)

Timestamped, leveled logging with loguru

Vanth는 모든 레코드를 구조화된 AGENT_EVENT 로그 줄로 라우팅하는 loguru 래퍼를 제공하므로, 로그가 일반 텍스트 대신 이벤트 테이블에 타임스탬프가 있고 레벨을 인식하는 이벤트(레벨 배지와 정확한 타임스탬프 포함)로 나타납니다:

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")

각 호출은 AGENT_EVENT {"type":"log","level":"info","message":"...","data":{...}}를 방출하며, 데몬은 이를 내구성 있는 이벤트로 영구 저장합니다. data는 추가 컨텍스트를 전달합니다. 모니터는 이를 metric/progress 이벤트와 함께 정확한 이벤트 테이블에 표시합니다.


Tool reference (all 20 MCP tools)

Tool

Purpose

job_start

명령을 분리된 작업으로 실행

job_rerun

원래 명령/env/cwd/대상으로 작업 재실행

job_wait

일치하는 이벤트(또는 타임아웃)까지 차단 — 작업을 기다리는 권장 방법

job_status

하나의 작업 상태, 명령, env, 진행률, 마지막 이벤트, 연결, 태그

job_list

최근 작업, status / thread_id / name / tags로 필터 가능

job_view

에이전트 대상 요약, 주의 우선순위로 정렬

job_events

작업의 구조화된 이벤트 (since_event_id로 앞으로, 또는 reverse로 최신순)

job_tail

바이트 오프셋이 있는 제한된 stdout/stderr 로그 꼬리

job_metrics_query

저장된 스칼라 메트릭 시리즈 읽기 (loss, acc, progress.percent, ...)

job_metric_compare

작업 간 하나의 메트릭 비교 (최신/평균/최소/최대/합계/개수)

job_run_summary

한 번 호출로 '작동했나요?' — 상태, 실행 시간, 진행률, 메트릭, 아티팩트

job_artifact_add

아티팩트 (체크포인트, CSV, 출력)를 작업에 첨부

job_artifacts

작업에 첨부된 아티팩트 목록

job_dashboard

모든 렌더러를 위한 다운샘플링된 차트 데이터 보기

job_deliveries

작업의 깨우기 전달, status로 필터 가능

job_mark_delivery

전달 상태를 수동으로 설정

job_retry_delivery

실패한 전달을 디스패치를 위해 다시 대기열에 넣기

job_delivery_attempts

하나의 전달에 대한 시도/임대 기록

job_stop

실행 중인 작업 중지 (프로세스 트리 종료)

job_doctor

데몬 상태, 스키마, 테이블, 바이너리 가용성

job_cleanup

오래된 종료 작업의 시험 실행 또는 실제 제거

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
)

job_id, status, worker_pid, 로그/이벤트 경로를 반환합니다.

job_status — see what a job is running

job_status(job_id="job_...")

상태, 명령, cwd, env, timeout_seconds, notes, run (작성자, 호스트명, OS, Python 버전, CPU/GPU, git 저장소/브랜치/커밋), runtime_seconds, 진행률, 마지막 이벤트, 스레드 연결, 태그, 종료 코드를 반환합니다. 이것은 에이전트가 "이 작업이 무엇을 하고 있나요?"에 답하는 가장 빠른 방법이며, W&B에서 실행에 대해 볼 수 있는 실행 개요를 반영합니다.

job_startnotes="..."를 전달하여 실행에 주석을 달 수 있습니다 ("이 실행을 특별하게 만드는 것은 무엇인가요?"), 이는 job_rerun에서 보존되고 모니터에 표시됩니다.

job_rerun — relaunch a failed job

job_rerun(job_id="job_...")

원래 명령, cwd, env, 타임아웃, 이름, 태그, 원본 스레드, 깨우기 대상으로 작업을 재실행합니다 — 새 job_id가 반환됩니다. 요청을 재구성하지 않고 실패한 다운로드, 불안정한 처리 배치, 또는 일시적 실패를 재시도하는 데 사용하세요.

job_list — filter by name or tag

job_list(status=["running"], name="train", tags=["gpu"], limit=20)

필터: status (목록), thread_id, name (부분 문자열), tags (나열된 모든 태그를 포함해야 함).

job_events — forward or latest-first

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 first

reverse: true는 가장 최근 이벤트를 반환합니다 (최신순) — "최근에 무슨 일이 있었나요?"에 이상적 — since_event_id와 결합하여 뒤로 페이지를 넘길 수 있습니다.

job_wait — 에이전트 사용의 핵심

job_wait(job_id="job_...", filters=["checkpoint","failed","completed"], timeout_seconds=3600)
  • 필터와 일치하는 첫 번째 이벤트를 기다렸다가 현재 상태와 함께 반환합니다.

  • since_event_id를 전달하면 이미 본 이벤트보다 최신 이벤트만 기다립니다.

  • 타임아웃 시 result: "timeout"을 반환하고, 데몬 종료 시 result: "shutdown"을 반환합니다.

job_view — 사용자에게 보여줄 내용

job_view(thread_id="019f...", limit=20)

주의 우선순위에 따라 정렬된 간결한 요약을 반환합니다: 실행 중인 작업과 실패한 작업이 먼저, 그다음으로 보류 중/실패한 전달이 있는 작업, 그 외 나머지 순서입니다. 각 항목에는 상태, 진행률, 최신 이벤트, 스레드 연결, 태그 및 전달 횟수가 포함됩니다.

job_stop — 실행 중인 작업 중지

job_stop(job_id="job_...", signal="terminate", kill_after_seconds=10)

작업의 프로세스 트리를 종료합니다. 먼저 정상 종료 signal(기본값 terminate)이 전송됩니다. kill_after_seconds 내에 작업이 종료되지 않으면 강제 종료됩니다. 작업은 워크로드 트리가 실제로 종료된 후에만 cancelled 상태가 됩니다. 그렇지 않으면 running 상태로 유지되며 중지를 재시도할 수 있습니다.

job_mark_delivery / job_retry_delivery — 수동 전달 제어

job_mark_delivery(delivery_id="del_...", status="delivered", error="optional reason")
job_retry_delivery(delivery_id="del_...")   # requeue a failed delivery

job_mark_delivery는 전달 상태를 수동으로 설정합니다(예: 어댑터 문제 해결 후). job_retry_delivery는 실패한 전달을 다음 디스패치 패스를 위해 다시 대기열에 넣습니다. job_delivery_attempts는 클레임/리스 기록을 보여줍니다.

job_cleanup — 오래된 종료 작업 제거

job_cleanup(older_than_seconds=86400, dry_run=true)   # preview
job_cleanup(older_than_seconds=86400, dry_run=false)  # delete

기준 시간보다 오래된 종료 작업을 제거합니다: 로그, 이벤트 미러, 스펙, 전달, 시도, 웨이크 대상, 이벤트, 그다음 작업 행 순서입니다. 실행 중인 작업은 절대 선택되지 않습니다. 드라이런은 완전히 읽기 전용입니다. 정리는 반복해도 안전합니다.

job_metrics_query — 저장된 스칼라 시계열 읽기

job_metrics_query(job_id="job_...", metric="loss", from_ms=..., to_ms=..., limit=1000)

하나의 작업에 대해 저장된 시계열을 메트릭 이름별로 그룹화하여 반환합니다. metric은 단일 시계열로 필터링합니다(예: loss, acc, progress.percent). from_ms/to_ms는 이벤트 타임스탬프(에포크 밀리초)로 필터링합니다. 포인트는 이벤트 순서대로 정렬됩니다. 이는 터미널 모니터 데이터의 읽기 측면입니다.

job_metric_compare — 실행 간 메트릭 비교

job_metric_compare(job_ids=["job_a", "job_b"], metric="val_loss", aggregation="min")

작업 간에 하나의 메트릭을 비교합니다(예: 시드 또는 구성 간 val_loss). aggregationlatest, mean, min, max, sum 또는 count입니다. 결과에는 작업별 값과 첫 번째/마지막 포인트가 포함됩니다. 이는 W&B 스타일의 "어떤 실행이 이겼는가?" 프리미티브입니다.

job_run_summary — 작동했는가?

job_run_summary(job_id="job_...")

한 번의 호출로 상태, 이름, 실행 시간, 종료 코드, 최신 진행률, 메모, 메트릭별 개요(최신/첫 번째/최소/최대/개수) 및 첨부된 아티팩트를 반환합니다. 에이전트가 완료된 작업을 보고하는 가장 빠른 방법입니다.

job_artifact_add / job_artifacts — 출력물 첨부

job_artifact_add(job_id="job_...", name="best.pt", uri="file:///...", kind="checkpoint",
                 size_bytes=..., sha256="...", meta={"epoch": 5})
job_artifacts(job_id="job_...")

아티팩트(체크포인트, CSV, 렌더링된 출력)를 작업에 첨부하여 job_run_summary에 나열되고 나중에 검색할 수 있도록 합니다. meta는 자유 형식 JSON입니다.

job_dashboard — 모든 렌더러를 위한 차트 데이터

job_dashboard(job_ids=["job_..."], limit=5000)

작업 목록과 모든 저장된 메트릭 시계열을 시계열당 limit 포인트로 다운샘플링하여 반환합니다. Go 터미널 모니터가 차트로 표시하는 동일한 데이터로, HTTP/MCP를 통해 노출되어 모든 클라이언트(향후 웹/클라우드 대시보드)가 렌더링할 수 있습니다.


웨이크 대상 (작업이 주의를 필요로 할 때 에이전트 깨우기)

작업이 일치하는 이벤트를 내보내면 데몬은 지속적인 전달을 생성하고 어댑터를 통해 디스패치합니다. 전달은 최소 한 번(at-least-once) 입니다. 모든 페이로드는 중복 제거를 위해 delivery_id를 전달합니다.

local_command

임의의 명령을 실행하고 전달 페이로드를 JSON으로 stdin에 전달합니다:

{
  "type": "local_command",
  "events": ["checkpoint", "failed", "completed"],
  "command": ["python", "deliver.py"]
}

종료 코드 0은 전달을 delivered로 표시하고, 다른 종료 코드는 failed로 표시합니다.

codex_thread

로컬 앱 서버를 통해 Codex 스레드를 재개합니다:

{
  "type": "codex_thread",
  "thread_id": "019f...",
  "events": ["checkpoint", "failed", "completed"],
  "codex_command": ["C:\\codex\\codex.exe"]
}

프로토콜: initialize -> thread/resume -> turn/start.

opencode_thread

OpenCode 세션을 재개합니다:

{
  "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
}

기본 OpenCode 턴 타임아웃은 30초입니다. 긴 턴의 경우 늘리십시오.

공유 전달 옵션

{
  "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
}

auto_dispatch: false인 경우, 전달은 에이전트가 수동으로 디스패치하거나 대상을 변경할 때까지 pending 상태로 유지됩니다.

전달 작업

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")

시도 기록에는 클레임 토큰, 시작/종료 시간, 상태 및 리스 만료 후 시도가 회수되었는지 여부가 기록됩니다. 어댑터가 웨이크를 수락했지만 Vanth가 성공을 기록하기 전에 데몬이 충돌하면 전달이 회수되어 재시도됩니다. 이는 정확히 한 번 전달로 클레임되는 것이 아니라 reclaimed 시도로 표시됩니다.


데몬 실행

포그라운드 (개발 또는 진단용):

uv run vanthd

로그인 시 시작 옵션:

  • Windows: 데몬은 사용자 시작 폴더(startup_commands.bat)에서 다른 시작 명령과 함께 시작됩니다. Task Scheduler 작업 템플릿도 deploy/vanthd.cmd에 있습니다.

  • Unix: deploy/vanthd.service는 systemd 사용자 서비스입니다.

VANTH_HOME당 하나의 데몬만 활성화하십시오. 동일한 홈에 대한 두 번째 데몬은 즉시 종료됩니다(OS 수준 잠금). 데몬은 루프백(127.0.0.1 / ::1 / localhost)에만 바인딩됩니다. 루프백이 아닌 VANTH_DAEMON_HOST는 거부됩니다.

보안

  • 모든 데이터 경로에는 Authorization: Bearer <token>이 필요합니다. 토큰은 홈별로 생성되며 절대 기록되지 않습니다. GET /health는 유일한 인증되지 않은 경로입니다(감독자를 위한 저렴한 활성 상태 프로브).

  • 데몬 시작 시 상태 디렉터리는 소유자로 다시 강화됩니다: Unix chmod 0700/0600, Windows는 ACL 상속을 비활성화하고 icacls를 통해 소유자, SYSTEM 및 Administrators에게만 권한을 부여합니다. 이는 다른 계정(예: 사용자 프로필에서 읽기 권한을 상속받는 샌드박스/CI 사용자)이 토큰이나 작업별 환경/스펙 데이터를 읽는 것을 차단합니다.

  • Windows에서는 소켓 SO_REUSEADDR이 비활성화되어 두 번째 데몬이 동일한 포트에서 팬텀 리스너가 될 수 없습니다. 바인딩 실패 시 홈 잠금이 해제되고 깔끔하게 종료됩니다.

Go 터미널 모니터

네이티브 Go 대시보드는 동일한 홈을 읽기 전용으로 읽고 실시간 플롯, 진행률 표시줄, 정확한 이벤트 테이블 및 로그 테일을 렌더링합니다:

uv run vanth-monitor

빌드된 휠에서 vanth-monitor는 번들된 네이티브 바이너리를 실행합니다(Go 도구 체인 불필요). 소스 체크아웃에서는 첫 사용 시 모니터를 빌드하고 ~/.cache/vanth/ 아래에 캐시합니다(PATH에 go 필요):

go build -o bin\vanth.exe ./cmd\vanth
bin\vanth.exe monitor

키: up/down 또는 j/k로 작업 선택 · enter로 작업 시계열 고정 · e 이벤트 테이블 · l 로그 테일 · +/- 차트 확대/축소 · [/] 이동 · t 라이브 테일로 돌아가기 · ? 도움말 · q 또는 Ctrl+C 종료.


구성 참조

환경 변수 (기본값은 src/vanth/server.py, src/vanth/daemon.py, src/vanth/migrations.py에 있음):

변수

기본값

목적

VANTH_HOME

~/.vanth

상태 루트 (별칭: AGENT_BG_HOME)

VANTH_DAEMON_URL

http://127.0.0.1:8765

클라이언트가 데몬에 도달하는 주소

VANTH_DAEMON_HOST

127.0.0.1

바인드 주소 (루프백만)

VANTH_DAEMON_PORT

8765

바인드 포트

VANTH_MAX_REQUEST_BYTES

1 MiB

HTTP 요청 본문 제한

VANTH_MAX_RESPONSE_BYTES

4 MiB

HTTP 응답 제한

VANTH_MAX_EVENT_BYTES

64 KiB

단일 이벤트 페이로드 제한

VANTH_MAX_EVENT_LINE_BYTES

1 MiB

AGENT_EVENT 라인 제한

VANTH_MAX_LOG_BYTES

10 MiB

스트림당 로그 제한 (드레인 계속)

VANTH_MAX_EVENTS_PER_JOB

100000

작업당 구조화된 이벤트 제한

VANTH_DELIVERY_POLL_INTERVAL

0.2s

유지 관리 루프 주기

VANTH_DELIVERY_LEASE_MARGIN

5s

어댑터 타임아웃을 초과하는 추가 리스 시간

VANTH_RUNNER_HEARTBEAT_INTERVAL

1s

러너 활성 상태 하트비트

VANTH_RUNNER_HEARTBEAT_STALE_AFTER

10s

하트비트 부실 임계값

VANTH_CODEX_BIN

codex / C:\codex\codex.exe

Codex 바이너리

VANTH_OPENCODE_BIN

opencode (shutil.which 통해)

OpenCode 바이너리

VANTH_LOG_LEVEL

INFO

데몬 로그 수준

VANTH_LOG_MAX_BYTES

5 MiB

순환 데몬 로그 크기

VANTH_LOG_BACKUP_COUNT

3

데몬 로그 순환 횟수

VANTH_BUSY_TIMEOUT_MS

30000

SQLite 쓰기 잠금 대기


운영

상태 레이아웃

~/.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 backups

상태, 준비 상태 및 진단

job_doctor()

상태 디렉터리, 데이터베이스 테이블, 상태별 전달 횟수, 스키마 버전, PRAGMA quick_check, 부실 전달 리스, 여유 디스크, 토큰 경로 및 Codex/OpenCode 바이너리 확인 가능 여부를 보고합니다. 토큰은 절대 공개하지 않습니다.

HTTP 데몬은 또한 다음을 노출합니다:

  • GET /health — 저렴하고 인증되지 않은 감독자용 활성 상태 프로브;

  • GET /ready — 인증된 준비 상태 (의사 보고서, 준비되지 않음 시 503).

업그레이드 및 백업

스키마 변경은 순서가 지정된 SQLite 마이그레이션입니다. 기존 데이터베이스의 첫 번째 마이그레이션 전에 SQLite 백업 API를 통해 backups/ 아래에 타임스탬프가 있는 백업이 기록됩니다(WAL이 활성화된 상태에서 원시 파일 복사는 절대 안 됨). 수동으로 업그레이드하려면 먼저 최신 backups/*.sqlite를 복사하십시오. 향후 데이터베이스 스키마는 파일을 건드리지 않고 거부됩니다.


HTTP API (MCP 도구와 동등)

Authorization: Bearer <token>으로 인증됩니다.

메서드

경로

목적

GET

/jobs

작업 목록 조회 (status, limit, thread_id, name, tags)

POST

/jobs

작업 시작

POST

/jobs/{id}/rerun

원래 설정으로 작업 재실행

GET

/jobs/{id}/status

작업 상태 (명령어/env/cwd 포함)

GET

/jobs/{id}/events

이벤트 (since_event_id, types, limit, reverse)

GET

/jobs/{id}/metrics

메트릭 시리즈 (metric, from_ms, to_ms, limit)

GET

/jobs/{id}/summary

실행 요약 (상태, 실행 시간, 메트릭, 아티팩트)

GET

/jobs/{id}/artifacts

아티팩트 (limit)

POST

/jobs/{id}/artifacts

아티팩트 추가

GET

/metrics/compare

작업 간 메트릭 비교 (job_ids, metric, aggregation)

GET

/dashboard

차트 데이터 (job_ids, limit)

GET

/jobs/{id}/tail

로그 꼬리 보기 (stream, max_bytes, offset)

POST

/jobs/{id}/wait

이벤트 대기

POST

/jobs/{id}/stop

작업 중지

GET

/view

에이전트 뷰 (thread_id, limit)

GET

/deliveries

전달 (job_id, status, limit)

GET

/deliveries/{id}/attempts

시도 이력

POST

/deliveries/{id}/mark

전달 표시

POST

/deliveries/{id}/retry

전달 재시도

POST

/cleanup

정리 (older_than_seconds, dry_run)

GET

/doctor

상태 보고서

GET

/health

인증 없는 활성 상태 확인


에이전트 사용 팁

  1. 대기(polling 대신). job_status를 반복 호출하는 대신 job_wait(job_id, filters=[...], timeout_seconds=...)를 사용하세요. 데몬은 일치하는 이벤트가 저장되는 즉시 대기를 깨웁니다.

  2. since_event_id 전달. 이벤트를 처리한 후 다음 job_waitsince_event_id를 전달하여 이전 이벤트를 다시 처리하지 않도록 하세요.

  3. 작업에 태그와 스레드를 지정하세요. origin_thread_id(작업을 시작한 에이전트 스레드)와 tags를 설정하고, job_view(thread_id=...)를 사용하여 요약하세요.

  4. 사용자에게 상황을 제시할 때는 job_viewjob_status보다 선호하세요. 이미 주의 우선순위별로 정렬되어 있습니다.

  5. 작업을 자체 설명 가능하게 만드세요. AGENT_EVENT progress / checkpoint / metric 라인을 내보내세요( 참조). 침묵하는 작업도 작동하지만, 추적된 작업이 훨씬 분석하기 쉽습니다.

  6. 장기 작업에는 웨이크 대상을 사용하세요. 훈련 실행이나 긴 다운로드가 체크포인트에서 결정을 필요로 하는 경우, events: ["checkpoint", "failed", "completed"]와 함께 codex_thread 또는 opencode_thread 대상을 추가하여 에이전트가 폴링 대신 재개되도록 하세요.

  7. 전달 실패를 검사하세요. job_delivery_attempts는 임대/클레임 내역을 보여줍니다. job_retry_delivery는 원인을 수정한 후 실패한 전달을 다시 대기열에 넣습니다.

  8. job_start에 적절한 timeout_seconds를 설정하세요. 중단된 명령어가 영원히 실행되는 대신 timeout(종료) 상태가 됩니다. 러너는 데몬 재시작에도 이 제한을 적용합니다.

  9. job_cleanup(older_than_seconds=..., dry_run=false)로 오래된 상태를 정리하세요. SQLite 저장소와 로그 파일의 크기를 제한할 수 있습니다.

  10. 실패한 작업을 재구축하지 말고 재실행하세요. job_rerun(job_id=...)는 원래 명령어, env, cwd 및 웨이크 대상으로 다시 실행합니다. 일시적으로 실패한 다운로드나 배치를 재시도하는 데 이상적입니다.

  11. "이 작업이 무엇인가요?"라고 묻는다면 job_status를 사용하세요. 이제 명령어, cwd, env 및 타임아웃을 반환하므로 로그를 읽지 않고도 사용자에게 작업을 설명할 수 있습니다.

  12. 이름/태그로 목록을 필터링하세요. job_list(name="train", tags=["gpu"])는 모든 것을 페이지로 탐색하지 않고도 증가하는 작업 목록을 좁힙니다.

  13. "최근에 무슨 일이 있었나요?"에는 reverse=true를 사용하세요. job_events(job_id, reverse=true, limit=20)는 가장 최근 이벤트를 먼저 반환하며, 본 가장 오래된 ID로 since_event_id를 설정하여 더 뒤로 페이지를 탐색할 수 있습니다.

  14. 작업은 데몬이 재시작되어도 유지됩니다. 러너는 분리되어 있습니다. 작업은 데몬/MCP 재시작에도 계속됩니다. 복구 시 러너가 없으면 작업은 orphaned(고아)로 표시됩니다(조용히 삭제되지 않음).


예제

uv run python examples\long_job.py    # emits progress + checkpoints

examples/long_job.pyvanth.agent_events를 사용하는 작은 참조 작업입니다. job_start를 통해 시작하고 vanth monitor에서 지켜보세요.


문제 해결

  • Unauthorized (401): ~/.vanth/token의 베어러 토큰이 데몬이 기대하는 토큰과 일치하는지 확인하세요. 데몬과 클라이언트가 동일한 VANTH_HOME을 사용하는지 확인하세요.

  • 두 번째 데몬이 시작되지 않음: another vanthd already owns this VANTH_HOME. 설계상 홈 디렉토리당 하나의 데몬만 실행됩니다.

  • 작업이 running 상태에서 orphaned로 멈춤: 러너 프로세스가 종료되었습니다. logs/<job_id>.runner.log와 하트비트 임계값을 확인하세요.

  • 모니터에 차트가 없음: 작업이 AGENT_EVENT metric 또는 progress 라인을 내보내지 않고 있습니다. 추가하세요(선택 사항).

  • OpenCode 웨이크 타임아웃: 웨이크 대상의 timeout_seconds를 예상 처리 시간보다 더 길게 늘리세요.

  • 모니터에 아무것도 표시되지 않음/빈 상태: VANTH_HOME이 데몬의 홈 디렉토리를 가리키고 있는지, 그리고 그 안에 jobs.sqlite가 존재하는지 확인하세요.


개발

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, monitor

휠 빌드는 hatchling 빌드 훅(build-hooks/bundle_monitor.py)을 실행하여 호스트 플랫폼용 Go 모니터를 컴파일하고 vanth/monitor-bin/ 아래에 번들링합니다. 따라서 vanth-monitor는 런타임에 Go 툴체인이 필요하지 않습니다. 휠을 빌드할 때는 go가 PATH에 있어야 하지만, 설치하거나 실행할 때는 필요하지 않습니다. 휠은 네이티브 바이너리를 포함하므로 플랫폼 태그(py3-none-<platform>)가 지정됩니다.

릴리스 게이트 자동화는 scripts/에 있습니다:

  • scripts/chaos_matrix.py — 대규모 합성 워크로드 및 종료/재시작 매트릭스;

  • scripts/real_adapter_smoke.py — 옵트인 실시간 Codex/OpenCode 웨이크 스모크 테스트(VANTH_SMOKE_CODEX_THREAD / VANTH_SMOKE_OPENCODE_SESSION 설정);

  • scripts/generate_go_fixture.pytestdata/의 결정론적 스키마 v5 적합성 픽스처를 재생성;

  • scripts/demo_jobs.py — 모니터용 데모 작업(훈련 실행, 빠른 작업, 실패하는 작업) 시작.

제한 사항 (v1)

  • 대화형 stdin 및 job_send는 구현되지 않았습니다. 작업은 stdin이 닫힌 상태로 실행됩니다(명령어에 비대화형 플래그 사용).

  • 전달은 최소 한 번(at-least-once)입니다. 어댑터가 웨이크를 수락한 후 Vanth가 성공을 기록하기 전에 충돌이 발생하면 문서화된 명백한 모호성이 발생합니다.

  • 원격 액세스, TLS, 다중 사용자 정책, 할당량, 분산 워커 및 사용자 정의 서비스 관리자는 범위를 벗어납니다.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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