Cross-DEX Prices & Spreads

io.github.donnywin85Published by GitHub account donnywin85v1.0.1Updated Oct 24, 2026

Live cross-DEX pool prices, liquidity and spreads on 6 EVM chains, read from on-chain pool state.

VerifiedSTDIODesktop onlyFinanceData & Analytics

Overview

AI-generated overview

Read-only MCP server giving an assistant live cross-DEX pool prices, liquidity and gross spreads on six EVM chains, plus a measurement archive.

What you can do
  • List covered chains, chain IDs, tokens and DEX venues, and see what is priceable on a chain
  • Fetch one pair's price at every venue holding a pool, with reserves, TVL, fee tier and cross-DEX spread
  • Sweep a whole chain for cross-venue dislocations ranked by gross USD at the optimal trade size
  • Inspect the measurement archive's coverage: rows, pairs tracked, chains seen, span and retention
  • Read one pair's per-venue price and liquidity series over 24h, 7d or 30d (paid plan)
When to use it
Useful when an assistant needs current on-chain DEX quotes or spread data across BSC, Polygon, Arbitrum, Base, Avalanche or Optimism, or wants to check whether a dislocation persisted rather than being a single sample. It is read-only market data, not a trading or profit-estimation tool.
Requirements
Runs locally over stdio via npx, requiring Node 18 or newer. An optional RAPIDAPI_KEY (from a RapidAPI subscription to the underlying API, free tier available) unlocks the paid tools; without it the server still starts and answers from a free hourly snapshot. ARB_DEX_TIMEOUT_MS defaults to 45000 ms because a full-chain live scan can take about 30 seconds. Network access to the API is needed.
Before you install
Spreads are gross, before gas, MEV and slippage beyond the optimal size, and are explicitly not profit estimates or trade advice. The server is read-only: it does not execute trades, hold funds or touch a wallet. RAPIDAPI_KEY is your own credential and should stay in the client config, not in code or commits. Higher plans are paid subscriptions, and the per-pair history tool requires the PRO tier or above.

Installation

In SourceWeft

  1. Open Cross-DEX Prices & Spreads in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

arb-dex-mcp

Live cross-DEX crypto prices for your AI agent — per-venue pool price, pool liquidity and the gross cross-venue spread on 6 EVM chains, read straight from on-chain pool state.

[npm] [npm downloads] [provenance] [MCP Registry] [Indexed on TensorBlock MCP Index] [Listed on mcpservers.org] [license]

Chains: BSC · Polygon · Arbitrum · Base · Avalanche · Optimism. Venues: PancakeSwap (v2 + v3), Uniswap v3, SushiSwap, QuickSwap, Biswap, ApeSwap, BaseSwap, Trader Joe, Pangolin — every v2-style pool and every v3 fee tier separately, because a $12k 1% pool and a $19M 0.01% pool are not the same quote.

Nothing is modelled, estimated or backfilled. Every payload states its own block number and carries its own scope note, so an agent that quotes a figure also has the caveats attached to it.

Works with no API key against a free hourly public snapshot. Docs · npm


Quickstart

Nothing to clone or build. Your MCP client fetches the package. Requires Node 18+.

Claude Desktop

claude_desktop_config.json — macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\:

json
{  "mcpServers": {    "arb-dex": {      "command": "npx",      "args": ["-y", "arb-dex-mcp"],      "env": {        "RAPIDAPI_KEY": "your-rapidapi-key-here"      }    }  }}

Restart Claude Desktop; the six tools appear under the connectors icon. Drop the env block entirely to run keyless — the server still starts and the free-snapshot tools still answer.

Claude Code

bash
claude mcp add arb-dex --env RAPIDAPI_KEY=your-rapidapi-key-here -- npx -y arb-dex-mcp

Keyless:

bash
claude mcp add arb-dex -- npx -y arb-dex-mcp

Then /mcp to confirm it connected.

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (per project):

json
{  "mcpServers": {    "arb-dex": {      "command": "npx",      "args": ["-y", "arb-dex-mcp"],      "env": {        "RAPIDAPI_KEY": "your-rapidapi-key-here"      }    }  }}

Cursor → Settings → MCP shows the server and its tools once the file is saved.

Any other MCP client

Same three facts: command npx, args ["-y", "arb-dex-mcp"], transport stdio, optional env RAPIDAPI_KEY.


