Hyperliquid-MCP

Servidor MCP para negociação perpétua na Hyperliquid, execução de ordens, sinais de livro de ordens/microestrutura em tempo real, análises de fluxo de negociação e risco de Monte Carlo, exposto a assistentes de IA através do Model Context Protocol.

Documentação

hyperliquid-mcp

hyperliquid-mcp in action

Um servidor MCP que dá ao seu IA/LLM acesso direto e assinado aos perpétuos da Hyperliquid. Construído sobre o SDK oficial em Python, endurecido para o único modo de falha que realmente custa dinheiro: uma ordem rejeitada reportada como sucesso. Cada escrita analisa a resposta da exchange antes de afirmar qualquer coisa. Cada leitura informa de onde vieram os dados.

Você aponta o Claude (ou qualquer cliente MCP) para ele, entrega uma chave, e ele negocia.

Início rápido

uvx --from mcp-hyperliquid hyperliquid-mcp

É isso. Sem arquivo .env, sem diretório de configuração — tudo vem do bloco env do seu cliente MCP:

{
  "mcpServers": {
    "hyperliquid": {
      "command": "uvx",
      "args": ["--from", "mcp-hyperliquid", "hyperliquid-mcp"],
      "env": {
        "HYPERLIQUID_PRIVATE_KEY": "0x...",
        "HYPERLIQUID_TESTNET": "true"
      }
    }
  }
}

Sim, "true". Comece na testnet. Mude para "false" depois que sua estratégia sobreviver ao dinheiro fictício.

Executando a partir do código-fonte:

git clone https://github.com/Dakkshin/hyperliquid-mcp.git
cd hyperliquid-mcp
uv sync
uv run python -m hyperliquid_mcp.server

(Mesma configuração do cliente, mas command: "uv", args: ["--directory", "/path/to/hyperliquid-mcp", "run", "python", "-m", "hyperliquid_mcp.server"].)

Antes de negociar

A Hyperliquid não conhece sua carteira até que ela tenha fundos. Configuração única:

Pule isso e toda escrita retornará User or API Wallet does not exist. O servidor entregará essa mensagem exata em vez de um stack trace — mas não pode depositar por você.

Escolha sua configuração

Apenas explorando / paper trading. HYPERLIQUID_TESTNET=true, sua chave de carteira, pronto. A testnet é um universo paralelo completo: ledger separado, aprovações de agente separadas e — isso pega todo mundo — índices de ativos separados. BTC é o índice 0 na mainnet e 3 na testnet. Nunca codifique um índice; resolva através de hyperliquid_get_meta toda vez.

Operando com dinheiro real. Use o modo agente. Gere uma carteira de API na interface da Hyperliquid (Mais -> API), aprove-a a partir da sua conta principal e então:

"env": {
  "HYPERLIQUID_PRIVATE_KEY": "0xApiWalletKey...",
  "HYPERLIQUID_ACCOUNT_ADDRESS": "0xYourMainAccount...",
  "HYPERLIQUID_TESTNET": "false"
}

A carteira de API assina; sua chave principal nunca toca a máquina que executa o modelo. Esta é a única configuração de produção sensata. As aprovações de agente são por rede — um agente aprovado na mainnet é um estranho na testnet.

Negociando perpétuos de dex de builder (ações, ouro, coisas HIP-3). Defina HYPERLIQUID_PERP_DEXS="xyz" (separados por vírgula para vários). Não definido significa apenas dex primário — inicialização de ~2s, cobre todos os perpétuos padrão. "all" carrega todos os dex descobertos: centenas de chamadas REST em série, ~90s, e seu cliente MCP mata a conexão aos 30s a menos que você aumente MCP_TIMEOUT=180000. Você quase certamente não quer "all".

Opcional: HYPERLIQUID_VAULT_ADDRESS se você negociar um vault.

O que ele faz

Trinta ferramentas. As interessantes:

