Deribit MCP with Claude Session injection
Negociação totalmente automática com Claude Opus
Documentação
Servidor MCP Deribit
"Deribit" é uma marca registrada da Deribit. Este projeto é independente e não é afiliado, endossado ou patrocinado pela Deribit ou Coinbase.
Dê ao Claude Opus as chaves de uma conta Deribit.
🤖 Negociação automática completa de spot, futuros e opções de criptomoedas a partir de um único prompt.
📡 Alertas e feed de notícias injetados diretamente na sessão — sem loops de polling lentos.
🧠 Conte sua estratégia ao Opus. Afaste-se. Ele gerencia o livro.
📰 Envie suas próprias notícias, sinais ou modelos de regime para a sessão via webhook.
🖥️ Acompanhe saúde, posições, alertas, decisões, negociações, notícias e estado da caixa de saída em um painel no navegador.
Um servidor Model Context Protocol que transforma o Claude Opus em um trader de derivativos totalmente autônomo na Deribit — tickers ao vivo, candles OHLCV, livros de ofertas, Gregas de opções, taxas de funding, estado da conta — combinado com um Claude Code Sidecar que envia alertas diretamente de volta para a sessão em execução como notificações nativas de canal. O agente não faz polling. Ele dorme até o mercado acordá-lo.
O Opus coloca suas próprias ordens. Define seus próprios stop-loss, take-profit e trailing stops. Agenda seus próprios alertas baseados em tempo para acordar mais tarde. Registra cada decisão em uma trilha de auditoria antes que a ordem chegue à rede. Sobrevive a reinicializações de contêiner com o estado totalmente intacto.
- Basta informar sua estratégia via prompt.
⚠️ Experimental — Leia Isto Primeiro
O pipeline de ativação Cloud Channel / Sidecar depende do
Channels Research Preview do Claude
Code — uma superfície de recursos alfa / não lançada dentro do Claude Code. O contrato
de transporte (notifications/claude/channel) e o modelo de plugin sidecar
podem mudar sem aviso prévio. Hoje isso funciona; no próximo mês pode não funcionar.
Negociação envolve dinheiro real. Quando DERIBIT_TEST_MODE=false, cada
chamada de ferramenta mutável atinge a exchange Deribit ao vivo. Use o interruptor
de emergência (DERIBIT_TRADING_ENABLED=false), a testnet (DERIBIT_TEST_MODE=true),
e o requisito de confirm_live_trade=true por chamada na Mainnet. Defina
limites rígidos em DERIBIT_MAX_AMOUNT_* e DERIBIT_MAX_NOTIONAL_USD.
Você é responsável pelo que seu modelo faz com este acesso.
⚠️ Esta é uma infraestrutura experimental de nível de pesquisa para um agente de negociação algorítmica através de IA generativa. Não é um substituto do Robinhood. ⚠️
O que você obtém
Os principais recursos, classificados por importância
-
Mais de 60 ferramentas MCP cobrindo toda a superfície da Deribit — dados de mercado somente leitura, estado da conta, todos os primitivos de ordem mutáveis (market, limit, stop_market, stop_limit, take_market, trailing_stop, brackets, combos), edição/cancelamento baseado em rótulo, escopo de cancelamento em massa, fechamento de posição, histórico de liquidação e ordens de gatilho.
-
Auditoria de decisão pré-negociação. Ferramentas mutáveis exigem um
decision_idemitido porrecord_decision, validado contra o banco de dados antes da chamada à Deribit. Cada ordem grava uma linha emorder_auditantes e depois da chamada. Odecision_idpercorre a Deribit como olabelda ordem, então a análise posterior é trivialmente unida. -
Pipeline de ativação por canal na nuvem (Alfa — veja aviso). Alertas marcados com
notification_channel="outbox"fluem para uma caixa de saída SQLite, transmitem pela sua rede privada para um plugin sidecar executando na máquina do Claude-Code, e aparecem na sessão como um bloco nativo<channel>. O agente não faz polling; ele dorme até o mercado acordá-lo. -
Alertas auto-agendados. O agente chama
set_price_alertpara condições de limite/cruzamento/variação percentual,set_time_alertpara agendar seus próprios wakeups futuros (ex.: "verificar funding em 4 horas"), e o mecanismo de alertas dispara assincronamente pelo mesmo pipeline de canal. -
Candles OHLCV e streams de livro de ofertas ao vivo.
get_chart_dataretorna candlesticks da Deribit em resolução de 1/3/5/10/15/30/60/120/180/360/720 minutos ou diária.get_orderbook_liveeget_orderbook_diffassinam via WebSocket e servem snapshots em cache — sem latência de requisição por tick. Fita de negociações, liquidações recentes, Gregas de opções, IV/DVOL tudo consultável. -
Webhook de notícias externo.
POST /news(protegido por bearer admin) permite que qualquer sistema externo armazene um item de notícia — título + resumo + payload estruturado — e opcionalmente o envie diretamente para a sessão do agente via canal de caixa de saída. Odedupe_keyopcional torna pushes cíclicos de agregadores idempotentes. Veja News Webhook e docs/webhook-contract.md. -
Arnês de segurança de negociação. Limites por chamada de valor e nocional em USD, dimensionamento ciente da família de instrumentos (inverso vs linear vs opção), verificações de nocional no pior caso para ordens de gatilho, chaves de idempotência para sobrevivência de
client_order_idem reinicializações, requisito deconfirm_cancel_all=truepara cancelamento em massa, duplo toque deconfirm_live_trade=truena mainnet. -
Camada de armazenamento de notícias. Itens de notícias enviados persistem em uma tabela
newsconsultável com fonte, escopo do instrumento, URL, pontuação, tags e variantes de payload compacto + completo. Odedupe_keyopcional com um índice parcial único torna a ingestão cíclica idempotente. Envie para Telegram, console ou canal de caixa de saída sob demanda. -
Painel no navegador.
/dashboard/serve uma visão do operador para saúde, consumidores sidecar registrados, símbolos mantidos, posições abertas, alertas, temporizadores, decisões recentes, auditorias de ordens MCP, negociações de usuário da Deribit, eventos de caixa de saída e notícias mais recentes. Também inclui um formulário de envio de notícias que persiste o item através de/newse o envia para a sessão do agente vianotification_channel="outbox".
Arquitetura de relance
+--------------------------------+ +--------------------------------+
| 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)
Caminho da ferramenta: Claude Code é o cliente MCP. Ele carrega este servidor
diretamente via stdio (MCP_TRANSPORT=stdio) ou via
streamable-http — opcionalmente através de um gateway MCP na frente. O transporte
HTTP é protegido por um segredo compartilhado X-Deribit-MCP-Secret.
O servidor é agnóstico de gateway; conecte-o como sua configuração preferir.
Caminho de ativação (plugin sidecar): Alertas marcados com
notification_channel="outbox" gravam eventos estruturados em uma caixa de saída
SQLite durável. Um pequeno plugin Bun/TS carregado na mesma sessão do Claude Code
transmite esses eventos de /events/stream, os emite como
blocos nativos notifications/claude/channel dentro da sessão e
envia ACKs de volta. O sidecar vive em channel-plugin/ —
veja HANDOFF.md.
Caminho de injeção de notícias: Qualquer pipeline externo POST um item de notícia
para /news com push=true. O MCP o persiste e então envia um resumo
curto pelo mesmo pipeline de canal para que o agente acorde com
a notícia no contexto. O dedupe_key opcional torna tentativas idempotentes —
postagens duplicadas retornam a linha existente e não enviam novamente.
Painel no navegador: /dashboard/ serve o painel local do Deribit MCP.
Seus dados JSON e formulário de envio de notícias usam
DERIBIT_EVENT_ADMIN_TOKEN como token Bearer. A UI é intencionalmente
pesada em leitura: mostra saúde do serviço, consumidores sidecar registrados,
símbolos mantidos, posições, alertas, temporizadores, decisões recentes, negociações
recentes da Deribit, auditorias de ordens MCP, notícias mais recentes e eventos de caixa de saída.
O formulário de notícias armazena uma linha através de /news e a envia para a sessão do agente
através do canal de caixa de saída.
Webhook de Notícias
Qualquer coisa que possa acessar um endpoint HTTPS pode acordar o agente de negociação com contexto estruturado.
# 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
}'
Use para: saída de scrapers de notícias, modelos de regime personalizados, lembretes
de calendário econômico, handoffs de plantão, resumos de sentimento social, ou
qualquer outra coisa que você queira que o agente leia agora. Com dedupe_key
definido, tentativas são idempotentes — um POST duplicado retorna a linha
existente com duplicate: true e não envia o evento novamente.
O agente então vê um bloco nativo <channel> com o título da notícia
e metadados, chama news_list(id=<news_id>, include_full=true) para puxar
o payload estruturado completo e decide.
Contrato completo — esquema de payload, autenticação, semântica de deduplicação, comportamento de tentativas, exemplos — veja docs/webhook-contract.md.
Referência de ferramentas
As ferramentas são expostas tanto via stdio MCP quanto pelo transporte streamable-http. Alguns gateways MCP prefixam nomes de ferramentas — verifique as convenções do seu gateway.
📈 Dados de mercado (somente leitura)
| Ferramenta | Propósito |
|---|---|
get_current_price(instrument, skip_cache=False, max_age_seconds=None) | Snapshot de preço último/marcação. skip_cache=True força uma nova busca REST (use antes de decisões sensíveis ao tempo onde dados em cache desatualizados poderiam enganar). A resposta carrega source + age_seconds para raciocínio de frescor. |
get_ticker(instrument) | Ticker completo (marcação, último, índice, funding, IV) |
get_greeks(instrument) | Δ Γ Θ Vega para uma opção |
get_instruments(currency, kind, expired) | Listar instrumentos |
get_instrument(instrument) | Metadados de um único instrumento |
get_order_book(instrument, depth) | Livro de ofertas REST de uma vez |
get_orderbook_live(instrument, depth) | Livro de ofertas em cache WS — sem latência por chamada |
get_orderbook_diff(instrument) | Delta vs o último snapshot em cache |
unsubscribe_orderbook(instrument) | Remover uma assinatura WS |
get_book_summary(currency, kind) | Resumo agregado do livro |
get_chart_data(instrument, start_ts, end_ts, resolution) | Candles OHLCV — 1/3/5/10/15/30/60/120/180/360/720 minutos ou diário |
get_last_trades_by_instrument(...) / get_last_trades_by_currency(...) | Fita de negociações públicas |
get_recent_liquidations(currency, kind) | Capturado de streams de negociações ao vivo |
get_funding_rate_history(instrument, start, end) | Histórico de funding de perpétuos |
get_historical_volatility(currency) | Curva de volatilidade realizada |
get_combos(currency) / get_combo_ids(...) / get_combo_details(combo_id) / get_leg_prices(...) | Combos e precificação de pernas |
💰 Conta e posições (somente leitura)
| Ferramenta | Propósito |
|---|---|
get_account_summary(currency) | Saldo, PnL, margem |
get_account_summaries(extended) | Todas as moedas em uma chamada |
get_positions(currency, kind) | Posições abertas |
get_position(instrument) | Posição de um instrumento |
get_open_orders(...) | Ordens abertas, multi-filtro |
get_open_orders_by_label(currency, label) | Inclui ordens de gatilho não acionadas |
get_order_state(order_id) / get_order_state_by_label(...) / find_order_by_client_id(...) | Consulta de ordens |
get_user_trades(...) | Seu histórico de negociações |
get_order_history(...) | Histórico de ordens |
get_trigger_order_history(currency, count) | Histórico paginado de ordens de gatilho |
get_settlement_history(...) | Liquidações de PnL |
get_transaction_log(...) | Movimentações de caixa/moedas |
get_order_margin(order_ids) | Estimativa de margem para ordens ao vivo |
get_margins(instrument, amount, price) | Estimativa de margem para ordem hipotética |
get_rate_limit_status(currency) | Folga de limite de taxa do lado Deribit |
🛎️ Alertas autogerenciados
| Ferramenta | Propósito |
|---|---|
set_price_alert(instrument, condition, threshold, channel) | above / below / crosses_above / crosses_below / percentage_change |
set_time_alert(when, message, channel) | Acordar a si mesmo em um timestamp futuro |
list_alerts(...) | Todos os alertas persistidos |
remove_alert(alert_id) | Cancelar um |
O agente usa set_time_alert para agendar seus próprios check-ins.
Alertas sobrevivem a reinicializações de contêiner e re-assinam o WS da Deribit na
inicialização.
🧠 Auditoria de decisão
| Ferramenta | Propósito |
|---|---|
record_decision(...) | Emitir um decision_id com raciocínio. Obrigatório antes de qualquer ordem mutável. |
update_decision_outcome(decision_id, outcome) | filled / cancelled / rejected / expired / partial / unknown |
list_decisions(...) | Consultar o log de decisões |
📓 Notas de forma livre
| Ferramenta | Propósito |
|---|---|
add_note(...) / list_notes(...) / update_note(...) / delete_note(...) | Bloco de rascunho persistente do agente |
📰 Notícias
| Ferramenta | Propósito |
|---|---|
news_save(headline, summary, source, instrument, url, score, dedupe_key, content, tags, push, channel) | Armazenar + opcionalmente enviar. dedupe_key torna idempotente. |
news_list(id, limit, source, instrument, status, include_full) | Listar ou buscar um item de notícia; filtrar por fonte/instrumento/status |
Mesma tabela de armazenamento do News Webhook.
⚡ Negociação (mutável, atrás de proteções de segurança)
| Ferramenta | Finalidade |
|---|---|
buy(instrument, amount, order_type, ...) | Entrada longa. Suporta market, limit, market_limit, stop_market, stop_limit, take_market, trailing_stop |
sell(...) | Entrada curta / saída de posição, mesma superfície que buy |
place_bracket(entry, take_profit, stop_loss, ...) | Entrada única + TP + SL. entry_type aceita market, limit, stop_market, stop_limit — entradas stop-* ficam estacionadas no lado da exchange até que entry_trigger_price seja atingido (sem latência de wake, sobrevive a interrupções do MCP). sl_type aceita stop_market, stop_limit (sl_trigger_price fixo) ou trailing_stop (use sl_trigger_offset — desvio absoluto do pico na moeda de cotação). Substituições de gatilho por perna via entry_trigger_source / sl_trigger_source / tp_trigger_source (comum: last_price na entrada + mark_price no SL/TP). Gatilhos já passados são rejeitados. |
edit_order(order_id, ...) | Modificar por ID Deribit |
edit_order_by_label(currency, instrument, label, ...) | Modificar por decision_id (pré-verificado) |
cancel_order(order_id, decision_id?) | Cancelamento único |
cancel_orders_by_label(currency, label) | Cancelamento por rótulo com escopo de moeda |
cancel_all_orders(scope, confirm_cancel_all) | Global requer confirmação explícita |
close_position(instrument, type, ...) | Achatar uma posição |
create_combo(...) | Construir um instrumento combo personalizado |
As respostas de ordens mutáveis são intencionalmente compactas: retornam IDs de ordem, estado, detalhes de preenchimento/preço médio, resolução de filhos SL/TP e resumos agregados de negociações. Os payloads completos do Deribit permanecem em order_audit para depuração e replay sem inundar as sessões do agente.
Contrato de segurança:
DERIBIT_TRADING_ENABLED=falsebloqueia toda ferramenta mutável por padrão.- Todos os quatro limites (
DERIBIT_MAX_AMOUNT_INVERSE / LINEAR / OPTIONeDERIBIT_MAX_NOTIONAL_USD) devem ser números positivos — a inicialização falha rapidamente caso contrário. - Mainnet (
DERIBIT_TEST_MODE=false) exigeconfirm_live_trade=trueem cada chamada. - A proteção nocional para ordens de gatilho usa o preço de execução no pior caso (máximo de
trigger_priceeprice) para que um stop acima do mark atual não possa subestimar o limite. - Ordens mutáveis sem um
decision_idválido são rejeitadas antes da chamada ao Deribit. - Ordens
post_onlyusamreject_post_only=truepor padrão: um limite cruzado é rejeitado em vez de ser silenciosamente re-precificado pelo Deribit para o próximo preço maker. Aplica-se a entradasbuy/sell(reject_post_only) eplace_bracket(entry_reject_post_only); passe o campo explicitamente comofalsepara optar novamente pelo comportamento de re-precificação.
Exemplo — long com stop-loss em 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)
Exemplo — bracket de breakout no lado da exchange com feeds de gatilho assimétricos. A entrada aguarda last_price cruzar 80100 (toque de mercado limpo), então SL/TP protege em mark_price (resistente a pavios). O bracket permanece no Deribit até a entrada disparar, então latência de wake e indisponibilidade do MCP não perdem o setup:
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,
)
Um buy cujo entry_trigger_price já está no preço atual ou abaixo dele é rejeitado antes da chamada ao Deribit (lógica espelhada para sell). A leitura do preço atual ignora o cache para que um feed WS desatualizado não possa mascarar a divergência.
Início rápido
💡 Entregue a instalação ao Claude Code. Aponte qualquer agente LLM para
llms.txte ele percorrerá toda a configuração — clone, configure, compile, teste de fumaça contra testnet e verifique o caminho de wakeup do sidecar. Você só preenche os segredos.
Este servidor roda como um contêiner de longa duração expondo MCP streamable-http. Stdio (MCP_TRANSPORT=stdio) é suportado para desenvolvimento local ou lançadores stdio diretos.
# 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 desenvolvimento local da imagem do contêiner, defina DERIBIT_MCP_IMAGE=deribit-mcp-server:local e execute docker compose up -d --build a partir de um checkout.
/mcp e /sse são protegidos por MCP_SHARED_SECRET — apenas chamadores com o cabeçalho X-Deribit-MCP-Secret correto alcançam a superfície MCP. /events/* usa tokens Bearer por consumidor para o pipeline do sidecar e pode ser exposto em uma rede privada (ex.: Tailscale, VPN, overlay) para onde quer que o sidecar rode.
⚠️ O teste ponta a ponta SMOKE-PLAYBOOK.md roda contra a testnet do Deribit (
test.deribit.com) comDERIBIT_TEST_MODE=true. Ele coloca ordens reais na testnet, exercita todas as ferramentas mutáveis e se limpa sozinho. Nunca o execute contra a mainnet.
Configuração
Toda a configuração vive em .env. As configurações são validadas na inicialização — o contêiner falha rapidamente em valores ausentes ou inconsistentes.
Deribit
| Var | Default | Finalidade |
|---|---|---|
DERIBIT_API_KEY | "" | ID do cliente |
DERIBIT_API_SECRET | "" | Segredo do cliente |
DERIBIT_TEST_MODE | true | true → test.deribit.com, false → mainnet |
Transporte / autenticação
| Var | Default | Finalidade |
|---|---|---|
MCP_TRANSPORT | stdio | http para backend de gateway, stdio para desenvolvimento local |
MCP_HTTP_JSON_RESPONSE | false | Defina true apenas se o seu gateway rejeitar respostas em streaming |
MCP_SHARED_SECRET | "" | Obrigatório quando MCP_TRANSPORT=http. Passe via X-Deribit-MCP-Secret |
DERIBIT_DB_PATH | /data/deribit.db | Localização do SQLite, volume montado |
Segurança de negociação
DERIBIT_TRADING_ENABLED=false é o padrão seguro. Ferramentas mutáveis (buy, sell, edit_order, cancel_order, cancel_all_orders, close_position, place_bracket, create_combo) se recusam a executar a menos que a negociação esteja explicitamente habilitada e todos os quatro limites abaixo sejam números positivos.
| Var | Notas |
|---|---|
DERIBIT_TRADING_ENABLED | Interruptor de emergência |
DERIBIT_MAX_AMOUNT_INVERSE | Limite por chamada. Perps inversos (BTC/ETH-PERPETUAL): amount é nocional em USD |
DERIBIT_MAX_AMOUNT_LINEAR | Perps/futuros lineares (*_USDC-PERPETUAL): amount é contagem de moedas |
DERIBIT_MAX_AMOUNT_OPTION | Opções: amount é contratos |
DERIBIT_MAX_NOTIONAL_USD | Limite nocional em USD por chamada. Ciente da família (inverso: quantidade; linear: quantidade × mark; opção: quantidade × tamanho_do_contrato × índice) |
Na Mainnet (DERIBIT_TEST_MODE=false), cada chamada de ferramenta mutável também exige confirm_live_trade=true — defesa contra chamadas acidentais à Mainnet a partir de uma sessão configurada para testnet.
Outbox de eventos / sidecar
| Var | Default | Finalidade |
|---|---|---|
DERIBIT_EVENT_ADMIN_TOKEN | "" | Obrigatório para POST /events/register, POST /news, POST /news/{id}/push e ações de dashboard JSON/news-push |
DERIBIT_EVENT_RETENTION_DAYS | 7 | Por quanto tempo manter eventos ACKed no outbox |
DERIBIT_EVENT_STREAM_CLAIM_SECONDS | 90 | Por quanto tempo a reivindicação de stream de um sidecar sobrevive sem renovação |
DERIBIT_TRADING_EVENT_OUTBOX_ENABLED | true | Espelhar eventos de ciclo de vida de ordens/preenchimentos autenticados do Deribit user.* no 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 | Canais user.* do Deribit separados por vírgula para transmitir em wakeups de sessão |
Notificações
Telegram para o usuário humano, outbox para o pipeline de wakeup do agente:
| Var | Finalidade |
|---|---|
TELEGRAM_BOT_TOKEN | Token do bot para heartbeat de inicialização + alertas com notification_channel="telegram" (escalonamento opcional; canal padrão é outbox) |
TELEGRAM_CHAT_ID | Onde entregar |
Streams de mercado
| Var | Default | Finalidade |
|---|---|---|
DERIBIT_ORDERBOOK_INTERVAL | 100ms | Cadência de assinatura do orderbook: raw, 100ms ou agg2 |
DERIBIT_ORDERBOOK_DIFF_RETENTION_SECONDS | 300 | Por quanto tempo diffs do orderbook ao vivo permanecem consultáveis |
DERIBIT_ORDERBOOK_IDLE_UNSUBSCRIBE_SECONDS | 300 | Descarta assinaturas WS de orderbook ociosas |
DERIBIT_LIQUIDATION_BUFFER_SIZE | 1000 | Tamanho do ring buffer por stream de liquidação |
DERIBIT_WS_MAX_ACTIVE_CHANNELS | 450 | Guarda de canais ativos do WebSocket local; o Deribit documenta um limite de 500 canais |
Docker compose
Estas variáveis são consumidas por docker-compose.yml, não pelo aplicativo Python em si:
| Var | Default | Finalidade |
|---|---|---|
DERIBIT_MCP_IMAGE | ghcr.io/schroejahr2/deribit-mcp:latest | Imagem de runtime publicada para puxar |
BIND_IP | 127.0.0.1 | Interface do host para a porta 8000; defina 0.0.0.0 apenas quando pretender expô-la |
Arquitetura de wakeup (pipeline do sidecar)
Quando um alerta com notification_channel="outbox" dispara, o servidor grava um evento permitido na lista de payload na tabela event_outbox. O plugin sidecar rodando na máquina do Claude:
- Mantém um stream longo aberto em
GET /events/stream?consumer_id=<id>(autenticação Bearer, token por consumidor). - Recebe o evento como NDJSON.
- Emite
notifications/claude/channelcomcontent=payload.messageemeta= metadados chaveados por identificador (alert_id,instrument,severity,event_id,event_type). - Chama
POST /events/{event_id}/ackpara que o servidor pare de reentregar.
Comandos do 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"}'
As chaves meta devem corresponder a [A-Za-z0-9_]. A severidade no lado do servidor é determinística: percentage_change com |threshold| >= 5 → warning, caso contrário info. A lista de permissões de payload de eventos está em src/event_outbox.py:ALLOWED_PAYLOAD_KEYS — qualquer coisa não listada é descartada antes de persistir.
Pushes de notícias com notification_channel="outbox" emitem eventos news_ready. Eles são deduplicados no lado do servidor por news:{url} quando a linha de notícia tem uma URL, caso contrário por news:{news_id}. Eles carregam apenas metadados de notícias permitidos: news_id, source, instrument, headline, summary, url, score, tags, message.
Eventos de negociação autenticados do Deribit usam o mesmo caminho do sidecar quando DERIBIT_TRADING_EVENT_OUTBOX_ENABLED=true: o servidor assina o DERIBIT_TRADING_EVENT_CHANNELS configurado, converte atualizações de ciclo de vida de ordens e preenchimentos em eventos sanitizados deribit_order_update / deribit_trade_update e pula snapshots brutos de posição para evitar spam de preço mark na sessão.
API HTTP de notícias
Itens de notícias armazenados são consultáveis através do 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"}'
Os endpoints de salvar e enviar exigem o token bearer de administrador; os endpoints de leitura não são autenticados (o transporte HTTP já está atrás de X-Deribit-MCP-Secret para o caminho MCP; os endpoints de leitura ficam no mesmo bind).
Esquema completo de payload, semântica de deduplicação, comportamento de retry, códigos de erro — veja docs/webhook-contract.md.
Persistência
Banco de dados SQLite único montado em um volume do host. Tabelas:
alerts— alertas de preço + tempo, estado completo incluindolast_pricepara condições cruzadas. Reidratado no início do lifespan; instrumentos de alerta de preço reassinam no WebSocket e executam uma verificação de preço imediata para que alertas acumulados disparem prontamente.decisions— registros de raciocínio do modelo, aplicados antes de chamadas de negociação mutáveis. Enum de resultado:filled/cancelled/rejected/expired/partial/unknown.order_audit— toda ferramenta de negociação mutável grava uma linha antes e depois da chamada ao Deribit. Operações em massa preenchemderibit_order_ids_jsone deixam o singularderibit_order_idnulo.notes— bloco de rascunho de forma livre do agente.idempotency_keys— cache por chamada paraclient_order_id. TTL de 5 min, coletado a cada 5 min. Sobrevive ao reinício do contêiner.event_outbox,event_consumers,event_deliveries— estado do pipeline de wakeup do sidecar. O reaper exclui apenas eventos cujas entregas estão todas ACKed e cujoexpires_atjá passou.news— itens de notícias ingeridos externamente com manchete, resumo, fonte, escopo de instrumento, URL, pontuação, tags, conteúdo JSON de forma livre, status de processamento, atribuição opcional de modelo e metadados de push de notificação.dedupe_keyopcional com um índice parcial único permite ingestão cíclica idempotente.
Testes
Duas camadas:
Testes unitários (tests/, ~200 casos): proteções de negociação, incluindo
limites de valor/nocional por família de instrumentos, roteamento de cancel_all,
repositório de decisões + enum de resultado, cache de idempotência, deduplicação de outbox +
allowlist, persistência/deduplicação/roteamento de push de notícias, semântica de auditoria
de cancelamento em massa, middleware de segredo compartilhado do http_app, passagem de
lifespan, codificação de colchetes de array GET.
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest tests/
A imagem de runtime GHCR publicada intencionalmente não inclui a suíte de testes nem as dependências de desenvolvimento. Use o venv local para testes unitários, ou construa uma imagem de desenvolvimento temporária a partir do checkout.
Playbook de smoke de ponta a ponta (SMOKE-PLAYBOOK.md): execução autônoma em múltiplas fases por outra sessão Claude, cobrindo todas as ferramentas somente-leitura, todos os ciclos de vida de ordens mutáveis, os quatro testes negativos de segurança de negociação, burst de canal, wakeup de alerta por tempo e uma fase de limpeza. Projetado para deixar a conta testnet no mesmo estado em que começou.
Runbook do 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())
"
Estrutura do projeto
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 e atribuição
Originalmente baseado em Oishh/telegram-signal-mcp-server (MIT). Clientes REST/WS do Deribit adaptados do upstream; canal na nuvem / outbox de eventos, persistência, proteções de negociação, ingestão de notícias, streams de mercado, notas e integração de gateway são trabalhos novos. Atribuição completa em NOTICE.
Licença
Licença dupla: AGPL-3.0 OU Comercial.
- Padrão: GNU Affero General Public License v3.0. Livre para usar, modificar e auto-hospedar. Se você operar o Deribit MCP como um serviço de rede, a AGPL-3.0 exige que você disponibilize o código-fonte correspondente completo — incluindo suas modificações e o código do serviço ao redor — aos seus usuários.
- Licença comercial: se a AGPL-3.0 não for atraente para sua implantação em produção (serviço de código fechado, produto pago, plataforma de negociação interna, oferta hospedada, SLA formal / garantia / indenização), compre uma licença comercial da GS Technik GmbH. Veja COMMERCIAL.md — também cobre hospedagem gerenciada de alto desempenho e operação 24/7. Contato: info@schroejahr.de.
- Hospedagem por terceiros: a AGPL ou uma licença comercial rege seus direitos apenas sobre este código. Hospedar este software para outros usuários, ou operá-lo com chaves de API Deribit de terceiros, pode exigir acordos separados de exchange, KYC, uso de API ou comerciais com a Deribit/Coinbase. Entre em contato diretamente com a exchange; este projeto não pode conceder esses direitos.
Partes derivadas do upstream de telegram-signal-mcp-server por Oishh permanecem sob os termos originais do MIT preservados em LICENSE-MIT. Trabalho novo substancial — pipeline de outbox/canal, persistência, negociação auditada, ingestão de notícias, streams de mercado, integração de gateway — é trabalho sob AGPL-3.0. Atribuição completa em NOTICE.
Aviso legal
Deribit e Coinbase são marcas registradas de seus respectivos proprietários. Este projeto é independente e não é afiliado, endossado ou patrocinado pela Deribit, Deribit B.V., Coinbase ou Coinbase Global, Inc.
Este software se conecta a uma exchange de derivativos ao vivo. Negociar derivativos de
criptomoedas envolve risco substancial de perda. Nada neste repositório é aconselhamento
financeiro. Os autores não aceitam responsabilidade por quaisquer perdas, alertas perdidos,
erros de modelo, desconexões de sidecar ou qualquer outra consequência do uso deste software.
Você é responsável pelo que seu modelo faz com este acesso. Use a testnet, o kill switch e
os limites de negociação. Leia o código antes de ativar DERIBIT_TRADING_ENABLED=true.
Autor
Construído por Georg Schröjahr — schroejahr.de.
Issues, ideias e pull requests são bem-vindos em github.com/schroejahr2/deribit-mcp.