Try it

Real prompts, and the real shape that comes back. Payloads below were measured live on 2026-08-15; they are trimmed for width but nothing is invented.

1. "What is WBNB/USDT trading at on every BSC venue right now?"

get_prices reads every pool holding the pair — v2 pairs and each v3 fee tier separately — at one stated block:

json
{  "pair": "WBNB/USDT",  "network": "bsc",  "chainId": 56,  "blockNumber": 116151268,  "pricesByVenue": [    { "venue": "pancake",        "surface": "v2", "feeBps": 25,  "price": 611.7347, "tvlUsd": 56834814.36 },    { "venue": "biswap",         "surface": "v2", "feeBps": 10,  "price": 610.8278, "tvlUsd": 415733.94 },    { "venue": "apeswap",        "surface": "v2", "feeBps": 20,  "price": 611.1244, "tvlUsd": 3659.06 },    { "venue": "pancakeV3:1",    "surface": "v3", "feeBps": 1,   "price": 610.5684, "tvlUsd": 18596810.32 },    { "venue": "pancakeV3:5",    "surface": "v3", "feeBps": 5,   "price": 610.6531, "tvlUsd": 4941099.44 },    { "venue": "pancakeV3:25",   "surface": "v3", "feeBps": 25,  "price": 610.6304, "tvlUsd": 52534.35 },    { "venue": "pancakeV3:100",  "surface": "v3", "feeBps": 100, "price": 609.1025, "tvlUsd": 12206.21 }  ],  "bestBuy":  { "venue": "pancakeV3:100", "price": 609.1025 },  "bestSell": { "venue": "pancake",       "price": 611.7347 },  "midSpreadBps": 43.22,  "crossDex": {    "grossSpreadBps": 0,    "grossUsd": 0,    "optimalInput": { "amount": 0, "token": "WBNB", "usd": 0 },    "buyVenue": "-",    "sellVenue": "-"  },  "liquidity": { "venues": 7, "totalTvlUsd": 80856857.67 },  "source": "rpc"}

Read the two spread numbers against each other. The raw mid spread is 43 bps — and the gross capturable spread is 0. The 609.10 quote lives in a $12k pool; the size that would actually clear it moves the price past the gap before you get there. A tool that reported only the 43 bps would be handing an agent a number it cannot trade. This one reports both, and optimalInput is where the honesty lands.

2. "Show me the cross-DEX spreads on Base — are any actually capturable?"

get_spreads sweeps a whole chain and ranks by gross USD at the optimal size, not by headline basis points:

json
{  "network": "base",  "chainId": 8453,  "scannedPairs": 11,  "opportunities": [],  "found": 0,  "filters": { "minSpreadBps": 10, "minVenueTvlUsd": 1000, "minGrossUsd": 0.01, "limit": 5 },  "ranking": "gross USD at the optimal trade size, NOT raw spread — a large spread with a tiny optimal size is not an opportunity",  "scope": "GROSS cross-venue spread from live pool state, BEFORE gas, MEV and any slippage beyond the optimal size. Not a profit estimate and not trade advice. Venues below the liquidity floor are excluded because a spread against a dust pool is an artefact, not an opportunity.",  "elapsedMs": 2847}

found: 0 is a real answer and it is the common one. Eleven pairs scanned, nothing cleared the floor. Venues under $1,000 TVL are dropped outright. When rows do come back, each carries capturable, warning and shallowestSideTvlUsd so a big basis-point number cannot mislead on its own. This tool will tell your agent there is nothing there — which is the whole point of asking it.

3. "How much history does arb-dex actually have, and for which chains?"

get_history_summary sizes the archive before you query it:

json
{  "rows": 133,  "rowsWithPairDetail": 103,  "rowsByEra": { "digest-totals-only": 30, "top-list-pairs": 5, "full-sweep": 98 },  "pairsTracked": 107,  "firstAt": "2026-08-10T17:35:09.355Z",  "lastAt":  "2026-08-15T20:54:34.417Z",  "spanHours": 123.32,  "chainsSeen": ["arbitrum", "avalanche", "base", "bsc", "optimism", "polygon"],  "pairs": [    { "chain": "polygon",  "pair": "WBTC/USDC", "observations": 103, "qualifiedObservations": 39 },    { "chain": "bsc",      "pair": "BTCB/USDT", "observations": 99,  "qualifiedObservations": 15 },    { "chain": "arbitrum", "pair": "ARB/USDC",  "observations": 98,  "qualifiedObservations": 0 }  ]}

