Skip to main content
Glama

x402 Funding Divergence

npm version npm downloads license node x402-funding MCP server

X402 Funding MCP server

Perpetual funding rates, compared across venues. Hyperliquid against a liquid CEX benchmark — Binance, or OKX where Binance restricts the region — annualized with each venue's real funding interval, filtered for pairs liquid on both legs, with the direction of the basis trade already resolved.

One call returns every pair where the two venues disagree, sorted by the size of the gap. No API keys, no signup, no rate-limit negotiation.

import { fundingDivergence } from "x402-funding-divergence";

const { top } = await fundingDivergence({ topN: 5 });
[
  {
    "coin": "AAVE",
    "hl_apr_pct": 10.95,
    "cex_apr_pct": -7.29,
    "divergence_bps": 1823.8,
    "hl_interval_hours": 1,
    "cex_interval_hours": 8,
    "oi_usd": 58969834,
    "vol_24h_usd": 8784527,
    "cex_vol_24h_usd": 103668389,
    "anomaly": false,
    "trade": "short_hyperliquid_long_binance",
    "stability": { "window_hours": 72, "cex_samples": 9, "hl_samples": 72, "cex_mean_apr_pct": -0.03, "cex_std_apr_pct": 7.47, "hl_mean_apr_pct": 6.2, "hl_std_apr_pct": 9.79 }
  }
]

That trade field is the whole point: it tells you which leg to short and which to long, and it names the venue those numbers came from. No interpretation needed downstream.

Why this exists

A funding rate on one venue tells you what that venue thinks. The gap between two venues tells you how far apart their carry expectations sit — the raw input for a basis decision, not a return forecast.

Doing it by hand means reconciling funding intervals that differ per venue and per instrument, two unit conventions, and a filter for pairs where both order books are deep enough to trade. This package does that in one call.

  • Intervals are read, not assumed. Hyperliquid funds hourly. Binance defaults to 8-hour funding, but 4-hour is common — of the 820 contracts it lists, 465 settle every 4 hours, 2 every hour — so the interval comes from /fapi/v1/fundingInfo per symbol. OKX varies per instrument, so it is derived from nextFundingTime − fundingTime. Assuming 8 hours everywhere halves the annualized figure on every 4-hour contract, with no visible error.

  • Both legs must be liquid. Open interest ≥ $1M and 24h volume ≥ $2M on Hyperliquid, plus 24h quote volume ≥ $2M on the benchmark venue. A pair that is deep on one side and empty on the other cannot be traded, however wide the gap looks.

  • Dislocations are flagged, not promoted. Beyond 2,000 bps the row is marked anomaly: true and ranked after the ordinary rows. A gap that wide is usually one venue dislocating, not a carry you can hold.

  • It works from a blocked region. Binance answers HTTP 451 from US addresses, and Bybit's CDN refuses them too. The sensor tries Binance, falls back to OKX, and tells you which one it used in benchmark.venue. Nothing to configure — it takes whichever responds.

  • The sensor module has zero dependencies. Native fetch, nothing else, so it runs in Node 20+, in a serverless function, or on an edge runtime. The full package adds the x402 payment server on top.

Three ways to consume it. Locally, through the library or the MCP tool — free, and the only network calls are to the venue APIs. Remotely over HTTP, at two prices: /funding at $0.02 per call for the divergence itself, or /ultra at $0.25 per call to add measured execution capacity — how much size each gap actually carries. Same sensor underneath; Ultra adds order-book depth. See Use the hosted endpoint and Ultra.

Whether you use the free local package or the paid hosted endpoint, you never manage blockchain complexity: no RPC endpoint, no ETH, no KYC.

Related MCP server: usenami-mcp

Install

npm install x402-funding-divergence

Requires Node.js 20 or newer.

Integrate in two minutes

TypeScript. The package ships its own declarations — nothing to install, nothing to write by hand.

import { fundingDivergence, type FundingResponse } from "x402-funding-divergence";

const data: FundingResponse = await fundingDivergence({ topN: 5 });
const best = data.top[0];                 // fully typed
if (best) console.log(best.coin, best.trade, best.divergence_bps);

