refactor(V2): get_instruments common-only on /mcp (enriched with Deribit filters)

Move get_instruments off the per-exchange Deribit router and onto the
unified interface, without losing the advanced Deribit filtering.

- /mcp/tools/get_instruments now accepts the Deribit-specific filters
  (currency, kind, expiry_from/to, strike_min/max, min_open_interest) and
  pagination (offset/limit). Venues that list everything (Hyperliquid)
  ignore them. Response adds `meta: {deribit: {total, offset, limit,
  has_more}}` surfacing per-source pagination.
- Remove /mcp-deribit/tools/get_instruments (endpoint + tool wrapper +
  GetInstrumentsReq schema). The DeribitClient.get_instruments METHOD
  stays — it's what the unified normalizer calls.

Tests: cover the enriched filters + meta passthrough; app-boot asserts
/mcp-deribit/tools/get_instruments is gone. Docs (API_REFERENCE/README/
CLAUDE) and smoke updated; also fixed the stale Hyperliquid tool count
(14 → 15) found during the doc check.

325 passed, ruff clean. Verified live: kind=option limit=5 → 5/940
has_more=true; /mcp-deribit/tools/get_instruments → 404.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano
2026-05-29 11:06:09 +00:00
parent 6faf21369d
commit 8d7e2ca30f
10 changed files with 126 additions and 75 deletions
+27 -18
View File
@@ -51,15 +51,16 @@ richiede `X-Bot-Tag`.
| Namespace | Tool | Tipo | Note |
|---|---|---|---|
| `/mcp/tools/*` | 3 | **interfaccia comune** | `get_instruments` + `get_historical` + `get_indicators` (single exchange o consensus) |
| `/mcp-deribit/tools/*` | 32 | exchange (options-first) | DVOL, GEX, dealer gamma, spread payoff |
| `/mcp-hyperliquid/tools/*` | 14 | exchange (perp DEX) | L1 signing, leverage cap |
| `/mcp-deribit/tools/*` | 31 | exchange (options-first) | DVOL, GEX, dealer gamma, spread payoff |
| `/mcp-hyperliquid/tools/*` | 15 | exchange (perp DEX) | L1 signing, leverage cap |
| `/mcp-ibkr/tools/*` | 24 | exchange (multi-asset broker) | OAuth 1.0a, streaming WS, bracket/OCO/OTO |
| `/mcp-macro/tools/*` | 11 | data provider (read-only) | yields, FRED, COT |
| `/mcp-sentiment/tools/*` | 9 | data provider (read-only) | news, social, funding cross-exchange |
`get_historical` e `get_indicators` vivono **solo** sull'interfaccia comune
`/mcp` (non più per-exchange). I restanti tool per-exchange (ticker, ordini,
analytics options, …) restano sui rispettivi router `/mcp-{exchange}`.
`get_instruments`, `get_historical` e `get_indicators` vivono **solo**
sull'interfaccia comune `/mcp` (non più per-exchange). I restanti tool
per-exchange (ticker, ordini, analytics options, …) restano sui rispettivi
router `/mcp-{exchange}`.
---
@@ -76,10 +77,16 @@ Request body:
| Campo | Tipo | Default | Note |
|---|---|---|---|
| `exchange` | `"deribit"\|"hyperliquid"` \| null | `null` | se omesso → fan-out su tutti gli exchange integrati |
| `currency` | str | `"BTC"` | solo Deribit |
| `kind` | str \| null | `"future"` | solo Deribit (`future`/`option`/`spot`) |
| `currency` | str | `"BTC"` | filtro Deribit |
| `kind` | str \| null | `"future"` | filtro Deribit (`future`/`option`/`spot`) |
| `expiry_from` / `expiry_to` | str \| null | `null` | filtro Deribit (data scadenza) |
| `strike_min` / `strike_max` | float \| null | `null` | filtro Deribit (opzioni) |
| `min_open_interest` | float \| null | `null` | filtro Deribit |
| `offset` / `limit` | int | `0` / `100` | paginazione Deribit |
Ogni elemento di `instruments[]` ha **schema uniforme**:
I filtri/paginazione si applicano a **Deribit**; gli exchange che elencano
tutto (es. Hyperliquid `get_markets`) li ignorano. Ogni elemento di
`instruments[]` ha **schema uniforme**:
```json
{
@@ -94,7 +101,9 @@ Ogni elemento di `instruments[]` ha **schema uniforme**:
}
```
Risposta: `{ "instruments": [...], "failed_sources": [{exchange, error}] }`.
Risposta: `{ "instruments": [...], "failed_sources": [{exchange, error}],
"meta": { "deribit": {total, offset, limit, has_more} } }`. Il blocco `meta`
riporta la paginazione per-sorgente quando disponibile (oggi: Deribit).
> **Copertura `fees` / `history_start`** — popolati live dall'upstream dove
> disponibili. Oggi: **Deribit** li espone (commissioni maker/taker +
@@ -152,13 +161,12 @@ sources_used }` (+ `failed_sources` in modalità consenso).
### Market data
- `get_ticker`, `get_ticker_batch`
- `get_instruments`
- `get_orderbook`, `get_orderbook_imbalance`
- `get_trade_history`
> Lo storico OHLCV e gli indicatori tecnici NON sono più qui: usa
> `/mcp/tools/get_historical` e `/mcp/tools/get_indicators` (sezione 5) con
> `exchange="deribit"`.
> Lista strumenti, storico OHLCV e indicatori tecnici NON sono più qui: usa
> `/mcp/tools/get_instruments`, `/mcp/tools/get_historical` e
> `/mcp/tools/get_indicators` (sezione 5) con `exchange="deribit"`.
### Account
- `get_positions`
@@ -333,15 +341,16 @@ uniforme `candles: [{timestamp(ms), open, high, low, close, volume}]`.
### Tool dati comuni (`/mcp`)
| Tool | Request body | Risposta (campi principali) |
|---|---|---|
| `get_instruments` | `{exchange?, currency:"BTC", kind:"future"}` | `instruments[]` uniforme: `exchange`, `symbol`, `asset_class`, `type`, `fees`, `history_start`, `tick_size`, `native` · `failed_sources[]` |
| `get_instruments` | `{exchange?, currency:"BTC", kind:"future", expiry_from?, expiry_to?, strike_min?, strike_max?, min_open_interest?, offset:0, limit:100}` | `instruments[]` uniforme: `exchange`, `symbol`, `asset_class`, `type`, `fees`, `history_start`, `tick_size`, `native` · `failed_sources[]` · `meta:{deribit:{total,offset,limit,has_more}}` |
| `get_historical` | `{exchange?, instrument, interval, start_date, end_date, asset_class?}` | single: `{exchange, instrument, interval, candles, sources_used}` · consensus (no `exchange`): `+ div_pct`/`sources` per bar, `failed_sources` |
| `get_indicators` | come `get_historical` + `indicators:["rsi","atr",…]` | `{exchange, instrument, interval, indicators:{…}, candles_used, sources_used}` |
`get_instruments` Deribit (sorgente grezza): `instruments[]` include `name`,
Sorgenti normalizzate dentro `get_instruments`: Deribit espone `name`,
`expiry`, `option_type`, `tick_size`, `min_trade_amount`, `maker_commission`,
`taker_commission`, `creation_timestamp`; Hyperliquid `get_markets` (sorgente):
`{asset, mark_price, funding_rate, open_interest, volume_24h, max_leverage}`.
Ogni risposta `/tools/*` riceve inoltre `data_timestamp` dal middleware.
`taker_commission`, `creation_timestamp` (→ `fees`/`history_start`); Hyperliquid
`get_markets` espone `{asset, mark_price, funding_rate, open_interest,
volume_24h, max_leverage}`. Ogni risposta `/tools/*` riceve inoltre
`data_timestamp` dal middleware.
### Convenzione simboli Deribit
- **BTC/ETH** → perpetui *inverse*: `BTC-PERPETUAL`, `ETH-PERPETUAL`