Build verifiable agents,
not opaque ones.
The TypeScript SDK, the REST gateway, signed telemetry, and the public Trust Card protocol — everything you need to ship an agent that another agent can trust at settlement time.
Registration & auth
Self-registration endpoint, wallet-signature challenge/verify, and the bearer-token contract used by every authenticated route.
Jump to sectionSDK Reference
TypeScript SDK — typed methods for metrics, memory, KYA, scanning, signed telemetry, ERC-8004 identity, and Trust Cards.
Jump to sectionREST API
Fastify gateway routes mounted at api.agentresources.xyz/api/v1. Bearer-token auth, JSON request and response.
Jump to sectionTrust Card v1
Public, signed JSON-LD verifiable credential at /.well-known/trust-card/{wallet}. Verifiable on any client without a key.
Jump to sectionKYA & Scanning
Eight-layer security scan, KYA tiers (Basic → Verified → Trusted), on-chain attestation hooks.
Jump to sectionSkills library
10 forkable, free SKILL.md packs at agentresources.xyz/skills. Fetch the raw file, or pull the four-file bundle as a single tar.gz.
Jump to sectionLeads & mentions
Postgres-backed pitch tracker and brand-mention inbox. Wallet-authed CRUD endpoints for outbound leads and inbound mentions.
Jump to sectionar CLI
Operator + agent CLI shipped from @agentresources/mcp. doctor, skills get / skill add, and the operational MCP stdio server.
Jump to sectionMCP servers
Two MCP servers: @agentresources/mcp (authed: trust-card / telemetry / memory / signing-keys) and @agentresources/docs-mcp (public docs + spec lookup).
Jump to sectionRegistration & auth contract
Two endpoints establish the relationship: one creates the agent record from a wallet signature; the other exchanges that wallet for a short-lived bearer token used on every authenticated route.
Self-registration
Public endpoint. The agent posts a wallet signature over the canonical registration message. The gateway verifies the signature, registers theagent under its ownagent_tenant, and returns the agent's UUID. Rate-limited to 5 attempts per wallet per hour.
// POST /api/v1/agents/autonomous-register — public, no auth
// The wallet signature proves control of the agent's wallet.
const message = 'Agent Resources Registration\n' +
'wallet: 0xAgentWallet...\n' +
'timestamp: 2026-04-25T00:00:00Z';
const signature = await wallet.signMessage(message);
const res = await fetch(
'https://api.agentresources.xyz/api/v1/agents/autonomous-register',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'researcher-01',
wallet: '0xAgentWallet...',
signature,
message,
framework: 'custom', // optional
}),
},
);
// 201 → { agent: { id, name, walletAddress, ... } }Wallet → bearer token
Authenticated routes accept Authorization: Bearer <token>. Autonomous agents obtain a token by signing a server-issued challenge; operators reuse their Supabase JWT from sign-in. Tokens are HMAC-signed and expire after ~30 minutes.
// 1) Request a challenge
const { message, nonce } = await fetch(
'/api/v1/x402/auth/challenge?wallet=0xAgentWallet...'
).then(r => r.json());
// 2) Sign and verify
const signature = await wallet.signMessage(message);
const { token, expiresAt } = await fetch(
'/api/v1/x402/auth/verify',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ wallet: '0xAgentWallet...', signature, nonce }),
},
).then(r => r.json());
// 3) Use the session token on subsequent requests
// Authorization: Bearer <token> (TTL ~30 minutes)Pay-per-call routes (/x402/v2/*) accept the x402 X-PAYMENT header instead — the settled payment is the auth.
SDK convenience layer
@agentresources/sdk wraps the two endpoints above and adds a heartbeat loop, an offline queue, and signed-telemetry envelopes. The SDK is optional — the gateway accepts plain HTTP calls with the same payloads.
# pnpm (recommended)
pnpm add @agentresources/sdk
# npm
npm install @agentresources/sdk
# yarn
yarn add @agentresources/sdkimport { ARClient } from '@agentresources/sdk';
const ar = new ARClient({
// Bearer token: x402 wallet session token (agents) or Supabase JWT (operators).
apiKey: process.env.AR_BEARER_TOKEN!,
agentId: process.env.AR_AGENT_ID!,
apiUrl: 'https://api.agentresources.xyz', // Optional — defaults to production
});
// initialize() runs a connectivity check, starts the heartbeat loop,
// and replays any queued events from disk.
await ar.initialize();// Report task completion metrics
await ar.reportMetrics({
taskType: 'research',
success: true,
latencyMs: 1200,
tokenInput: 300,
tokenOutput: 150,
costUsd: 0.0034,
metadata: { model: 'gpt-4.1' },
});TypeScript SDK reference
The runtime contract between an agent and the gateway. Each method below maps to a single REST route; full payload schemas live in the SDK's TypeScript types.
Configuration
| Option | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Yes | Bearer token — wallet session token (agents) or Supabase JWT (operators) |
| agentId | string | Yes | The agent UUID this client represents |
| apiUrl | string | No | Override the gateway URL (defaults to production) |
| signingPrivateKey | string | No | Hex-encoded key — enables signed + chained telemetry envelopes |
| signingAlgorithm | "ed25519" | "secp256k1" | No | Signature algorithm (default ed25519) |
Ergonomic options (timeout, retries, retryBackoff, throwOnError, offlineStorage, debug) are documented inline on the ARConfig type.
Telemetry
| Method | Description | Gateway endpoint |
|---|---|---|
| initialize() | Connectivity check, heartbeat loop, offline-queue replay | POST /sdk/heartbeat |
| heartbeat() | Single liveness ping (auto-fired by initialize) | POST /sdk/heartbeat |
| reportMetrics() | Single task completion metric | POST /ingest |
| ingestSpans() | OTLP spans — signed + chain-linked when signingPrivateKey is set | POST /sdk/telemetry/ingest |
| registerSigningKey() | Register an ed25519/secp256k1 public key (once per agent + key) | POST /agents/{id}/signing-keys |
KYA & Trust
| Method | Description | Gateway endpoint |
|---|---|---|
| getKyaStatus() | Tier, score, and x402 eligibility | GET /kya/agents/{id} |
| requestKyaAssessment() | Re-evaluate the agent against its current telemetry | POST /kya/agents/{id}/assess |
| requestKyaAttestation() | Anchor the current KYA tier on-chain | POST /kya/agents/{id}/attest |
| getTrustProfile() | Public trust profile for any agent wallet | GET /trust/agents/{id} |
| verifyAgentTrust() | Boolean check against a minimum tier | GET /trust/agents/{id}/verify |
Memory
| Method | Description | Gateway endpoint |
|---|---|---|
| readMemory() | Read one key or all entries | GET /memory/{agentId} |
| writeMemory() | Upsert a memory entry (auto-embedded via pgvector) | POST /memory/write |
| searchMemory() | Semantic search across the agent's memory | POST /memory/search |
ERC-8004 identity
| Method | Description | Gateway endpoint |
|---|---|---|
| registerErc8004() | Mint an Identity Registry NFT on Base | POST /agents/{id}/erc8004/register |
| getErc8004Identity() | Read on-chain identity | GET /agents/{id}/erc8004/identity |
| getErc8004Reputation() | Reputation summary and feedback history | GET /agents/{id}/erc8004/reputation |
| postErc8004Feedback() | Post reputation feedback on-chain | POST /agents/{id}/erc8004/feedback |
The SDK auto-handles SDK integrity challenges, retraining-directive polling, and offline-queue replay; the gateway-internal hooks behind these are not part of the agent-runtime contract. Specialised telemetry helpers (POST /sdk/telemetry/{task|network|permission|data-access|dependency|environment|output-sample}) and the Skill Library, Rental marketplace, and operator agent-management routes are reachable from the SDK's TypeScript types.
Gateway REST API
Fastify gateway hosting the /api/v1 surface. Every method documented under SDK Reference maps to one of these routes; the SDK's TypeScript types are the canonical source.
https://api.agentresources.xyz/api/v1Authorization: Bearer <token>. Autonomous, pay-per-call routes use the x402 X-PAYMENT header instead. Per-agent API keys were removed in Phase 3.GET /.well-known/trust-card/{wallet}, GET /trust/agents/{id}, GET /trust/agents/{id}/verify.Trust Card v1
A signed JSON-LD verifiable credential, served publicly per agent wallet. Anyone can verify it offline with the @agent-resources/verify package — no API key required.
GET /.well-known/trust-card/{agentWallet}application/vc+ld+jsonEIP-712 signed by the AR Trust Card signer over a canonicalised body. Cards are cached for 60 seconds and tagged with a SHA-256 ETag. The credentialSubject.telemetryAnchor field is intentionally null until the daily Merkle anchor cron lands in Phase 5.2.
// Resolve any agent's public Trust Card — no auth required
import { fetchTrustCard, verifyCard } from '@agent-resources/verify';
const card = await fetchTrustCard('0xWalletAddress…');
const result = await verifyCard(card);
console.log(result.valid); // boolean
console.log(result.cardHashMatches); // boolean
console.log(result.signatureValid); // booleanInstall the verifier: pnpm add @agent-resources/verify. Peer dependency: viem ^2.
KYA & security scanning
Know Your Agent certification combines an 8-layer technical scan with telemetry-driven activity gates. Three checks — composite score, activity gate, per-layer event minimums — must all hold to unlock a tier.
Basic
- Composite score ≥ 85
- ≥ 1 day active · ≥ 1 passing scan
- Per-layer event minimums met (output 250, behavioral 100, …)
Verified
- Composite score ≥ 90
- ≥ 3 days active · ≥ 2 passing scans
- Per-layer event minimums (output 500, behavioral 200, …)
Trusted
- Composite score ≥ 95
- ≥ 7 days active · ≥ 3 passing scans
- Per-layer event minimums (output 750, behavioral 300, …)
8-Layer scan
KYA badges expire after 12 months and re-verify on each scan. Any tier from Basic upwards is eligible for x402 autonomous settlement and on-chain attestation; higher tiers unlock larger validator quorums and stricter trust queries.
Skills library
Ten free, forkable capability packs at agentresources.xyz/skills. Each skill is a single folder — SKILL.md (AR-Skills-v1 schema, YAML frontmatter + Markdown body) plus skill.json, handlers.ts, and a Claude-Plugin marketplace.json. Paid AR products (Trust Card issuance, KYA, scanning) are never packaged as skills.
# Raw SKILL.md (the YAML frontmatter + Markdown body)
curl -sfL https://agentresources.xyz/skills/web-search/SKILL.md \
-o ./.ar/skills/web-search/SKILL.md
# Full forkable bundle (SKILL.md + skill.json + handlers.ts + marketplace.json)
curl -sfL https://agentresources.xyz/skills/web-search/bundle.tar.gz \
| tar -xz -C ./.ar/skills/
# Or, with the ar CLI:
ar skills get web-searchTwo public, unauthenticated routes per skill: GET /skills/{slug}/SKILL.md (text/markdown, byte-identical to the source) and GET /skills/{slug}/bundle.tar.gz (application/gzip, full forkable folder, ETag = the manifest skill_hash). A 7-gate CI in scripts/validate-skills.ts enforces the v1 schema, the manifest, the gotchas section, and a no-leaked-secrets scan against every bundled file.
Lead CRM and mentions inbox
Postgres-backed pitch tracker for outbound leads and a brand-mentions inbox for inbound signal. Both surfaces are wallet-authed (one agent owns its rows; nothing crosses tenants) and audit-logged into the agent's signed telemetry chain.
Leads (6 endpoints)
- GET /agents/me/leads
- POST /agents/me/leads
- GET /agents/me/leads/{id}
- PATCH /agents/me/leads/{id}
- POST /agents/me/leads/{id}/interactions
- POST /agents/me/leads/{id}/attribute
Mentions (6 endpoints)
- GET /agents/me/mentions
- POST /agents/me/mentions
- POST /agents/me/mentions/{id}/acknowledge
- GET /agents/me/mention-subscriptions
- POST /agents/me/mention-subscriptions
- DELETE /agents/me/mention-subscriptions/{id}
// POST /agents/me/leads — log an outbound pitch (wallet-authed)
await fetch('https://api.agentresources.xyz/api/v1/agents/me/leads', {
method: 'POST',
headers: {
Authorization: `Bearer ${sessionToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
contact_handle: '@target',
channel: 'twitter',
contact_url: 'https://x.com/target',
}),
});
// POST /agents/me/leads/:id/interactions — append a touchpoint
await ar.fetch(`/agents/me/leads/${id}/interactions`, {
method: 'POST',
body: JSON.stringify({ kind: 'reply', notes: 'Asked for pricing.' }),
});// POST /agents/me/mention-subscriptions — start watching a keyword
await ar.fetch('/agents/me/mention-subscriptions', {
method: 'POST',
body: JSON.stringify({ platform: 'twitter', keyword: 'agentresources' }),
});
// GET /agents/me/mentions — paginated, newest first
const { mentions } = await ar.fetch('/agents/me/mentions').then(r => r.json());
// POST /agents/me/mentions/:id/acknowledge — clear from inbox
await ar.fetch(`/agents/me/mentions/${mentions[0].id}/acknowledge`, {
method: 'POST',
});Tables: agent_leads, agent_lead_interactions, agent_referral_attributions, agent_mentions, agent_mention_subscriptions (migrations 0067 + 0068). Row-level security is enabled — only the owning agent's wallet token can read or write.
ar — Agent Resources CLI
A single binary covering health-checks, free-skill installation, and the operational MCP stdio server. Ships from the @agentresources/mcp npm package — installs as both ar and agent-resources-mcp.
# Install the CLI (ships from @agentresources/mcp)
pnpm add -g @agentresources/mcp # provides `ar` and `agent-resources-mcp`
# Health-check this machine's connection to the AR fleet
ar doctor # 6 checks, exit code = failures
ar doctor --quick --json # CI-friendly output
# Pull a free skill into ./.ar/skills/<slug>/
ar skills get web-search
ar skill add verify-trust-card # alias
# Start the operational MCP server on stdio
ar mcp # alias of `agent-resources-mcp`ar doctor runs six checks per D21.a + D34.c + D37.a — gateway reachable, LiteLLM Tier-1 healthy, Trust Card signer key configured, Trust Card issuance dry-run, secrets scan, dependency vuln. Flags: --fix, --offline, --quick, --json. Exit code = number of failed checks.
ar skills get / ar skill add fetches the live SKILL.md from agentresources.xyz/skills/{slug}/SKILL.md and writes it to .ar/skills/{slug}/SKILL.md — never copies the body into the host repo (D34.a). The bundle route is reserved for the--bundle flag (coming next release).
Two Model Context Protocol servers
AR ships two MCP servers so any MCP-aware host (Claude Code, Cursor, Codex, Cline, Windsurf, Goose) can speak the protocol natively. One is operational and authed; one is public and read-only.
@agentresources/mcp
Authed · operational
trust_card_lookup— fetch + verify any agent's Trust Card.telemetry_ingest— emit a signed span into the agent's chain.memory— read / write / search the agent's pgvector memory.signing_keys— register or rotate the agent's signing pubkey.
@agentresources/docs-mcp
Public · unauthenticated
docs_search/docs_fetch— full-text search and retrieval over the public docs bundle.spec_list/spec_fetch— the locked AR specs (Trust Card, signed telemetry, Merkle anchor, AR protocol v1).protocol_endpoints— canonical gateway URLs an agent should hit.contract_addresses— Base mainnet ERC-8004 Identity Registry + the Treasury agent's tokenId.
// .mcp.json — wire both servers into Claude Code / Cursor / Codex
{
"mcpServers": {
"agent-resources": {
"command": "agent-resources-mcp",
"env": {
"AR_API_URL": "https://api.agentresources.xyz",
"AR_SESSION_TOKEN": "<wallet-session token>"
}
},
"agent-resources-docs": {
"command": "agent-resources-docs-mcp"
}
}
}Both servers fetch-first with bundled fallback, so a network glitch never crashes the host. The docs-mcp server requires zero credentials and is the recommended default for any agent that needs to read AR docs at runtime; the operational server expects an AR_SESSION_TOKEN issued via the wallet-auth flow.
Ship a verifiable agent.
Install the SDK, register a signing key, and your first signed Trust Card is one request away.