Any other language. The response validates against JSON Schema Draft 2020-12. The schema ships inside the package (schema/funding-divergence.schema.json), so you can generate a client from it instead of reading this page:

npx ajv-cli@5 validate \
  -s node_modules/x402-funding-divergence/schema/funding-divergence.schema.json \
  -d response.json

An agent (MCP). One entry in Claude Desktop, Cursor, or any MCP client:

{
  "mcpServers": {
    "x402-funding": { "command": "npx", "args": ["-y", "x402-funding-divergence"] }
  }
}

Coinbase AgentKit. Coinbase's X402ActionProvider is built to call any x402-protected endpoint, and both prices here sit below its default 1.00 USDC per-request cap. It only calls services it knows about, so register the URL once:

const provider = x402ActionProvider({
  registeredServices: ["https://x402-funding.onrender.com"],
  // maxPaymentUsdc defaults to 1.00, which already covers both routes
});

That is the whole integration. Every field is documented under Response shape.

Only want the data? This package ships the full payment server along with its dependencies. If you just need the sensor, install hyperliquid-binance-funding — same sensor file, same output, zero dependencies.

Use it as a library

import { fundingDivergence } from "x402-funding-divergence";

const data = await fundingDivergence({ topN: 10 });

console.log(data.benchmark.venue);   // "binance" or "okx"
console.log(data.pairs_tradable);    // pairs that cleared both liquidity floors
console.log(data.top);               // first topN rows, ordinary rows before anomalies
console.log(data.all);               // every tradable row

Tune the floors when the defaults are too strict for your universe:

MIN_OI_USD=500000 MIN_VOL_USD=1000000 MIN_CEX_VOL_USD=1000000 node your-script.mjs

Use it as an MCP tool

Any MCP-compatible client can call the sensor directly. Add this to your client configuration:

{
  "mcpServers": {
    "x402-funding": {
      "command": "npx",
      "args": ["-y", "x402-funding-divergence"]
    }
  }
}

The tool is exposed as get_funding_divergence and accepts an optional limit (1–50, default 5). An agent that speaks MCP gets funding divergence with no integration work and no payment setup.

Use the hosted endpoint (pay per call)

A hosted instance runs at https://x402-funding.onrender.com and is billed per request over x402, the HTTP-native payment protocol: the server answers 402 Payment Required, your client attaches a signed USDC authorization, the request completes.

GET https://x402-funding.onrender.com/funding?limit=5            # $0.02
GET https://x402-funding.onrender.com/ultra?limit=5&capacity=5   # $0.25
  • Prices: /funding is $0.02 per call, /ultra is $0.25 per call, both in USDC on Base.

  • Optional query parameters: limit (1–50 on /funding, 1–20 on /ultra); capacity and fees_bps on /ultra only.

  • No account, no key: the paying address is the only identity involved.

  • Free diagnostics: GET /health for liveness, GET /sources for which benchmark venues that host can actually reach.

Zero configuration. Your agent needs no ETH and no exchange account.

Automatic payment. The x402 SDK signs the USDC payment and handles authentication in the background.

100% gasless. Coinbase, acting as facilitator, pays the network fee. You only pay the call price.

To your code this is an API call like any other: one request in, one JSON body out. No wallet UI, no signing prompt, no blockchain library to configure beyond the snippet below.

Client example, using the x402 SDK:

npm install @x402/fetch @x402/evm viem
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.PRIVATE_KEY);

const client = new x402Client();
registerExactEvmScheme(client, { signer: account });

const pay = wrapFetchWithPayment(fetch, client);
const res = await pay("https://x402-funding.onrender.com/funding?limit=5");

console.log(await res.json());

Ultra: what the gap can actually absorb

A divergence says the venues disagree. It does not say whether anyone can act on it. A 1,800 bps gap on a pair whose Hyperliquid book holds $15k is not the same opportunity as the same gap on an $8M book — and nothing in a funding feed tells you which one you are looking at.

GET /ultra — $0.25 per call — adds, for each pair:

Field

