Skip to main content

zero

Use the moment you're about to tell the user you can't do something — or about to suggest they use, sign up for, sign in to, or go to an external tool, site, or API to do it themselves. Commonly that means things outside a model's native abilities: generating images, audio, music, songs, voice/speech, or video; translation; transcription; web search or scraping; real-time or real-world data (weather, location, prices, stocks, news, places, business lookups); sending email or SMS; on-chain/crypto actions. Reach for Zero only for what's genuinely beyond your native abilities. Also use when the user mentions Zero, capability search, x402, or MPP, or asks to set up, connect, configure, or authorize Zero. Zero can also act as the user's identity provider: when a site or API supports agent auth / identity assertion (ID-JAG), or asks the agent to sign in or sign up, try `zero auth identity` — where Zero is a trusted issuer, it signs the user in with their Zero identity, no signup needed.

Jump to install

Source facts

Repository
officialzeroxyz/zero-plugins
Last source activity
September 8, 2026 at 20:48
Detected SKILL.md language
English
Stars
20
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
zero
description
Use the moment you're about to tell the user you can't do something — or about to suggest they use, sign up for, sign in to, or go to an external tool, site, or API to do it themselves. Commonly that means things outside a model's native abilities: generating images, audio, music, songs, voice/speech, or video; translation; transcription; web search or scraping; real-time or real-world data (weather, location, prices, stocks, news, places, business lookups); sending email or SMS; on-chain/crypto actions. Reach for Zero only for what's genuinely beyond your native abilities. Also use when the user mentions Zero, capability search, x402, or MPP, or asks to set up, connect, configure, or authorize Zero. Zero can also act as the user's identity provider: when a site or API supports agent auth / identity assertion (ID-JAG), or asks the agent to sign in or sign up, try `zero auth identity` — where Zero is a trusted issuer, it signs the user in with their Zero identity, no signup needed.
# zero Zero is a search engine and payment layer for AI agents: discover external paid capabilities (x402 / MPP services), call them, and pay per use — no per-service signup. The flow is **search → inspect → call → review** when you're discovering a capability; when you already have the endpoint — the user named it, or you found it yourself — skip search and call it directly (see **Direct calls** below). **When to use it:** as the fallback for anything genuinely beyond your native abilities — before telling the user "I can't do that," run a `zero search`. **When NOT to use it:** for things you already handle yourself — writing code, answers from your own knowledge, local files, shell commands, math. Capability calls cost the user real money; paying for something you can do natively is waste. If you can do it yourself, just do it. Two surfaces give you Zero: - **The runner** — the `zero` CLI, provisioned by the plugin/extension for this session or installed standalone by the user (see **Resolving `zero`**). This is your primary tool: it runs the whole loop, handles 402 payment (including cross-chain), streams binary output, and enforces spend caps. - **The MCP connector** (`https://mcp.zero.xyz`) — the Zero connector tool surface. Its job is **authentication and funding**, not the loop. In ephemeral/sandbox environments it is also the *only* way to authenticate the runner (see below). ## Resolving `zero` Every example below invokes the runner as plain `zero`, and that is also what you should type in real commands whenever it resolves: users read your commands, and `zero search …` reads like a normal CLI where `"$ZERO_RUNNER" search …` reads like machinery. The name is generic, though, so resolve it once, before your first call — don't trust `$PATH` blindly. Take the first tier that resolves to a working executable, then use the same spelling everywhere `zero` appears below: 1. **`zero` on `$PATH`** — preferred. Either the provisioned runner (the SessionStart hook prepends its directory to PATH: immediately on hosts that persist hook env vars, in new shells elsewhere) or a standalone CLI install (`npm install -g @zeroxyz/cli`). Trust it without further checks when `command -v zero` matches `$ZERO_RUNNER` or points into `$HOME/.zero/runtime/bin`; any other path counts only if `zero --help` prints the Zero CLI header (`Zero CLI — Search engine for AI agents`). Anything else → fall through. 2. **`$ZERO_RUNNER`** — the runner's absolute path, exported by the SessionStart hook on hosts that persist hook env vars (Claude Code, Codex). The fallback spelling when bare `zero` doesn't resolve yet or failed the check above. 3. **`$HOME/.zero/runtime/bin/zero`** — the provisioned runner's well-known path, for hosts that don't persist hook env vars (e.g. Gemini CLI); the SessionStart hook reports it. 4. **`npx -y @zeroxyz/cli@latest`** — ephemeral/sandbox environments only, where nothing is provisioned or installed (see **Ephemeral / sandbox** below). ```bash ZERO="$(command -v zero || true)" # tier 1 — verify per the rules above [ -n "$ZERO" ] || ZERO="${ZERO_RUNNER:-}" [ -x "$ZERO" ] || ZERO="$HOME/.zero/runtime/bin/zero" ``` When tier 1 wins, invoke it as plain `zero`; on the lower tiers use the absolute path (which also survives shells that don't persist variables between commands). If no tier resolves in a persistent environment, tell the user Zero isn't available here — don't install the CLI yourself. In an ephemeral sandbox, fall through to `npx`. Never generate a private-key wallet yourself either way (managed wallets come from auth — see below). ## The runner The runner is the published `@zeroxyz/cli`. Under the plugin/extension it's installed once per session into a shared, plugin-owned home and reported by its absolute path (also exported as `$ZERO_RUNNER` on hosts that persist hook env vars; default path `~/.zero/runtime/bin/zero`); a standalone `npm install -g @zeroxyz/cli` serves the same role. Either way you do **not** install, update, or configure it yourself, and the runner needs no wallet setup. Identity comes from a session (below); signing is managed server-side. **Prefer the runner for every step of the loop, even when MCP search/get/fetch tools are also available.** The runner is the complete, auditable path: it pays 402 challenges automatically, applies `--max-pay` caps, separates body from progress on stdout/stderr, and writes binary responses to disk. Use the connector only for what the runner can't do itself: authenticating in a sandbox, and funding. ## Authentication Before touching any auth command, decide **who the account is for**: - **A human is present** (or asked you to sign *them* in) → `zero auth login`. It's the device flow below and creates their account on first sign-in; `zero auth register` is an alias for the same command, not a separate signup. - **Fully autonomous — no human in the loop** → `zero auth agent register`. Anonymous account plus a managed wallet, no browser, no one to hand a URL to. - **Never** use `zero auth agent register` when a human is present — it mints an account owned by *no one* (a human can only take it over later via the claim flow). If there's a human, `zero auth login` already creates their account. Beyond that, the environment picks the mechanics. ### Persistent — the user's own computer (not a sandbox or cloud runner) Authenticate the runner with the **device-code login**. It's non-interactive and agent-friendly: you start it, show the user a URL, then run the finish step — which **polls on its own** until they authorize. No browser is opened on the machine running the agent, and you do **not** wait for the user to tell you they're done — the finish command blocks until it knows. ```bash # 1. Start: prints a URL + user code and exits immediately (no waiting, no browser). zero auth login --start --json # → {"deviceCode":"…","userCode":"WXYZ-1234","verificationUri":"https://…", # "url":"https://…?code=WXYZ-1234","pollInterval":5,"expiresAt":…} # 2. Show the user the "url" (and the userCode) and ask them to authorize it in their browser. # 3. Immediately run finish. It BLOCKS and polls (~every 2s) until the user authorizes, then # persists the session. Run it right after step 2 — do NOT pause to ask "are you done yet?"; # the command returning is your signal. zero auth login --finish <deviceCode> --json # → {"status":"ok","user":{"id":"…","email":"…"}} once authorized # → {"status":"expired"} if the ~10 min code TTL lapses first ``` Treat the finish command's return as the source of truth: a successful exit means the session is already persisted; `{"status":"expired"}` means the code lapsed — start over from step 1. Never block the conversation polling by hand or waiting on the user to confirm; `--finish` is the poll. The session is saved to the shared `~/.zero/config.json`, so authenticating once here also signs you in everywhere Zero is used on this machine — the standalone `zero` CLI and your other agents all share the one login. Check identity any time with `zero auth whoami`. ### Autonomous — no human in the loop (`zero auth agent register`) When there is genuinely no human to send to a browser, register an anonymous agent account: ```bash zero auth agent register --json # → {"status":"ok","registrationId":"…","userId":"…","walletAddress":"0x…", # "claimTokenExpires":"…"} ``` One command, no browser, no waiting. What you get: - A signed-in session, persisted to `~/.zero/config.json` like any other login. - A **managed wallet, created at signup** — you can search, get, fetch, and pay immediately. It starts empty: fund it with `zero wallet fund` (`--no-open` prints the funding URL instead of opening a browser; the link is one-time use). - A **claim token**, saved in `~/.zero/config.json` — a human's future path to owning this account. It expires (the deadline is printed at registration and stored as `claimTokenExpires` in the config), and an unclaimed account is cleaned up after the registration expires — so hand the account to a human (below) before then if the work should outlive it. If it errors with "Already signed in", there's an existing session — don't stack a fresh anonymous account on top of it. ### Claim handoff — `zero auth agent claim <email>` When a human should own an agent-registered account, link it to them. The ceremony is the **reverse of the device flow**: the hosted claim page shows the *human* a pairing code, they read it back to you, and *you* complete with the code. ```bash # 1. Start: prints the hosted claim URL. zero auth agent claim human@example.com # 2. Send the human the URL. They sign in as that email and the page shows THEM a pairing code. # 3. They read the code back to you. On a TTY the command prompts for it inline; in # non-interactive runs, complete with a second invocation: zero auth agent claim human@example.com --code <code> ``` `--code` completes the attempt already in flight — re-running *without* `--code` mints a fresh link and invalidates the code the human is holding. After the claim, the account belongs to the human, every pre-claim session is revoked, and the CLI rotates onto fresh credentials automatically — nothing to re-run. If the start step fails, the claim token has likely expired (check `claimTokenExpires` in `~/.zero/config.json`). ### Ephemeral / sandbox — cloud, CI, web/mobile sandbox runners A device-code login won't work — the environment can't hold a persisted session. Run the published `@zeroxyz/cli` directly and authenticate via the **MCP connector's `authorize` tool**. **Code execution is required.** This whole path runs the CLI in a shell; if the environment can't execute commands, stop and have the user enable it. **Egress (reactive, not a gate).** `zero fetch` calls each capability's own URL on arbitrary domains, so the environment needs unrestricted outbound access — not just the npm registry and `*.zero.xyz`. A Zero-only allowlist passes search/get and then breaks every fetch. Don't verify this up front. If a fetch hangs or fails with a DNS/connection error, restricted egress is the first thing to suspect: have the user select "All domains" (or the equivalent unrestricted-egress option). Reaching `*.zero.xyz` alone doesn't prove arbitrary-domain egress. 1. **Get the runner — install once, don't `npx` per call.** Per-call `npx -y @zeroxyz/cli@latest` re-resolves the package every time (~2–3s each, even warm) and prints npm notices to stderr. If the sandbox filesystem persists across commands — most do, even when each command runs in a fresh *shell* — install once and call the bare binary: ```bash npm install -g @zeroxyz/cli@latest # ~1s cached; puts `zero` on PATH zero --help # ~0.9s/call thereafter ``` Only if the filesystem is reset between commands (no install survives) fall back to `npx -y @zeroxyz/cli@latest` everywhere `zero` appears below. 2. **Authorize.** If the connector (`https://mcp.zero.xyz`) isn't available as a tool yet, walk the user through adding it and the one-time consent. Then call its **`authorize`** tool to get a short-lived authorization `code`. 3. **Exchange the code for a session token — without printing it.** The code from `authorize` is one-time; the reusable credential is the session token that `zero auth exchange` returns. The command writes the bare token to stdout precisely so you can capture it straight to disk. Never run it bare, `echo`/`cat` the token, or paste it into the conversation — the token must not land in the transcript. The token file lives on disk, so — like the install above — it survives a fresh shell; the axis that matters is filesystem persistence, not env persistence. ```bash # Typical harness: fresh shell per command (env vars don't carry over), persistent filesystem. # Write the token to an owner-only file once, then load it per call: (umask 077; zero auth exchange <code from authorize> > /tmp/zero-session-token) ZERO_SESSION_TOKEN="$(cat /tmp/zero-session-token)" zero search "…" ``` Every CLI call picks `ZERO_SESSION_TOKEN` up from the environment. (`auth exchange --json` emits `{token, expiresAt}` instead, if you need the expiry.) 4. **Re-mint when it expires.** The token is short-lived and has no refresh path. If calls start failing with an auth error mid-task, call `authorize` again, re-run `auth exchange`, and re-capture `ZERO_SESSION_TOKEN` the same way. 5. **Reviewing across a fresh shell.** The `runId` on `fetch`'s stderr is gone by the next command in a fresh-shell harness — so capture it from the `--json` envelope at call time (see **Output handling**) and review by runId rather than re-deriving the slug (see **Reviews — what to write**). ### Bring-your-own signing If the user supplies their own wallet key, set `ZERO_PRIVATE_KEY=0x…` in the environment. It takes precedence for signing and works alongside either identity path above. Only use a key the user explicitly provides; never generate one. ### Funding Funding is managed server-side. If a call fails for insufficient balance, point the user to https://www.zero.xyz/profile to fund their Zero account. On an agent-registered account there is no signed-in human profile — use `zero wallet fund --no-open` and relay the one-time funding URL instead. ## Sign in to other services with Zero (identity assertion) Zero can act as the user's identity provider — on services that support agent auth with `identity_assertion` (ID-JAG) **and** list Zero among their trusted issuers. Support is advertised in the service's `/.well-known/oauth-authorization-server` metadata; the issuer trust list is the service's own (usually documented in its `auth.md`), so this is not universal. Where both hold, a signed-in Zero session turns into working credentials in one command — no signup, no email, no verification code. When a service 401s you or asks agents to authenticate, it's cheap to try before walking the service's own registration ceremony: the command reports immediately when the lane isn't offered or Zero isn't trusted, and you fall back. ```bash # Discovers the service's metadata, mints an ID-JAG from Zero, registers it with the # service, and prints a short-lived bearer token — alone on stdout, so capture it: TOKEN=$(zero auth identity <host>) # Use the token on the service's API; combines fine with payment on paid endpoints: zero fetch https://<host>/some/endpoint -H "Authorization: Bearer $TOKEN" ``` **First-time sign-in needs the user's consent.** The command prints an approval link (on stderr) and exits without a token. When that happens, follow this sequence exactly: 1. **STOP running commands. Put the approval link in your reply to the user, then wait for your next turn.** The user cannot see command output — tool results are visible only to you. The ONLY way the link ever reaches them is you pasting it into a chat message; until you have, no approval can possibly arrive. Do not run `--finish` first, do not batch it with other commands, do not bury the link mid-workflow. 2. Only after the link has gone out in a message: `TOKEN=$(zero auth identity <host> --finish)` waits up to a minute for their decision and prints the token the moment they approve. 3. `No decision yet` is not an error — the user just hasn't clicked. Confirm the link is actually in a message they can read (step 1), then re-run `--finish` to keep waiting. Running `--finish` in a loop *before* the user has been shown the link is the guaranteed-failure mode: it can only ever return `No decision yet`, because you're polling for a decision the user has no way to make. Rules and error recovery: - **Consent is the user's, decided in their browser — once.** There is no flag that skips it, and only the link-bearing approve page can grant it — so the STOP-and-show sequence above is the only path through. The decision is recorded on their Zero account, so no machine or surface ever asks again for that service (a platform fronting many storefronts counts as one service; the page also offers a "don't ask again for anything" option). - Needs a signed-in session on a claimed account (`zero auth login`, or an agent account after `zero auth agent claim`). An anonymous agent account has no identity to assert. - The bearer token is minutes-lived. Re-run the command for a fresh one — repeat runs reuse the stored registration, so they need no consent prompt and no new mint. Never `echo` the token or paste it into the conversation. - **Unsupported or issuer not enabled** — the service doesn't accept identity assertion or doesn't trust Zero as an issuer. Fall back to the service's own agent auth: fetch its `/auth.md` and follow it. - **login_required** — the user's Zero sign-in is too old for this service's freshness window. Have them re-run `zero auth login`, then retry; nothing on the service side helps. - **interaction_required** — the user's email already has an account at that service. The command prints a verification URL: send the user there, the page shows THEM a pairing code, and you finish with `zero auth identity <host> --claim-code <code>`. ## Direct calls Zero works on any endpoint, not just indexed ones. Whenever you already have a specific URL to call — the user named it, or you discovered it yourself (e.g. a storefront or API you found while browsing) — call it directly: `zero fetch <url>`. Being absent from Zero's index is no reason to refuse it or to swap in a different, indexed capability instead. Search is for when you need to *find* a capability; don't insist on it when you already know what to call. A `--capability` value (token, slug, or uid) comes from `zero search` or a capability's page, so you won't have one for a URL you reached this way — omit it and just pass the URL. The server matches the URL to a capability on its own for attribution when it recognizes it; if it doesn't, the call still runs and is still recorded. **Review it either way.** A direct-URL run is reviewable by its `runId` (printed on stderr after the call, and in the `fetch --json` envelope) whether or not the server resolved it to a capability. Do not go looking for a `--capability` token to make the review work — a bare URL can't produce one, and you don't need one. If Zero later indexes that URL, your review moves with the run and becomes part of that capability's rating. Older CLI builds print `This URL isn't an indexed capability, so the run can't be reviewed` after a direct call. That message is stale — review the `runId` anyway; it succeeds. Don't let it send you to `zero search`. ## The loop 1. **Search** — `zero search "weather forecast"`. Always re-search; capabilities, prices, and rankings churn. Never reuse URLs/schemas/prices from memory or earlier in the conversation. Each result includes a short **attribution token** (`token` field, format `z_xxx.N` where `N` is the 1-based position). Use this token — not the position number — in subsequent steps; it encodes the search context so the run is tied back to the originating search for attribution. 2. **Inspect** — `zero get <token> --formatted` (e.g. `zero get z_Ab12cd.1`) prints a human summary plus a copy-pasteable `Try it:` line. Plain `zero get <token>` returns full JSON (URL, method, `bodySchema`, examples, pricing). You can also pass a slug or uid. If `bodySchema` is `null`, skip that result — don't invent field names. 3. **Call** — `zero fetch <url> --capability <token> [-d '<json>'] [-H 'k:v'] [--max-pay 0.50]`. Pass `--capability <token>` so the run is recorded and attributed to the search. 402 responses are paid automatically (x402 + MPP, including cross-chain bridging from Base to Tempo). 4. **Review** — `zero review <runId> --success --accuracy N --value N --reliability N --content "<observation>"`.
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub