CLI
On this page
The self-agent CLI ships with the TypeScript SDK. It generates the agent key on your machine, prints a QR URL for the human to scan with the Self app, and reads completion straight from the registry. The agent key never leaves the machine.
npx -p @selfxyz/agent-sdk self-agent --help
# or, inside a project that depends on @selfxyz/agent-sdk:
npx self-agent --help
The CLI supports two modes, and generates the agent key in both: linked, where the human’s wallet (--human-address) owns the NFT, and wallet-free, where the agent’s own address owns it. For ed25519, ed25519-linked, privy and smartwallet, use requestRegistration or the REST API.
Register
# 1. Create a local session (generates the agent key)
npx -p @selfxyz/agent-sdk self-agent register init \
--mode linked --human-address 0xYourWallet --network testnet \
--minimum-age 18 --ofac --out .self/session.json
# 2. Print the QR URL; the human opens it and scans the QR code with the Self app
npx -p @selfxyz/agent-sdk self-agent register open --session .self/session.json
# 3. Wait until the agent is verified on-chain
npx -p @selfxyz/agent-sdk self-agent register wait --session .self/session.json --timeout-seconds 1800
# 4. Export the agent key (explicit --unsafe required)
npx -p @selfxyz/agent-sdk self-agent register export --session .self/session.json --unsafe --out-key .self/agent.key
register open prints a URL on the API (https://agent-api.self.xyz/cli/register?payload=...) that renders the Self app QR code as a PNG. The payload holds only public data. register wait polls the registry until the agent appears, then prints stage: "onchain_verified", agentAddress and agentId. register status shows the session state at any time.
Deregister
npx -p @selfxyz/agent-sdk self-agent deregister init \
--mode linked --human-address 0xYourWallet --agent-address 0xAgent --network testnet \
--out .self/dereg.json
npx -p @selfxyz/agent-sdk self-agent deregister open --session .self/dereg.json
npx -p @selfxyz/agent-sdk self-agent deregister wait --session .self/dereg.json
Use the same disclosure flags as at registration. deregister wait finishes with stage: "onchain_deregistered".
Commands and flags
| Command | Required | Optional |
|---|---|---|
register init | --mode; --human-address for linked | --network, --out, --ttl-minutes (30), disclosure flags, --chain --registry --rpc, --app-url, --app-name, --scope |
deregister init | --mode, --agent-address; --human-address for linked | Same as register init |
register open, deregister open | --session | None |
register wait, deregister wait | --session | --open (print the QR URL first), --timeout-seconds (1800), --poll-ms (4000) |
register status, deregister status | --session | None |
register export | --session, --unsafe, and --out-key <path> and/or --print-private-key | None |
Disclosure flags: --minimum-age 0|18|21, --ofac, --nationality, --name, --date-of-birth, --gender, --issuing-state. Without --out, the session is written to .self/session-<id>.json.
Exit codes for wait:
0: success.2:--timeout-secondselapsed. The session stays valid, so runwaitagain until itsexpiresAt.1: any other error, including an expired session.
Session file
Session files are written with mode 0600 and hold the generated agent key, so treat them as secrets and delete them once the key is stored. Top-level keys: version, operation, sessionId, createdAt, expiresAt, mode, disclosures, network (chainId, rpcUrl, registryAddress, endpointType, appUrl, appName, scope), registration (humanIdentifier, agentAddress, userDefinedData, challengeHash, signature), state and secrets.
state.stage moves from initialized to handoff_opened to onchain_verified (or onchain_deregistered), or ends as expired.
Orchestrating from a backend
An agent product can drive the CLI instead of asking users to run it: run init, send the open URL to the user, run wait until onchain_verified, then store the exported key encrypted. To avoid shelling out, call the REST API directly.
Refreshing a proof
The CLI has no refresh command. Use requestProofRefresh({ agentId, network }) or the REST API’s proof refresh, which keeps the same agent ID and key.
Configuration
| Variable or flag | Default | Purpose |
|---|---|---|
SELF_AGENT_APP_URL / --app-url | https://agent-api.self.xyz | API that renders the /cli/register QR code |
SELF_AGENT_APP_NAME / --app-name | Self Agent ID | Self app name (must match the registry config) |
SELF_AGENT_SCOPE / --scope | self-agent-id | Self scope (must match the registry config) |
--chain, --registry, --rpc | From --network | Custom chain configuration |
A flag wins over its environment variable, which wins over the default.
Thanks. What went wrong?
Thanks for your feedback!