Meaning

capacity.usd

Largest notional executable on both legs at once before their combined market impact exceeds impact_budget_bps (10 by default)

capacity.hl_impact_bps, capacity.cex_impact_bps

The impact of each leg at that size — so the number can be checked, not trusted

capacity.hl_book_usd, capacity.cex_book_usd

Visible depth on each side

capacity.entry_cost_bps

Taker fees (assumed, overridable with fees_bps) plus impact at that size

capacity.breakeven_days

Entry cost divided by the funding carry per day

How the number is computed — and the closed-form case that validates the solver — is in CAPACITY.md. The short version: each book is consumed level by level, the volume-weighted price of each leg is compared to its best quoted price, and the largest size whose two impacts still fit the budget is found by bisection. Depth beyond what a venue publishes is never extrapolated, and when the internal safety ceiling is hit the response says usd_lower_bound: true rather than presenting a bound as a measurement.

curl -i "https://x402-funding.onrender.com/ultra?limit=5&capacity=5"
# HTTP 402, accepts[0].amount = "250000"  (6 decimals = $0.25)

Query parameters: limit (1–20, default 5), capacity (1–10 rows measured, default 5), fees_bps (0–200, default 9.5).

One row from a live call, verbatim — every number in it can be recomputed from the others, which is the point:

"coin": "ZEC",
"divergence_bps": 1238.3,
"trade": "short_hyperliquid_long_binance",
"capacity": {
  "available": true,
  "usd": 329154,              // notional executable before impact exceeds the budget
  "usd_lower_bound": false,   // true would mean "at least this much", not "exactly this"
  "impact_budget_bps": 10,
  "hl_impact_bps": 6.38,      // Hyperliquid leg at that size
  "cex_impact_bps": 3.62,     // 6.38 + 3.62 = 10.00, the budget, exactly
  "hl_book_usd": 1235946,     // visible depth, Hyperliquid
  "cex_book_usd": 592188,     // visible depth, benchmark venue
  "side_hyperliquid": "bid",  // sell Hyperliquid
  "side_benchmark": "ask",    // buy Binance
  "fees_assumed_bps": 9.5,    // 4.5 Hyperliquid + 5 CEX, base tier
  "entry_cost_bps": 19.5,     // 9.5 fees + 6.38 + 3.62 impact
  "carry_bps_per_day": 3.393, // 1238.3 / 365
  "breakeven_days": 5.75,     // 19.5 / 3.393
  "reason": "impact_budget"   // or "capped_by_visible_depth", "capped_by_request"
}

Ultra is measurement, not advice. It never suggests a position size or an allocation: it publishes what the market can absorb and what entering costs. If no pair's book can be measured, the endpoint answers 502 instead of 200, so the facilitator cancels settlement and you are not charged for an empty answer.

Response shape

{
  "updated_at": "2026-10-30T20:15:21.409Z",
  "benchmark": {
    "venue": "binance",              // or "okx" where Binance restricts the region
    "funding_interval": "read per instrument from the venue",
    "fallbacks": []                  // venues tried and failed before this one
  },
  "methodology": "Annualised funding, each leg with its own funding interval: ...",
  "liquidity_floor": { "min_oi_usd": 1000000, "min_vol_usd": 2000000, "min_cex_vol_usd": 2000000 },
  "anomaly_threshold_bps": 2000,
  "pairs_considered": 49,             // cleared the Hyperliquid floor
  "pairs_not_checked_on_venue": 0,    // skipped because of the per-venue call cap
  "pairs_compared": 46,               // of those, also listed on the benchmark venue
  "pairs_rejected_illiquid": 130,     // failed the Hyperliquid floor
  "pairs_rejected_cex_illiquid": 0,   // failed the benchmark-venue floor
  "pairs_tradable": 46,               // published
  "pairs_flagged_anomaly": 11,
  "top": [ /* first topN rows */ ],
  "all": [ /* every tradable row, ordinary rows first */ ]
}

Each row:

Field

Type

Meaning

coin

string

Base asset, e.g. BTC

hl_apr_pct

number

