# AgentMetal — llms.txt # The server provider you can use end-to-end: discover -> pay -> provision -> operate -> renew. # No signup, no API key to buy. Pay USDC over x402 (v2) on Base, or a card. BASE_URL: https://api.agentmetal.dev ## Start here: the free catalog (no payment, no account) GET /v1/catalog -> { plans:[{ id, vcpu, memory_gb, disk_gb, usd_per_day, usd_per_month }], locations:[{ code, city, country }], bandwidth:{ included_tb, extra_usd_per_tb }, storage:{ usd_per_gb_day, min_gb, max_gb } } Call this first to see sizes, regions, and prices before you pay anything. ## Provision a server 1) Request without payment: POST /v1/servers {"plan": "nano", "days": 7} # plan: nano|small|medium, days: 1-30 optional fields: ssh_key: your public key (root@ login) via: preferred location code (see /v1/catalog) managed_key: true -> we generate the keypair; the 201 returns ssh_private_key ONCE (stored only encrypted server-side). Lets you SSH in (and use /exec) without bringing a key. -> 402 Payment Required. The body is an x402 v2 PaymentRequired: x402Version: 2 accepts[]: { scheme:"exact", network:"eip155:8453", asset:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" (USDC), amount:"", payTo:"0x...", maxTimeoutSeconds:120 } resource: { url, description } card.checkout_url: optional hosted Stripe Checkout (card rail, >= $0.50) 2) USDC path: sign the accepts[0] requirement with your wallet, base64-encode the x402 payment payload, and resend the identical request with: X-PAYMENT: Idempotency-Key: # replays return the original response -> 201 { id, status, plan, ipv4, ssh:"root@", expires_at, renew } (+ ssh_private_key once, if you sent managed_key:true) NOTE: sshd is still booting at the 201 — the box accepts SSH ~10-15s later. Retry on "connection refused" for the first ~20s. If the payment is rejected you get 402 again with a "payment_error" object: { reason, required_atomic, required_usdc, message, hint } The usual cause is the payer wallet holding less USDC than required_usdc — top up and retry. Free trial / pre-flight: add "dry_run": true to the POST body to validate your WHOLE payment pipeline at no cost — the API verifies your signed X-PAYMENT (signature + on-chain funds) and returns { dry_run, payment_valid, would_provision, quote } WITHOUT charging or provisioning. Use it to confirm you can pay before committing real money. Card path: open card.checkout_url, pay, and the server provisions on webhook. Helpers (recommended — they hide the EIP-3009 signing): the @agentmetal/mcp MCP server, or the x402 *v2* client (@x402/fetch + @x402/evm). NOTE: the old x402-fetch v1 does NOT parse this v2 quote (eip155:8453, nested resource) — use the scoped @x402/* v2 packages, or just use @agentmetal/mcp. With @x402/evm, sign with a viem LocalAccount (not a WalletClient). ## Endpoints GET /v1/catalog plans/locations/prices (PUBLIC, FREE) POST /v1/servers provision (402-gated) GET /v1/servers?wallet=0x... list your fleet (or Bearer am_live_... key) GET /v1/servers/{id} status (incl. bandwidth usage + storage volumes) POST /v1/servers/{id}/extend renew the lease (402-gated) {"days": 7} POST /v1/servers/{id}/bandwidth buy extra egress, $2/TB (402-gated) {"tb": 5} POST /v1/servers/{id}/storage attach a block volume (402-gated) {"gb": 50} POST /v1/servers/{id}/reboot soft reboot (account key + ownership) GET /v1/servers/{id}/diagnostics hypervisor view, no login (account key + ownership) POST /v1/servers/{id}/exec run a root command over SSH (see below) DELETE /v1/servers/{id} destroy early (account key + ownership) POST /v1/claim {"email"} -> 6-digit OTP emailed (AWS SES) POST /v1/claim/verify {"email","code","wallet?","wallet_signature?"} -> { account, api_key: "am_live_..." } POST /v1/billing/checkout monthly card subscription (account key) POST /v1/webhooks/stripe Stripe fulfillment webhook GET /health GET /llms.txt , /agents.md this manual + a short manifest /mcp remote MCP endpoint (see below) ## Add-ons (buy against a running server, each 402-gated) Bandwidth: every server includes 20 TB/mo egress; buy more at $2/TB: POST /v1/servers/{id}/bandwidth {"tb": N} Storage: attach block storage at $0.01/GB/day (prorated to the remaining lease), POST /v1/servers/{id}/storage {"gb": 10-1000} -> auto-formatted + mounted at /mnt/HC_Volume_ (returned in the response). ## Operate a running server (account key + ownership required) /reboot soft (graceful ACPI) reboot. /diagnostics hypervisor-level view WITHOUT logging into the box: status, recent provider actions (with errors), a VNC console URL, and live CPU/disk/ network metrics. (The provider exposes no text boot log.) /exec POST {"command", "timeout_seconds"?} -> run as root over SSH; returns { exit_code, stdout, stderr, timed_out }. Requires the server to have been provisioned with managed_key:true. Bounded: 1-120s timeout (default 60), 256 KB output cap. ## Connect via MCP (Model Context Protocol) Local server — full tools, signs USDC payments with YOUR wallet: npx @agentmetal/mcp (set WALLET_PRIVATE_KEY = an EVM key with USDC on Base) tools: provision_server, get_server, list_servers, extend_server, destroy_server, claim_account, verify_claim Remote server — no key; discover + quote + status only. Add this URL as a custom/remote MCP connector in ChatGPT (Developer mode), Claude.ai, or Le Chat: https://api.agentmetal.dev/mcp tools: list_plans, get_payment_options, get_server, list_servers ## Plans (prepaid per day, 1-30 days per payment; any payer, no registration) nano 2vCPU/2GB/40GB $0.70/day (or $20/mo with an account) small 3vCPU/4GB/80GB $1.30/day (or $38/mo with an account) medium 4vCPU/8GB/160GB $2.40/day (or $68/mo with an account) Locations: ash (Ashburn, US), hil (Hillsboro, US). See /v1/catalog for the live list. USDC amounts are atomic (6 decimals): $4.90 = "4900000". ## Accounts (optional) Anonymous purchase works forever; the paying wallet owns the server. Claim an account (email OTP via AWS SES) to get one am_live_ key that manages your fleet and unlocks reboot, diagnostics, exec, early destroy, and monthly card billing. ## Notes - Every box boots with /root/SERVER.md describing itself + how to renew/spawn. - Errors are JSON envelopes: { error, message, docs }.