CRA AGENT
Lets an agent pay for x402 APIs in USDC on Arc, under a spending policy it cannot change.
التثبيت
أضف هذا إلى إعدادات MCP في عميلك (Claude Desktop: claude_desktop_config.json، وCursor: .cursor/mcp.json، ويستخدم VS Code وغيره الصيغة نفسها «mcpServers»).
@cra-agent/mcpclaude mcp add cra-agent -e 'CRA_NETWORK=arcTestnet' -e 'CRA_KEY_FILE=<CRA_KEY_FILE>' -e 'CRA_POLICY=<CRA_POLICY>' -e 'CRA_RPC_URL=<CRA_RPC_URL>' -e 'DATABASE_URL=<DATABASE_URL>' -- npx -y @cra-agent/mcp@0.0.11
{
"mcpServers": {
"cra-agent": {
"command": "npx",
"args": [
"-y",
"@cra-agent/mcp@0.0.11"
],
"env": {
"CRA_NETWORK": "arcTestnet",
"CRA_KEY_FILE": "<CRA_KEY_FILE>",
"CRA_POLICY": "<CRA_POLICY>",
"CRA_RPC_URL": "<CRA_RPC_URL>",
"DATABASE_URL": "<DATABASE_URL>"
}
}
}
}
متغيرات البيئة
CRA_NETWORKإلزامي arc (mainnet) or arcTestnetCRA_KEY_FILEإلزامي Path to a chmod 600 file holding the agent's private key. Never put the key in a prompt.CRA_POLICYSpending limits, e.g. daily=5,per_seller=0.5,per_payment=0.05CRA_RPC_URLOptional RPC endpoints, comma separated, in priority orderDATABASE_URLOptional Postgres for the ledger; in memory without it
التوثيق
مأخوذ من ملف README للمشروع على GitHub ويُحدَّث أسبوعيًا. تفتح الروابط على GitHub.
المحتويات
CRA AGENT
Payments for AI agents on Arc, Circle's USDC-native L1. One tool call and an agent can buy an API call for a fraction of a cent: the rail reads the x402 price, applies a spending policy the model cannot change, verifies the seller, pays gas-free through Circle Gateway, and writes the receipt to a ledger.
TypeScript monorepo, npm workspaces, Node 22. Site: cra-agent.tech.
Status: the buyer agent, the seller middleware and the MCP server are built and exercised end to end on
Arc testnet. See docs/arc-verification.md for every value verified against docs.arc.io.
Packages
| Package | What it does |
|---|---|
packages/accounting | The only module allowed to do arithmetic on USDC amounts. Branded types Usdc6 (ERC-20 interface) and Usdc18 (native/gas interface), dust-preserving conversions, property tests |
packages/policy | Pure spend control: caps per payment, per day and per counterparty, rate limit, allow/deny lists, required identity, seller-bond hook. Compact syntax daily=5,per_seller=0.5,… |
packages/ledger | Every payment attempt (quoted / rejected / signed / settled / failed) with amount, counterparty, latency and transaction. MemoryLedger and PgLedger; exposure() per counterparty |
packages/identity | Signing with an explicit scheme parameter (secp256k1 today, post-quantum reserved) and ERC-8004 resolution, fail closed. registerIdentity() mints the agent identity |
packages/router | The buyer rail: rail.quote(url) and rail.fetch(url) over x402 with Circle Gateway batched settlement (gas-free) or the standard on-chain exact scheme. chooseRail() is pure: nanopayment vs escrow |
packages/escrow | The ERC-8183 rail for jobs: createJob, setBudget, fund (with USDC approval), submit, complete/reject, claimRefund. ABI taken from the verified implementation on chain; the evaluator is injected |
packages/seller | createSeller().route("GET /x", "$0.001") for Hono, createExpressSeller() for Express. Payments verified and settled by Circle Gateway; any x402 buyer can pay |
packages/collector | Block-zero collector: blocks, per-block stats by operation, contract deploys, base fee inputs, per-provider RPC observations. Optionally transactions, receipts, logs and revert reasons. Append-only Postgres with the raw JSON-RPC preserved |
packages/api | Read API over the collector database (Hono): /v1/network, /v1/fees, /v1/fees/estimate, /v1/activity, /v1/deploys, /v1/rpc, /v1/fx, /v1/token, /v1/health, plus the paid /v1/paid/* routes, described for agents and directories at /openapi.json. Also serves the website |
packages/web | The site: product landing (/), live network page (/network) and token page (/token, price, burns and payouts). Plain HTML, CSS and TypeScript, hand-drawn SVG charts |
packages/mcp | MCP server over stdio: arc_quote, arc_pay, arc_balance, arc_deposit, arc_ledger, arc_policy, plus the escrow tools arc_job_create, arc_job_fund, arc_job_status, arc_job_decide, arc_job_submit. Also a CLI |
Setup
nvm use # Node 22
npm install
cp .env.example .env # then set DATABASE_URL and ARC_RPC_URLS
npm test
npm run db:migrate
npm run collector
npm run web:build && npm run api # http://localhost:8791
Local Postgres (Homebrew, keg-only):
LC_ALL=en_US.UTF-8 /opt/homebrew/opt/postgresql@17/bin/pg_ctl -D /opt/homebrew/var/postgresql@17 -l /opt/homebrew/var/postgresql@17/server.log start
The agent
# .env: CRA_NETWORK=arc, CRA_KEY_FILE=.secrets/agent.key (chmod 600), CRA_POLICY=…
npm run rail -- policy
npm run rail -- quote https://api.cra-agent.tech/v1/paid/fees/forecast
npm run rail -- deposit 1 # wallet USDC into the Gateway balance
npm run rail -- pay https://api.cra-agent.tech/v1/paid/fees/forecast
npm run rail -- ledger
npm run mcp # MCP server on stdio
npm run rail -- identity-register https://cra-agent.tech/.well-known/agent.json # ERC-8004, costs gas
npm run rail -- job status 1 # ERC-8183
As an MCP server, for any MCP client:
{ "mcpServers": { "cra-agent": {
"command": "cra-agent-mcp",
"env": {
"CRA_NETWORK": "arc",
"CRA_KEY_FILE": "/etc/cra-agent/agent.key",
"CRA_POLICY": "daily=5,per_seller=0.5,per_payment=0.05,identity=required"
}
} } }
The policy is read from the environment, not from the conversation: the model cannot raise its own limit, and never sees the key.
Selling
import { createSeller } from "@cra-agent/seller";
const seller = createSeller({ sellerAddress, network: "arc" })
.route("GET /v1/forecast", "$0.001", { description: "Weather forecast, per call" });
app.use(seller.middleware()); // Hono; createExpressSeller() for Express
Setting SELLER_ADDRESS in .env turns on our own paid routes: the API then serves /v1/paid/*
(catalogue at /v1/paid) priced per call, described for agents at /openapi.json.
A route can also be offered on a second network at the same price. The x402 discovery catalogues are
filled by the facilitator that settles a payment, and no facilitator settles Arc except Circle's,
which does not catalogue: DISCOVERY_FACILITATOR_URL (or CDP_API_KEY_ID / CDP_API_KEY_SECRET)
adds that rail, and scripts/pay-on-network.mts <url> [network] buys a route there once so the
catalogue picks it up. The Arc rail is untouched and our own buyer keeps choosing it.
Two guarantees worth knowing
- A broken endpoint costs the buyer nothing. x402's default flow verifies the payment, runs the
handler, and settles only if it succeeded. Our own API exposes
GET /v1/paid/selftest/fail, a priced route that always answers 500, so anyone can check it: the response is 500, the receipt readsnot_charged, and the Gateway balance does not move. - Every receipt can be checked by someone who was not there. It carries the limits the payment
passed under and what had already been spent, and it is signed with the agent's key (EIP-712).
cra-agent verify receipt.jsonrecovers the signer and redoes the arithmetic, with no key and no network. Be clear about what that proves: the agent's key issued this statement and nobody altered it since. It is the rail vouching for its own decision. The independent half is the settlement. - Every settled payment ends with a transaction anyone can check. Circle Gateway settles in batches,
so the transfer reaches the seller after the response.
cra-agent proof(MCP:arc_proof) matches settled payments to the on-chain USDC transfer that carried them and stores the hash in the ledger.
Collector
- Head worker: follows the chain head (250 ms poll), ingests in batches (two JSON-RPC calls per block:
the full block and all its receipts), keeps a contiguous cursor in
collector_state. - Backfill worker: fills the history down to block zero and any gap the head left behind, at low priority; it pauses whenever the head worker falls behind.
- Scanner: every 10 minutes, looks for numeric holes and
parent_hashdiscontinuities. Never auto-fixes. - Probe: every 5 seconds asks every endpoint for
latest,finalizedandsafe, storinghead_observations(per-provider lag and latency) and evaluating alerts. - Enrich: revert reasons by replaying failed transactions with
eth_callagainst the parent block; runtime bytecode size and hash for deploys. - Startup guard: every endpoint must report the expected chain id and the same genesis hash; the database binds itself to that genesis and refuses any other chain.
- Prices: for every watched pair (EURC, and the project token when
TOKEN_ADDRESSis set) it records each swap against USDC at the rate it executed. Transfers are netted per pair of addresses, so a token that taxes transfers is priced correctly, and a hop that merely forwarded what it was handed is skipped instead of guessed. Served at/v1/fx?symbol=and, with the size curve and venues, at/v1/paid/fx/execution. - Modes:
COLLECTOR_MODE=light(default: blocks, per-block stats by operation, deploys, RPC observations, around 0.5 GB/day) orfull(also transactions, receipts, logs and reverts). - Health:
GET :8790/health(JSON, 503 when lagging or stalled),GET :8790/metrics(Prometheus). - Alerts: log plus optional Telegram on lag, stall, all RPCs down, open gaps, low disk.
Database summary: npm run status -w @cra-agent/collector.
Deploy
deploy/setup.sh installs everything on an Ubuntu VPS running Caddy (Node 22, Postgres 17, systemd units
for the collector and the API, a Caddy site). See deploy/README.md.
Tests and migrations
npm testruns the vitest suites inpackages/*/test: property tests on the accounting module (fast-check), block parsing, RPC pool failover, spend policy, rail choice, signing, escrow mapping. CI runs them on every push together with a ledger round-trip against a real Postgres.- Migrations live in
packages/collector/sql/NNN_*.sqland are applied in order bypackages/collector/src/db/migrate.ts(tableschema_migrations), automatically when the collector starts or vianpm run db:migrate. The ledger has its own inpackages/ledger/sql, applied byPgLedger.migrate().
Publishing
npm login
scripts/publish.sh --dry-run # then without the flag
House rules
- No arithmetic on USDC amounts outside
packages/accounting. - No mainnet deployment without explicit confirmation.
- Keys and API keys only in
.env(git-ignored) or a file withchmod 600, never in chat or in code.
License
MIT.
الأسئلة الشائعة
ما هو CRA AGENT؟
Lets an agent pay for x402 APIs in USDC on Arc, under a spending policy it cannot change.
كيف أثبّت CRA AGENT؟
يعمل على جهازك. في Claude Code: claude mcp add cra-agent -e 'CRA_NETWORK=arcTestnet' -e 'CRA_KEY_FILE=<CRA_KEY_FILE>' -e 'CRA_POLICY=<CRA_POLICY>' -e 'CRA_RPC_URL=<CRA_RPC_URL>' -e 'DATABASE_URL=<DATABASE_URL>' -- npx -y @cra-agent/mcp@0.0.11. وفي العملاء الآخرين، الصق إعداد JSON من هذه الصفحة في إعدادات MCP الخاصة بهم.
هل يحتاج CRA AGENT إلى مفتاح API؟
نعم. يتطلب CRA_NETWORK, CRA_KEY_FILE، وتضبطها في إعداداته.
هل CRA AGENT مفتوح المصدر؟
نعم. شيفرته متاحة على GitHub بترخيص MIT.
من يصون CRA AGENT؟
ينشره giupy997. يدرجه AI.tn لكنه لا يصونه ولا يوصي به.
من سجل MCP الرسمي. الإدراج ليس توصية: راجع شيفرة الخادم وصلاحياته قبل منحه الوصول إلى بياناتك.