Execução. place_order, place_bracket_order, modify_order, cancel_order, cancel_all_orders, update_leverage. Ordens de mercado são emuladas da forma que o SDK faz — limite IoC agressivo no mid ±5% — porque a Hyperliquid não tem ordem de mercado nativa e uma ordem de compra parada a $0 ficaria lá para sempre.

Brackets são OCO reais. Entrada + TP + SL são enviados como um grupo normalTpsl atômico. TP e SL são filhos da entrada: um preenche, a exchange mata o outro; cancele a entrada, ambos morrem. Sem stop obsoleto deixado no livro às 3h da manhã. O stop-loss dispara como mercado com um limite limitado por slippage — um stop com limite pode atravessar o preço e nunca preencher, o que anula todo o propósito de um stop.

O servidor recusa lixo antes de assinar. Stop no lado errado para uma posição long (SL acima da entrada)? Rejeitado localmente — dispararia no instante em que tocasse o livro. size: "NaN"? Rejeitado — o codificador de wire do SDK assinaria feliz caso contrário. asset: 5.7? Rejeitado, não truncado para 5 — truncamento silencioso significa ordenar o instrumento errado.

E ele nunca mente sobre resultados. Um cancelamento rejeitado diz Cancel failed com o motivo da exchange. Um bracket com uma perna inválida reporta a rejeição do grupo atômico. cancel_all_orders retorna resultados por oid e uma contagem honesta — incluindo os stops TP/SL não disparados, que o endpoint ingênuo de ordens abertas nem lista. Se uma escrita expirar, a resposta diz "pode ter executado, verifique novamente" — porque um timeout após a requisição sair do prédio não é uma falha, e tratá-lo como tal é como você faz double-fill.

Dados de mercado com recibo de frescor. Livros de ofertas, trades, candles, funding, open interest. Leituras quentes são servidas de um espelho WebSocket em memória — O(1), sem round-trip REST — e cada resposta carrega source: "websocket" ou "rest" para você saber exatamente o que recebeu. O socket do SDK não reconecta automaticamente; quando morre, as leituras degradam silenciosamente para REST em vez de servir um livro obsoleto. Mais lento, nunca errado.

Quant no servidor, payloads do tamanho de tokens. O ponto de calcular no servidor: um modelo de 8B não deveria fazer comparações de float, e você não deveria pagar tokens por 1000 níveis brutos de livro.

  • get_microstructure — OBI, micro-price de Stoikov, spread em bps. ~20 tokens.
  • get_orderflow — CVD, volume de compra/venda agressora, desequilíbrio de fluxo de trades da fita ao vivo. O livro diz intenção, a fita diz ação; leia ambos.
  • get_indicators — RSI (de Wilder, fixado por testes contra o de Cutler), Bollinger (desvio padrão populacional, também fixado), EMA 9/21/50/200, SMA de volume. Uma chamada, um intervalo. Retorna valores brutos mais flags determinísticas — rsi.zone, ema.is_ordered_up, bollinger.is_squeeze. Apenas fatos matemáticos. Nunca dirá signal: "BUY"; formar opiniões é trabalho do seu modelo.
  • run_monte_carlo — GBM vetorizado, 10k+ caminhos, retorna VaR, percentis terminais, probabilidade de lucro. Amostra preços terminais diretamente (um sorteio por caminho, O(iterações) qualquer que seja o horizonte). Drift padrão é martingale — retorno esperado zero — porque 30 dias de histórico é uma vibe, não uma estimativa de drift. Verifique observations na saída: a API de candles limita em torno de 5000 linhas, então um lookback de 30 dias com candles de 1m é silenciosamente ~3,5 dias de dados. O campo existe para você perceber.
  • get_beta — beta, correlação, R² contra um benchmark que você deve nomear (sem default sorrateiro). Regressão de log-retornos alinhada por timestamp. Sem alpha, sem flags — beta é uma entrada contínua de dimensionamento, e um booleano beta > 1 inventaria um precipício que não existe.

Não implementado: place_twap_order / cancel_twap_order são stubs de schema que lançam erro. São declarados para que clientes vejam que virão; ainda não funcionam. ¯_(ツ)_/¯

Falando com ele

