Add a common cross-exchange interface (/mcp) over the integrated venues
(deribit, hyperliquid):
- get_instruments: uniform schema where each row carries its own
`exchange`, `fees` (maker/taker, live from Deribit, null where the
venue has no per-instrument schedule) and `history_start` (listing
date, live from Deribit creation_timestamp), plus type/tick_size and a
lossless `native` blob. Optional `exchange` filter; fan-out otherwise.
- get_historical: generalized to {exchange, instrument, interval,
start_date, end_date}, returning a single chosen venue's candles.
Consensus merge stays available on /mcp-cross.
New: routers/unified.py, exchanges/cross/instruments.py (normalizers),
UnifiedClient in cross/client.py, schemas in cross/tools.py. Deribit
get_instruments now also surfaces maker/taker_commission and
creation_timestamp (additive).
Retire Bybit and Alpaca from the API surface: move clients, routers,
settings classes and their tests under old/ (history preserved via
git mv); drop them from the builder, /mcp-cross dispatch and symbol_map.
Bybit remains a public funding/OI data source in sentiment (not the
trading client). IBKR is intentionally excluded from /mcp for now.
Docs: rewrite API_REFERENCE.md (remove Bybit/Alpaca, document /mcp,
clarify that data_timestamp is injected globally by middleware).
Tests: add unified-interface coverage; update cross/settings/builder/boot
tests for the reduced venue set. Fix a pre-existing flaky assertion in
the Hyperliquid signing test (r/s use eth_utils.to_hex like the official
SDK, so a leading zero byte yields <66 chars ~1/256 of the time).
323 passed, ruff clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
13 KiB
Cerbero MCP — API Reference (V2.0.0)
Documento di riferimento completo per tutti gli endpoint HTTP e i tool MCP
esposti dal container cerbero-mcp. Generato dall'analisi diretta dei
router FastAPI in src/cerbero_mcp/routers/.
Nota V2 — Bybit e Alpaca sono stati ritirati dalla superficie API (codice archiviato in
old/). Gli exchange di trading attivi sono Deribit, Hyperliquid e IBKR; Macro e Sentiment restano data-provider read-only.
1. Autenticazione
Tutte le chiamate ai namespace /mcp* richiedono:
| Header | Valore | Note |
|---|---|---|
Authorization |
Bearer <TOKEN> |
TESTNET_TOKEN → upstream testnet · MAINNET_TOKEN → upstream live · token sconosciuto → 401 |
X-Bot-Tag |
stringa ≤ 64 char | identifica il bot chiamante, loggato nell'audit · mancante → 400 |
Gli endpoint pubblici (/health, /apidocs, /openapi.json) non
richiedono auth. L'endpoint /admin/audit richiede bearer ma non
richiede X-Bot-Tag.
2. Endpoint pubblici
| Path | Metodo | Descrizione |
|---|---|---|
/health |
GET | Liveness — sempre 200 finché il processo è vivo |
/health/ready |
GET | Readiness — itera i client registry, status ready / degraded / not_ready. Forza 503 se READY_FAILS_ON_DEGRADED=true |
/apidocs |
GET | Swagger UI interattiva |
/openapi.json |
GET | Schema OpenAPI 3.1 |
3. Endpoint admin
| Path | Metodo | Descrizione |
|---|---|---|
/admin/audit |
GET | Query del JSONL AUDIT_LOG_FILE. Filtri: from, to, actor, exchange, action, bot_tag, limit (default 1000, max 10000) |
/admin/ibkr/rotate-keys/confirm?env= |
POST | Swap atomico chiavi IBKR con auto-rollback su validazione fallita |
4. Namespace MCP — panoramica
| Namespace | Tool | Tipo | Note |
|---|---|---|---|
/mcp/tools/* |
2 | interfaccia comune | schema strumenti uniforme + storico per-exchange |
/mcp-deribit/tools/* |
33 | exchange (options-first) | DVOL, GEX, dealer gamma, spread payoff |
/mcp-hyperliquid/tools/* |
16 | 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 |
/mcp-cross/tools/* |
1 | aggregator | storico consensus multi-exchange |
I router per-exchange (/mcp-deribit, …) restano disponibili durante la
transizione; per nuovi consumatori è raccomandata l'interfaccia comune /mcp.
5. /mcp/tools/* — interfaccia comune (raccomandata)
Interfaccia unica trasversale agli exchange integrati: il campo exchange
è dentro ogni risultato, non nel path. Exchange supportati: deribit,
hyperliquid.
get_instruments — schema strumenti uniforme
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) |
Ogni elemento di instruments[] ha schema uniforme:
{
"exchange": "deribit",
"symbol": "BTC-PERPETUAL",
"asset_class": "crypto",
"type": "perpetual", // perpetual | future | option | spot
"fees": {"maker": 0.0, "taker": 0.0005}, // null se l'exchange non lo espone
"history_start": "2018-08-13", // data inizio storico, null se ignota
"tick_size": 0.5,
"native": { /* campi specifici dell'exchange, lossless */ }
}
Risposta: { "instruments": [...], "failed_sources": [{exchange, error}] }.
Copertura
fees/history_start— popolati live dall'upstream dove disponibili. Oggi: Deribit li espone (commissioni maker/taker +creation_timestamp→history_start); Hyperliquid ha fee a livello account e nessuna data di listing per-strumento → entrambinull.
get_historical — storico di un singolo exchange
Request body:
| Campo | Tipo | Default | Note |
|---|---|---|---|
exchange |
"deribit"|"hyperliquid" |
— | obbligatorio: sceglie la sorgente |
instrument |
str | — | simbolo nativo sull'exchange scelto |
interval |
str | "1h" |
1m/5m/15m/1h/4h/1d |
start_date |
str | — | YYYY-MM-DD o ISO datetime (UTC) |
end_date |
str | — | idem |
Risposta: { "exchange", "instrument", "interval", "candles": [...] } con la
chiave uniforme candles: [{timestamp(ms), open, high, low, close, volume}].
Per il consenso multi-exchange (mediana cross-venue) usare invece
/mcp-cross/tools/get_historical (sezione 11).
6. /mcp-deribit/tools/*
Info
is_testnet— flag ambiente correnteenvironment_info— stringa diagnostica completa
Market data
get_ticker,get_ticker_batchget_instrumentsget_orderbook,get_orderbook_imbalanceget_historical(chiavecandlesuniforme)get_trade_history
get_historical— semantica distart_date/end_date(vale anche perget_dvoleget_technical_indicators). Tutti i timestamp sono in UTC.
- Date nude
YYYY-MM-DD:start_date=00:00:00,end_date=23:59:59.999dello stesso giorno (inclusivo dell'intero giorno). Quindiend_date = oggirestituisce l'intraday fino all'ultima candela chiusa, non solo fino a mezzanotte.- Sono accettati anche timestamp con orario (
2026-05-28T14:00:00), onorati così come sono per finestre intraday precise; un valore naive è trattato come UTC.- Nessun cap a ~5000 righe: i range ampi sono paginati internamente finestra-per-finestra, così
start_dateè sempre rispettato.
Account
get_positionsget_account_summary
Options analytics
get_dvol,get_dvol_historyget_gex,get_dealer_gamma_profileget_vanna_charmget_oi_weighted_skew,get_smile_asymmetry,get_atm_vs_wings_volget_pc_ratio,get_skew_25d,get_term_structureget_iv_rank,get_realized_volfind_by_delta,calculate_spread_payoff
Technicals
get_technical_indicatorsrun_backtest
Write (richiede leverage cap)
place_order,place_combo_ordercancel_orderset_stop_loss,set_take_profitclose_position
7. /mcp-hyperliquid/tools/*
Info
environment_info
Market data
get_markets,get_ticker,get_orderbookget_historical,get_trade_historyget_funding_rate,basis_spot_perp
Account
get_positions,get_account_summary,get_open_orders
Technicals
get_indicators
Write (L1 signing + leverage cap)
place_order,cancel_orderset_stop_loss,set_take_profitclose_position
8. /mcp-ibkr/tools/*
Auth via OAuth 1.0a Self-Service con minting di session token unattended. Setup one-time per ambiente (paper + live) — vedi sezione "IBKR Setup" del README.
IBKR non è ancora integrato nell'interfaccia comune
/mcp(il suo endpoint bars usa unperiodrelativo invece di(start, end)); usare il router dedicato/mcp-ibkr.
Info / clock
environment_info,get_clock
Account
get_account,get_positionsget_open_orders,get_activities
Market data
get_ticker,get_bars,get_snapshotget_option_chain,search_contracts
Streaming (WebSocket singleton)
get_tick,get_depthsubscribe_tick,unsubscribe
Write
place_order,amend_ordercancel_order,cancel_all_ordersclose_position,close_all_positions
Complex orders
place_bracket_order— entry + TP + SL atomicoplace_oco_order— One-Cancels-Other (OCA group)place_oto_order— One-Triggers-Other (parent → child)
9. /mcp-macro/tools/* (read-only)
| Tool | Sorgente |
|---|---|
get_economic_indicators |
FRED + Yahoo |
get_macro_calendar |
Finnhub + impact heuristic |
get_market_overview |
mix Yahoo + Deribit DVOL |
get_asset_price |
Yahoo Finance |
get_treasury_yields |
US Treasury XML |
get_equity_futures |
Yahoo |
get_yield_curve_slope |
derivato da treasury yields |
get_breakeven_inflation |
FRED (T10YIE / T5YIE) |
get_cot_tff |
CFTC TFF report |
get_cot_disaggregated |
CFTC disaggregated report |
get_cot_extreme_positioning |
percentili COT (gate ±5%) |
10. /mcp-sentiment/tools/* (read-only)
| Tool | Fonte |
|---|---|
get_crypto_news |
CryptoPanic + CoinDesk + CryptoCompare + Messari (deduped) |
get_world_news |
aggregato generalista |
get_social_sentiment |
LunarCrush + Fear&Greed Index |
get_funding_rates |
per-asset multi-exchange |
get_cross_exchange_funding |
snapshot multi-asset multi-venue |
get_funding_arb_spread |
spread arbitraggio funding |
get_oi_history |
open interest serie storica |
get_liquidation_heatmap |
heatmap liquidazioni |
get_cointegration_pairs |
screening coppie cointegrate |
Le fonti di funding/OI includono endpoint pubblici multi-venue (Binance, Bybit, OKX, Hyperliquid): qui Bybit è una sorgente dati pubblica, non il client di trading ritirato.
11. /mcp-cross/tools/*
get_historical
Aggregatore cross-exchange. Fan-out a tutti gli exchange che supportano
(symbol, asset_class), poi consensus per-bar:
close= mediana delle closeopen/high/low= mediana corrispondentesources= numero di exchange che hanno contribuito al bardiv_pct = (max - min) / median→ quality gate per i bot
Crypto (asset_class: "crypto"): BTC, ETH via Hyperliquid + Deribit;
SOL via Hyperliquid.
In caso di fallimento parziale ritorna i bar disponibili più
failed_sources: [...]. Se tutti gli upstream falliscono → 502 Bad Gateway retryable.
12. Observability
Request log (mcp.request)
Una riga JSON per richiesta con: request_id, method, path,
status_code, duration_ms, actor, bot_tag, exchange, tool,
client_ip, user_agent.
Audit log (mcp.audit)
Persistito su AUDIT_LOG_FILE (JSONL) per le operazioni write.
Rotazione configurabile via AUDIT_LOG_BACKUP_DAYS.
Correlation
Lo stesso request_id appare in mcp.request, mcp.audit e
nell'envelope di errore restituito al client.
data_timestamp
Ogni risposta JSON sotto /tools/* riceve dal middleware un campo
data_timestamp (ISO UTC) al top level — oltre all'header X-Data-Timestamp.
13. Esempio chiamata
# Interfaccia comune: storico Deribit
curl -X POST http://localhost:9000/mcp/tools/get_historical \
-H "Authorization: Bearer $MAINNET_TOKEN" \
-H "X-Bot-Tag: scanner-alpha-prod" \
-H "Content-Type: application/json" \
-d '{"exchange":"deribit","instrument":"BTC-PERPETUAL","interval":"1h","start_date":"2026-05-01","end_date":"2026-05-29"}'
Per lo schema completo dei body di richiesta e risposta: http://localhost:9000/apidocs.
14. Discovery strumenti & schemi candele
Schemi verificati sulle risposte live. Tutti i get_historical ritornano la
chiave uniforme candles: [{timestamp(ms), open, high, low, close, volume}].
Lista strumenti
| Interfaccia | Tool | Request body | Risposta (campi principali) |
|---|---|---|---|
/mcp (comune) |
get_instruments |
{exchange?, currency:"BTC", kind:"future"} |
instruments[] uniforme: exchange, symbol, asset_class, type, fees, history_start, tick_size, native · failed_sources[] |
Deribit (/mcp-deribit) |
get_instruments |
{currency:"BTC"|…, kind:"future", offset:int, limit:100} — paginato (has_more) |
instruments[]: name, expiry, option_type, tick_size, min_trade_amount, maker_commission, taker_commission, creation_timestamp · meta: total, offset, limit, has_more, testnet, data_timestamp |
Hyperliquid (/mcp-hyperliquid) |
get_markets |
{} |
lista {asset, mark_price, funding_rate, open_interest, volume_24h, max_leverage} |
get_historical — body per exchange
| Interfaccia | Body | Note risoluzione |
|---|---|---|
/mcp (comune) |
{exchange, instrument, interval, start_date, end_date} |
1m/5m/15m/1h/4h/1d · ritorna il singolo exchange |
| Deribit | {instrument, start_date:"YYYY-MM-DD", end_date, resolution} |
1/5/15/60/1D (paginazione interna, no cap) |
| Hyperliquid | {asset|instrument, start_date, end_date, resolution, interval?, limit:50} |
1m/5m/15m/1h/1d · limit default 50 (alzare per finestre lunghe) |
Convenzione simboli Deribit
- BTC/ETH → perpetui inverse:
BTC-PERPETUAL,ETH-PERPETUAL - Altcoin → perpetui lineari USDC:
<COIN>_USDC-PERPETUAL(es.SOL_USDC-PERPETUAL), storia da ~2022 - Esistono anche
BTC_USDC-PERPETUAL/ETH_USDC-PERPETUAL(varianti lineari) - ⚠️
LTC-PERPETUAL/ADA-PERPETUAL(inverse) non esistono (0 candele);SOL-PERPETUALè elencato ma è un contratto vuoto/stale (prezzo ~9.6 vs SOL reale ~82) → usareSOL_USDC-PERPETUAL
Nota testnet
Con TESTNET_TOKEN le risposte includono "testnet": true (ticker,
get_instruments, …) e i prezzi possono divergere dal mainnet. Su testnet
alcuni feed sono inaffidabili: validare la congruenza cross-exchange prima di
usare i dati per backtest/trading.