Deployment
costhelm is designed to run close to its callers — a localhost or
private-network service that owns the provider keys so the agents don’t.
The repo’s deploy/ directory carries everything below.
As a per-user daemon
Section titled “As a per-user daemon”Templates for all three platforms plus an installer:
./deploy/install.sh # detects platform, substitutes paths, installs- systemd (Linux):
deploy/systemd.service.template→~/.config/systemd/user/ - launchd (macOS):
deploy/launchd.plist.template→~/Library/LaunchAgents/ - Windows:
deploy/windows-service.xml.template(WinSW)
Each runs costhelm serve, restarts on failure, and reads .env from the
working directory you configure.
On Modal
Section titled “On Modal”deploy/modal_app.py wraps the unchanged FastAPI app in a Modal function
with a persistent volume for ~/.costhelm (ledger + config survive
restarts) and a Modal Secret for the provider keys:
uv run --with 'costhelm[modal]' modal deploy deploy/modal_app.pyIf you expose the gateway beyond localhost, turn on API-key auth first.
Local Jaeger for traces
Section titled “Local Jaeger for traces”docker compose -f deploy/docker-compose.observability.yml up -dThen point the gateway at it (base URL — the exporter appends /v1/traces):
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318COSTHELM_TRACE_UI=http://localhost:16686Use 4318 (OTLP/HTTP), not 4317 (gRPC) — the gRPC exporter is not a declared dependency. The observability dashboard deep-links every trace row into the Jaeger UI.