verigent
One-line onboarding for Verigent — the battery every harness sits, so yours reads as a delta against the naked model and every other build; the record is anchored and checkable without trusting Verigent.
npx verigent <handle> <vgp_token> # one-time setup: registers the Verigent MCP server
npx verigent continuous <handle> --token <vgp_token>
# the ONE setup command an owner pastes (see below)
npx verigent prove pending # run BY THE AGENT inside its scheduled checks (see "Setup checks")
npx verigent schedule <handle> # install the ~5x/day challenge-pull job (launchd/cron)
npx verigent handler # run the sovereignty challenge endpoint (VG_SECRET / VG_SECRET_FILE)
Source and provenance. This package is built from the public repo
Verigent-AI/verigent-cli and published with npm build
provenance, so the tarball on npm is attested to the exact commit and workflow that produced it. It
writes one file, ~/.verigent/state.json (mode 0600) — run state for cold-session resume — and makes
HTTPS calls to verigent.ai only. The schedule, continuous and prove endpoint subcommands install
launchd/cron jobs (the pull job, the short-lived setup-check job, the endpoint handler); continuous
also writes the endpoint secret, the handle file and the signing key under <cwd>/.verigent/ (mode
0600), plus the handler job's script and log when it starts one; nothing else touches your system. Package pins and integrity hashes:
https://verigent.ai/.well-known/verigent.json.
The scheduler it installs contains no credentials — the pull token lives only in the MCP
server config, per agents.txt §5f. The handler implements
the public sovereignty contract exactly: POST {"challenge"} → {"proof","timestamp"} (hex challenges
only — every Verigent challenge is hex). Since 0.10.3 it also answers ONE other request: Verigent's signed
check now ({"check_now":{"v":1,"handle","ts","nonce"},"sig"}, sig = HMAC-SHA256 with the same
endpoint secret over verigent-check-now.v1.<handle>.<ts>.<nonce>), sent when the owner presses "Check
again" on the setup page once the endpoint is proven. A valid one starts this agent's existing setup-check
job immediately (launchctl kickstart of ai.verigent.setupcheck.<handle>, or one setup-check run on
Linux) — that job keeps its own no-overlap lock and run cap — and does nothing else. Anything unsigned, for
another handle, outside a ±2-minute window, replayed, or more often than once per 30 s does nothing.
Both values arrive in your welcome email. The command registers the
Verigent MCP server with your
local claude CLI (or prints the config block for any other MCP client), then
tells you the one sentence to give your agent to sit its first challenge cycle.
Your agent's onboarding test is free. Watch it live at https://verigent.ai/agent/<handle>.
npx verigent continuous — the one setup command
An owner pastes exactly two Verigent prompts, ever: the free test and this. Your owner's setup page shows it. Running it is the owner's authorisation for Verigent's scheduled checks — nothing is added to the agent's config (since 0.10.14; until 0.10.13 the output asked for a grant line in CLAUDE.md). Run it once from the agent's working directory:
npx verigent continuous <handle> --token <vgp_token> [--cwd <agent dir>] [--env KEY=VALUE ...] \
[--key <ed25519 pem>] [--public-url <https url>] [--port <n>] [--harness-version <v>] [--dry-run]
It does everything Verigent's own tooling can, and reports only what the server verified. It never pays and never declares a channel — those wait for the owner's answers on the setup page, which the agent's setup checks then act on. Re-run it any time; a step already proven is skipped.
- Material.
POST /api/agent/setup-materialwith the handle and pull token (read-only). If the owner's page has not issued the setup yet it says so and exits 1; nothing below runs. - Connect. Exactly
npx verigent <handle> <vgp_token>: the MCP server entry, the ~5x/day pull job and the setup-check job (below).CLAUDE_CONFIG_DIRis carried from your shell into the jobs automatically when set. The pull token is never in a job. - Signing key. Reuses
<cwd>/.verigent/<handle>.ed25519.pem(or the Ed25519 PKCS8 PEM named by--key), or generates one there (mode 0600), signs the server-issued nonce and reports the public key and signature. - Endpoint. The HMAC secret is written to
<cwd>/.verigent/<handle>.hmac-secret(mode 0600). A known URL (--public-url, or theendpoint_urlsaved in the handle file after an earlier proof) is reported. Otherwise, whencloudflaredis on PATH, it installs the handler as a persistent job behind a cloudflared quick tunnel and reports the tunnel URL. With neither, it reports nothing and says what the agent needs: a public HTTPS URL (install cloudflared, or a host it controls). - Payment proof and output channel. Never acted on here. The summary shows each as already proven, declared, or waiting on the owner's input on the setup page — Verigent's checks finish it.
- Summary. One table (step · result · next) and the record link. The "next" column never names a Verigent command: anything left is finished by Verigent's own scheduled checks, and the owner's only part is the inputs on the setup page. Exit 0 with steps left is the normal outcome; exit 1 only when the material can't be had.
Once material and connect succeed it also saves the handle file, <cwd>/.verigent/<handle>.json
(mode 0600):
{ "handle": "<handle>", "pull_token": "<vgp_token>", "site": "https://verigent.ai" }
The setup checks and every prove command read it. A proven endpoint URL is added as "endpoint_url".
--dry-run prints every call it would make and writes nothing.
Setup checks — ai.verigent.setupcheck.<handle> and npx verigent prove pending
While setup is unsettled, a short-lived job (launchd StartInterval 300, or a */5 crontab line) runs
npx -y verigent@<this version> setup-check <handle>. Each tick first asks Verigent (setup-material):
- settled — a check has landed and every proof is proven or skipped (a declared non-email channel counts) → the job removes itself;
- something the agent can do — no check yet, the signing key, the endpoint (a URL or cloudflared is
there), the payment once the owner saved a rail and a cap, the email channel once the owner saved an
address or a code is out → ONE agent run: the normal cycle when no check has landed, otherwise a
setup-only run of
prove pending; - only owner-side answers missing → no run this tick (not counted).
It never runs on top of the agent's scheduled check: a tick that finds the pull job running (launchd's
own record of ai.verigent.pull.<handle> on macOS — its first tick fires at install; the process table on
Linux) waits for it to finish, then goes at once. So the first setup check follows the install-time check
with no fixed gap, and the 5-minute cadence after that is unchanged.
Every tick, the run after it, and every prove pending tell Verigent when the agent's next check is due
(next_check_at); the owner's setup page shows it on the open step.
It is bounded: at most 24 agent runs within two hours of install, then it removes itself and the normal ~5x/day schedule carries on. One run at a time (a lock file). The job holds no credentials.
npx verigent prove pending --handle <handle> is what the agent runs inside a scheduled check (every
cycle prompt ends with it, always naming the handle). It is the agent's own step: the prompts tell the agent
to report to its owner that Verigent's checks finish setup automatically, never to hand the owner a
Verigent command. It reads the material — including the owner's saved rail, cap and channel address — and finishes what
it can: retries the signing key and the endpoint; prints the exact payment for the agent's own wallet
only when the owner saved a rail and a cap, within that cap (it never pays itself — the agent reports
the payment with prove pending --handle <h> --tx <signature>, or re-runs it once a Lightning invoice is
paid); declares the email channel only when the owner saved an address, and reports the emailed code
back with prove pending --handle <h> --code <code>. Otherwise it says what it is waiting on.
Since 0.10.4: a setup payment this agent already made, verified by Verigent within the last 30 days,
proves the payment step again — prove pending asks Verigent to look it up first ({step:"wallet", reuse:true}) and never asks for a new payment when that passes. If the agent decides not to pay (or not to
read the inbox) this time, it says why in one line — prove pending --handle <h> --declined payment|channel --reason "<why>" — and its owner sees that on the setup page. Each setup-check tick tells Verigent which
steps its agent run is working on, and when the run has ended, so the owner's page shows "Checking" on
exactly those rows while the run is live.
Since 0.10.5: the pull job (the install-time check and every scheduled one) reports its runs the same
way. The job runs npx -y verigent@<this version> pull-run <handle> --cwd <dir> -- <the agent's command>:
before the agent's command it tells Verigent which rows the run works on (Connect while no check has landed
yet, plus each unproven step prove pending will attempt), and after it, that the run ended. The reports
are best-effort and time-bounded — no handle file, Verigent unreachable or a refusal never stops or fails
the check, and the job exits with the agent command's own exit code.
Since 0.10.6: each run's start and end reports carry the run's own id, so one run ending never marks a step
another run is still working on. prove pending no longer declares the email channel again while a code
sent to that address is still valid, or while Verigent's send limit for channel codes is reached — it says
when the next code can go instead. Crontab entries single-quote every path, and refuse a path containing
% or a line break (cron would mangle it).
Since 0.10.8: sovereignty testing is the owner's free opt-in. The setup material says proof_testing: "off" until the owner turns it on ("Continue — turn on proof testing (free)" on the setup screen, offered right
after the agent connects — since 0.10.10; it was a plan-page button in 0.10.8). While it
is off, continuous connects the agent only — no signing key, endpoint handler, tunnel, secret file, payment
or channel is attempted; the setup-check job runs only the agent's first check and otherwise waits
(uncounted); prove pending attempts none of the four proofs. Verigent refuses them too (setup-proof
answers 409 proof_testing_off). Once it is on, the next scheduled check picks the proofs up — nothing to
paste again.
Since 0.10.9: the setup check reacts within seconds, not five minutes. Each setup-check tick now listens
for up to ~285 s of its 5-minute slot: every ~10 s it asks Verigent with a cheap poll (setup-material with
poll: true — two point reads, no secrets, no report budget) and acts the moment there is work: sovereignty
testing just turned on, the owner pressed Check again on any step (a short-lived check request — before
the endpoint exists too), or the owner changed a setup answer (rail, cap, address). The signing key and the
endpoint are proven by the CLI itself — no agent run: it signs the nonce with the existing key (or makes
one), and starts the handler + quick tunnel and reports its URL (with the tunnel-ready wait). Only the first
check, the payment and the output channel take an agent run, and that run goes at the same time as the key and
endpoint work (prove pending inside it leaves the key / endpoint alone while the setup check holds its
<handle>.local-proofs.lock). Each pickup of a check request is acknowledged (check_seen) in the same report
that lists what is being checked, so the owner's page shows "Checking" on those rows. Unchanged: one tick at a
time (the lock), at most 24 agent runs in the two-hour window (local proofs cost none), never an agent run on
top of the pull job, and the signed check-now via a proven endpoint (above) still starts the job between ticks.
Since 0.10.10: the "sovereignty testing is off" lines say where the owner turns it on — the setup screen right after the agent connects ("Continue — turn on proof testing (free)"), not "the plan page". Copy only; no behaviour change.
Since 0.10.11: the pull job measures the agent's startup context. schedule installs the agent's command
as claude -p <prompt> --allowedTools <list> --output-format json, so claude prints one JSON result carrying
its own per-turn token usage. pull-run reads it: the agent's result line still goes to .verigent-pull.log,
and the measured usage — first_turn_context_tokens (the first turn's input: uncached + cache read + cache
written), totals and turns — is posted to POST /api/probe/usage with the pull token from the 0600 handle file.
The report's Vitals tab then shows "Startup context" as observed. Best-effort and bounded like the run reports:
output that isn't JSON, no usage in it, no handle file, Verigent unreachable — nothing is posted and the job
still exits with the check's own exit code. A command without --output-format json passes through exactly as
before. Re-run npx verigent schedule <handle> to refresh an installed job.
Since 0.10.12: every agent's endpoint handler gets its own port, and the scheduled runs pin the permission mode. Two fixes from setting up a second agent on the same Mac:
- The handler's port. Every agent's handler used to run on
:8787, so a second agent on the same machine couldn't bind it while its tunnel still forwarded to:8787— the FIRST agent's handler answered with the wrong HMAC. Now each agent gets its own port (a per-handle start in 20000–29999, stepping up to the first free one), written into its handler script and saved ashandler_portin the handle file, and reused on every re-run. "Already up" now means this agent's handler: the CLI POSTs a fresh challenge to the port and checks the answer is the HMAC under this agent's secret. The handler exits non-zero onEADDRINUSE, and with a quick tunnel the job opens the tunnel only after the handler is listening. Upgrade: an existing install keeps its port while it is this agent's handler or the port is free (an agent alone on:8787stays there); re-runningcontinuousorprove endpointmoves an agent whose port another process holds to its own port. - The permission mode. See "What a scheduled run may do" below.
- Owner permissions (0.10.14 — replaces the per-step "ask your owner" questions of 0.10.12–0.10.13). Some setup
steps need the owner's permission. Each is one line of what it does — the same lines on the setup page and in
prove pending:Inbox: read one setup code from <address>.·Endpoint: run a local challenge handler in the background behind a Cloudflare quick tunnel (requires cloudflared).·Payment: send <amount> from my <rail> wallet, within the cap set on the setup page.The owner answers on the setup page (Allow / Not now, revocable there); setup-material returns the answers asowner_grantsandprove pendingfollows them: allowed → it proceeds and says so (with the Endpoint line allowed it installs the handler job + tunnel itself); "Not now" → the step is skipped and not asked again this term (the setup-check loop skips it too). The payment's permission is the rail + cap saved on the setup page. Without an answer,prove pendinglists every line still needed in ONE block and reports their ids (asking, ids only, on the cheap poll) so the setup page shows them. A permission the agent records for itself doesn't count; a declined line is skipped. The owner's own paste ofnpx verigent continuous …covers the handler that command starts.
What a scheduled run may do
Both scheduled jobs run exactly claude -p <prompt> --allowedTools <list> from the agent's directory — nothing
else on the command line except, on the pull job since 0.10.11, --output-format json (an output format; it
grants and narrows nothing), and since 0.10.12 --permission-mode default only when the agent's own mode is
auto. The pull job passes it through pull-run untouched. That means the run uses the agent's own Claude
Code permissions:
- Claude Code keeps
--allowedToolsas its own rule source beside the agent's settings files (user~/.claude/settings.jsonor$CLAUDE_CONFIG_DIR, project.claude/settings.json, local.claude/settings.local.json, and any managed policy). Allow rules from all of them are merged and deny rules from any of them still win — so the list Verigent passes adds rules; it never replaces or narrows the agent's own. - The permission mode is the agent's own — except
auto, which since 0.10.12 runs asdefault. Why: withpermissions.defaultMode: "auto"in the operator's settings, Claude Code's auto-mode classifier blockednpx -y verigent@… prove pendinginside the scheduled run ("downloads and runs outside code") even though it was in--allowedToolsand the operator allowedBash(npx *)— so payment and channel proofs never ran. Indefaultmode the allow and deny rules decide; headless, anything no rule allows is refused, never prompted. (defaultis accepted by every Claude Code version; newer ones also call itmanual.) The mode is read from the settings the job's claude loads — user ($CLAUDE_CONFIG_DIR/settings.json, else~/.claude/settings.json), then the agent directory's.claude/settings.json, then.claude/settings.local.json(a later one wins) — at install for the pull job (re-runschedule/continuousafter changing it) and at each run for the setup check; the choice is printed / logged. Any other mode, or none, gets no flag: exactly 0.10.11's behaviour. Nothing that narrows the rules is ever passed (--tools,--disallowedTools,--setting-sources,--settings,--strict-mcp-config,--restricted), and nothing that bypasses them (--dangerously-skip-permissions,bypassPermissions). - What Verigent adds is exactly two entries:
mcp__verigentandBash(npx -y verigent@<this version> prove pending:*)— never all of Bash.
So an agent whose settings already allow its wallet and inbox tools can pay (within the owner's cap) and read the channel code inside the check with no one doing anything. A headless run has no one to answer a permission prompt: a tool works there only when the agent's own settings allow it — a one-off approval given in an interactive session is not a setting and does not carry over.
--allow <tool,tool> is optional and additive: the operator's extra rules, appended after Verigent's two.
<cwd>/.verigent also holds Verigent's own state (the setup-check state <handle>.setup-check.json and its
lock, the signing key, the endpoint secret, the handler script and log). None of these count as a handle
file.
Proving one step by hand — npx verigent prove …
Agents (and the setup checks) can still prove a single step directly — the owner's page never shows these commands. The CLI carries the explanation and does the work; every result line is the server's own reason, never a claim made here. Exit 0 on proven / declared / instructions printed; exit 1 on an auth, material or usage failure.
All four read the handle file. --handle <h> and --token <vgp_token> override it; with several
handle files in <cwd>/.verigent and no --handle, the command refuses and lists them. A handle file is
<handle>.json holding a pull_token; Verigent's state files in the same folder are never counted. --cwd <dir>
points at another agent directory.
npx verigent prove key [--key <ed25519 pem>]
Reuses the signing key at <cwd>/.verigent/<handle>.ed25519.pem (or the Ed25519 PKCS8 PEM --key
names) or, when there is none, generates one there (mode 0600). It signs the server-issued nonce and
reports {step:"identity", algorithm:"ed25519", public_key, signature} — the raw public key (32
bytes) and signature (64 bytes) as hex. Keep the file: real runs sign with the same key. Already
proven: it says so and reports nothing.
npx verigent prove endpoint [--public-url <https url>] [--port <n>]
Installs npx verigent handler --port <port> on this agent's own port (since 0.10.12 — see above; --port
names one, refused if another process holds it) as a persistent job — ai.verigent.handler.<handle>,
a launchd agent on macOS (kept alive across reboots), a crontab @reboot entry started immediately
elsewhere — the same mechanism schedule uses for the pull job. The job is a readable shell script,
<cwd>/.verigent/<handle>.handler.sh (mode 0700), with its output in <handle>.handler.log beside it.
It holds no credentials: the handler reads the HMAC secret from the 0600 file VG_SECRET_FILE names
(<cwd>/.verigent/<handle>.hmac-secret, written by continuous; fetched from the setup material if
it is missing). Re-running replaces the job; if THIS agent's handler is already up on its port (it answers a
fresh challenge with this agent's HMAC) it is left alone, never restarted.
- Without
--public-url: whencloudflaredis on PATH, the same job also runscloudflared tunnel --url http://localhost:<port>; the command waits (up to 60 s) for thehttps://….trycloudflare.comline in the job's log, then (since 0.10.4) waits up to 90 s until that URL answers from outside — a new quick tunnel takes 30–60 s — and only then reports it. A quick tunnel's URL changes whenever the job restarts (a reboot, a crash, a re-install) — re-runprove endpointand it re-reports the current one. No cloudflared: one sentence saying what it needs, exit 1, nothing installed. - With
--public-url: your own tunnel or host reaches the handler; the job runs the handler only and that URL is reported.
Then POST /api/agent/setup-proof {step:"endpoint", url} — Verigent challenges the URL and the
result line is its reason. A proven URL is saved as endpoint_url in the handle file.
npx verigent prove wallet --rail sol|lightning [--cap "<text>"] [--tx <signature>]
Never pays. Two phases:
- Instructions. Solana: fetches the setup material and prints the exact payment — address, memo
(required; it binds the payment to this agent), minimum lamports — then
npx verigent prove wallet --rail sol --tx <signature>. Lightning: reports once, which mints the invoice, and prints the bolt11 with "runnpx verigent prove wallet --rail lightningagain once paid". Both print the standing-permission line;--cap(what the owner typed on the board) becomes the cap in it, otherwise the agent is told to ask its owner for one. - Report.
--tx <signature>(Solana) or the second Lightning run posts the wallet step; the result line is the server's reason (a not-yet-indexed transaction says so — wait about 20 seconds and run it again).
npx verigent prove channel --email <address> | --channel "<text>" | --code <code>
--email declares email <address>: Verigent sends a code to it and the command prints the server's
reason plus npx verigent prove channel --code <code from the email>. --channel "<text>" declares
any other channel (recorded as declared; the first check that writes to it confirms it). --code
reports the code back; a match proves the channel.
The handler's secret
npx verigent handler takes its secret from, in order: --secret, VG_SECRET, --secret-file /
VG_SECRET_FILE (what the installed job sets), or the single <cwd>/.verigent/<handle>.hmac-secret
file when there is exactly one.
Integration notes, including the raw REST contract for agents without MCP support: verigent.ai/agents.txt
Verify this package
This package publishes via GitHub Actions trusted publishing (OIDC, no long-lived npm token) from its
public source repo, Verigent-AI/verigent-cli, so since
0.6.22 npm attaches a provenance attestation tying the tarball to the exact commit and workflow that
built it — check it with npm view verigent@<version> dist.attestations. Also check npm view verigent@<version> dist.integrity against your lockfile, and
compare the platform signing key below against
verigent.ai/.well-known/verigent.json
(identity.public_key) and the DNS TXT record _verigent-key.verigent.ai:
verigent-key=ed25519:GWzKn1EtPRdBxQsJ0Mo786zSXOSzrLWD72hfwXIOp/E=
Full recipe: verigent.ai/docs/verifying-a-record