git mv docs/API_REFERENCE.md → API_REFERENCE.md (history preserved) and update the CLAUDE.md reference accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.4 KiB
CLAUDE.md
Guida per Claude Code che lavora su Cerbero MCP — server MCP multi-exchange (FastAPI) distribuito come singola immagine Docker, con routing testnet/mainnet per-request basato sul token bearer.
Comandi
Gestione progetto con uv (Python ≥ 3.11):
uv sync # installa dipendenze (incl. dev)
uv run cerbero-mcp # avvia il server (porta da .env, default 9000)
uv run pytest # suite completa (~323 test attesi)
uv run pytest tests/unit -v # solo unit
uv run pytest tests/unit/exchanges/cross/test_unified.py::test_get_historical_single_exchange # singolo test
uv run ruff check src tests # lint (E,F,I,W,UP,B,SIM; line-length 100)
uv run mypy src/cerbero_mcp # type check (non-strict)
Tutti e quattro (pytest, ruff, mypy) devono essere verdi prima di committare.
testpaths = ["tests"] → old/ non viene mai raccolto dai test.
Architettura
Flusso runtime:
Bot → Authorization: Bearer <TESTNET|MAINNET>_TOKEN (+ header X-Bot-Tag)
→ auth middleware → request.state.environment ∈ {testnet, mainnet}
→ Router (/mcp/... , /mcp-{exchange}/... , /mcp-cross/...)
→ ClientRegistry.get(exchange, env) → client cached lazy per (exchange, env)
→ tool function (logica pura) → exchange API
File chiave:
src/cerbero_mcp/__main__.py—_make_app()registra tutti i router.src/cerbero_mcp/server.py—build_app(), Swagger, exception handler, e_TimestampInjectorMiddlewareche iniettadata_timestamp(ISO UTC) nel top level di ogni risposta JSON sotto/tools/*(+ headerX-Data-Timestamp).src/cerbero_mcp/auth.py— bearer → env, eX-Bot-Tagobbligatorio (path whitelisted:/health,/health/ready,/apidocs,/openapi.json).src/cerbero_mcp/client_registry.py— cache{(exchange, env): client}.src/cerbero_mcp/exchanges/__init__.py—build_client(): factory per exchange.src/cerbero_mcp/settings.py— Pydantic Settings da.env.src/cerbero_mcp/routers/— un file per exchange +unified.py(/mcp) +cross.py(/mcp-cross).src/cerbero_mcp/exchanges/<ex>/{client.py,tools.py}— client HTTP + schemi Pydantic / wrapper tool.cross/contiene aggregatore consensus, interfaccia unificata, normalizzatori e symbol-map.
Exchange attivi
Trading: deribit, hyperliquid, ibkr. Data-provider read-only: macro,
sentiment. Bybit e Alpaca sono ritirati dalla superficie API in V2:
codice archiviato in old/ (fuori dal package, non importato, non testato).
Nota: nel modulo sentiment "bybit" resta come fonte dati pubblica
(funding/OI), non come client di trading.
Interfacce dati
/mcp(comune) — gli unici tool dati trasversali.get_instruments(schema uniforme:exchange,fees,history_start,type,tick_size,native; filtri/paginazione Deribit +metaper-sorgente);get_historicaleget_indicatorsconexchangeopzionale → singolo venue se valorizzato, consenso multi-exchange (mediana OHLC +div_pct) se omesso. Supporta deribit + hyperliquid (IBKR non integrato)./mcp-{exchange}— router per-exchange per il resto (ticker, ordini, options analytics, …). NON espongono piùget_instruments/get_historical/get_indicators.
Convenzione: get_historical ritorna la chiave uniforme
candles: [{timestamp(ms), open, high, low, close, volume}] (validatore in
common/candles.py). fees/history_start sono popolati live dove
l'upstream li espone (oggi: Deribit), altrimenti null. Il calcolo indicatori
è centralizzato in common/indicators.py::compute_indicators.
Convenzioni
- Schemi richiesta = modelli Pydantic in
<ex>/tools.py; il router fa solo dependency-injection di env + client e chiama il wrapper del tool. - Errori applicativi: sollevare
fastapi.HTTPException; gli handler inserver.pyli avvolgono in un envelope conrequest_id. - Firme/crittografia: il signing L1 Hyperliquid usa
eth_utils.to_hexcome l'SDK ufficiale →r/shex possono essere < 66 char (byte alto a zero, ~1/256); non assumere lunghezza fissa. - Branch di produzione:
V2.0.0(nonmain). Deploy viascripts/deploy-vps.sh.
Documentazione
README.md— overview, setup, deploy, migrazione V1→V2, IBKR OAuth.API_REFERENCE.md(root) — catalogo completo endpoint/tool. Aggiornarlo quando si aggiungono/rimuovono tool o si cambiano gli schemi.