MCP gateway for AI agents to dYdX v4: market data, funding heatmap, TA, verified trader analytics (deposit-adjusted PnL), leaderboards, anomaly & liquidation-cascade detectors. Analytics-only: no trading tools, no keys.
Strong foundation with 15 well-named, read-only tools covering dYdX market data and trader analytics. All tools have descriptions (avg ~180 chars) and input schemas with types. However, output schemas are documented only in descriptions, not as formal JSON Schema. Parameter descriptions are present but sometimes terse. Error handling is minimal, most tools lack recovery guidance. No tool annotations (readOnlyHint, etc.). Naming is consistent (verb_noun pattern: list_, market_, candles, recent_, trader_, etc.), but some descriptions could be more LLM-optimized (e.g., 'Snapshot of any trader's subaccount' is vague about what 'snapshot' includes).
Real-time market anomaly detectors: funding extremes (|annualized %| >= 300%), OI spikes without price moves (OI +5% while price ±0.5% over 6h), and liquidation cascade signatures (price ±1.5% & OI -4% in 2h, or ±3% & -6% in 6h). Returns lists of detected anomalies with details.
OHLCV candles with open interest for a market. resolution: 1MIN|5MIN|15MIN|30MIN|1HOUR|4HOURS|1DAY. Each candle: startedAt, open/high/low/close (price), baseTokenVolume (base-coin size), usdVolume (USD), startingOpenInterest. Rows are ordered oldest -> newest (the indexer sends newest-first; we normalize). limit is capped at 1000.
Screener: take recent candidate addresses from the registry and probe the indexer for live equity; return funded ones (real active traders). Useful for finding traders with minimum equity threshold.
Event log: published anomalies, equity jumps, and other alerts. Paginated by recency. Each row: id, ts, kind, subject, payload, published. Useful for monitoring and alert routing (Telegram, webhooks).
Execution quality snapshot: fill count, avg fill size, maker share (%), and a 'farmer' flag (high-frequency small fills = likely a bot). Useful for due-diligence on traders before copying/following.
Output schemas documented only in prose descriptions, not as formal JSON Schema. LLMs cannot parse unstructured text to infer response structure for chaining.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All tools are read-only but this is not declared in schema, forcing LLMs to infer safety from descriptions.
Error handling lacks recovery guidance. Tools like market_detail raise ValueError on unknown ticker but do not suggest calling list_markets or provide available alternatives.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Top markets by absolute funding rate (annualized %). Sorted by |annualized %| descending. Each row: ticker, funding_pct_1h, funding_pct_annualized, oi_usd, longs_pay (bool), oraclePrice. Useful for funding-rate arbitrage scouts and crowding detectors. limit capped at 100.
Top traders by metric (pnl_window, pnl_total, equity, day_winrate). Paginated. Each row: address, equity, pnl_total, pnl_window, day_winrate, max_dd, maker_share, avg_fill, farmer_flag, identity_residual. Computed from the latest leaderboard run (run leaderboard.py separately).
All dYdX v4 perpetual markets: oracle price, 24h volume, open interest, next funding rate. Sorted by 24h USD volume by default (or 'oi'). Each row: ticker, oraclePrice, volume24h_USD, openInterest_USD (size x oracle price) and nextFundingRate_pct_1h (pct per hour). Returns {"count_total", "count", "offset", "has_more", "next_offset", "markets", "summary"}; only ACTIVE markets — delisted/settled ones are excluded. Page with offset when has_more is true.
One perpetual market in depth: prices, 24h stats computed from candles (the raw API priceChange field is unreliable), OI, funding. Returns oraclePrice, openInterest, nextFundingRate_pct_1h (pct/hour), volume24h_USD, change24h_pct_from_candles (24h pct change, computed from 25 x 1h candles), trades24h, basis_pct (mark-vs-oracle deviation in pct: (last candle close - oraclePrice) / oraclePrice x 100), and the latest three 1h candles (t/open/close/usdVolume). An unknown or delisted ticker raises an error (MCP isError) — settled markets are not served.
Recently active addresses from the on-chain registry, excluding high-frequency committers. Paginated. Each row: address, hits (on-chain activity count), first_seen, last_seen, last_height. Useful for discovering new traders to analyze.
Latest public trades of a market (price, side, size, type, time). Newest first; limit capped at 100. side is BUY/SELL, size in base coin.
Live stats of our on-chain address registry (block scanner): how many active addresses collected, scan height, freshness. Returns addresses_total, scanned_up_to_height (last ingested dYdX block), seen_last_24h (addresses seen in the last 24h) and the sqlite path. On hosts where the optional scanner has not run, returns a note instead — market/trader tools still work via the public indexer.
Deep PnL statistics from the equity curve: daily PnL, day-winrate, max drawdown (deposit-adjusted), Sharpe-like daily ratio, and the data-accuracy reconciliation residual (phantom-PnL detector). NOTE: pass limit as keyword: trader_pnl_stats(addr, limit=500), NOT positionally (second positional arg is subaccountNumber). Key fields: day_winrate_pct (0-100), max_drawdown_pct (pct, net of deposits/withdrawals) with max_drawdown_usd (same drawdown in USD) and dd_pct_unreliable (true when the deposit-adjusted peak at the worst drawdown was near zero — trust the USD figure then), avg_daily_pnl / best_day / worst_day (USD per UTC day), sharpe_like_daily, identity_max_residual_usd (expect < $1 on clean data). limit: history depth in points — 1000 ≈ 42 days (default, fast), 5000 ≈ 7 months (slower, multi-page fetch).
Snapshot of any trader's subaccount: equity, open positions, and PnL curve statistics (all-time window from up to 1000 history points). Returns equity_now / totalPnl_now / totalPnl_delta_window (USD), window_start / window_end, and open_positions (market, side, size, entry, unrealizedPnl in USD). Pair with trader_pnl_stats for deeper statistics.
Tool-call counters (traction metrics for usage tracking). Returns calls_total, calls_24h, calls_7d, and top_tools (list of most-called tools).
Parameter descriptions are minimal (avg ~40 chars). E.g., 'Subaccount number' lacks context on valid range (0-255?) or what a subaccount is. LLMs cannot infer constraints.
Some tool descriptions are vague. 'Snapshot of any trader's subaccount' does not clarify what fields are included or when to use it vs trader_pnl_stats.