@seekdaseek/agentfeed-mezo

中文文档
0.2.0发布于 2026/11/02MITES Module

Pay AgentFeed per call in MUSD on Mezo and Base. An MCP server and CLI for agents, plus the HTTP 402 gateway behind mezo.ochinimus.app.

原始使用文档
文档目录15 节
  1. Judge it in five minutes
  2. How it works
  3. Why permit, not x402 "exact"
  4. Replay and abuse protection
  5. Routes
  6. Addresses (Mezo testnet, chain 31611)
  7. Sample paid transactions
  8. For agents: client and MCP tool
  9. How it extends AgentFeed
  10. Run your own
  11. Tests
  12. Status and honest limits
  13. Wave 2 plan
  14. Known advisories
  15. License

agentfeed-mezo

AI agents pay AgentFeed per call in MUSD, Mezo's Bitcoin-backed stablecoin.

AgentFeed is a live, paid crypto-data API for agents: liquidations, funding, prices, Solana pre-trade checks and language tasks, 83 paid routes, an MCP server and an elizaOS plugin, already settling real USDC. This repo is the gateway that lets the same data be bought in MUSD on Mezo: the agent signs one EIP-2612 permit, the gateway settles it on-chain and pays the gas, and the data comes back in the same HTTP call.

$ curl -i https://mezo.ochinimus.app/api/sol-price
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi...   (base64 JSON: MUSD, eip155:31611, 0.01 MUSD, treasury, nonce)

Judge it in five minutes

No wallet needed for steps 1 to 3.

  1. See the 402 challenge. curl -s https://mezo.ochinimus.app/api/sol-price | head -40. It names the token (MUSD 0x118917a4...Ac503), the network (eip155:31611), the price in wei, the treasury and an HMAC-bound nonce.
  2. See real settlements. Open /stats and /payments.csv, then click any transfer_tx_url. The explorer shows a transferFrom from the gateway's settler moving 0.01 to 0.05 MUSD from the agent wallet to the treasury, and the matching permit transaction.
  3. Read the manifest. /.well-known/x402 lists the 8 routes with MUSD prices.
  4. Pay a call yourself (about 3 minutes, needs a Mezo testnet wallet):
    git clone https://github.com/seekdaseek/agentfeed-mezo && cd agentfeed-mezo && npm install
    # 1. testnet BTC to your address: https://faucet.test.mezo.org  (0.05 BTC)
    # 2. mint testnet MUSD by opening a trove on Mezo Borrow (about 0.042 BTC in, 1850 MUSD out):
    AGENT_PRIVATE_KEY=0x... TARGET_ICR_PCT=165 node scripts/fund-musd.mjs --send
    # 3. pay for data:
    AGENT_PRIVATE_KEY=0x... node src/client.js sol-price
    AGENT_PRIVATE_KEY=0x... node src/client.js liquidations limit=5 symbol=SOL
    AGENT_PRIVATE_KEY=0x... node src/client.js summarize url=https://mezo.org
    
    The client prints the status, latency, the answer and the explorer link. --scheme transfer pays with a plain MUSD transfer instead of a permit.
  5. Run the tests: npm test (62 tests, no network needed).
  6. Re-check the evidence against the chain: node scripts/verify-evidence.mjs reads every row of the public ledger from Mezo testnet (receipt status, the MUSD Transfer from payer to treasury, the amount) and prints verifiedOnChain and the treasury balance.

How it works

agent                         gateway (mezo.ochinimus.app)                  Mezo testnet         AgentFeed
  | GET /api/liquidations          |                                              |                    |
  |------------------------------->|                                              |                    |
  | 402 + PAYMENT-REQUIRED         |                                              |                    |
  |<-------------------------------|  MUSD, 0.02, treasury, spender, nonce        |                    |
  | read nonces(agent) -------------------------------------------------------->|                    |
  | sign Permit(agent -> settler, 0.02 MUSD, deadline)   (off-chain, no gas)     |                    |
  | GET + PAYMENT-SIGNATURE        |                                              |                    |
  |------------------------------->| verify: network, token, payTo, nonce, sig,   |                    |
  |                                |         balance, eth_call permit()  -------->|                    |
  |                                | GET /api/liquidations (prepaid key) --------------------------->  |
  |                                |<-------------------------------------------------- data ---------|
  |                                | permit() + transferFrom(agent -> treasury) ->| (gateway pays gas) |
  | 200 + data + explorer link     |                                              |                    |
  |<-------------------------------|                                              |                    |

