Hyperliquid-MCP

Servidor MCP para trading perpetuo en Hyperliquid, ejecución de órdenes, señales de libro de órdenes/microestructura en vivo, análisis de flujo de operaciones y riesgo Monte Carlo, expuesto a asistentes de IA a través del Protocolo de Contexto de Modelo.

Documentación

hyperliquid-mcp

hyperliquid-mcp in action

Un servidor MCP que le da a tu IA/LLM acceso directo y firmado a los perpétuos de Hyperliquid. Construido sobre el SDK oficial de Python, endurecido para el único modo de fallo que realmente cuesta dinero: una orden rechazada reportada como éxito. Cada escritura analiza la respuesta del exchange antes de afirmar nada. Cada lectura te dice de dónde vienen los datos.

Lo apuntas a Claude (o a cualquier cliente MCP), le das una clave, y opera.

Inicio rápido

uvx --from mcp-hyperliquid hyperliquid-mcp

Eso es todo. Sin archivo .env, sin directorio de configuración — todo viene del bloque env de tu cliente MCP:

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

Sí, "true". Empieza en testnet. Cámbialo a "false" después de que tu estrategia sobreviva al dinero falso.

Ejecutando desde el código fuente en su lugar:

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

(La misma configuración del cliente, pero command: "uv", args: ["--directory", "/path/to/hyperliquid-mcp", "run", "python", "-m", "hyperliquid_mcp.server"].)

Antes de que pueda operar

Hyperliquid no conoce tu wallet hasta que tiene fondos. Configuración única:

Si te saltas esto, cada escritura devuelve User or API Wallet does not exist. El servidor te dará ese mensaje exacto en lugar de un stack trace — pero no puede depositar por ti.

Elige tu configuración

Solo explorando / paper trading. HYPERLIQUID_TESTNET=true, tu clave de wallet, listo. Testnet es un universo paralelo completo: ledger separado, aprobaciones de agentes separadas, y — esto muerde a todos — índices de activos separados. BTC es el índice 0 en mainnet y 3 en testnet. Nunca hardcodees un índice; resuélvelo a través de hyperliquid_get_meta cada vez.

Operando con dinero real. Usa el modo agente. Genera una wallet API en la interfaz de Hyperliquid (Más -> API), apruébala desde tu cuenta principal, luego:

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

La wallet API firma; tu clave principal nunca toca la máquina que ejecuta el modelo. Esta es la única configuración de producción sensata. Las aprobaciones de agentes son por red — un agente aprobado en mainnet es un extraño en testnet.

Operando perpétuos de builder-dex (acciones, oro, cosas HIP-3). Establece HYPERLIQUID_PERP_DEXS="xyz" (separados por comas para varios). Sin establecer significa solo dex principal — ~2s de arranque, cubre todos los perpétuos estándar. "all" carga cada dex descubierto: cientos de llamadas REST en serie, ~90s, y tu cliente MCP mata la conexión a los 30s a menos que subas MCP_TIMEOUT=180000. Casi con seguridad no quieres "all".

Opcional: HYPERLIQUID_VAULT_ADDRESS si operas un vault.

Qué hace

Treinta herramientas. Las interesantes:

Ejecución. place_order, place_bracket_order, modify_order, cancel_order, cancel_all_orders, update_leverage. Las órdenes de mercado se emulan como lo hace el SDK — orden IoC agresiva al mid ±5% — porque Hyperliquid no tiene orden de mercado nativa y una orden de compra resting a $0 se quedaría ahí para siempre.

Los brackets son OCO reales. Entrada + TP + SL se envían como un grupo atómico normalTpsl. TP y SL son hijos de la entrada: uno se llena, el exchange mata al otro; cancela la entrada, ambos mueren. Sin stop obsoleto resting en el libro a las 3am. El stop-loss se activa como mercado con un límite acotado por slippage — un stop límite puede atravesar su precio y nunca llenarse, lo que anula el propósito de un stop.

El servidor rechaza basura antes de firmarla. ¿Stop en el lado equivocado en un long (SL por encima de la entrada)? Rechazado localmente — se activaría en el instante en que tocara el libro. ¿size: "NaN"? Rechazado — el codificador de cable del SDK lo firmaría felizmente de otro modo. ¿asset: 5.7? Rechazado, no truncado a 5 — el truncamiento silencioso significa ordenar el instrumento equivocado.

Y nunca miente sobre los resultados. Una cancelación rechazada dice Cancel failed con la razón del exchange. Un bracket con una pata inválida reporta el rechazo del grupo atómico. cancel_all_orders devuelve resultados por oid y un conteo honesto — incluyendo los stops TP/SL no activados, que el endpoint ingenuo de órdenes abiertas ni siquiera lista. Si una escritura expira, la respuesta dice "puede que aún se haya ejecutado, vuelve a verificar" — porque un timeout después de que la solicitud salió no es un fallo, y tratarlo como tal es cómo haces un doble llenado.

Datos de mercado con recibo de frescura. Libros de órdenes, trades, velas, funding, interés abierto. Las lecturas calientes se sirven desde un espejo WebSocket en memoria — O(1), sin round-trip REST — y cada respuesta lleva source: "websocket" o "rest" para que sepas exactamente qué obtuviste. El socket del SDK no se reconecta automáticamente; cuando muere, las lecturas degradan silenciosamente a REST en lugar de servirte un libro obsoleto. Más lento, nunca incorrecto.

