For agents and the devs behind them

Your agent drives a real arm.

It discovers the shell, pays for a few minutes in USDC with x402, gets a token and sends commands. All over HTTP or MCP, no account.

Payment
x402 · USDC on Solana devnet
Gas
none, facilitator pays
Rate limit
10 commands / s

Give your agent this

One sentence is enough. The site publishes llms.txt with the live gateway and a client that pays once, then takes one command at a time. The agent's wallet only needs USDC on Solana: no SOL, the x402 facilitator pays the fee.

1 · Install the skill once
npx skills add francoperez03/rent-a-shell --skill rent-a-shell
2 · Create its wallet, then fund the address with USDC (devnet: faucet.circle.com)
node rent.mjs wallet
3 · Say this to your agent
Go to https://rent-a-shell.vercel.app, pick the shell, pay for 5 minutes, open the gripper and then ask me what to do next.
01

Endpoints

Every Forger runs a gateway next to their robot, and every gateway exposes the same API. This site only lists them: https://rent-a-shell.vercel.app/api/catalog gives each shell's gateway (today https://watched-playlist-women-newer.trycloudflare.com).

GET/api/shellsShell specs: ranges, HOME, routines, sensors, price, camera and status.
GET/api/shells/:id/stateReal angles and whether it is moving (current in mA when the shell has the sensor).
GET/api/shells/:id/frameCurrent JPEG camera frame.
GET/api/shells/:id/queueCurrent session and how many are waiting.
POST/api/sessions/x402?shell=&blocks=Answers 402 with the requirement. With the signed payment it returns the token.
GET/api/sessionBearerYour session status: start, expiry, whether it is active.
POST/api/cmdBearerjoint, dance or stop. Out-of-range values are clamped to the safe range.
POST/api/sessions/endBearerEnds the session and sends the robot to HOME.
GET/api/eventsSSE with status, sessions and payments.
02

Pay with x402

  1. 01Have a Solana wallet with USDC on the shell's network (devnet: faucet.circle.com). No SOL: the facilitator pays the fee.
  2. 02POST to /api/sessions/x402 with the shell and the time you want (blocks of five minutes). The response is a 402 with the payment requirement.
  3. 03Your client signs the USDC payment and retries with the header. No gas: the facilitator pays it.
  4. 04You get token, starts_at and expires_at. If the robot is busy, your time starts when the previous session ends.
  5. 05Send commands with Authorization: Bearer. When time runs out, the robot returns to HOME on its own.
TypeScript · x402 fetch client
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { ExactSvmScheme } from "@x402/svm/exact/client";
import { toClientSvmSigner } from "@x402/svm";
import { createKeyPairSignerFromBytes, getBase58Encoder } from "@solana/kit";

const GW = "https://watched-playlist-women-newer.trycloudflare.com";
// Solana wallet with USDC; the facilitator pays the fee, no SOL needed
const signer = await createKeyPairSignerFromBytes(getBase58Encoder().encode(process.env.AGENT_SOLANA_KEY));

// 1. Pay for five minutes (blocks=1): the 402 carries the requirement, the client signs and retries.
const client = new x402Client();
client.register("solana:*", new ExactSvmScheme(toClientSvmSigner(signer)));
const pay = wrapFetchWithPayment(fetch, client);
const res = await pay(`${GW}/api/sessions/x402?shell=el-tucu&blocks=1`, { method: "POST" });
const { token, starts_at, expires_at } = await res.json();

// 2. Send commands with the token while the session lasts.
await fetch(`${GW}/api/cmd`, {
  method: "POST",
  headers: { "content-type": "application/json", authorization: `Bearer ${token}` },
  body: JSON.stringify({ cmd: "joint", args: { joint: "base", angle: 130 } }),
});

// 3. End early (optional). When time runs out it returns to HOME on its own.
await fetch(`${GW}/api/sessions/end`, { method: "POST", headers: { authorization: `Bearer ${token}` } });
Commands · POST /api/cmd body
{ "cmd": "joint", "args": { "joint": "base", "angle": 130 } }
{ "cmd": "dance", "args": { "rutina": "saludo" } }
{ "cmd": "stop" }
03

MCP

Two servers. The catalog at https://rent-a-shell.vercel.app/mcp (list_shells, get_shell) and each gateway's own at <gateway>/mcp, where renting and commands happen.

  • list_shells
  • rent_shell
  • send_command
  • get_frame
  • get_state
  • end_session
MCP config
{ "mcpServers": { "rent-a-shell": { "type": "http", "url": "https://rent-a-shell.vercel.app/mcp" }, "el-tucu": { "type": "http", "url": "https://watched-playlist-women-newer.trycloudflare.com/mcp" } } }