V-Pod for agents
GPU compute an agent can discover, price, pay and use without a human in the loop. MCP first: https://v-pod.com/mcp. No account, no API key — payment is the authorization.
Overview
V-Pod aggregates GPU capacity from many upstream clouds and marketplaces into one normalized, source-agnostic catalog — one schema, one USD-per-GPU-hour price, upstream identity never exposed. Paying in USDC provisions a real SSH pod; it terminates automatically when the paid hours end.
- ✓ MCP first — 7 tools over Streamable HTTP;
tools/listis open, discovery needs no auth. - ✓ Machine-payable — x402 on Base, or a plain USDC transfer on Base/Solana. Exact amounts, idempotent.
- ✓ Real provisioning — a settled rental opens a pod; a reaper closes it at expiry, every time.
- ✓ LLM-readable — /llms.txt and the agent card summarize everything on this page.
MCP quickstart
Stateless JSON-RPC 2.0 over POST (Streamable HTTP). Point any MCP client at the endpoint, or speak raw JSON-RPC:
# 1 · handshake
curl -X POST https://v-pod.com/mcp -H 'content-type: application/json' -d '{
"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-06-18","capabilities":{},
"clientInfo":{"name":"my-agent","version":"1.0"}}}'
# 2 · discover (no auth)
curl -X POST https://v-pod.com/mcp -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 3 · browse live inventory
curl -X POST https://v-pod.com/mcp -H 'content-type: application/json' -d '{
"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{"name":"list_gpu_offers","arguments":{"gpu":"H100","region":"eu","limit":5}}}'Claude Code: claude mcp add v-pod --transport http https://v-pod.com/mcp
Tool reference
list_gpu_offersgpu substring, region, min_vram_gb, max_usd_hr, limit). Returns offers with id, gpu, gpuCount, vramGb, region, pricePerHrUsd, tier, availability, useCases. Ids stay stable while the inventory shape persists.get_gpu_offeroffer_id.quote_rentaloffer_id × hours (1–720): USD total, 6-decimal atomic USDC amount, and every open payment rail with its receiving address. Total = pricePerHrUsd × gpuCount × hours.rent_gpu_hourspaid · USDCaccepts[] carries the exact, guaranteed terms. Sign an EIP-3009 transferWithAuthorization for that exact amount and retry with the X-PAYMENT header → V-Pod settles on-chain, provisions the pod, returns a rental receipt + X-PAYMENT-RESPONSE. Idempotent per authorization.redeem_rental_transferpaid · USDCquote_rental (Base or Solana), then submit the tx hash / signature. Chain auto-detected, transfer verified on-chain, pod provisioned. Idempotent per transaction.get_rental_statusrental_id: provisioning → active → closed, expiry, and live SSH details (host, port, user) once the pod is up.close_rentalrental_id. Unused hours are not refunded in v1 (hourly spot pricing).Paying in USDC
Two rails, both exact-amount, both idempotent. The 402 price is the settled price — quotes float with inventory, only the challenge guarantees an amount.
# Rail A — x402 (Base, EIP-3009 gasless)
POST /mcp tools/call rent_gpu_hours {offer_id, hours} → HTTP 402
accepts[0] = { scheme:"exact", network:"base",
maxAmountRequired:"5570000", # atomic, 6 decimals
payTo:"0xb12B…59C0",
asset:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", # USDC contract
extra:{ name:"USD Coin", version:"2" } } # EIP-712 domain
sign TransferWithAuthorization{from,to,value,validAfter,validBefore,nonce}
retry with X-PAYMENT: base64({x402Version:1,scheme:"exact",network:"base",
payload:{signature,authorization}})
→ 200 + rental receipt + X-PAYMENT-RESPONSE {success,network,transaction,payer}
# Rail B — plain transfer (Base or Solana)
quote_rental → { usdc_atomic, base:{pay_to}, solana:{pay_to} }
send EXACTLY usdc_atomic to pay_to on either chain
tools/call redeem_rental_transfer {offer_id, hours, tx_hash}
→ 200 + rental receiptFail-closed by design: verification failures never charge; if provisioning fails after settlement, the payment is banked as credits on the paying wallet — never a silent loss.
Rental lifecycle
paid → provisioning → active (SSH via get_rental_status) → closed
├─ close_rental (early, no refund)
└─ auto-terminated at expires_at (reaper, ≤10 min)The rental_id in the receipt is the capability token for status and close — store it like a secret. Pods run a PyTorch CUDA image with SSH; connection details appear in get_rental_status once the pod boots (typically ~60s).
REST API
The catalog is also plain REST — public, no auth:
/api/podscurl https://v-pod.com/api/pods
# → { "count": 103, "offers": [ { "id":"m_…", "gpu":"NVIDIA H100 80GB",
# "gpuCount":1, "vramGb":80, "region":"eu", "pricePerHrUsd":2.99,
# "tier":"secure", "availability":"high",
# "useCases":["inference","fine-tuning","training"], "source":"market" } ] }source is only ever market or community — never a provider name. Writes (quote / pay / provision / close) go through MCP.
Agent identity
- ✓ /.well-known/agent-card.json — A2A card: name, provider, skills, endpoints
- ✓ /llms.txt — LLM-readable site summary
- ✓ Listed on jishie (agent-standard conformant: open introspection, machine-readable USDC pricing, idempotent paid calls)
Errors & limits
- · Errors are typed JSON —
{"error":"…"}or a JSON-RPC error object. Never HTML. - ·
/mcp: 60 requests/min/IP →429withRetry-After. Back off with jitter. - · Paid surfaces can pause for maintenance →
503withRetry-After. - · Hours per rental: 1–720. Amounts: exact only — over- or underpayment is rejected, nothing is charged.
- · Paid calls are idempotent: replaying a payment returns the same rental, never a second charge.
https://v-pod.com/mcp