Quant del lado del servidor, payloads del tamaño de un token. El punto de computar en el servidor: un modelo de 8B no debería hacer comparaciones de floats, y no deberías pagar tokens por 1000 niveles crudos del libro.

  • get_microstructure — OBI, micro-precio de Stoikov, spread en bps. ~20 tokens.
  • get_orderflow — CVD, volumen de compra/venta agresor, desequilibrio del flujo de trades desde la cinta en vivo. El libro dice intención, la cinta dice acción; lee ambos.
  • get_indicators — RSI (de Wilder, fijado por tests contra el de Cutler), Bollinger (desviación estándar poblacional, también fijado), EMA 9/21/50/200, SMA de volumen. Una llamada, un intervalo. Devuelve valores crudos más flags deterministas — rsi.zone, ema.is_ordered_up, bollinger.is_squeeze. Solo hechos matemáticos. Nunca te dirá signal: "BUY"; formar opiniones es trabajo de tu modelo.
  • run_monte_carlo — GBM vectorizado, 10k+ caminos, devuelve VaR, percentiles terminales, probabilidad de ganancia. Muestrea precios terminales directamente (un draw por camino, O(iteraciones) sea cual sea el horizonte). El drift por defecto es martingala — retorno esperado cero — porque 30 días de historia son una vibra, no una estimación de drift. Revisa observations en la salida: la API de velas limita alrededor de 5000 filas, así que un lookback de 30 días con velas de 1m es silenciosamente ~3.5 días de datos. El campo existe para que puedas detectarlo.
  • get_beta — beta, correlación, R² contra un benchmark que debes nombrar (sin default oculto). Regresión de log-retornos alineada por timestamp. Sin alpha, sin flags — beta es una entrada continua de sizing, y un booleano beta > 1 inventaría un precipicio que no existe.

No implementado: place_twap_order / cancel_twap_order son stubs de esquema que lanzan error. Están declarados para que los clientes puedan verlos venir; aún no funcionan. ¯_(ツ)_/¯

Hablando con él

No llamas a estas herramientas — tu modelo lo hace. Prompts que funcionan:

Show me my Hyperliquid balance

Devuelve ambos ledgers — perp y spot. Hyperliquid los mantiene separados, y una wallet que solo tiene USDC en spot reporta un balance perp de $0. Lo aprendí de la manera molesta; la herramienta ahora muestra totalUsdcAcrossAccounts para que nadie más tenga que hacerlo.

Is there buy or sell pressure on HYPE right now?

Una llamada 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 = las ofertas llevan el 62% del volumen top-of-book. Micro-precio por encima del mid = presión hacia arriba. Spread ~2bps = líquido.

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

El modelo resuelve el índice de SOL vía get_meta, dispara place_bracket_order, obtiene tres patas con estados. Si hubiera pedido un stop por encima de la entrada, la orden nunca sale de la máquina.

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

run_monte_carlo -> VaR_5pct: 0.0836 = pérdida del 8.4% en el percentil 5. Diez mil caminos simulados, ninguno cruza el cable — solo el resumen lo hace.

Cuando se rompe

User or API Wallet does not exist — wallet no registrada en esta red, o agente no aprobado en esta red. Deposita/usa faucet primero; aprueba agentes por red.

Order has invalid price. / Order has invalid size. — reglas de tick y lote. Precios: máximo 5 cifras significativas y límites decimales por activo. Tamaños: szDecimals desde get_meta. Y size × price ≥ $10, siempre.

La conexión expira al arrancar — estableciste HYPERLIQUID_PERP_DEXS="all". Quítalo, o sube MCP_TIMEOUT. Esto es un problema de velocidad de arranque, no un error de configuración.

Cada lectura dice source: "rest" — el WebSocket murió (no se reconecta) o aún no se ha calentado. La primera lectura de una moneda siempre es REST; el espejo toma el control en un par de segundos. REST persistente significa reiniciar el servidor. Los datos siguen siendo correctos de cualquier manera — eso es el fallback haciendo su trabajo.

Depurando cualquier otra cosa:

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

Seguridad, sin rodeos

  1. La clave en tu configuración MCP puede firmar órdenes. Trata ese archivo como la clave misma.
  2. Modo agente para cualquier cosa real. La clave principal se queda offline.
  3. Testnet primero. El universo paralelo es gratis.
  4. Brackets sobre entradas desnudas. El OCO del lado del exchange existe para que un proceso muerto no pueda dejar huérfano tu stop.
  5. El servidor nunca registra ni repite la clave privada. Tampoco puede evitar que la pegues en un chat. No lo hagas.

Desarrollo

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

Todo vive en src/hyperliquid_mcp/server.py — una clase, dos clientes SDK, una tabla de dispatch, y un motor de estado WebSocket con hilos. Los tests son el contrato: RSI de Wilder vs Cutler, Bollinger ddof=0 vs ddof=1, drift martingala, parsing de estado OCO — cambia una fórmula y la suite falla ruidosamente, que es el punto.

PRs bienvenidos. Trae tests; los de matemáticas especialmente — un número incorrecto que parsea es peor que un crash.

Recursos

Licencia

Este proyecto está licenciado bajo la Licencia MIT - consulta el archivo LICENSE para más detalles.

Aviso legal

Esto es software que permite a un modelo de lenguaje firmar órdenes contra un exchange de perpétuos con apalancamiento real. Se proporciona tal cual, tiene casos límite, y a los mercados no les importas. Opera solo con lo que puedas perder por completo. Nadie aquí es responsable de tu P&L.