meridian402.xyz / quickstart
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.
4663 (Robinhood Chain)0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168https://api.meridian402.xyz/mcp: opening with the public desk; every line below also runs against a self-hosted Meridian.npm i viem @modelcontextprotocol/sdkCall 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.
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"));
| tool | what your agent gets | price |
|---|---|---|
| meridian_basis_feed | 24/7 pool price vs the latest real-market print, per depth-verified ticker: the convergence signal | $0.10 |
| meridian_lp_score | which pools are safe to make markets in: real volume, fee flow, 30-min markout | $0.05 |
| meridian_suggest_route | the desk strategy's current read, with its reasoning | $0.05 |
| meridian_market_universe | the mapped RWA universe: venues, depth, fee traps | $0.02 |
| meridian_carry_quote | yield-carry terms: price vs par, depth, route | $0.02 |
| meridian_market_data | live 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.
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.