Hyperliquid funding, annualized, in percent

cex_apr_pct

number

Benchmark venue funding, annualized, in percent

divergence_bps

number

hl_apr_pct − cex_apr_pct, in basis points

hl_interval_hours

number

Hyperliquid funding interval, always 1

cex_interval_hours

number

Benchmark venue funding interval for this instrument

oi_usd

number

Hyperliquid open interest, USD

vol_24h_usd

number

Hyperliquid 24h notional volume, USD

cex_vol_24h_usd

number

Benchmark venue 24h quote volume, USD

anomaly

boolean

Divergence beyond anomaly_threshold_bps

trade

string

short_hyperliquid_long_<venue> or long_hyperliquid_short_<venue>, where <venue> is benchmark.venue

stability

object | null

Recent mean and standard deviation of both legs. Costs two upstream calls per row, so it is computed for the first STABILITY_MAX_ROWS rows only; null elsewhere

Methodology

  • Hyperliquid publishes funding hourly: rate × 8760.

  • Binance defaults to 8-hour funding, but 465 of the 820 contracts it lists settle every 4 hours and 2 every hour. The interval is read per symbol, then rate × (8760 / interval).

  • OKX publishes one rate per instrument. The interval is derived from the response, then the same formula.

  • Divergence is HL − benchmark, expressed in basis points.

  • A positive divergence means Hyperliquid funding is richer, so the carry shorts Hyperliquid and longs the venue named in benchmark.venue.

  • Rows are sorted by absolute divergence, with anomalies placed after ordinary rows.

Both venues are public and unauthenticated. On the Binance path the sensor issues three parallel requests and returns in about 1.5 s. The OKX fallback costs one request per pair, so roughly 3.5 s for the liquid universe.

What this is not

The divergence is an instantaneous annualization, not a forecast. A funding rate that reads −200% annualized today can read +50% tomorrow, because the annualization multiplies whatever the last settlement was by 1,095 or 2,190. That is why every row carries stability: how much this pair's rate has actually moved over the recent window, and where it sat on average.

A gap of 3,000 bps does not mean a 30% annual return. It usually means one venue is briefly dislocated, which is exactly what anomaly is there to tell you.

Self-host it

The package ships the full server. Clone the repository, install, and point it at a receiving address:

npm install
cp .env.example .env
npm start

Variable

Required

Purpose

PAY_TO

yes

EVM address that receives payments. Public address only; no private key on the server.

NETWORK

no

eip155:8453 (Base mainnet, default) or eip155:84532 (Base Sepolia)

CDP_API_KEY_ID / CDP_API_KEY_SECRET

mainnet

Coinbase CDP credentials; the hosted facilitator authenticates with them

PRICE

no

Per-call price for /funding, default $0.02

ULTRA_PRICE

no

Per-call price for /ultra, default $0.25

CAPACITY_IMPACT_BPS

no

Impact budget used to solve capacity, default 10

CAPACITY_FEES_BPS

no

Taker fees assumed in entry_cost_bps, default 9.5

ULTRA_TIMEOUT_MS

no

Hard timeout on /ultra, default 20000 (then 502, no charge)

MIN_OI_USD / MIN_VOL_USD

no

Hyperliquid liquidity floor

MIN_CEX_VOL_USD

no

Benchmark-venue liquidity floor

ANOMALY_BPS

no

Anomaly threshold, default 2000

X402_BENCHMARK_ORDER

no

Venue order, default binance,okx

OKX_MAX_COINS

no

Max pairs compared on the OKX path, default 50 (one request each)

STABILITY_MAX_ROWS

no

Rows enriched with stability, default 10

STABILITY_WINDOW_HOURS

no

Lookback for stability, default 72

PORT

no

Default 4021

GET /health and GET /sources are free. GET /funding and GET /ultra are the paid routes.

Mainnet requires CDP credentials because the public x402 facilitator serves testnets only. The server refuses to start on eip155:8453 without them rather than failing at the first payment.

The first 1,000 settlements each month are free; beyond that the facilitator charges $0.001 per settlement. That figure sets your floor for a viable per-call price.

