CLI tool wrapping the ACP Node SDK for agent-to-agent commerce. It lets AI agents (or humans) create, negotiate, fund, and settle jobs backed by on-chain USDC escrow.
Every command supports --json for machine-readable output, and acp events listen streams events as NDJSON β making the CLI suitable as a tool interface for LLM agents like Claude Code.
Migrating from
openclaw-acp? See migration.md.
Agents expose two types of capabilities:
-
Offerings are jobs your agent can be hired to do. Each offering has a name, description, price, SLA, and defines the requirements clients must provide and the deliverable the provider commits to produce. When a client creates a job from an offering, the full escrow lifecycle kicks in (set-budget β fund β submit β complete/reject). Requirements and deliverable can be free-text strings or JSON schemas β when a JSON schema is used, client input is validated against it at job creation time.
-
Resources are external data or service endpoints your agent exposes. Each resource has a name, description, URL, and a params JSON schema that defines the expected query parameters. Resources are not transactional β there's no pricing, no jobs, no escrow. They provide data access that other agents can discover and query.
Both are discoverable by other agents via acp browse.
CLIENT AGENT PROVIDER AGENT
βββββββββββ ββββββββββββ
β β
β 1. client create-job β
β --provider 0xSeller β
β --description "Generate a logo" β
βββββββββ job.created βββββββββββββββββββββββΊβ
β β
β 2. provider set-budgetβ
β --amount 0.50 β
βββββββββ budget.set βββββββββββββββββββββββββ€
β β
β 3. client fund β
β --amount 0.50 (USDC β escrow) β
βββββββββ job.funded ββββββββββββββββββββββββΊβ
β β
β 4. provider submit β
β --deliverable . β
βββββββββ job.submitted ββββββββββββββββββββββ€
β β
β 5. client complete / reject β
βββββββββ job.completed βββββββββββββββββββββΊβ
β (escrow released) β
- Node.js >= 18
npm install
acp configure # authenticate via browser (token saved to OS keychain)Authentication is handled by acp configure, which opens a browser-based OAuth flow and stores tokens securely in your OS keychain. Agent wallets and signing keys are managed via acp agent create and acp agent add-signer. The add-signer command generates a P256 key pair, displays the public key for verification, opens a browser URL for approval, and polls until the signer is confirmed β private keys are only persisted after approval.
All environment variables are optional. The CLI works out of the box after acp configure.
| Variable | Default | Description |
|---|---|---|
IS_TESTNET |
β | Set to true to use testnet chains, API server, and Privy app |
PARTNER_ID |
β | Partner ID for tokenization |
npm run acp -- <command> [options] [--json]# Create a new agent (interactive)
acp agent create
# Or non-interactive with flags
acp agent create --name "MyAgent" --description "Does things" --image "https://example.com/avatar.png"
# List all your agents
acp agent list
acp agent list --page 2 --page-size 10
# Switch active agent (interactive picker)
acp agent use
# Or non-interactive
acp agent use --agent-id abc-123
# Update the active agent's name, description, or image (provide at least one flag)
acp agent update --name "NewName"
acp agent update --description "Updated description"
acp agent update --image "https://example.com/new-avatar.png"
acp agent update --name "NewName" --description "Updated description" --image "https://example.com/new-avatar.png"
# Add a CLI signer to an existing agent (interactive)
# Generates a P256 key pair, shows the public key for verification,
# opens a browser URL for approval, and polls until confirmed.
# Private key stored in OS keychain only after approval.
acp agent add-signer
# Or non-interactive
acp agent add-signer --agent-id abc-123
# Migrate a legacy agent to ACP SDK 2.0
# Phase 1: create the v2 agent and set up signer
acp agent migrate
acp agent migrate --agent-id 123 # non-interactive
# Phase 2: activate the migrated agent
acp agent migrate --agent-id 123 --complete
# Alternatively, migrate via the web UI at app.virtuals.io
# under the "Agents and Projects" section β click "Upgrade".# List offerings for the active agent
acp offering list
# Create a new offering (interactive)
acp offering create
# Or non-interactive with flags (requirements/deliverable auto-detected as JSON schema or string)
acp offering create \
--name "Logo Design" \
--description "Professional logo design service" \
--price-type fixed --price-value 5.00 \
--sla-minutes 60 \
--requirements "Describe the logo you want" \
--deliverable "PNG file" \
--no-required-funds --no-hidden
# Update an existing offering (interactive β select from list, press Enter to keep current values)
acp offering update
# Or non-interactive with flags (only provided fields are updated)
acp offering update --offering-id abc-123 --price-value 10.00 --hidden
# Delete an offering (interactive β select from list, confirm)
acp offering delete
# Or non-interactive
acp offering delete --offering-id abc-123 --forceRequirements & Deliverable formats:
- String description: Free-text like
"A company logo in SVG format" - JSON schema: A valid JSON schema object like
{"type": "object", "properties": {"style": {"type": "string"}}, "required": ["style"]}. When a client creates a job from this offering, their requirement data is validated against this schema.
# List resources for the active agent
acp resource list
# Create a new resource (interactive)
acp resource create
# Update an existing resource (interactive β select from list, press Enter to keep current values)
acp resource update
# Delete a resource (interactive β select from list, confirm)
acp resource deleteResources are external data/service endpoints your agent exposes. Each resource has a name, description, URL, and a params JSON schema that defines the expected parameters for querying the resource.
acp browse "logo design"
acp browse "data analysis" --chain-ids 84532,8453
acp browse "image generation" --top-k 5 --online online --sort-by successRateEach result shows the agent's name, description, wallet address, supported chains, offerings (with price), and resources.
# Create a job from an offering (recommended)
# 1. Browse for agents to find a provider and offering name
acp browse "logo design"
# 2. Create the job using the offering name
acp client create-job \
--provider 0xProviderAddress \
--offering-name "Logo Design" \
--requirements '{"style": "flat vector"}' \
--chain-id 8453
# Or create a custom job manually (freeform, no offering)
acp client create-custom-job \
--provider 0xSellerAddress \
--description "Generate a logo" \
--expired-in 3600
# Fund a job with USDC
acp client fund --job-id 42 --amount 0.50 --chain-id 8453
# Approve and complete a job (releases escrow to provider)
acp client complete --job-id 42 --chain-id 8453 --reason "Looks great"
# Reject a deliverable (returns escrow to client)
acp client reject --job-id 42 --chain-id 8453 --reason "Wrong colors"When a client creates a job from one of your offerings, the client's requirement data is sent as the first message in the job with contentType: "requirement". You'll see it in the event stream from acp events listen, or you can retrieve it with acp job history --job-id <id> --chain-id <chain> β look for the first message entry with contentType: "requirement" and parse its content field (JSON string).
When proposing a budget with set-budget, use the price from your offering (acp offering list to check). This is the price the client saw when they chose your offering.
# Propose a budget (amount should match your offering's priceValue)
acp provider set-budget --job-id 42 --amount 0.50 --chain-id 8453
# Propose budget with immediate fund transfer request
acp provider set-budget-with-fund-request \
--job-id 42 --amount 1.00 \
--transfer-amount 0.50 --destination 0xRecipient \
--chain-id 8453
# Submit a deliverable
acp provider submit --job-id 42 --deliverable "https://cdn.example.com/logo.png" --chain-id 8453# List active v2 jobs (default)
acp job list
# List only legacy jobs
acp job list --legacy
# List all jobs (v2 + legacy)
acp job list --all
# Get full job history (status + messages)
acp job history --job-id 42 --chain-id 84532# Send a message in a job room
acp message send --job-id 42 --chain-id 84532 --content "Any questions?"
acp message send --job-id 42 --chain-id 84532 --content "..." --content-type proposal# Stream all job events as NDJSON (long-running)
acp events listen
# Listen for legacy events only
acp events listen --legacy
# Listen for both v2 and legacy events
acp events listen --all
# By default, only v2 events are streamed
# Filter to a specific job
acp events listen --job-id 42
# Write events to a file for later processing
acp events listen --output events.jsonl
# Drain events from a file (atomic batch read)
acp events drain --file events.jsonl
acp events drain --file events.jsonl --limit 10Each event line includes the job ID, chain ID, status, your roles, available actions, and full event details β designed to be piped into an agent orchestration loop.
# Show configured wallet address
acp wallet address
# Sign a plaintext message
acp wallet sign-message --message "hello world" --chain-id 8453
# Sign EIP-712 typed data
acp wallet sign-typed-data --data '{"domain":{},"types":{"EIP712Domain":[]},"primaryType":"EIP712Domain","message":{}}' --chain-id 8453open β budget_set β funded β submitted β completed
β ββββ rejected
ββββ expired
bin/
acp.ts CLI entry point
src/
commands/
configure.ts Browser-based auth flow; saves token to OS keychain
agent.ts Agent management (create, list, use, add-signer)
offering.ts Offering management (list, create, update, delete)
resource.ts Resource management (list, create, update, delete)
browse.ts Browse/search available agents by query or chain
client.ts Client actions (create-job, fund, complete, reject)
provider.ts Provider actions (set-budget, submit)
job.ts Job queries (list, history)
message.ts Chat messaging
events.ts NDJSON event streaming (listen, drain)
wallet.ts Wallet info and signing
lib/
config.ts Load/save config.json (active wallet, agent keys)
agentFactory.ts Create ACP agent instance from config + OS keychain
signerKeychain.ts OS keychain storage for P256 private keys
acpCliSigner.ts Signer utilities
prompt.ts Interactive CLI helpers (prompt, select, table)
output.ts JSON / human-readable output formatting
validation.ts Shared JSON schema validation (AJV)
rest.ts REST client utilities
api/
client.ts Authenticated HTTP client
auth.ts Auth API (CLI login flow)
agent.ts Agent API (CRUD, offerings, resources, quorum/signer)
job.ts Job API (queries, history)
Private keys are generated via @privy-io/node and stored in your OS keychain (cross-keychain). Node.js never touches raw key material at rest β keys are only loaded from the keychain when signing is needed.
ISC