Você não chama essas ferramentas — seu modelo chama. Prompts que funcionam:

Show me my Hyperliquid balance

Retorna ambos os ledgers — perp e spot. A Hyperliquid os mantém separados, e uma carteira segurando apenas USDC em spot reporta saldo perp de $0. Aprendi isso do jeito chato; a ferramenta agora expõe totalUsdcAcrossAccounts para ninguém mais precisar.

Is there buy or sell pressure on HYPE right now?

Uma chamada get_microstructure:

{"asset":"HYPE","source":"websocket","depth":5,"OBI":0.62,"micro_price":1.452,"mid":1.451,"spread_bps":2.1}

OBI 0,62 = bids carregando 62% do volume no topo do livro. Micro-price acima do mid = pressão apontando para cima. Spread ~2bps = líquido.

Long 4.12 SOL, entry 218, target 219.50, stop 216.80

O modelo resolve o índice da SOL via get_meta, dispara place_bracket_order, recebe três pernas com status. Se tivesse pedido um stop acima da entrada, a ordem nunca sairia da máquina.

If I hold BTC for 7 days, what's my downside?

run_monte_carlo -> VaR_5pct: 0.0836 = perda de 8,4% no 5º percentil. Dez mil caminhos simulados, nenhum atravessa o wire — apenas o resumo vai.

Quando quebra

User or API Wallet does not exist — carteira não registrada nesta rede, ou agente não aprovado nesta rede. Deposite/use faucet primeiro; aprove agentes por rede.

Order has invalid price. / Order has invalid size. — regras de tick e lote. Preços: máximo de 5 algarismos significativos e limites decimais por ativo. Tamanhos: szDecimals de get_meta. E size × price ≥ $10, sempre.

Conexão expira na inicialização — você definiu HYPERLIQUID_PERP_DEXS="all". Remova, ou aumente MCP_TIMEOUT. Isso é um problema de velocidade de inicialização, não um erro de configuração.

Toda leitura diz source: "rest" — o WebSocket morreu (não reconecta) ou ainda não aqueceu. A primeira leitura de uma moeda é sempre REST; o espelho assume em alguns segundos. REST persistente significa reiniciar o servidor. Os dados permanecem corretos de qualquer forma — é o fallback fazendo seu trabalho.

Depurando qualquer outra coisa:

HYPERLIQUID_LOG_LEVEL=DEBUG uvx --from mcp-hyperliquid hyperliquid-mcp

Segurança, sem rodeios

  1. A chave na sua configuração MCP pode assinar ordens. Trate esse arquivo como a própria chave.
  2. Modo agente para qualquer coisa real. A chave principal fica offline.
  3. Testnet primeiro. O universo paralelo é grátis.
  4. Brackets em vez de entradas nuas. O OCO do lado da exchange existe para que um processo morto não orfane seu stop.
  5. O servidor nunca registra ou ecoa a chave privada. Também não pode impedir você de colá-la num chat. Não faça.

Desenvolvimento

uv sync
uv run pytest        # ~100 tests: golden-value math pins, response-parsing fixtures, liveness guards
uv run black src/
uv run mypy src/

Tudo vive em src/hyperliquid_mcp/server.py — uma classe, dois clientes SDK, uma tabela de dispatch e um motor de estado WebSocket com threads. Os testes são o contrato: RSI de Wilder vs Cutler, Bollinger ddof=0 vs ddof=1, drift martingale, parsing de status OCO — troque uma fórmula e a suíte falha alto, que é exatamente o ponto.

PRs são bem-vindos. Traga testes; os de matemática especialmente — um número errado que faz parse é pior que um crash.

Recursos

Licença

Este projeto é licenciado sob a Licença MIT — veja o arquivo LICENSE para detalhes.

Aviso

Este é um software que permite a um modelo de linguagem assinar ordens contra uma exchange de perpétuos com alavancagem real. É fornecido como está, tem casos de borda, e mercados não se importam com você. Negocie apenas o que pode perder inteiramente. Ninguém aqui é responsável pelo seu P&L.