Order matters: the gateway fetches the data before it settles, so if AgentFeed is down the agent is never charged and can retry with the same signed payment (upstream_unavailable, charged:false). A settlement that fails after a good answer withholds the data.

Why permit, not x402 "exact"

x402's EVM exact scheme uses EIP-3009 transferWithAuthorization. MUSD does not implement it. Checked on the deployed testnet token 0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503 (OpenZeppelin ERC20Permit, "Mezo USD", version "1", 18 decimals): the bytecode has the permit and nonces selectors and none of transferWithAuthorization, receiveWithAuthorization, authorizationState. So the gateway defines two schemes on the same 402:

schemethe agentgas paid byhow it is verified
permit (default)signs an EIP-2612 Permit(owner, settler, price, nonce, deadline)the gatewaysignature recovered against the live domain and on-chain nonce, balance read, permit() simulated with eth_call, then permit + transferFrom from the settler key
transfersends a plain MUSD transfer to the treasury, presents the tx hash plus a signed claimthe agentreceipt is successful, has enough confirmations, is newer than the challenge, has a MUSD Transfer event to the treasury of at least the price, and the claim signature recovers to that transfer's sender (so nobody can claim someone else's transfer)

Permit is the default because it gives the agent a one-shot, gasless call: the only thing an agent must hold is MUSD.

Replay and abuse protection

