A Model Context Protocol (MCP) server for Hyperliquid
This MCP server has significant definition quality issues. While tool names follow verb_noun conventions (get_, order, cancel_), descriptions are inconsistent, some tools have identical descriptions despite different functionality (e.g., get_spot_clearinghouse_state and get_perp_clearinghouse_state both say 'Get the clearinghouse state of a user on Hyperliquid'). Parameter descriptions are often redundant or missing critical context. Schema definitions mix Zod validation objects with JSON Schema, creating inconsistency. Critical parameters lack type constraints (e.g., 'coin' in get_l2_book should constrain to enum values like 'BTC-PERP', 'ETH-PERP'). The order tool has ambiguous required parameters, limit_px is required even for market orders where it makes no sense. Error handling, output schemas, and recovery guidance are absent from visible code. No evidence of input validation, rate limiting, or permission checks.
Cancel an order on Hyperliquid
Get mid prices for all coins on Hyperliquid
Get candlestick data for a token on Hyperliquid
Get the L2 book of a token on Hyperliquid
Get all open orders on Hyperliquid, if no user is provided, the open orders of the wallet address will be returned
Get all order history on Hyperliquid, if no user is provided, the order history of the wallet address will be returned
Identical descriptions for distinct tools (get_spot_clearinghouse_state and get_perp_clearinghouse_state both say 'Get the clearinghouse state of a user on Hyperliquid'). LLMs cannot distinguish when to use each tool.
Missing output schema documentation. No indication of what fields or structure the tools return. LLMs cannot plan downstream tool calls or extract needed data.
Parameter 'coin' in get_l2_book and other tools lacks enum constraint. Description mentions examples ('BTC-PERP', 'ETH-PERP', 'SOL-PERP', 'BTC-SPOT') but does not declare them as valid options, inviting hallucinated values.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 39 | - | v1 |
Get the status of an order on Hyperliquid
Get the clearinghouse state of a user on Hyperliquid, if no user is provided, the clearinghouse state of the wallet address will be returned
Get the clearinghouse state of a user on Hyperliquid, if no user is provided, the clearinghouse state of the wallet address will be returned
Request spot trading metadata
Place an order on Hyperliquid
Transfer spot to perp, or perp to spot, based on the toPerp value
order tool requires 'limit_px' (limit price) even when is_market=true. Market orders do not use limit prices. This parameter constraint is semantically broken.
Schema mixing: walletClient/tools.ts uses Zod validation objects in 'required' array (e.g., z.string(), z.enum()) instead of JSON Schema types. publicClient/tools.ts uses proper JSON Schema. This inconsistency breaks tool registration.
Parameter 'user' in clearinghouse and order tools is not required (required: []), but description says 'if no user is provided, the clearinghouse state of the wallet address will be returned'. Behavior when parameter is omitted is undocumented, where does 'wallet address' come from?
No error handling or recovery guidance visible. Tools return failures but do not tell the LLM what to do next. A refused order returns nothing, the LLM cannot retry or diagnose.
Destructive tools (order, cancel_order, transfer_spot_perp) lack confirmation or dry-run support. An agent can execute trades or transfer funds irreversibly without a chance to preview.
No pagination support. get_open_orders and get_order_history return all results without limit or offset. If a user has 1000 orders, the response bloats the context window.
Parameter descriptions are often redundant copies of the tool name. E.g., 'user' parameter in get_order_status has description 'Get the status of an order on Hyperliquid', which repeats the tool description instead of explaining what the parameter controls.
Tool composition: multiple tools operate on the same resources (orders, positions, transfers) but no clear chain of outputs to inputs. If get_open_orders returns an 'oid' field, is it the same as the 'oid' parameter expected by get_order_status? Not documented.