Coverage is only what was measured. A gap stays a gap — rowsByEra says how much detail each era of rows carries, and ARB/USDC having 98 observations but 0 qualified is the archive telling you that pair has never once cleared the spread floor.


Tools

ToolWhat it answersAccess
get_chainsWhich chains are covered, their chain IDs, tokens and DEX venuesAny key · keyless returns the chain list only, and says so
get_pairsWhat is priceable on one chain: token universe, venues, pair syntaxAny key · keyless returns the measured subset, labelled as such
get_pricesOne pair's price at every venue holding a pool for it, plus reserves, TVL, fee tier and the cross-DEX spreadAny key
get_spreadsA whole chain's cross-venue dislocations, ranked by gross USD at the optimal sizeAny key for live: true · keyless serves the free hourly snapshot
get_history_summaryWhat the measurement archive covers: rows, pairs tracked, chains seen, span, retentionAny key (free tier included)
get_historyOne pair's per-venue price/liquidity series and gross cross-venue spread over 24h / 7d / 30dPRO plan — see Plans

The two history tools read the service's own measurement archive, so they answer the question the live tools cannot: whether a dislocation persisted or was a single sample. Sampling is roughly hourly, and gaps are never interpolated or backfilled. Call get_history_summary first to see what span exists before asking for a window.

What it will not do

  • Spreads are gross — before gas, MEV and slippage beyond the optimal size. Not a profit estimate and not trade advice.
  • It never fabricates a row. Without a key, get_chains, get_pairs and get_spreads answer from the free public surface and each carries a limitation field naming exactly what a key would add. get_prices, get_history_summary and get_history return an explicit key-required error with the signup link rather than a thinner answer dressed up as a full one.
  • It does not execute trades, hold funds, or touch a wallet. It is read-only market data.
  • This package ships no credentials of any kind. The key is yours and stays in your config.

Get a key

The paid tools call the API through RapidAPI using your own key.

  1. Subscribe — there is a free tier: https://rapidapi.com/donnydev/api/multi-chain-dex-prices-liquidity
  2. Copy your X-RapidAPI-Key from the RapidAPI dashboard.
  3. Put it in RAPIDAPI_KEY in the config above — never in code, and never in a commit.

Plans

Five of the six tools work on the free tier. Only the per-pair history series is gated:

PlanAdds
BASIC ($0)Live quotes on every chain, plus get_history_summary so you can size the archive before you buy it
PRO ($15/mo)get_history — the measured per-venue series for one pair, 24h window, 1000 calls/mo
ULTRA ($49/mo)No window limit and no history meter, plus depth/slippage and spread alerts
MEGA ($149/mo)Bulk paging over the complete archive for your own store

Calling get_history below PRO returns an explicit tier_required error naming the plan and the upgrade URL — it does not fail silently or return an empty series.

Configuration

Env varDefaultPurpose
RAPIDAPI_KEY—Your RapidAPI key. Required for the paid tools.
ARB_DEX_TIMEOUT_MS45000Request timeout. A live full-chain sweep is a real on-chain read and can take ~30s.
ARB_DEX_FREE_BASE_URLproduction originOverride the free-surface host.
ARB_DEX_RAPIDAPI_HOSTmulti-chain-dex-prices-liquidity.p.rapidapi.comOverride the RapidAPI host.

Set these in your MCP client's env block (see the configs above). .env.example ships in the package and documents the same variables for local runs from a clone.

Test

The test suite is not in the npm tarball — run it from a clone:

bash
git clone https://github.com/donnywin85/arb-dex-mcp.gitcd arb-dex-mcp && npm install
npm run selftest                    # keyless: exercises the free fallbacksRAPIDAPI_KEY=... npm run selftest   # keyed: exercises the paid routes

The test spawns the server over stdio and calls every tool against the real production API — nothing is mocked. It asserts on live values (block number, per-venue prices, scanned-pair counts), so a run that passes is evidence the data path works end to end.

Links

License

MIT — see LICENSE.

Source: README.md at commit 475e0e7

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v1.0.1LatestSep 16, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts