meridian402.xyz / quickstart

Your agent's first paid call.

Meridian sells live RWA market intelligence on Robinhood Chain to autonomous agents. There are no accounts, no API keys, and nothing to sign up for: your agent calls a tool, receives a price, pays it in USDG on-chain, and gets the data. About five minutes, start to first answer.

payment is the auth USDG · Robinhood Chain MCP over HTTP from $0.01 per call

01 What you need

a wallet
Any EVM wallet your agent controls, funded with a few dollars of USDG and a little ETH for gas on Robinhood Chain.
chain id
4663 (Robinhood Chain)
USDG contract
0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168
explorer
robinhoodchain.blockscout.com
endpoint
https://api.meridian402.xyz/mcp: opening with the public desk; every line below also runs against a self-hosted Meridian.
runtime
Node 18+, npm i viem @modelcontextprotocol/sdk

02 How the rail works

Call a priced tool with no payment attached and the server answers HTTP 402 with formal terms: the price in USDG (6 decimals), the treasury address, and the network:

{"x402Version":1,"accepts":[{
  "scheme":"exact",
  "network":"robinhood-chain",
  "maxAmountRequired":"100000",        // $0.10, USDG 6-decimals
  "resource":"meridian_basis_feed",
  "payTo":"0x76a4fF023Faa6Ea3E378d9e6d74Eb6B2676FB38c"
}]}

Your agent pays with a plain USDG transfer() to payTo, then retries the same call with an X-PAYMENT header: base64({"txHash":"0x…"}). The server verifies the transfer on-chain and answers. Three rules: the transfer must be at least the price, mined within the last 15 minutes, and one tx buys exactly one call: hashes are burned after use, replays are rejected.

03 The whole client, ~60 lines

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { createWalletClient, createPublicClient, http, parseAbiItem, defineChain } from "viem";
import { privateKeyToAccount } from "viem/accounts";

const MERIDIAN = "https://api.meridian402.xyz/mcp";
const USDG = "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168";
const chain = defineChain({ id: 4663, name: "robinhood",
  nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
  rpcUrls: { default: { http: [process.env.RPC_URL!] } } });
const account = privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`);
const wallet = createWalletClient({ account, chain, transport: http() });
const pub = createPublicClient({ chain, transport: http() });

async function callOnce(tool: string, args: object, payment?: string) {
  const transport = new StreamableHTTPClientTransport(new URL(MERIDIAN),
    { requestInit: { headers: payment ? { "X-PAYMENT": payment } : {} } });
  const client = new Client({ name: "my-agent", version: "1.0.0" });
  await client.connect(transport);
  try { return await client.callTool({ name: tool, arguments: args }); }
  finally { await client.close(); }
}

export async function paidCall(tool: string, args: object = {}) {
  try { return await callOnce(tool, args); }        // free tools answer here
  catch (err) {
    const msg = String((err as Error).message);
    const at = msg.indexOf('{"x402Version"');
    if (at < 0) throw err;                       // not a payment challenge
    const terms = JSON.parse(msg.slice(at)).accepts[0];

    // pay: one USDG transfer for the quoted amount
    const hash = await wallet.writeContract({ address: USDG,
      abi: [parseAbiItem("function transfer(address,uint256) returns (bool)")],
      functionName: "transfer",
      args: [terms.payTo, BigInt(terms.maxAmountRequired)] });
    await pub.waitForTransactionReceipt({ hash });

    // retry with proof
    const payment = Buffer.from(JSON.stringify({ txHash: hash })).toString("base64");
    return await callOnce(tool, args, payment);
  }
}

// first paid call: the live pool-vs-market basis, $0.10
console.log(await paidCall("meridian_basis_feed"));

04 What's on the shelf

toolwhat your agent getsprice
meridian_basis_feed24/7 pool price vs the latest real-market print, per depth-verified ticker: the convergence signal$0.10
meridian_lp_scorewhich pools are safe to make markets in: real volume, fee flow, 30-min markout$0.05
meridian_suggest_routethe desk strategy's current read, with its reasoning$0.05
meridian_market_universethe mapped RWA universe: venues, depth, fee traps$0.02
meridian_carry_quoteyield-carry terms: price vs par, depth, route$0.02
meridian_market_datalive prices + momentum from the venue's own pools$0.01

Free, no payment needed: meridian_list_chains, meridian_list_assets, meridian_agent_thoughts (the live reasoning feed of our own agent), meridian_index_yield.

05 Verify everything

Every payment you make is a public transaction, and so is everything our desk does with its own money: same wallet, same explorer: the Meridian treasury & trading wallet. If a payment fails verification you'll get the reason in plain text: payment tx already used, payment tx too old, or insufficient payment.

Building a fleet instead of a single agent? The same tools power hosted Meridian agents you can reserve in two decisions: build a profile on the main page and you're in the launch queue.