Hosted vs. self-hosted: what you are actually paying for

Self-hosting costs nothing in money. It costs an afternoon of setup and a standing obligation to keep the service running. Both paths run the same two routes; only who receives the payment changes.

  • Zero maintenance. No upstream API changes to track, no restarts, no CDP credentials to rotate.

  • Always warm. The hosted instance runs continuously, so an agent loop never pays for a cold start. You configure no keep-alive job of your own.

  • One line of code. No clone, no .env, no full dependency install. A fetch call is the whole integration.

Hosted

Self-hosted

Time to first call

one fetch

clone, install, credentials, deploy

Ongoing work

none

Node runtime, facilitator config, restarts

Marginal cost

$0.02 or $0.25 per call

your own infrastructure

Liquidity floors

fixed at OI ≥ $1M, HL volume ≥ $2M, CEX volume ≥ $2M

you choose

Payments go to

the operator

you

Uptime

handled

yours to arrange

Choose the hosted endpoint when this data is an input to something else you are building. Self-host when you need your own liquidity floors, your own receiving address, or a different network.

License

MIT


Built on public venue APIs. Funding rates change continuously; the numbers this package returns are a snapshot, not a forecast.

Available Tools

1 tool
get_funding_divergenceA

Returns the perpetual funding-rate divergence between Hyperliquid and a liquid CEX benchmark (Binance, or OKX where Binance restricts the region), annualised with each venue's real funding interval, for pairs liquid on both legs, with the direction of the basis trade to open.

NameRequiredDescriptionDefault
limitNoNumber of pairs to return (default 5).

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the venue-fallback behavior (OKX when Binance restricts the region), that annualisation uses each venue's real funding interval, that only pairs liquid on both legs are included, and that the response carries trade direction. It omits error behavior, rate limits, and an explicit read-only statement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One dense sentence that front-loads the core output and then qualifies scope; no filler. It is slightly overstuffed with parenthetical detail, but every clause conveys real behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single optional-parameter read tool with no output schema, the description explains what is returned (annualised divergence plus trade direction) and the pair universe. Missing only return-shape detail such as per-pair fields, which is partly offset by the explicit mention of direction and annualisation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single `limit` parameter is fully documented in the schema, so the description need not repeat it. It does not mention `limit` at all, which is acceptable under the high-coverage baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Returns') and a precise resource: perpetual funding-rate divergence between Hyperliquid and a CEX benchmark. It goes further than the name by specifying the benchmark venues, annualisation method, universe filtering, and that the basis-trade direction is included.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case (funding-rate basis/arbitrage analysis) through mentions of 'basis trade to open', but never states when to call this versus other data tools or any prerequisites. With no siblings, there is no alternative to route to, so implied usage is the ceiling here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.0
    • First observedget_funding_divergence

TDQS

A3.9/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so no selection ambiguity is possible. Its purpose—perpetual funding-rate divergence between Hyperliquid and a CEX benchmark—is clearly stated.

Naming Consistency5/5

The single name follows a clear snake_case verb_noun convention (get_funding_divergence). With one tool there is no pattern to violate.

Tool Count3/5

One tool is thin for a server that implies a funding/basis analytics domain, leaving an agent with no adjacent operations. It is defensible if the server is intentionally a single-signal endpoint, but it sits at the borderline of the 1-2 tool range.

Completeness2/5

The surface offers a single derived metric with no way to list supported pairs, fetch historical funding series, or adjust venue/pair parameters beyond what the description implies. An agent needing funding data over time or across more venues hits a dead end immediately.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Perp-first funding rate & RWA spread data for AI agents. 30+ CEX/DEX venues, 6 tools (4 x402-paywalled, 2 free), bring-your-own-wallet via Base mainnet.
    6
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Real-time crypto spread, funding rates, and cash & carry yields across Binance and OKX for AI assistants.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Scans funding rate arbitrage opportunities across perpetual exchanges (Hyperliquid, Binance, Bybit, OKX) and returns cross-venue spreads and annualized yields. Uses x402 micropayments for pay-per-call access.
    MIT