Deribit MCP with Claude Session injection
Comercio totalmente automatizado con Claude Opus
Documentación
Servidor MCP de Deribit
"Deribit" es una marca comercial de Deribit. Este proyecto es independiente y no está afiliado, respaldado ni patrocinado por Deribit o Coinbase.
Pon las llaves de una cuenta de Deribit en manos de Claude Opus.
🤖 Operaciones automáticas completas de spot, futuros y opciones de criptomonedas desde un solo prompt.
📡 Alertas y ticker de noticias inyectados directamente en la sesión — sin bucles de sondeo lentos.
🧠 Cuéntale a Opus tu estrategia. Aléjate. Él gestiona el libro.
📰 Envía tus propias noticias, señales o modelos de régimen a la sesión mediante webhook.
🖥️ Observa salud, posiciones, alertas, decisiones, operaciones, noticias y estado de la bandeja de salida en un panel de navegador.
Un servidor de Protocolo de Contexto de Modelo que convierte a Claude Opus en un operador de derivados totalmente autónomo en Deribit — tickers en vivo, velas OHLCV, libros de órdenes, griegas de opciones, tasas de financiación, estado de la cuenta — junto con un Sidecar de Claude Code que empuja alertas directamente de vuelta a la sesión en ejecución como notificaciones nativas de canal. El agente no sondea. Duerme hasta que el mercado lo despierta.
Opus coloca sus propias órdenes. Establece sus propios stop-loss, take-profit y stops trailing. Programa sus propias alertas basadas en tiempo para despertarse más tarde. Registra cada decisión en un rastro de auditoría antes de que la orden llegue al cable. Sobrevive a reinicios de contenedor con el estado completo intacto.
- Simplemente indica tu estrategia.
⚠️ Experimental — Lee Esto Primero
El pipeline de activación de Canal en la Nube / Sidecar depende de la
Vista Previa de Investigación de Canales de Claude Code — una
superficie de funciones no publicada / alfa dentro de Claude Code. El contrato
de transporte (notifications/claude/channel) y el modelo de plugin sidecar
pueden cambiar sin previo aviso. Hoy esto funciona; el próximo mes podría no hacerlo.
Operar es dinero real. Cuando DERIBIT_TEST_MODE=false, cada
llamada de herramienta mutante golpea el intercambio de Deribit en vivo. Usa el interruptor
de apagado (DERIBIT_TRADING_ENABLED=false), la testnet (DERIBIT_TEST_MODE=true),
y el requisito de confirm_live_trade=true por llamada en Mainnet. Establece
límites máximos en DERIBIT_MAX_AMOUNT_* y DERIBIT_MAX_NOTIONAL_USD.
Eres responsable de lo que tu modelo haga con este acceso.
⚠️ Esto es infraestructura experimental de grado de investigación para un agente de trading algorítmico a través de IA generativa. No es un reemplazo de Robinhood. ⚠️
Lo que obtienes
Las características principales, clasificadas por importancia
-
Más de 60 herramientas MCP que cubren toda la superficie de Deribit — datos de mercado de solo lectura, estado de la cuenta, cada primitiva de orden mutante (mercado, límite, stop_market, stop_limit, take_market, trailing_stop, brackets, combos), edición/cancelación basada en etiquetas, alcance de cancelación masiva, cierre de posición, historial de liquidaciones y órdenes de activación.
-
Auditoría de decisiones previa a la operación. Las herramientas mutantes requieren un
decision_idemitido porrecord_decision, validado contra la base de datos antes de la llamada a Deribit. Cada orden escribe una fila enorder_auditantes y después de la llamada. Eldecision_idviaja a través de Deribit como ellabelde la orden, por lo que el análisis posterior se une trivialmente. -
Pipeline de activación de canal en la nube (Alfa — ver advertencia). Alertas etiquetadas
notification_channel="outbox"fluyen a una bandeja de salida SQLite, se transmiten a través de tu red privada a un plugin sidecar que se ejecuta en la máquina de Claude-Code, y aparecen dentro de la sesión como un bloque nativo<channel>. El agente no sondea; duerme hasta que el mercado lo despierta. -
Alertas auto-programadas. El agente llama a
set_price_alertpara condiciones de umbral/cruce/cambio porcentual,set_time_alertpara programar sus propios despertares futuros (por ejemplo, "revisar financiación en 4 horas"), y el motor de alertas se dispara asincrónicamente a través del mismo pipeline de canal. -
Velas OHLCV y flujos de libro de órdenes en vivo.
get_chart_datadevuelve velas de Deribit a resolución de 1/3/5/10/15/30/60/120/180/360/720 minutos o diaria.get_orderbook_liveyget_orderbook_diffse suscriben vía WebSocket y sirven instantáneas en caché — sin latencia de solicitud por tick. Cinta de operaciones, liquidaciones recientes, griegas de opciones, IV/DVOL todo consultable. -
Webhook de noticias externo.
POST /news(protegido por bearer de administrador) permite que cualquier sistema externo guarde un elemento de noticias — titular + resumen + payload estructurado — y opcionalmente lo empuje directamente a la sesión del agente a través del canal de bandeja de salida. Opcionaldedupe_keyhace que los empujes cíclicos de agregadores sean idempotentes. Ver Webhook de Noticias y docs/webhook-contract.md. -
Arnés de seguridad de trading. Límites máximos por llamada de cantidad y nocional en USD, dimensionamiento consciente de la familia de instrumentos (inverso vs lineal vs opción), verificaciones de nocional en el peor caso para órdenes de activación, claves de idempotencia para supervivencia de
client_order_ida través de reinicios, requisito deconfirm_cancel_all=truepara cancelación masiva, doble toque deconfirm_live_trade=trueen mainnet. -
Capa de almacenamiento de noticias. Los elementos de noticias empujados persisten en una tabla
newsconsultable con fuente, alcance de instrumento, URL, puntuación, etiquetas y variantes de payload compacto + completo. Opcionaldedupe_keycon un índice parcial único hace que la ingesta cíclica sea idempotente. Empuja a Telegram, consola o canal de bandeja de salida bajo demanda. -
Panel de navegador.
/dashboard/sirve una vista de operador para salud, consumidores sidecar registrados, símbolos mantenidos, posiciones abiertas, alertas, temporizadores, decisiones recientes, auditorías de órdenes MCP, operaciones de usuario de Deribit, eventos de bandeja de salida y últimas noticias. También incluye un formulario de empuje de noticias que persiste el elemento a través de/newsy lo empuja a la sesión del agente víanotification_channel="outbox".
Arquitectura de un vistazo
+--------------------------------+ +--------------------------------+
| Claude Code session | | Deribit MCP (port 8000) |
| MCP client | | |
| | | REST + WS to Deribit |
| tool calls --------------------------->| /mcp (X-Deribit-MCP-Secret) |
| stdio or streamable HTTP | | |
| | | SQLite |
| channel sidecar <----------------------| /events/stream + /events/ack |
| notifications/claude/channel | | outbox + alerts + audit + news |
+--------------------------------+ +--------------------------------+
^ ^
| |
News aggregator -----------------------------------+ |
POST /news (admin Bearer token, optional dedupe_key) |
|
Operator browser -------------------------------------------------+
GET /dashboard/ (admin Bearer token for JSON + news push)
Ruta de herramientas: Claude Code es el cliente MCP. Carga este servidor
ya sea directamente sobre stdio (MCP_TRANSPORT=stdio) o sobre
streamable-http — opcionalmente a través de una puerta de enlace MCP al frente. El transporte
HTTP está protegido por un secreto compartido X-Deribit-MCP-Secret.
El servidor es agnóstico a la puerta de enlace; conéctalo como prefiera tu configuración.
Ruta de activación (plugin sidecar): Alertas etiquetadas
notification_channel="outbox" escriben eventos estructurados a una bandeja de salida
SQLite duradera. Un pequeño plugin Bun/TS cargado en la misma sesión de Claude Code
transmite esos eventos desde /events/stream, los emite como
bloques nativos notifications/claude/channel dentro de la sesión, y
envía ACKs de vuelta. El sidecar vive en channel-plugin/ —
ver HANDOFF.md.
Ruta de inyección de noticias: Cualquier pipeline externo POST un elemento de noticias
a /news con push=true. El MCP lo persiste, luego empuja un resumen
corto a través del mismo pipeline de canal para que el agente se despierte con
las noticias en contexto. Opcional dedupe_key hace que los reintentos sean idempotentes —
las publicaciones duplicadas devuelven la fila existente y no empujan de nuevo.
Panel de navegador: /dashboard/ sirve el panel local de Deribit MCP.
Sus datos JSON y el formulario de empuje de noticias usan
DERIBIT_EVENT_ADMIN_TOKEN como token Bearer. La interfaz es intencionalmente
pesada en lectura: muestra salud del servicio, consumidores sidecar registrados,
símbolos mantenidos, posiciones, alertas, temporizadores, decisiones recientes, operaciones
recientes de Deribit, auditorías de órdenes MCP, últimas noticias y eventos de bandeja de salida.
El formulario de noticias almacena una fila a través de /news y lo empuja a la sesión del agente
a través del canal de bandeja de salida.
Webhook de Noticias
Cualquier cosa que pueda golpear un endpoint HTTPS puede despertar al agente de trading con contexto estructurado.
# Stash a news item AND push it to the agent's session
curl -sS -X POST http://<deribit-host>:8000/news \
-H "Authorization: Bearer $DERIBIT_EVENT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"headline": "BTC ETF inflows hit $1.2B record",
"summary": "BlackRock IBIT absorbed $487M in 24h; spot reclaiming $98k.",
"source": "newsapi",
"instrument": "BTC-PERPETUAL",
"url": "https://example.com/btc-etf-record",
"score": 0.85,
"tags": ["btc", "etf", "institutional"],
"dedupe_key": "newsapi:btc-etf-2026-05-11",
"notification_channel": "outbox",
"push": true
}'
Úsalo para: salida de raspadores de noticias, modelos de régimen personalizados, recordatorios
de calendario económico, traspasos de guardia, resúmenes de sentimiento social, o
cualquier otra cosa que quieras que el agente lea ahora. Con dedupe_key
configurado, los reintentos son idempotentes — un POST duplicado devuelve la fila
existente con duplicate: true y no empuja el evento de nuevo.
El agente entonces ve un bloque nativo <channel> con el titular de la noticia
y metadatos, llama a news_list(id=<news_id>, include_full=true) para extraer
el payload estructurado completo, y decide.
Contrato completo — esquema de payload, autenticación, semántica de deduplicación, comportamiento de reintento, ejemplos — ver docs/webhook-contract.md.
Referencia de herramientas
Las herramientas se exponen tanto vía MCP stdio como el transporte streamable-http. Algunas puertas de enlace MCP prefijan los nombres de las herramientas — verifica las convenciones de tu puerta de enlace.
📈 Datos de mercado (solo lectura)
| Herramienta | Propósito |
|---|---|
get_current_price(instrument, skip_cache=False, max_age_seconds=None) | Instantánea de precio último/marca. skip_cache=True fuerza una búsqueda REST fresca (úsalo antes de decisiones sensibles al tiempo donde datos en caché obsoletos podrían engañar). La respuesta lleva source + age_seconds para razonamiento de frescura. |
get_ticker(instrument) | Ticker completo (marca, último, índice, financiación, IV) |
get_greeks(instrument) | Δ Γ Θ Vega para una opción |
get_instruments(currency, kind, expired) | Listar instrumentos |
get_instrument(instrument) | Metadatos de un solo instrumento |
get_order_book(instrument, depth) | Libro de órdenes REST de una sola vez |
get_orderbook_live(instrument, depth) | Libro de órdenes en caché WS — sin latencia por llamada |
get_orderbook_diff(instrument) | Delta vs la última instantánea en caché |
unsubscribe_orderbook(instrument) | Soltar una suscripción WS |
get_book_summary(currency, kind) | Resumen de libro agregado |
get_chart_data(instrument, start_ts, end_ts, resolution) | Velas OHLCV — 1/3/5/10/15/30/60/120/180/360/720 minutos o diarias |
get_last_trades_by_instrument(...) / get_last_trades_by_currency(...) | Cinta de operaciones públicas |
get_recent_liquidations(currency, kind) | Capturado de flujos de operaciones en vivo |
get_funding_rate_history(instrument, start, end) | Historial de financiación de perps |
get_historical_volatility(currency) | Curva de volatilidad realizada |
get_combos(currency) / get_combo_ids(...) / get_combo_details(combo_id) / get_leg_prices(...) | Combos y precios de patas |
💰 Cuenta y posiciones (solo lectura)
| Herramienta | Propósito |
|---|---|
get_account_summary(currency) | Saldo, PnL, margen |
get_account_summaries(extended) | Todas las monedas en una llamada |
get_positions(currency, kind) | Posiciones abiertas |
get_position(instrument) | Posición de un instrumento |
get_open_orders(...) | Órdenes abiertas, multi-filtro |
get_open_orders_by_label(currency, label) | Incluye órdenes de activación no disparadas |
get_order_state(order_id) / get_order_state_by_label(...) / find_order_by_client_id(...) | Búsqueda de órdenes |
get_user_trades(...) | Tu historial de operaciones |
get_order_history(...) | Historial de órdenes |
get_trigger_order_history(currency, count) | Historial paginado de órdenes de activación |
get_settlement_history(...) | Liquidaciones de PnL |
get_transaction_log(...) | Movimientos de efectivo/monedas |
get_order_margin(order_ids) | Estimación de margen para órdenes en vivo |
get_margins(instrument, amount, price) | Estimación de margen para órdenes hipotéticas |
get_rate_limit_status(currency) | Espacio de límite de tasa del lado de Deribit |
🛎️ Alertas auto-gestionadas
| Herramienta | Propósito |
|---|---|
set_price_alert(instrument, condition, threshold, channel) | above / below / crosses_above / crosses_below / percentage_change |
set_time_alert(when, message, channel) | Despertarse a sí mismo en una marca de tiempo futura |
list_alerts(...) | Todas las alertas persistidas |
remove_alert(alert_id) | Cancelar una |
El agente usa set_time_alert para programar sus propios check-ins.
Las alertas sobreviven a reinicios de contenedor y se re-suscriben al WS de Deribit al
arrancar.
🧠 Auditoría de decisiones
| Herramienta | Propósito |
|---|---|
record_decision(...) | Emitir un decision_id con razonamiento. Requerido antes de cualquier orden mutante. |
update_decision_outcome(decision_id, outcome) | filled / cancelled / rejected / expired / partial / unknown |
list_decisions(...) | Consultar el registro de decisiones |
📓 Notas de forma libre
| Herramienta | Propósito |
|---|---|
add_note(...) / list_notes(...) / update_note(...) / delete_note(...) | Bloc de notas persistente del agente |
📰 Noticias
| Herramienta | Propósito |
|---|---|
news_save(headline, summary, source, instrument, url, score, dedupe_key, content, tags, push, channel) | Almacenar + opcionalmente empujar. dedupe_key lo hace idempotente. |
news_list(id, limit, source, instrument, status, include_full) | Listar o buscar un elemento de noticias; filtrar por fuente/instrumento/estado |
Misma tabla de respaldo que el Webhook de Noticias.
⚡ Trading (mutante, detrás de salvaguardas de seguridad)
| Herramienta | Propósito |
|---|---|
buy(instrument, amount, order_type, ...) | Entrada larga. Soporta market, limit, market_limit, stop_market, stop_limit, take_market, trailing_stop |
sell(...) | Entrada corta / salida de posición, misma superficie que buy |
place_bracket(entry, take_profit, stop_loss, ...) | Entrada de un solo disparo + TP + SL. entry_type acepta market, limit, stop_market, stop_limit — las entradas stop-* se estacionan en el lado del exchange hasta que se alcanza entry_trigger_price (sin latencia de activación, sobrevive a interrupciones de MCP). sl_type acepta stop_market, stop_limit (sl_trigger_price fijo) o trailing_stop (usa sl_trigger_offset — desviación absoluta desde el pico en moneda de cotización). Anulaciones de disparo por tramo vía entry_trigger_source / sl_trigger_source / tp_trigger_source (común: last_price en entrada + mark_price en SL/TP). Los disparos ya pasados son rechazados. |
edit_order(order_id, ...) | Modificar por ID de Deribit |
edit_order_by_label(currency, instrument, label, ...) | Modificar por decision_id (preflight) |
cancel_order(order_id, decision_id?) | Cancelación individual |
cancel_orders_by_label(currency, label) | Cancelación por etiqueta con alcance de moneda |
cancel_all_orders(scope, confirm_cancel_all) | Global requiere confirmación explícita |
close_position(instrument, type, ...) | Aplanar una posición |
create_combo(...) | Construir un instrumento combinado personalizado |
Las respuestas de órdenes mutantes son intencionalmente compactas: devuelven IDs de orden,
estado, detalles de ejecución/precio promedio, resolución de hijos SL/TP y resúmenes
agregados de operaciones. Los payloads completos de Deribit permanecen en order_audit para depuración
y reproducción sin inundar las sesiones del agente.
Contrato de seguridad:
DERIBIT_TRADING_ENABLED=falsebloquea cada herramienta mutante por defecto.- Los cuatro límites (
DERIBIT_MAX_AMOUNT_INVERSE / LINEAR / OPTIONyDERIBIT_MAX_NOTIONAL_USD) deben ser números positivos — el inicio falla rápido de lo contrario. - Mainnet (
DERIBIT_TEST_MODE=false) requiereconfirm_live_trade=trueen cada llamada. - La protección nocional para órdenes de disparo usa el precio de ejecución en el peor caso
(máximo de
trigger_priceyprice) para que un stop por encima del mark actual no pueda verificar por debajo del límite. - Las órdenes mutantes sin un
decision_idválido son rechazadas antes de la llamada a Deribit. - Las órdenes
post_onlytienen por defectoreject_post_only=true: un límite cruzado es rechazado en lugar de ser silenciosamente re-preciado por Deribit al siguiente precio maker. Aplica abuy/sell(reject_post_only) y entradasplace_bracket(entry_reject_post_only); pasa el campo explícitamente comofalsepara optar de nuevo al comportamiento de re-precio.
Ejemplo — largo con stop-loss en mark × 0.97:
record_decision(...) → did_entry, did_sl
buy(BTC-PERPETUAL, amount=10, order_type="market",
decision_id=did_entry, confirm_live_trade=true)
sell(BTC-PERPETUAL, amount=10, order_type="stop_market",
trigger="mark_price", trigger_price=<mark*0.97>,
reduce_only=true, decision_id=did_sl,
confirm_live_trade=true)
Ejemplo — bracket de ruptura del lado del exchange con feeds de disparo asimétricos.
La entrada espera que last_price cruce 80100 (toque limpio del mercado), luego
SL/TP protegen en mark_price (resistente a mechas). El bracket permanece en
Deribit hasta que la entrada se dispara, por lo que la latencia de activación y el tiempo de inactividad de MCP no
pierden la configuración:
record_decision(
instrument="BTC-PERPETUAL",
reasoning="80100 break-up + 79200 reclaim long",
action_taken="place_bracket",
) → did
place_bracket(
decision_id=did,
instrument="BTC-PERPETUAL",
side="buy",
amount=10,
entry_type="stop_market",
entry_trigger_price=80100, # break trigger
sl_type="stop_market",
sl_trigger_price=79200, # reclaim invalid
tp_type="take_market",
tp_trigger_price=82500,
trigger_source="mark_price", # default for SL + TP legs
entry_trigger_source="last_price", # entry uses real-trade prints
confirm_live_trade=true,
)
Un buy cuyo entry_trigger_price ya está en o por debajo del precio actual
es rechazado antes de la llamada a Deribit (lógica espejo para sell). La
lectura del precio actual omite la caché para que un feed WS obsoleto no pueda enmascarar la
divergencia.
Inicio rápido
💡 Entrega la instalación a Claude Code. Apunta cualquier agente LLM a
llms.txty te guiará por la configuración completa — clonar, configurar, compilar, probar contra testnet y verificar la ruta de activación del sidecar. Solo tú llenas los secretos.
Este servidor se ejecuta como un contenedor de larga duración que expone MCP
streamable-http. Stdio (MCP_TRANSPORT=stdio) es compatible para desarrollo local o
lanzadores stdio directos.
# 1) Configure
cp .env.example .env
# Edit: DERIBIT_API_KEY/SECRET, TELEGRAM_BOT_TOKEN/CHAT_ID,
# MCP_SHARED_SECRET (`openssl rand -hex 32`),
# DERIBIT_EVENT_ADMIN_TOKEN (`openssl rand -hex 32`),
# trading limits if you flip TRADING_ENABLED=true
# 2) Pull the published image and start
docker compose pull
docker compose up -d
# 3) Health
curl http://<deribit-host>:8000/health # → {"ok":true}
# 4) Open the operator dashboard
# http://<deribit-host>:8000/dashboard/
# Use DERIBIT_EVENT_ADMIN_TOKEN when the dashboard asks for a token.
# 5) Wire it into your MCP client / gateway:
# transport: streamable-http
# url: http://<deribit-host>:8000/mcp/
# headers: {"X-Deribit-MCP-Secret": "<MCP_SHARED_SECRET>"}
# 6) Verify everything end-to-end on the testnet
# See SMOKE-PLAYBOOK.md — designed for autonomous execution by
# another Claude Code session against test.deribit.com. Run it
# BEFORE you ever flip DERIBIT_TEST_MODE=false.
Para desarrollo local de la imagen del contenedor, establece
DERIBIT_MCP_IMAGE=deribit-mcp-server:local y ejecuta
docker compose up -d --build desde un checkout.
/mcp y /sse están protegidos por MCP_SHARED_SECRET — solo los llamadores
con el encabezado X-Deribit-MCP-Secret correcto alcanzan la superficie MCP.
/events/* usa tokens Bearer por consumidor para el pipeline del sidecar
y puede exponerse a través de una red privada (por ejemplo, Tailscale, VPN,
overlay) a donde sea que se ejecute el sidecar.
⚠️ La prueba de extremo a extremo SMOKE-PLAYBOOK.md se ejecuta contra el testnet de Deribit (
test.deribit.com) conDERIBIT_TEST_MODE=true. Coloca órdenes reales en testnet, ejercita cada herramienta mutante y se limpia solo. Nunca lo ejecutes contra mainnet.
Configuración
Toda la configuración vive en .env. Los ajustes se validan al inicio —
el contenedor falla rápido ante valores faltantes o inconsistentes.
Deribit
| Var | Predeterminado | Propósito |
|---|---|---|
DERIBIT_API_KEY | "" | ID de cliente |
DERIBIT_API_SECRET | "" | Secreto de cliente |
DERIBIT_TEST_MODE | true | true → test.deribit.com, false → mainnet |
Transporte / autenticación
| Var | Predeterminado | Propósito |
|---|---|---|
MCP_TRANSPORT | stdio | http para backend de gateway, stdio para desarrollo local |
MCP_HTTP_JSON_RESPONSE | false | Establece true solo si tu gateway rechaza respuestas transmitidas |
MCP_SHARED_SECRET | "" | Requerido cuando MCP_TRANSPORT=http. Pasa vía X-Deribit-MCP-Secret |
DERIBIT_DB_PATH | /data/deribit.db | Ubicación de SQLite, volumen montado |
Seguridad de trading
DERIBIT_TRADING_ENABLED=false es el predeterminado seguro. Las herramientas mutantes
(buy, sell, edit_order, cancel_order, cancel_all_orders,
close_position, place_bracket, create_combo) se niegan a ejecutarse a menos que
el trading esté explícitamente habilitado y los cuatro límites siguientes sean números
positivos.
| Var | Notas |
|---|---|
DERIBIT_TRADING_ENABLED | Interruptor de apagado |
DERIBIT_MAX_AMOUNT_INVERSE | Límite por llamada. Perps inversos (BTC/ETH-PERPETUAL): amount es nocional en USD |
DERIBIT_MAX_AMOUNT_LINEAR | Perps/futuros lineales (*_USDC-PERPETUAL): amount es conteo de monedas |
DERIBIT_MAX_AMOUNT_OPTION | Opciones: amount es contratos |
DERIBIT_MAX_NOTIONAL_USD | Límite nocional en USD por llamada. Consciente de familia (inverso: cantidad; lineal: cantidad × mark; opción: cantidad × tamaño_contrato × índice) |
En Mainnet (DERIBIT_TEST_MODE=false), cada llamada de herramienta mutante también
requiere confirm_live_trade=true — defensa contra llamadas
accidentales a Mainnet desde una sesión configurada para testnet.
Outbox de eventos / sidecar
| Var | Predeterminado | Propósito |
|---|---|---|
DERIBIT_EVENT_ADMIN_TOKEN | "" | Requerido para POST /events/register, POST /news, POST /news/{id}/push y acciones de dashboard JSON/noticias |
DERIBIT_EVENT_RETENTION_DAYS | 7 | Cuánto tiempo mantener eventos ACKed en el outbox |
DERIBIT_EVENT_STREAM_CLAIM_SECONDS | 90 | Cuánto tiempo sobrevive la reclamación de stream de un sidecar sin renovación |
DERIBIT_TRADING_EVENT_OUTBOX_ENABLED | true | Refleja eventos autenticados de ciclo de vida de órdenes/ejecuciones de Deribit user.* en el outbox |
DERIBIT_TRADING_EVENT_CHANNELS | user.changes.future.any.100ms,user.changes.option.any.100ms,user.changes.spot.any.100ms,user.changes.future_combo.any.100ms,user.changes.option_combo.any.100ms | Canales de Deribit user.* separados por comas para transmitir en activaciones de sesión |
Notificaciones
Telegram para el usuario humano, outbox para el pipeline de activación del agente:
| Var | Propósito |
|---|---|
TELEGRAM_BOT_TOKEN | Token del bot para heartbeat de inicio + alertas con notification_channel="telegram" (escalada opt-in; canal predeterminado es outbox) |
TELEGRAM_CHAT_ID | Dónde entregar |
Streams de mercado
| Var | Predeterminado | Propósito |
|---|---|---|
DERIBIT_ORDERBOOK_INTERVAL | 100ms | Cadencia de suscripción al libro de órdenes: raw, 100ms o agg2 |
DERIBIT_ORDERBOOK_DIFF_RETENTION_SECONDS | 300 | Cuánto tiempo los diffs del libro de órdenes en vivo permanecen consultables |
DERIBIT_ORDERBOOK_IDLE_UNSUBSCRIBE_SECONDS | 300 | Elimina suscripciones WS de libros de órdenes inactivos |
DERIBIT_LIQUIDATION_BUFFER_SIZE | 1000 | Tamaño del buffer circular por stream de liquidaciones |
DERIBIT_WS_MAX_ACTIVE_CHANNELS | 450 | Guardia local de canales WS activos; Deribit documenta un límite de 500 canales |
Docker compose
Estas variables son consumidas por docker-compose.yml, no por la
aplicación Python en sí:
| Var | Predeterminado | Propósito |
|---|---|---|
DERIBIT_MCP_IMAGE | ghcr.io/schroejahr2/deribit-mcp:latest | Imagen de runtime publicada a extraer |
BIND_IP | 127.0.0.1 | Interfaz de host para el puerto 8000; establece 0.0.0.0 solo cuando pretendes exponerlo |
Arquitectura de activación (pipeline del sidecar)
Cuando se dispara una alerta con notification_channel="outbox", el servidor
escribe un evento permitido por la lista blanca de payload en la tabla event_outbox. El
plugin del sidecar que se ejecuta en la máquina de Claude:
- Mantiene un stream largo abierto en
GET /events/stream?consumer_id=<id>(autenticación Bearer, token por consumidor). - Recibe el evento como NDJSON.
- Emite
notifications/claude/channelconcontent=payload.messageymeta= metadatos clave-identificador (alert_id,instrument,severity,event_id,event_type). - Llama a
POST /events/{event_id}/ackpara que el servidor deje de re-entregar.
Comandos del operador:
# Mint or rotate a consumer token
curl -sS -X POST http://<deribit-host>:8000/events/register \
-H "Authorization: Bearer $DERIBIT_EVENT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"consumer_id":"<uuid4>","display_name":"trading-claude-laptop"}'
Las claves meta deben coincidir con [A-Za-z0-9_]. La severidad del lado del servidor es
determinista: percentage_change con |threshold| >= 5 →
warning, de lo contrario info. La lista blanca de payload de eventos está en
src/event_outbox.py:ALLOWED_PAYLOAD_KEYS — cualquier cosa no listada se
descarta antes de persistir.
Los envíos de noticias con notification_channel="outbox" emiten eventos news_ready.
Se deduplican del lado del servidor por news:{url} cuando la fila de noticias
tiene una URL, de lo contrario por news:{news_id}. Llevan solo metadatos de noticias
permitidos: news_id, source, instrument, headline,
summary, url, score, tags, message.
Los eventos de trading autenticados de Deribit usan la misma ruta del sidecar cuando
DERIBIT_TRADING_EVENT_OUTBOX_ENABLED=true: el servidor se suscribe a
los DERIBIT_TRADING_EVENT_CHANNELS configurados, convierte las actualizaciones
del ciclo de vida de órdenes y ejecuciones en eventos sanitizados deribit_order_update /
deribit_trade_update, y omite los snapshots de posición crudos para evitar
spam de precios mark en la sesión.
API HTTP de noticias
Los elementos de noticias almacenados son consultables a través del wrapper FastAPI:
curl -sS 'http://<deribit-host>:8000/news?limit=10'
curl -sS 'http://<deribit-host>:8000/news/<news_id>?include_full=true'
curl -sS 'http://<deribit-host>:8000/news?source=newsapi&instrument=BTC-PERPETUAL'
curl -sS -X POST http://<deribit-host>:8000/news/<news_id>/push \
-H "Authorization: Bearer $DERIBIT_EVENT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"notification_channel":"outbox"}'
Los endpoints de guardar y enviar requieren el token Bearer de administrador; los
endpoints de lectura no están autenticados (el transporte HTTP ya está
detrás de X-Deribit-MCP-Secret para la ruta MCP; los endpoints de lectura están en
el mismo bind).
Esquema completo de payload, semántica de dedupe, comportamiento de reintento, códigos de error — ver docs/webhook-contract.md.
Persistencia
Base de datos SQLite única montada en un volumen de host. Tablas:
alerts— alertas de precio + tiempo, estado completo incluyendolast_pricepara condiciones cruzadas. Rehidratadas al inicio del ciclo de vida; los instrumentos de alerta de precio se resuscriben en el WebSocket y ejecutan una verificación de precio inmediata para que las alertas atrasadas se disparen rápidamente.decisions— registros de razonamiento del modelo, aplicados antes de llamadas de trading mutantes. Enum de resultado:filled/cancelled/rejected/expired/partial/unknown.order_audit— cada herramienta de trading mutante escribe una fila antes y después de la llamada a Deribit. Las operaciones masivas pueblanderibit_order_ids_jsony dejan el singularderibit_order_idnulo.notes— bloc de notas libre del agente.idempotency_keys— caché por llamada paraclient_order_id. TTL de 5 min, reclamado cada 5 min. Sobrevive al reinicio del contenedor.event_outbox,event_consumers,event_deliveries— estado del pipeline de activación del sidecar. El reaper elimina solo eventos cuyas entregas están todas ACKed y cuyoexpires_atha pasado.news— elementos de noticias ingeridos externamente con titular, resumen, fuente, alcance de instrumento, URL, puntuación, etiquetas, contenido JSON libre, estado de procesamiento, atribución de modelo opcional y metadatos de envío de notificaciones.dedupe_keyopcional con un índice parcial único permite ingesta cíclica idempotente.
Pruebas
Dos capas:
Pruebas unitarias (tests/, ~200 casos): guardas de trading que incluyen límites de monto/valor nocional por familia de instrumentos, enrutamiento de cancel_all, repositorio de decisiones + enumeración de resultados, caché de idempotencia, deduplicación de outbox + lista blanca, persistencia/deduplicación/enrutamiento de noticias, semántica de auditoría de cancelación masiva, middleware de secreto compartido de http_app, paso de ciclo de vida, codificación de corchetes de arreglo GET.
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest tests/
La imagen de runtime GHCR publicada intencionalmente no incluye la suite de pruebas ni las dependencias de desarrollo. Use el venv local para las pruebas unitarias, o construya una imagen de desarrollo temporal desde el checkout.
Manual de pruebas de humo de extremo a extremo (SMOKE-PLAYBOOK.md): ejecución autónoma multifase por otra sesión de Claude, que cubre cada herramienta de solo lectura, cada ciclo de vida de órdenes mutables, las cuatro pruebas negativas de seguridad de trading, ráfaga de canal, activación de alerta de tiempo y una fase de limpieza. Diseñado para dejar la cuenta de testnet en el mismo estado en que comenzó.
Manual del operador
# Container health
docker logs deribit-mcp --tail 30
curl http://<deribit-host>:8000/health
# Inspect the MCP tool list directly
curl -s -X POST http://<deribit-host>:8000/mcp/ \
-H "X-Deribit-MCP-Secret: $MCP_SHARED_SECRET" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Inspect SQLite directly (read-only)
docker exec deribit-mcp sqlite3 'file:/data/deribit.db?mode=ro' \
"SELECT id,instrument,condition,status FROM alerts ORDER BY created_at DESC LIMIT 10"
# Inspect deliveries for a sidecar consumer
docker exec deribit-mcp sqlite3 'file:/data/deribit.db?mode=ro' \
"SELECT consumer_id,event_id,delivered_at,acked_at,attempts \
FROM event_deliveries ORDER BY delivered_at DESC LIMIT 5"
# Trigger a synthetic outbox event (server-side, useful for sidecar tests)
docker exec deribit-mcp python3 -c "
import asyncio
from src.persistence import Database
from src.event_outbox import EventOutboxRepo
async def main():
db = Database('/data/deribit.db'); await db.connect()
repo = EventOutboxRepo(db)
eid = await repo.insert_event(
'price_alert_triggered',
{'message':'manual smoke','alert_id':'manual','instrument':'BTC-PERPETUAL'},
severity='info',
)
print('inserted', eid)
await db.close()
asyncio.run(main())
"
Estructura del proyecto
src/
├── server.py # tool registry: build_mcp() returns a FastMCP
├── deribit_rest.py # REST client with auth, rate-limit retry,
│ # bracket-array encoding, POST/JSON support
├── deribit_ws.py # WebSocket client with reconnect, ticker dedup,
│ # token-refresh loop
├── alerts.py # AlertManager, AlertCondition (incl. TIME),
│ # PriceAlert
├── trading.py # Trading-safety guards: TRADING_ENABLED,
│ # amount/notional limits, instrument family
├── persistence.py # aiosqlite, schema bootstrap, AlertRepo,
│ # DecisionRepo, OrderAuditRepo, IdempotencyRepo,
│ # NoteRepo, NewsRepo
├── news.py # compact/full response shaping + push formatting
├── news_api.py # FastAPI routes for /news/*
├── briefings.py # briefing row formatting
├── briefings_api.py # FastAPI routes for /briefings/*
├── event_outbox.py # Outbox repo, severity mapping, payload allowlist,
│ # consumer lifecycle, claim/ack/heartbeat/reaper
├── events_api.py # FastAPI routes for /events/*
├── notifications.py # TelegramChannel, OutboxNotificationChannel,
│ # NotificationManager
├── market_streams.py # WS-cached order books, trade tape, liquidations
├── scheduler.py # TimeAlertScheduler asyncio loop
├── lifespan.py # combined_lifespan, environment fail-fast,
│ # alert rehydrate + resubscribe + immediate check
├── http_app.py # FastAPI wrapper, shared-secret middleware,
│ # passthrough lifespan for FastMCP
├── config.py # pydantic-settings; validate_startup()
└── __main__.py # MCP_TRANSPORT switch (http vs stdio)
dashboard/ # Browser dashboard: `dashboard/api.py` + `dashboard/static/`
tests/ # pytest cases covering the layers above
channel-plugin/ # Sidecar handoff & build instructions
DEMO_CLAUDE.md # Example Claude Code operating prompt
llms.txt # Install guide for LLM agents
SMOKE-PLAYBOOK.md # End-to-end test catalogue
Créditos y atribución
Originalmente basado en Oishh/telegram-signal-mcp-server (MIT). Clientes REST/WS de Deribit adaptados del upstream; canal en la nube / outbox de eventos, persistencia, guardas de trading, ingesta de noticias, flujos de mercado, notas e integración de gateway son trabajo nuevo. Atribución completa en NOTICE.
Licencia
Doble licencia: AGPL-3.0 O Comercial.
- Predeterminada: GNU Affero General Public License v3.0. Libre de usar, modificar y autoalojar. Si opera Deribit MCP como un servicio de red, AGPL-3.0 le exige poner a disposición de sus usuarios el código fuente correspondiente completo, incluidas sus modificaciones y el código del servicio circundante.
- Licencia comercial: si AGPL-3.0 no es atractiva para su despliegue en producción (servicio de código cerrado, producto de pago, plataforma de trading interna, oferta alojada, SLA formal / garantía / indemnización), compre una licencia comercial de GS Technik GmbH. Consulte COMMERCIAL.md — también cubre alojamiento gestionado de alto rendimiento y operación 24/7. Contacto: info@schroejahr.de.
- Alojamiento de terceros: AGPL o una licencia comercial rige solo sus derechos sobre este código. Alojar este software para otros usuarios, u operarlo con claves API de Deribit de terceros, puede requerir acuerdos separados de intercambio, KYC, uso de API o comerciales con Deribit/Coinbase. Contacte directamente con el intercambio; este proyecto no puede otorgar esos derechos.
Las porciones derivadas de telegram-signal-mcp-server by Oishh permanecen bajo los términos MIT originales conservados en LICENSE-MIT. El trabajo nuevo sustancial — pipeline de outbox/canal, persistencia, trading auditado, ingesta de noticias, flujos de mercado, integración de gateway — es trabajo AGPL-3.0. Atribución completa en NOTICE.
Aviso legal
Deribit y Coinbase son marcas comerciales de sus respectivos propietarios. Este proyecto es independiente y no está afiliado, respaldado ni patrocinado por Deribit, Deribit B.V., Coinbase o Coinbase Global, Inc.
Este software se comunica con un intercambio de derivados en vivo. El trading de derivados de criptomonedas conlleva un riesgo sustancial de pérdida. Nada en este repositorio es asesoramiento financiero. Los autores no aceptan responsabilidad por pérdidas, alertas omitidas, errores de modelo, desconexiones de sidecar o cualquier otra consecuencia del uso de este software. Usted es responsable de lo que su modelo haga con este acceso. Use la testnet, el interruptor de apagado y los límites de trading. Lea el código antes de activar DERIBIT_TRADING_ENABLED=true.
Autor
Construido por Georg Schröjahr — schroejahr.de.
Problemas, ideas y solicitudes de extracción bienvenidos en github.com/schroejahr2/deribit-mcp.