Every payment is recorded in sqlite and refused on a second use, under all of these keys: the signature hash, the (owner, permit nonce) pair, the challenge nonce, and every settlement tx hash (so a settled permit's transferFrom cannot be re-presented as a transfer payment). Reservation is atomic and survives restarts. The challenge nonce is issuedAt.expiresAt.random.hmac, bound to one route and one price, expires in 300 s, and a permit deadline may not outlive it. Only one permit per owner address is in flight at a time. Over-payment is refused so no allowance is left behind. Failed payments never call AgentFeed.

Routes

routeMUSD per callwhat
/api/sol-price0.01SOL/USD spot
/api/btc-price0.01BTC/USD spot
/api/liq-pulse0.01what is being liquidated right now
/api/funding-pulse0.01the most extreme perp funding rates
/api/liquidations0.02live liquidation tape (symbol, scope, limit, min_usd)
/api/market-snapshot0.02market snapshot in one call
/api/trade-context0.03prices, funding and liquidations in one call
/api/summarize0.05language task: summarize ?url=

Unknown query parameters are dropped before the call is forwarded. HEAD, POST and the rest are refused with 405, so there is no free verb.

Addresses (Mezo testnet, chain 31611)

address
MUSD token0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503
Treasury (receives MUSD)0xf01d65DBd1B946C48b7dB1f0A02AaBd021c89227
Settler (permit spender, pays gas)0xaB7323cB6aaB188D7Dca697496534BA6C95ddbC2
Demo agent wallet0x9691FedC701cD8bbDF4D0b06Dd7C9ABf2e9037B4
Mezo Borrow (used to mint testnet MUSD)0xCdF7028ceAB81fA0C6971208e83fa7872994beE5

Source of the token address: solidity/artifacts/deployments/matsnet/MUSD.json in mezo-org/musd. The mainnet and ethereum deployment folders in that repo list 0xdD468A1DDc392dcdbEf6db6e34E89AA338F9F186, and a contract named "Mezo USD / MUSD", 18 decimals, with the same permit selectors, answers at that address on Base mainnet (checked by eth_getCode and eth_call against mainnet.base.org). That is the Wave 2 target below.

Sample paid transactions

routeschemeMUSDsettlement (transferFrom / transfer)permit tx
liquidationspermit0.020xeb5a798a…01972d0xe1c3029d…935ce6
summarizepermit0.050xa5326990…5902640xc7feba69…3b1c14
trade-contextpermit0.030xa7bfc89e…db27d00xf8a292bf…d9fdfd
funding-pulsetransfer0.010xf05aa01b…00de4enone, agent paid gas

How the demo agent got its MUSD: faucet BTC, then openTrove on Mezo Borrow (0.042 BTC collateral at 165% ICR, 1850 MUSD out), the same flow scripts/fund-musd.mjs automates.

For agents: client and MCP tool

Install nothing: an MCP client can run the server straight from npm (listed in the official MCP Registry as io.github.seekdaseek/agentfeed-mezo):

{ "mcpServers": { "agentfeed-mezo": { "command": "npx", "args": ["-y", "@seekdaseek/agentfeed-mezo"],
  "env": { "NETWORK": "base", "AGENT_PRIVATE_KEY": "0x...", "MAX_PRICE_MUSD": "0.10" } } } }

NETWORK is mezo-testnet (default, test MUSD), base or mezo-mainnet (real MUSD). Use a dedicated wallet with a small MUSD balance: the server signs one permit per call and refuses any price above MAX_PRICE_MUSD. Without AGENT_PRIVATE_KEY the server still starts and list_routes (free) works.

Tools: list_routes and call_route { route, params?, scheme? }, which pays in MUSD and returns the data and the explorer link of the settlement. node scripts/mcp-smoke.mjs drives the same server over stdio from a clone.

From a clone, the command-line client does the same without MCP:

AGENT_PRIVATE_KEY=0x... NETWORK=base node src/client.js <route> [key=value ...] [--scheme permit|transfer] [--n 5] [--pretty]

src/client.js refuses to sign a challenge for another network or token, or one above MAX_PRICE_MUSD (default 0.10). A registered agent should use the default permit scheme and may read GET /agents/<address> first for its remaining budget.

How it extends AgentFeed

AgentFeed (x402.ochinimus.app, 83 paid routes, MCP server on the official registry, elizaOS plugin @seekdaseek/plugin-agentfeed) already takes USDC on Solana, Base, Polygon, Arbitrum and Arc, but every one of those rails depends on EIP-3009 or SPL transfers. MUSD is a different kind of token: ERC-20 plus EIP-2612 permit. This gateway adds that rail without touching the production server: it is a separate service that buys from AgentFeed with a prepaid API key (half list price) and resells in MUSD at 1 to 5 cents. Nothing in /opt/agentfeed was restarted or edited.

Run your own

npm install && npm test
cat > .env <<'EOF2'
TREASURY_ADDRESS=0x...        # receives the MUSD
SETTLER_PRIVATE_KEY=0x...     # permit spender; needs a little testnet BTC for gas
CHALLENGE_SECRET=<random hex> # HMAC key for challenge nonces
UPSTREAM_KEY=afk_...          # an AgentFeed prepaid key (x402.ochinimus.app/keys)
PUBLIC_URL=http://localhost:3034
EOF2
chmod 600 .env && npm start

Optional: PORT, HOST, MEZO_RPC_URL, MUSD_ADDRESS, UPSTREAM_URL, DB_PATH, CHALLENGE_TTL_SEC, CONFIRMATIONS, DAILY_UPSTREAM_CAP (defaults in src/config.js). Deployed here as PM2 agentfeed-mezo on port 3034 behind its own Cloudflare tunnel.

Tests

npm test runs 62 tests with Node's built-in runner. 52 run the real gateway code over a fake chain adapter and a fake AgentFeed, with real EIP-712 and EIP-191 signatures; 10 start src/mcp.js over stdio and drive it with the MCP SDK client against a loopback fake gateway (tool annotations, list_routes, call_route refusing a price above MAX_PRICE_MUSD, a wrong token or network, an unreachable gateway, bad arguments, and no array type in any tool input schema). They cover the happy path for both schemes, replay (same permit, same challenge, same tx hash, a settlement tx re-presented as a transfer), underpayment, over-payment, wrong token, wrong chain (network field and a permit signed for another chain id), wrong recipient, wrong spender, stale permit nonce, a signature by someone else, expired nonce, a nonce for another route, RPC down, AgentFeed down (clean 502, payer not charged, same payment works after recovery), settlement failure, and a concurrent double spend. Mocks are used only here; none of the paid-call evidence above is simulated.

Status and honest limits

  • One payment was refused after the agent had paid: the first transfer-scheme call hit a Mezo RPC node that had not indexed the receipt and got tx_not_found. The 0.01 MUSD stays in the treasury as unmatched dust (evidence/unclaimed.md). The gateway now retries a missing receipt for about 8 seconds and the client retries that refusal with the same payment; 6 transfer calls afterwards all succeeded.
  • The public Mezo RPC answers from several nodes and the same receipt can read as null on one call and be present on the next (measured). The gateway's reads can therefore, rarely, refuse a good payment; refusals never take money in the permit scheme.
  • Testnet only. MUSD on Mezo testnet has no dollar value; the point is that the full payment path runs against the real contract and chain.
  • Gas for settlement is paid by the gateway's settler key, funded from the faucet. On mainnet that cost has to be priced into the call or fronted by a fee, see Wave 2.
  • One permit in flight per agent address. An agent that wants parallel calls uses several addresses or the transfer scheme.
  • The gateway calls AgentFeed with one prepaid key and a daily cap (DAILY_UPSTREAM_CAP, default 5000 calls).

Wave 2 plan

  1. Mezo mainnet MUSD. Same code with a mainnet chain id, RPC and token address from the Mezo docs; add a per-call gas surcharge.
  2. MUSD on Base. MUSD already trades on Base, so agents that live on Base can pay without bridging. Add the Base network to the 402 accepts, and a read-only price check against the Base pools.
  3. A Telegram bot that tops up and spends MUSD for agents. A person funds a bot-held budget in MUSD, sets per-day caps, and the bot signs permits for their agents, so a trading bot or eliza agent gets data without ever holding a key. This is the Track 2 distribution surface.
  4. A permit-based spend allowance per agent (one signature, many calls) to remove the one-in-flight limit.

Known advisories

  • zod, GHSA-mrhx-c7xc-m3w5 (high): memory exhaustion when an array schema with no length limit validates a huge array of failing elements; affected < 4.6.6, patched in 4.6.6. This repo was on zod 3.25.76, which a dependency scan flagged on Oct 29 2026 (the scan listed no patched version; the GitHub advisory database and npm audit do list 4.6.6). It now depends on zod 4.6.7, the current release, with @modelcontextprotocol/sdk 1.32.2 (its peer range is ^3.25 || ^4.0). npm audit --omit=dev reports 0 vulnerabilities and all 62 tests pass on zod 4.6.7.
  • Independently of the version, the vulnerable path is not reachable from this repo's inputs: no MCP tool input schema contains an array (list_routes takes nothing; call_route takes a string, an optional string-to-string record and an enum; test/mcp.test.js asserts there is no array, items or prefixItems in either JSON schema), and the MCP server runs locally over stdio for the user's own agent. The gateway (src/server.js) does not import zod or the MCP SDK; it parses its own headers and query strings.
  • Not verified: the zod copy still installed in the gateway's node_modules on the VPS is 3.25.76. No gateway code imports it (read from the source, not tested at runtime), so it was left as is rather than redeployed.

License

MIT, see LICENSE.

版本与发布记录

@seekdaseek/agentfeed-mezo 共发布 2 个版本,首次发布于 2026/11/02;过去 12 个月发布了 2 个版本。

版本发布日期距今
0.2.0latest2026/11/021 天前
0.0.0-stage2026/11/021 天前

关于 @seekdaseek/agentfeed-mezo 的常见问题

@seekdaseek/agentfeed-mezo 是什么?

在Mezo和Base的MUSD上,每次呼叫都向AgentFeed付费。MCP服务器和用于代理的CLI,以及mezo.ochinimus.app背后的HTTP 402网关。

如何安装 @seekdaseek/agentfeed-mezo?

在项目目录运行 npm install @seekdaseek/agentfeed-mezo,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 agentfeed-mezo、agentfeed-mezo-mcp,可以用 npx agentfeed-mezo 直接运行。

@seekdaseek/agentfeed-mezo 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/seekdaseek__agentfeed-mezo 是否存在。

@seekdaseek/agentfeed-mezo 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@seekdaseek/agentfeed-mezo 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@seekdaseek/agentfeed-mezo 可以商用吗?

@seekdaseek/agentfeed-mezo 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@seekdaseek/agentfeed-mezo 还在维护吗?

最新版本 0.2.0 发布于 2026/11/02(1 天前);至今共发布 2 个版本,其中过去 12 个月发布了 2 个;首次发布于 2026/11/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。