MCP server for Robinhood Chain (Arbitrum Orbit L2, chainId 4663) — JSON-RPC reads, explorer-indexed token discovery, EIP-3009/USDG tooling, and unsigned transaction builders. Never holds keys.
28 tools with consistent naming (verb_noun pattern) and descriptions (all 25+ chars). Input schemas present for all tools with proper type definitions. However, parameter descriptions are sparse or missing for many tools, most params lack guidance on format, constraints, or valid ranges. Output schemas are undocumented; responses are text-only without structured field definitions. Error handling is generic ('Error: {message}') with no recovery guidance. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite all tools being read-only. Composition is sound, tools are single-responsibility and chainable via address/token parameters.
L2 block number from the ArbSys precompile. This is the value eth_blockNumber returns — distinct from the block.number a contract observes.
Chain ID reported by the ArbSys precompile, cross-checked against eth_chainId.
Speed limit, gas pool size, and max transaction gas from ArbGasInfo.
Full gas price breakdown from ArbGasInfo: per-L2-tx, per-L1-calldata-byte, per storage allocation, and the base fee components.
Current L1 base fee estimate used for data-availability pricing.
L1 pricing internals: surplus, per-batch gas charge, and the amortized cost cap.
Output schemas undocumented. All tools return text-only responses without structured field definitions. LLMs cannot plan downstream calls or extract typed data.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Minimum gas price (floor) enforced by the chain.
ArbOS version running on this chain.
Explain the three different 'block numbers' on this chain: the L2 height from eth_blockNumber, the L1 height a contract sees via block.number, and ArbSys.arbBlockNumber(). Getting these confused is the most common Orbit integration bug.
Build the EIP-712 payload to cancel an unused EIP-3009 authorization before it can be redeemed.
Build an EIP-2612 permit payload (gasless approval). Requires the token's current nonce, which is read on-chain.
Build the EIP-712 payload for receiveWithAuthorization. Unlike transferWithAuthorization, only the payee may submit it — which closes the front-running window where anyone can relay a valid authorization.
Build an UNSIGNED transaction for external signing. This server never holds keys and cannot broadcast.
Assemble the final transferWithAuthorization CALLDATA from a signed authorization, ready for a relayer to submit.
Get Robinhood Chain network identity and live head: chain ID, RPC, explorer, native currency, latest block, gas price.
Estimate gas for a call without sending it.
Estimate the L1 data-availability component of a transaction's cost via the NodeInterface precompile — the part a plain eth_estimateGas does not show.
Current gas price, with an EIP-1559 fee breakdown when the chain provides one.
Native ETH balance for an address.
Get a block by number ('latest', 'earliest', a decimal height, or a hex height).
Transaction count (nonce) for an address.
ERC-20 balance for an address. Accepts a known symbol (e.g. USDG) or a token address.
Whether an address holds contract code, and how much.
All token balances held by an address, via the explorer index. Mainnet only.
Which Arbitrum precompiles are actually usable on this chain. Probes each with a real call rather than trusting that a canonical address implies a working precompile.
Low-level eth_call with hand-built calldata. Returns raw returndata, and identifies the revert selector when the call reverts — useful for probing whether a function exists on a Diamond.
Call a read-only contract function using a human-readable signature, e.g. 'function balanceOf(address) view returns (uint256)'.
Verify an EIP-3009 signature offline: does it recover to the claimed signer, for this exact token and chain? Catches wrong-domain and cross-chain-replay signatures before they cost gas.
Parameter descriptions missing or minimal. Most parameters lack format guidance, constraints, or valid ranges. E.g., 'block' param in get_block accepts 'latest', 'earliest', decimal, or hex but description only says 'Block number or tag'.
No tool annotations. All 28 tools are read-only but lack readOnlyHint annotation. Agents cannot distinguish safe-to-retry tools from destructive ones without explicit hints.
Generic error handling. All errors return 'Error: {message}' with no recovery guidance. LLMs cannot determine if an error is retryable, user-fixable, or fatal.
list_token_holdings lacks pagination parameters. No limit, offset, or cursor support. Large token lists will blow context window.