docs(V2): update README + add CLAUDE.md for /mcp interface and Bybit/Alpaca retirement
- README: three active exchanges (Deribit/Hyperliquid/IBKR); document the unified /mcp interface (get_instruments uniform schema + per-exchange get_historical); drop Bybit/Alpaca from endpoints, tool list, audit filters, migration table and URL-override notes; update test count (323) and source layout (routers/unified.py, old/). - CLAUDE.md: new project guide — commands (uv/pytest/ruff/mypy), runtime architecture, active exchanges, data interfaces, conventions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# 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):
|
||||
|
||||
```bash
|
||||
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 `_TimestampInjectorMiddleware` che inietta `data_timestamp` (ISO UTC) nel
|
||||
top level di **ogni** risposta JSON sotto `/tools/*` (+ header `X-Data-Timestamp`).
|
||||
- `src/cerbero_mcp/auth.py` — bearer → env, e `X-Bot-Tag` obbligatorio (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, raccomandata)** — `get_instruments` con schema uniforme
|
||||
(ogni elemento porta `exchange`, `fees`, `history_start`, `type`, `tick_size`,
|
||||
`native`); `get_historical` con `exchange` selezionabile (singolo venue).
|
||||
Supporta deribit + hyperliquid (IBKR non ancora integrato).
|
||||
- **`/mcp-cross`** — `get_historical` a consenso multi-exchange (mediana OHLC,
|
||||
`sources`, `div_pct`).
|
||||
- **`/mcp-{exchange}`** — router per-exchange legacy, ancora attivi.
|
||||
|
||||
Convenzione: ogni `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`.
|
||||
|
||||
## 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 in
|
||||
`server.py` li avvolgono in un envelope con `request_id`.
|
||||
- Firme/crittografia: il signing L1 Hyperliquid usa `eth_utils.to_hex` come
|
||||
l'SDK ufficiale → `r`/`s` hex possono essere < 66 char (byte alto a zero,
|
||||
~1/256); non assumere lunghezza fissa.
|
||||
- Branch di produzione: **`V2.0.0`** (non `main`). Deploy via
|
||||
`scripts/deploy-vps.sh`.
|
||||
|
||||
## Documentazione
|
||||
|
||||
- `README.md` — overview, setup, deploy, migrazione V1→V2, IBKR OAuth.
|
||||
- `docs/API_REFERENCE.md` — catalogo completo endpoint/tool. Aggiornarlo
|
||||
quando si aggiungono/rimuovono tool o si cambiano gli schemi.
|
||||
Reference in New Issue
Block a user