hyperliquid-agent-gateway
hyperliquid-agent-gateway
An MCP (Model Context Protocol) server that gives AI agents read-only,
keyless access to Hyperliquid public data - the ~233-perp DEX
market, ~326 spot pairs, funding, per-account risk and HyperEVM (chain
999) token transfers. No API keys, no auth, no signing, no writes:
every tool reads public endpoints only (api.hyperliquid.xyz/info and
rpc.hyperliquid.xyz/evm), cached and rate-limited so an enthusiastic
agent cannot hammer the upstream.
Use cases
Watch a wallet's risk — per-account margin summary, leverage, liquidation distance on any address (
account riskview)Fund the carry, not the noise — funding history + carry screener across 233 perps to find stable paid positions
Trace HyperEVM flows — token transfers on chain 999 tied back to the perp markets (
token_transfers)Read the book before you enter — order book + recent trades + all-mids in one pass
Trader scouting — activity of any address: positions, volume, what they actually trade
Full walkthroughs: examples/use-cases.md.
Quickstart
stdio (default, for local agents):
uvx hyperliquid-agent-gatewayor from a checkout:
git clone https://github.com/alekskram/hyperliquid-agent-gateway
cd hyperliquid-agent-gateway
uv sync
uv run hyperliquid-agent-gatewayClaude Desktop / Cursor config:
{
"mcpServers": {
"hyperliquid": {
"command": "uvx",
"args": ["--from",
"git+https://github.com/alekskram/hyperliquid-agent-gateway",
"hyperliquid-agent-gateway"]
}
}
}Hosted form - streamable HTTP on port 8903:
uv run hyperliquid-agent-gateway --http # 127.0.0.1:8903
curl http://127.0.0.1:8903/health # -> {"ok": true, "service": "hyperliquid-agent-gateway", ...}[mcp_servers.hyperliquid]
command = "uvx"
args = ["hyperliquid-agent-gateway"]# 1) start the gateway (keep it running)
uvx hyperliquid-agent-gateway --http --port 8903 &
# 2) register it (merges into ~/.zcode/cli/config.json)
python3 - <<'PY'
import json, os
p = os.path.expanduser("~/.zcode/cli/config.json")
os.makedirs(os.path.dirname(p), exist_ok=True)
cfg = json.load(open(p)) if os.path.exists(p) else {}
cfg.setdefault("mcp", {}).setdefault("servers", {})["hyperliquid"] = {
"type": "http", "url": "http://127.0.0.1:8903/mcp"}
json.dump(cfg, open(p, "w"), indent=2)
print("hyperliquid-agent-gateway registered:", p)
PYHosted form — streamable HTTP on port 8903:
uvx hyperliquid-agent-gateway --httpTools
All 12 tools are read-only (annotated readOnlyHint: true, destructiveHint: false, openWorldHint: true).
# | Tool | Signature | What it does |
1 |
|
| Perp market snapshot from ONE |
2 |
|
| Spot pairs from |
3 |
|
| Bid/ask/mid/spread + top-of-book sizes from |
4 |
|
| Book levels per side with nSigFigs aggregation and per-side total liquidity. |
5 |
|
| OHLCV rows newest-first; intervals 1m/15m/1h/4h/1d/1w/1M; |
6 |
|
| Recent public fills WITH both sides' addresses ( |
7 |
|
| Hourly funding rows + |
8 |
|
| Per-account risk: margin summary, cross maintenance margin, per-position leverage + |
9 |
|
| Fills PnL/fees/volume/win-rate, funding net, open positions, per-coin breakdown. |
10 |
|
| Ranks ALL perps from ONE call; |
11 |
|
| HyperEVM ERC-20 Transfer logs via adaptive-window |
12 |
|
| Native (eth_getBalance) + up to 20 ERC-20s (eth_call balanceOf, resolved from spotMeta) + Hyperliquid spot balances; every row carries |
Rate limits
Two independent, locally enforced budgets protect the upstream:
/info - 1200 weight per rolling 60s (Hyperliquid's documented
weight pricing), tracked per request type:
type | weight |
| 2 |
| 2 |
| 20 |
| 20 |
| 20 base + extra per 20 items beyond the first |
| 60 |
When the next request would exceed the budget the client waits once (<=5s) for the window to roll, then raises a clear error naming the limit - it never sleep-blocks forever.
HyperEVM RPC - 100 requests per rolling 60s (flat 1 per request),
enforced separately from /info. Over-budget calls raise immediately
(rpc-limit) - tools surface an honest error dict, and
wallet_balance stops its ERC-20 scan at the cap.
TTL caches additionally dedupe repeated calls per data type: allMids 15s, recentTrades 15s, l2Book 5s, metaAndAssetCtxs 60s, spotMeta 3600s, spotMetaAndAssetCtxs 60s, candleSnapshot 300s, fundingHistory 300s, per-address account types 60s.
Data notes
Every numeric from the API is a STRING upstream; the gateway parses them with a never-raising helper -
nullalways means "not available", never zero.Every upstream failure returns an error dict
{"error": ..., "source": ..., "reason": ...}, never a traceback; partial data degrades field-by-field withwarnings[].liquidation_risknever invents a liquidation price: when the venue publishes none,liq_pxstaysnulland the distance is an explicitly flagged estimate (formula in the tool's note). Mark px is likewise never invented: live positions carry nomarkPx, so it is resolved frommetaAndAssetCtxs(fallbackallMids) and the row'smark_px_sourcesays which; no source ->null.funding_drag/funding_net: the venue'suserFundingreturns only NON-ZERO funding events, so a livenull/empty for a fresh or quiet address is expected behaviour, not a bug.ERC-20 amounts use a static decimals map for canonical HyperEVM tokens (6 for USDC/USDT-style, 18 for PURR/HYPE); unknown tokens assume 18 and every row says
decimals_source: "assumed_18"- do not trust 6dp precision for unmapped tokens.Cached responses carry
age_seconds/fetched_atfreshness fields.
License
MIT.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/alekskram/hyperliquid-agent-gateway'
If you have feedback or need assistance with the MCP directory API, please join our Discord server