hyperliquid-agent-gateway 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hyperliquid_agent_gateway-0.1.1/.github/workflows/release.yml +26 -0
- hyperliquid_agent_gateway-0.1.1/.github/workflows/tests.yml +27 -0
- hyperliquid_agent_gateway-0.1.1/.gitignore +7 -0
- hyperliquid_agent_gateway-0.1.1/CHANGELOG.md +51 -0
- hyperliquid_agent_gateway-0.1.1/LICENSE +21 -0
- hyperliquid_agent_gateway-0.1.1/PKG-INFO +205 -0
- hyperliquid_agent_gateway-0.1.1/README.md +178 -0
- hyperliquid_agent_gateway-0.1.1/deploy/hyperliquid-recorder.service +16 -0
- hyperliquid_agent_gateway-0.1.1/deploy/hyperliquid-recorder.timer +15 -0
- hyperliquid_agent_gateway-0.1.1/hyperliquid_mcp/API_NOTES.md +92 -0
- hyperliquid_agent_gateway-0.1.1/hyperliquid_mcp/__init__.py +11 -0
- hyperliquid_agent_gateway-0.1.1/hyperliquid_mcp/evm.py +380 -0
- hyperliquid_agent_gateway-0.1.1/hyperliquid_mcp/info.py +350 -0
- hyperliquid_agent_gateway-0.1.1/hyperliquid_mcp/server.py +1230 -0
- hyperliquid_agent_gateway-0.1.1/pyproject.toml +43 -0
- hyperliquid_agent_gateway-0.1.1/scripts/recorder.py +125 -0
- hyperliquid_agent_gateway-0.1.1/scripts/smoke_api_offline.py +191 -0
- hyperliquid_agent_gateway-0.1.1/scripts/smoke_server_offline.py +231 -0
- hyperliquid_agent_gateway-0.1.1/scripts/smoke_v011_live.py +87 -0
- hyperliquid_agent_gateway-0.1.1/tests/conftest.py +95 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/allMids.json +954 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/candleSnapshot.json +590 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/clearinghouseState.json +1032 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/fundingHistory.json +1010 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/getLogs.json +182 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/l2Book.json +210 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/meta.json +1585 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/metaAndAssetCtxs.json +4916 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/recentTrades.json +132 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/spotClearinghouseState.json +25 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/spotMeta.json +8947 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/spotMetaAndAssetCtxs.json +16141 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/userFills.json +9017 -0
- hyperliquid_agent_gateway-0.1.1/tests/fixtures/userFunding.json +6002 -0
- hyperliquid_agent_gateway-0.1.1/tests/test_evm.py +336 -0
- hyperliquid_agent_gateway-0.1.1/tests/test_info.py +269 -0
- hyperliquid_agent_gateway-0.1.1/tests/test_live_regressions.py +124 -0
- hyperliquid_agent_gateway-0.1.1/tests/test_online.py +92 -0
- hyperliquid_agent_gateway-0.1.1/tests/test_server.py +752 -0
- hyperliquid_agent_gateway-0.1.1/uv.lock +2303 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
contents: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v5
|
|
15
|
+
- uses: actions/setup-python@v6
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.13"
|
|
18
|
+
- run: pip install build twine
|
|
19
|
+
- run: python -m build
|
|
20
|
+
- run: python -m twine check dist/*
|
|
21
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
22
|
+
- name: GitHub Release
|
|
23
|
+
uses: softprops/action-gh-release@v2
|
|
24
|
+
with:
|
|
25
|
+
files: dist/*
|
|
26
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
offline:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python: ["3.11", "3.13"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v5
|
|
16
|
+
- uses: actions/setup-python@v6
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python }}
|
|
19
|
+
- run: pip install -e ".[dev]"
|
|
20
|
+
- name: Run tests
|
|
21
|
+
run: |
|
|
22
|
+
pytest tests/ -q --cov=hyperliquid_mcp --tb=short > pytest_output.txt 2>&1 || FAILED=1
|
|
23
|
+
grep -E "^(FAILED|ERROR)|Error|error" pytest_output.txt | head -25 | while IFS= read -r line; do
|
|
24
|
+
echo "::error::${line:0:250}"
|
|
25
|
+
done
|
|
26
|
+
tail -40 pytest_output.txt
|
|
27
|
+
exit ${FAILED:-0}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.1 (2026-09-06)
|
|
4
|
+
|
|
5
|
+
Fix release from the independent v0.1.0 review.
|
|
6
|
+
|
|
7
|
+
- `liquidation_risk` (blocker): the LIVE `clearinghouseState` response
|
|
8
|
+
carries no `markPx` in positions, so `mark_px` and
|
|
9
|
+
`liq_distance_pct` were null in every branch live. Mark is now
|
|
10
|
+
resolved per coin from `metaAndAssetCtxs` (60s cache) with an
|
|
11
|
+
`allMids` fallback; each row reports `mark_px_source`
|
|
12
|
+
('position' | 'metaAndAssetCtxs' | 'allMids' | null) and distances
|
|
13
|
+
stay null (honest) when no source knows the coin. `trader_activity`
|
|
14
|
+
open-position rows get the same resolver. Note documents that
|
|
15
|
+
`withdrawable` may be omitted by the venue while positions are open.
|
|
16
|
+
- `tests/fixtures/clearinghouseState.json` re-recorded from the live
|
|
17
|
+
API (no `markPx` in positions, no `withdrawable` in marginSummary)
|
|
18
|
+
so the offline suite exercises the live shape; regression tests
|
|
19
|
+
cover mark from cache / allMids fallback / neither, liqPx present
|
|
20
|
+
and null, cross and isolated.
|
|
21
|
+
- `wallet_balance` / `token_transfers`: per-token decimals via a
|
|
22
|
+
static map of canonical HyperEVM tokens (6 for USDC/USDT-style,
|
|
23
|
+
18 for PURR/HYPE) with honest `decimals_source`
|
|
24
|
+
('static_map' | 'assumed_18') on every row; unknown tokens assume
|
|
25
|
+
18 and say so.
|
|
26
|
+
- `funding_history` / `userFunding` README note: the venue returns
|
|
27
|
+
only non-zero funding events, so a live `funding_drag` of null for a
|
|
28
|
+
fresh address is expected, not a bug.
|
|
29
|
+
- Version bumped to 0.1.1 (pyproject == package == server).
|
|
30
|
+
|
|
31
|
+
## 0.1.0 (2026-09-06)
|
|
32
|
+
|
|
33
|
+
Initial release.
|
|
34
|
+
|
|
35
|
+
- Read-only, keyless MCP gateway to Hyperliquid public data.
|
|
36
|
+
- `/info` client (`hyperliquid_mcp/info.py`): weight-based rate bucket
|
|
37
|
+
(1200 weight/min), per-type TTL caches, retries with backoff on
|
|
38
|
+
429/5xx, `User-Agent: hyperliquid-agent-gateway/0.1`.
|
|
39
|
+
- HyperEVM JSON-RPC client (`hyperliquid_mcp/evm.py`): separate 100
|
|
40
|
+
req/min budget, `RpcError` taxonomy, adaptive `eth_getLogs` window
|
|
41
|
+
(30-block start, halve on too-big, double on quiet, cap 60).
|
|
42
|
+
- 12 MCP tools (`hyperliquid_mcp/server.py`): market_overview,
|
|
43
|
+
spot_overview, quote, order_book, candles, trades, funding_history,
|
|
44
|
+
liquidation_risk, trader_activity, funding_carry_screener,
|
|
45
|
+
token_transfers, wallet_balance - all annotated read-only with honest
|
|
46
|
+
degradation (error dicts, never tracebacks) and freshness fields.
|
|
47
|
+
- Offline test suite on schema-realistic fixtures (well over a hundred
|
|
48
|
+
checks; run `pytest -q` for the exact count); live online checks are
|
|
49
|
+
opt-in via `-m online`.
|
|
50
|
+
- `scripts/recorder.py` live-fixture recorder + systemd units
|
|
51
|
+
(6h schedule, disabled by default).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hyperliquid-agent-gateway contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: hyperliquid-agent-gateway
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: MCP gateway for AI agents to Hyperliquid public data: perp/spot market overviews, quotes, order books, candles, trades, funding, account risk and HyperEVM transfers. Read-only, keyless.
|
|
5
|
+
Project-URL: Homepage, https://github.com/alekskram/hyperliquid-agent-gateway
|
|
6
|
+
Project-URL: Repository, https://github.com/alekskram/hyperliquid-agent-gateway
|
|
7
|
+
Project-URL: Issues, https://github.com/alekskram/hyperliquid-agent-gateway/issues
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: ai-agents,defi,funding,hyper evm,hyperliquid,mcp,perps
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: fastmcp>=3.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: hatchling; extra == 'dev'
|
|
23
|
+
Requires-Dist: pip-audit; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# hyperliquid-agent-gateway
|
|
29
|
+
|
|
30
|
+
[](https://github.com/alekskram/hyperliquid-agent-gateway/actions/workflows/tests.yml)
|
|
31
|
+
[](https://pypi.org/project/hyperliquid-agent-gateway/)
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
[](pyproject.toml)
|
|
34
|
+
|
|
35
|
+
An MCP (Model Context Protocol) server that gives AI agents read-only,
|
|
36
|
+
keyless access to **Hyperliquid** public data - the ~233-perp DEX
|
|
37
|
+
market, ~326 spot pairs, funding, per-account risk and HyperEVM (chain
|
|
38
|
+
999) token transfers. No API keys, no auth, no signing, no writes:
|
|
39
|
+
every tool reads public endpoints only (`api.hyperliquid.xyz/info` and
|
|
40
|
+
`rpc.hyperliquid.xyz/evm`), cached and rate-limited so an enthusiastic
|
|
41
|
+
agent cannot hammer the upstream.
|
|
42
|
+
|
|
43
|
+
## Use cases
|
|
44
|
+
|
|
45
|
+
- **Watch a wallet's risk** — per-account margin summary, leverage, liquidation distance on any address (`account risk` view)
|
|
46
|
+
- **Fund the carry, not the noise** — funding history + carry screener across 233 perps to find stable paid positions
|
|
47
|
+
- **Trace HyperEVM flows** — token transfers on chain 999 tied back to the perp markets (`token_transfers`)
|
|
48
|
+
- **Read the book before you enter** — order book + recent trades + all-mids in one pass
|
|
49
|
+
- **Trader scouting** — activity of any address: positions, volume, what they actually trade
|
|
50
|
+
|
|
51
|
+
Full walkthroughs: [examples/use-cases.md](examples/use-cases.md).
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
stdio (default, for local agents):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uvx hyperliquid-agent-gateway
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
or from a checkout:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/alekskram/hyperliquid-agent-gateway
|
|
65
|
+
cd hyperliquid-agent-gateway
|
|
66
|
+
uv sync
|
|
67
|
+
uv run hyperliquid-agent-gateway
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Claude Desktop / Cursor config:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"hyperliquid": {
|
|
76
|
+
"command": "uvx",
|
|
77
|
+
"args": ["--from",
|
|
78
|
+
"git+https://github.com/alekskram/hyperliquid-agent-gateway",
|
|
79
|
+
"hyperliquid-agent-gateway"]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Hosted form - streamable HTTP on port **8903**:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv run hyperliquid-agent-gateway --http # 127.0.0.1:8903
|
|
89
|
+
curl http://127.0.0.1:8903/health # -> {"ok": true, "service": "hyperliquid-agent-gateway", ...}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
<details>
|
|
93
|
+
<summary><b>Codex</b> (~/.codex/config.toml)</summary>
|
|
94
|
+
|
|
95
|
+
```toml
|
|
96
|
+
[mcp_servers.hyperliquid]
|
|
97
|
+
command = "uvx"
|
|
98
|
+
args = ["hyperliquid-agent-gateway"]
|
|
99
|
+
```
|
|
100
|
+
</details>
|
|
101
|
+
|
|
102
|
+
<details>
|
|
103
|
+
<summary><b>ZCode</b> — register the server (copy-paste)</summary>
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# 1) start the gateway (keep it running)
|
|
107
|
+
uvx hyperliquid-agent-gateway --http --port 8903 &
|
|
108
|
+
|
|
109
|
+
# 2) register it (merges into ~/.zcode/cli/config.json)
|
|
110
|
+
python3 - <<'PY'
|
|
111
|
+
import json, os
|
|
112
|
+
p = os.path.expanduser("~/.zcode/cli/config.json")
|
|
113
|
+
os.makedirs(os.path.dirname(p), exist_ok=True)
|
|
114
|
+
cfg = json.load(open(p)) if os.path.exists(p) else {}
|
|
115
|
+
cfg.setdefault("mcp", {}).setdefault("servers", {})["hyperliquid"] = {
|
|
116
|
+
"type": "http", "url": "http://127.0.0.1:8903/mcp"}
|
|
117
|
+
json.dump(cfg, open(p, "w"), indent=2)
|
|
118
|
+
print("hyperliquid-agent-gateway registered:", p)
|
|
119
|
+
PY
|
|
120
|
+
```
|
|
121
|
+
</details>
|
|
122
|
+
|
|
123
|
+
Hosted form — streamable HTTP on port **8903**:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
uvx hyperliquid-agent-gateway --http
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Tools
|
|
130
|
+
|
|
131
|
+
All 12 tools are read-only (annotated `readOnlyHint: true,
|
|
132
|
+
destructiveHint: false, openWorldHint: true`).
|
|
133
|
+
|
|
134
|
+
| # | Tool | Signature | What it does |
|
|
135
|
+
|---|------|-----------|--------------|
|
|
136
|
+
| 1 | `market_overview` | `market_overview(limit=20, sort="open_interest")` | Perp market snapshot from ONE `metaAndAssetCtxs` call: per-coin mark, open interest, day volume, premium, max leverage + totals. `sort` in {open_interest, volume, premium}. |
|
|
137
|
+
| 2 | `spot_overview` | `spot_overview(limit=20)` | Spot pairs from `spotMeta` + ctxs with HIP-1 to ERC-20 links; `@{index}` names resolved to readable token names. |
|
|
138
|
+
| 3 | `quote` | `quote(coin)` | Bid/ask/mid/spread + top-of-book sizes from `allMids` + `l2Book`. Unknown coin raises with 5 examples. |
|
|
139
|
+
| 4 | `order_book` | `order_book(coin, depth=10)` | Book levels per side with nSigFigs aggregation and per-side total liquidity. |
|
|
140
|
+
| 5 | `candles` | `candles(coin, interval="1h", limit=100)` | OHLCV rows newest-first; intervals 1m/15m/1h/4h/1d/1w/1M; `startTime` computed from `limit`. |
|
|
141
|
+
| 6 | `trades` | `trades(coin, limit=20)` | Recent public fills WITH both sides' addresses (`users: [maker, taker]`). |
|
|
142
|
+
| 7 | `funding_history` | `funding_history(coin, limit=100)` | Hourly funding rows + `premium_now` from the live asset ctx. |
|
|
143
|
+
| 8 | `liquidation_risk` | `liquidation_risk(address)` | Per-account risk: margin summary, cross maintenance margin, per-position leverage + `liquidationPx` when published; when null, an explicitly flagged ESTIMATED distance from the maintenance-margin ratio. Mark px is resolved per coin from `metaAndAssetCtxs` (fallback `allMids`) because live positions carry no `markPx` - see `mark_px_source` on each row. Includes funding drag. |
|
|
144
|
+
| 9 | `trader_activity` | `trader_activity(address, limit=50)` | Fills PnL/fees/volume/win-rate, funding net, open positions, per-coin breakdown. |
|
|
145
|
+
| 10 | `funding_carry_screener` | `funding_carry_screener(topN=10, metric="premium")` | Ranks ALL perps from ONE call; `fundingHistory` fetched only for the topN (weight economy). |
|
|
146
|
+
| 11 | `token_transfers` | `token_transfers(contract, limit=100, from_block=None)` | HyperEVM ERC-20 Transfer logs via adaptive-window `eth_getLogs`; rows carry from/to/value/txHash/blockNumber/ts with per-token `decimals` + `decimals_source` (static map or `assumed_18`). |
|
|
147
|
+
| 12 | `wallet_balance` | `wallet_balance(address)` | Native (eth_getBalance) + up to 20 ERC-20s (eth_call balanceOf, resolved from spotMeta) + Hyperliquid spot balances; every row carries `decimals`/`decimals_source`. |
|
|
148
|
+
|
|
149
|
+
## Rate limits
|
|
150
|
+
|
|
151
|
+
Two independent, locally enforced budgets protect the upstream:
|
|
152
|
+
|
|
153
|
+
**`/info` - 1200 weight per rolling 60s** (Hyperliquid's documented
|
|
154
|
+
weight pricing), tracked per request type:
|
|
155
|
+
|
|
156
|
+
| type | weight |
|
|
157
|
+
|------|--------|
|
|
158
|
+
| `allMids` | 2 |
|
|
159
|
+
| `l2Book` | 2 |
|
|
160
|
+
| `meta`, `metaAndAssetCtxs`, `spotMeta`, `spotMetaAndAssetCtxs` | 20 |
|
|
161
|
+
| `recentTrades`, `clearinghouseState`, `userFills`, `userFunding`, `spotClearinghouseState` | 20 |
|
|
162
|
+
| `fundingHistory` | 20 base + extra per 20 items beyond the first |
|
|
163
|
+
| `candleSnapshot` | 60 |
|
|
164
|
+
|
|
165
|
+
When the next request would exceed the budget the client waits once
|
|
166
|
+
(<=5s) for the window to roll, then raises a clear error naming the
|
|
167
|
+
limit - it never sleep-blocks forever.
|
|
168
|
+
|
|
169
|
+
**HyperEVM RPC - 100 requests per rolling 60s** (flat 1 per request),
|
|
170
|
+
enforced separately from /info. Over-budget calls raise immediately
|
|
171
|
+
(`rpc-limit`) - tools surface an honest error dict, and
|
|
172
|
+
`wallet_balance` stops its ERC-20 scan at the cap.
|
|
173
|
+
|
|
174
|
+
TTL caches additionally dedupe repeated calls per data type: allMids
|
|
175
|
+
15s, recentTrades 15s, l2Book 5s, metaAndAssetCtxs 60s, spotMeta 3600s,
|
|
176
|
+
spotMetaAndAssetCtxs 60s, candleSnapshot 300s, fundingHistory 300s,
|
|
177
|
+
per-address account types 60s.
|
|
178
|
+
|
|
179
|
+
## Data notes
|
|
180
|
+
|
|
181
|
+
- Every numeric from the API is a STRING upstream; the gateway parses
|
|
182
|
+
them with a never-raising helper - `null` always means "not
|
|
183
|
+
available", never zero.
|
|
184
|
+
- Every upstream failure returns an error dict
|
|
185
|
+
`{"error": ..., "source": ..., "reason": ...}`, never a traceback;
|
|
186
|
+
partial data degrades field-by-field with `warnings[]`.
|
|
187
|
+
- `liquidation_risk` never invents a liquidation price: when the venue
|
|
188
|
+
publishes none, `liq_px` stays `null` and the distance is an
|
|
189
|
+
explicitly flagged estimate (formula in the tool's note). Mark px is
|
|
190
|
+
likewise never invented: live positions carry no `markPx`, so it is
|
|
191
|
+
resolved from `metaAndAssetCtxs` (fallback `allMids`) and the row's
|
|
192
|
+
`mark_px_source` says which; no source -> `null`.
|
|
193
|
+
- `funding_drag` / `funding_net`: the venue's `userFunding` returns
|
|
194
|
+
only NON-ZERO funding events, so a live `null`/empty for a fresh or
|
|
195
|
+
quiet address is expected behaviour, not a bug.
|
|
196
|
+
- ERC-20 amounts use a static decimals map for canonical HyperEVM
|
|
197
|
+
tokens (6 for USDC/USDT-style, 18 for PURR/HYPE); unknown tokens
|
|
198
|
+
assume 18 and every row says `decimals_source: "assumed_18"` - do
|
|
199
|
+
not trust 6dp precision for unmapped tokens.
|
|
200
|
+
- Cached responses carry `age_seconds` / `fetched_at` freshness fields.
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
MIT.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# hyperliquid-agent-gateway
|
|
2
|
+
|
|
3
|
+
[](https://github.com/alekskram/hyperliquid-agent-gateway/actions/workflows/tests.yml)
|
|
4
|
+
[](https://pypi.org/project/hyperliquid-agent-gateway/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](pyproject.toml)
|
|
7
|
+
|
|
8
|
+
An MCP (Model Context Protocol) server that gives AI agents read-only,
|
|
9
|
+
keyless access to **Hyperliquid** public data - the ~233-perp DEX
|
|
10
|
+
market, ~326 spot pairs, funding, per-account risk and HyperEVM (chain
|
|
11
|
+
999) token transfers. No API keys, no auth, no signing, no writes:
|
|
12
|
+
every tool reads public endpoints only (`api.hyperliquid.xyz/info` and
|
|
13
|
+
`rpc.hyperliquid.xyz/evm`), cached and rate-limited so an enthusiastic
|
|
14
|
+
agent cannot hammer the upstream.
|
|
15
|
+
|
|
16
|
+
## Use cases
|
|
17
|
+
|
|
18
|
+
- **Watch a wallet's risk** — per-account margin summary, leverage, liquidation distance on any address (`account risk` view)
|
|
19
|
+
- **Fund the carry, not the noise** — funding history + carry screener across 233 perps to find stable paid positions
|
|
20
|
+
- **Trace HyperEVM flows** — token transfers on chain 999 tied back to the perp markets (`token_transfers`)
|
|
21
|
+
- **Read the book before you enter** — order book + recent trades + all-mids in one pass
|
|
22
|
+
- **Trader scouting** — activity of any address: positions, volume, what they actually trade
|
|
23
|
+
|
|
24
|
+
Full walkthroughs: [examples/use-cases.md](examples/use-cases.md).
|
|
25
|
+
|
|
26
|
+
## Quickstart
|
|
27
|
+
|
|
28
|
+
stdio (default, for local agents):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uvx hyperliquid-agent-gateway
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
or from a checkout:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/alekskram/hyperliquid-agent-gateway
|
|
38
|
+
cd hyperliquid-agent-gateway
|
|
39
|
+
uv sync
|
|
40
|
+
uv run hyperliquid-agent-gateway
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Claude Desktop / Cursor config:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"hyperliquid": {
|
|
49
|
+
"command": "uvx",
|
|
50
|
+
"args": ["--from",
|
|
51
|
+
"git+https://github.com/alekskram/hyperliquid-agent-gateway",
|
|
52
|
+
"hyperliquid-agent-gateway"]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Hosted form - streamable HTTP on port **8903**:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv run hyperliquid-agent-gateway --http # 127.0.0.1:8903
|
|
62
|
+
curl http://127.0.0.1:8903/health # -> {"ok": true, "service": "hyperliquid-agent-gateway", ...}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary><b>Codex</b> (~/.codex/config.toml)</summary>
|
|
67
|
+
|
|
68
|
+
```toml
|
|
69
|
+
[mcp_servers.hyperliquid]
|
|
70
|
+
command = "uvx"
|
|
71
|
+
args = ["hyperliquid-agent-gateway"]
|
|
72
|
+
```
|
|
73
|
+
</details>
|
|
74
|
+
|
|
75
|
+
<details>
|
|
76
|
+
<summary><b>ZCode</b> — register the server (copy-paste)</summary>
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# 1) start the gateway (keep it running)
|
|
80
|
+
uvx hyperliquid-agent-gateway --http --port 8903 &
|
|
81
|
+
|
|
82
|
+
# 2) register it (merges into ~/.zcode/cli/config.json)
|
|
83
|
+
python3 - <<'PY'
|
|
84
|
+
import json, os
|
|
85
|
+
p = os.path.expanduser("~/.zcode/cli/config.json")
|
|
86
|
+
os.makedirs(os.path.dirname(p), exist_ok=True)
|
|
87
|
+
cfg = json.load(open(p)) if os.path.exists(p) else {}
|
|
88
|
+
cfg.setdefault("mcp", {}).setdefault("servers", {})["hyperliquid"] = {
|
|
89
|
+
"type": "http", "url": "http://127.0.0.1:8903/mcp"}
|
|
90
|
+
json.dump(cfg, open(p, "w"), indent=2)
|
|
91
|
+
print("hyperliquid-agent-gateway registered:", p)
|
|
92
|
+
PY
|
|
93
|
+
```
|
|
94
|
+
</details>
|
|
95
|
+
|
|
96
|
+
Hosted form — streamable HTTP on port **8903**:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uvx hyperliquid-agent-gateway --http
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Tools
|
|
103
|
+
|
|
104
|
+
All 12 tools are read-only (annotated `readOnlyHint: true,
|
|
105
|
+
destructiveHint: false, openWorldHint: true`).
|
|
106
|
+
|
|
107
|
+
| # | Tool | Signature | What it does |
|
|
108
|
+
|---|------|-----------|--------------|
|
|
109
|
+
| 1 | `market_overview` | `market_overview(limit=20, sort="open_interest")` | Perp market snapshot from ONE `metaAndAssetCtxs` call: per-coin mark, open interest, day volume, premium, max leverage + totals. `sort` in {open_interest, volume, premium}. |
|
|
110
|
+
| 2 | `spot_overview` | `spot_overview(limit=20)` | Spot pairs from `spotMeta` + ctxs with HIP-1 to ERC-20 links; `@{index}` names resolved to readable token names. |
|
|
111
|
+
| 3 | `quote` | `quote(coin)` | Bid/ask/mid/spread + top-of-book sizes from `allMids` + `l2Book`. Unknown coin raises with 5 examples. |
|
|
112
|
+
| 4 | `order_book` | `order_book(coin, depth=10)` | Book levels per side with nSigFigs aggregation and per-side total liquidity. |
|
|
113
|
+
| 5 | `candles` | `candles(coin, interval="1h", limit=100)` | OHLCV rows newest-first; intervals 1m/15m/1h/4h/1d/1w/1M; `startTime` computed from `limit`. |
|
|
114
|
+
| 6 | `trades` | `trades(coin, limit=20)` | Recent public fills WITH both sides' addresses (`users: [maker, taker]`). |
|
|
115
|
+
| 7 | `funding_history` | `funding_history(coin, limit=100)` | Hourly funding rows + `premium_now` from the live asset ctx. |
|
|
116
|
+
| 8 | `liquidation_risk` | `liquidation_risk(address)` | Per-account risk: margin summary, cross maintenance margin, per-position leverage + `liquidationPx` when published; when null, an explicitly flagged ESTIMATED distance from the maintenance-margin ratio. Mark px is resolved per coin from `metaAndAssetCtxs` (fallback `allMids`) because live positions carry no `markPx` - see `mark_px_source` on each row. Includes funding drag. |
|
|
117
|
+
| 9 | `trader_activity` | `trader_activity(address, limit=50)` | Fills PnL/fees/volume/win-rate, funding net, open positions, per-coin breakdown. |
|
|
118
|
+
| 10 | `funding_carry_screener` | `funding_carry_screener(topN=10, metric="premium")` | Ranks ALL perps from ONE call; `fundingHistory` fetched only for the topN (weight economy). |
|
|
119
|
+
| 11 | `token_transfers` | `token_transfers(contract, limit=100, from_block=None)` | HyperEVM ERC-20 Transfer logs via adaptive-window `eth_getLogs`; rows carry from/to/value/txHash/blockNumber/ts with per-token `decimals` + `decimals_source` (static map or `assumed_18`). |
|
|
120
|
+
| 12 | `wallet_balance` | `wallet_balance(address)` | Native (eth_getBalance) + up to 20 ERC-20s (eth_call balanceOf, resolved from spotMeta) + Hyperliquid spot balances; every row carries `decimals`/`decimals_source`. |
|
|
121
|
+
|
|
122
|
+
## Rate limits
|
|
123
|
+
|
|
124
|
+
Two independent, locally enforced budgets protect the upstream:
|
|
125
|
+
|
|
126
|
+
**`/info` - 1200 weight per rolling 60s** (Hyperliquid's documented
|
|
127
|
+
weight pricing), tracked per request type:
|
|
128
|
+
|
|
129
|
+
| type | weight |
|
|
130
|
+
|------|--------|
|
|
131
|
+
| `allMids` | 2 |
|
|
132
|
+
| `l2Book` | 2 |
|
|
133
|
+
| `meta`, `metaAndAssetCtxs`, `spotMeta`, `spotMetaAndAssetCtxs` | 20 |
|
|
134
|
+
| `recentTrades`, `clearinghouseState`, `userFills`, `userFunding`, `spotClearinghouseState` | 20 |
|
|
135
|
+
| `fundingHistory` | 20 base + extra per 20 items beyond the first |
|
|
136
|
+
| `candleSnapshot` | 60 |
|
|
137
|
+
|
|
138
|
+
When the next request would exceed the budget the client waits once
|
|
139
|
+
(<=5s) for the window to roll, then raises a clear error naming the
|
|
140
|
+
limit - it never sleep-blocks forever.
|
|
141
|
+
|
|
142
|
+
**HyperEVM RPC - 100 requests per rolling 60s** (flat 1 per request),
|
|
143
|
+
enforced separately from /info. Over-budget calls raise immediately
|
|
144
|
+
(`rpc-limit`) - tools surface an honest error dict, and
|
|
145
|
+
`wallet_balance` stops its ERC-20 scan at the cap.
|
|
146
|
+
|
|
147
|
+
TTL caches additionally dedupe repeated calls per data type: allMids
|
|
148
|
+
15s, recentTrades 15s, l2Book 5s, metaAndAssetCtxs 60s, spotMeta 3600s,
|
|
149
|
+
spotMetaAndAssetCtxs 60s, candleSnapshot 300s, fundingHistory 300s,
|
|
150
|
+
per-address account types 60s.
|
|
151
|
+
|
|
152
|
+
## Data notes
|
|
153
|
+
|
|
154
|
+
- Every numeric from the API is a STRING upstream; the gateway parses
|
|
155
|
+
them with a never-raising helper - `null` always means "not
|
|
156
|
+
available", never zero.
|
|
157
|
+
- Every upstream failure returns an error dict
|
|
158
|
+
`{"error": ..., "source": ..., "reason": ...}`, never a traceback;
|
|
159
|
+
partial data degrades field-by-field with `warnings[]`.
|
|
160
|
+
- `liquidation_risk` never invents a liquidation price: when the venue
|
|
161
|
+
publishes none, `liq_px` stays `null` and the distance is an
|
|
162
|
+
explicitly flagged estimate (formula in the tool's note). Mark px is
|
|
163
|
+
likewise never invented: live positions carry no `markPx`, so it is
|
|
164
|
+
resolved from `metaAndAssetCtxs` (fallback `allMids`) and the row's
|
|
165
|
+
`mark_px_source` says which; no source -> `null`.
|
|
166
|
+
- `funding_drag` / `funding_net`: the venue's `userFunding` returns
|
|
167
|
+
only NON-ZERO funding events, so a live `null`/empty for a fresh or
|
|
168
|
+
quiet address is expected behaviour, not a bug.
|
|
169
|
+
- ERC-20 amounts use a static decimals map for canonical HyperEVM
|
|
170
|
+
tokens (6 for USDC/USDT-style, 18 for PURR/HYPE); unknown tokens
|
|
171
|
+
assume 18 and every row says `decimals_source: "assumed_18"` - do
|
|
172
|
+
not trust 6dp precision for unmapped tokens.
|
|
173
|
+
- Cached responses carry `age_seconds` / `fetched_at` freshness fields.
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Hyperliquid Agent Gateway - fixture recorder (one pass)
|
|
3
|
+
Documentation=https://github.com/hyperliquid-agent-gateway/hyperliquid-agent-gateway
|
|
4
|
+
After=network-online.target
|
|
5
|
+
Wants=network-online.target
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
# One pass = 13 /info requests (~264 weight, well inside 1200/min) plus
|
|
10
|
+
# 1-2 HyperEVM eth_getLogs calls (inside 100/min). Fixtures land in
|
|
11
|
+
# tests/fixtures/ of the checkout below.
|
|
12
|
+
WorkingDirectory=/opt/hyperliquid-agent-gateway
|
|
13
|
+
ExecStart=/usr/bin/env python scripts/recorder.py --out tests/fixtures
|
|
14
|
+
Environment=PYTHONUNBUFFERED=1
|
|
15
|
+
# A full pass is ~15 requests: 1-3 minutes worst case with retries
|
|
16
|
+
TimeoutStartSec=300
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Hyperliquid Agent Gateway - fixture recorder schedule (6h)
|
|
3
|
+
Documentation=https://github.com/hyperliquid-agent-gateway/hyperliquid-agent-gateway
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
# Every 6 hours; keeps tests/fixtures/ schema-realistic without
|
|
7
|
+
# approaching either rate budget (a pass costs ~264 /info weight and
|
|
8
|
+
# 1-2 rpc requests).
|
|
9
|
+
# OPT-IN ONLY: this unit ships DISABLED. Enable explicitly with
|
|
10
|
+
# systemctl enable --now hyperliquid-recorder.timer
|
|
11
|
+
OnCalendar=*-*-* 00/6:00:00
|
|
12
|
+
Persistent=true
|
|
13
|
+
|
|
14
|
+
[Install]
|
|
15
|
+
WantedBy=timers.target
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# API notes - Hyperliquid public surfaces (as verified 2026-09-05/06)
|
|
2
|
+
|
|
3
|
+
Facts the gateway depends on. Every claim below was checked against the
|
|
4
|
+
live endpoints before v0.1.0 was coded; fixtures in `tests/fixtures/`
|
|
5
|
+
mirror these shapes.
|
|
6
|
+
|
|
7
|
+
## /info (POST https://api.hyperliquid.xyz/info)
|
|
8
|
+
|
|
9
|
+
- Single POST endpoint; body is `{"type": "<Type>", ...}`. Keyless,
|
|
10
|
+
read-only. Action types (signing) are NOT used by this gateway.
|
|
11
|
+
- **ALL numerics are STRINGS** (`"42350.1"`, `"-0.00012"`). Parse with
|
|
12
|
+
a never-raising `_f()`; empty/absent optionals become `None`.
|
|
13
|
+
- Weight-based rate limit: **1200 weight / 60s**. Per-request weights
|
|
14
|
+
implemented in `hyperliquid_mcp/info.py`:
|
|
15
|
+
|
|
16
|
+
| type | weight |
|
|
17
|
+
|------|--------|
|
|
18
|
+
| allMids | 2 |
|
|
19
|
+
| l2Book | 2 |
|
|
20
|
+
| meta, metaAndAssetCtxs, spotMeta, spotMetaAndAssetCtxs | 20 |
|
|
21
|
+
| recentTrades, clearinghouseState, userFills, userFunding, spotClearinghouseState | 20 |
|
|
22
|
+
| fundingHistory | 20 base + extra per 20 items beyond the first |
|
|
23
|
+
| candleSnapshot | 60 |
|
|
24
|
+
|
|
25
|
+
- `metaAndAssetCtxs` returns a **pair** `[meta, assetCtxs]`: meta =
|
|
26
|
+
`{"universe": [{"name", "szDecimals", "maxLeverage",
|
|
27
|
+
"onlyIsolated"}]}`; assetCtxs rows align by index with universe and
|
|
28
|
+
carry `dayNtlVlm`, `openInterest` (coin units), `premium`, `markPx`,
|
|
29
|
+
`midPx`, `oraclePx`, `impactPxs {bidPx, askPx}`, `funding`
|
|
30
|
+
(hourly). ~233 perps at capture time.
|
|
31
|
+
- `spotMeta` = `{"universe": [{"name": "@1/PURR", "tokens": [int
|
|
32
|
+
indices], "isCanonical", "index"}], "tokens": [{"name", "index",
|
|
33
|
+
"token"}], "deployAuctionStatus", "registeredContracts": [{"name",
|
|
34
|
+
"builder"}]}`. `token` is the ERC-20 contract (0x...) for HIP-1
|
|
35
|
+
deployed coins, otherwise the coin name. ~326 pairs.
|
|
36
|
+
- `spotMetaAndAssetCtxs` likewise returns `[spotMeta, spotCtxs]`;
|
|
37
|
+
spotCtxs rows carry `coin`, `markPx`, `midPx`, `dayNtlVlm`,
|
|
38
|
+
`prevDayPx`, `circulating`, `funding`.
|
|
39
|
+
- `l2Book` body `{"coin"}` -> `{"coin", "time", "levels": {"bids":
|
|
40
|
+
[{"px","sz","nSigFigs"}], "asks": [...]}}` - already aggregated to
|
|
41
|
+
significant figures by the venue.
|
|
42
|
+
- `candleSnapshot` body `{"coin", "interval", "startTime"}`; intervals
|
|
43
|
+
`1m,15m,1h,4h,1d,1w,1M`; rows oldest-first with `t/T` (ms), `o/c/h/l/v`
|
|
44
|
+
(STRINGS), `n` (int trade count).
|
|
45
|
+
- `recentTrades` body `{"coin"}` -> rows with `side` ('B'/'A'), `px`,
|
|
46
|
+
`sz`, `time` (ms), `hash`, **`users: [maker, taker]`** (both sides).
|
|
47
|
+
- `fundingHistory` body `{"coin", "startTime?", "endTime?"}` -> flat
|
|
48
|
+
`[{coin, fundingRate, premium, time}]`, hourly, newest-last.
|
|
49
|
+
- `clearinghouseState` body `{"user": address}` ->
|
|
50
|
+
`marginSummary {accountValue, totalNtlPos, totalRawUsd,
|
|
51
|
+
totalMarginUsed, withdrawable}`, `crossMaintenanceMarginUsed`,
|
|
52
|
+
`assetPositions [{type, position {coin, szi, leverage {type, value},
|
|
53
|
+
entryPx, positionValue, unrealizedPnl, returnOnEquity,
|
|
54
|
+
liquidationPx | null, marginUsed, maintMarginUsed, isolatedMargin}}]`.
|
|
55
|
+
**`liquidationPx` can be null** - the estimate path in
|
|
56
|
+
`liquidation_risk` exists for exactly that case.
|
|
57
|
+
- `userFills` -> `[{coin, dir, px, sz, time, closedPnl, fee, feeToken,
|
|
58
|
+
builderFee, hash, oid}]`.
|
|
59
|
+
- `userFunding` -> non-zero funding payments `[{coin, fundingRate,
|
|
60
|
+
premium, time, delta}]`; `delta` is the USD payment, negative when
|
|
61
|
+
the trader pays.
|
|
62
|
+
- `spotClearinghouseState` -> `{"balances": [{"coin": "@/PURR",
|
|
63
|
+
"hold", "total"}]}`.
|
|
64
|
+
|
|
65
|
+
## HyperEVM RPC (POST https://rpc.hyperliquid.xyz/evm)
|
|
66
|
+
|
|
67
|
+
- Chain id **999** (0x3e7). Keyless public node, separate from /info
|
|
68
|
+
budgets: this gateway enforces its own **100 requests/min** cap
|
|
69
|
+
locally.
|
|
70
|
+
- `eth_getLogs` responses are capped (~1MB); active tokens need
|
|
71
|
+
roughly **30-60 block windows**. `evm.get_logs` adapts: start 30
|
|
72
|
+
blocks, halve on failure/too-big (floor 2), double on quiet success
|
|
73
|
+
(cap 60), max 14 slices.
|
|
74
|
+
- Transfer topic
|
|
75
|
+
`0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef`;
|
|
76
|
+
`balanceOf(address)` selector `0x70a08231`; native balance via
|
|
77
|
+
`eth_getBalance`.
|
|
78
|
+
- Env override: `HL_EVM_RPC_URL`.
|
|
79
|
+
|
|
80
|
+
## Endpoints NOT used, and why
|
|
81
|
+
|
|
82
|
+
- **info type `leaderboard`** - returns 403 behind Cloudflare bot
|
|
83
|
+
protection for non-browser clients; unreliable for a gateway.
|
|
84
|
+
- **Blockscout-style explorers** (`explorer.hyperliquid.xyz` API) - the
|
|
85
|
+
free tier was dead/unstable at verification time; all on-chain reads
|
|
86
|
+
go through the raw RPC instead.
|
|
87
|
+
- **WebSocket subscriptions** (`wss://api.hyperliquid.xyz/ws`) -
|
|
88
|
+
deferred to v0.2; the MCP request/response model gains little from
|
|
89
|
+
push feeds and the TTL caches already cover freshness.
|
|
90
|
+
- **Exchange/exchangeAction (signing) endpoints** - out of scope by
|
|
91
|
+
design: this gateway is strictly read-only and keyless; no private
|
|
92
|
+
keys ever enter the process.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""hyperliquid_mcp - read-only, keyless MCP gateway to Hyperliquid public data.
|
|
2
|
+
|
|
3
|
+
Package layout:
|
|
4
|
+
info.py stdlib-only POST client for https://api.hyperliquid.xyz/info
|
|
5
|
+
evm.py stdlib-only JSON-RPC client for https://rpc.hyperliquid.xyz/evm
|
|
6
|
+
server.py FastMCP server wiring the 12 read-only tools
|
|
7
|
+
|
|
8
|
+
No private keys, no signing, no order placement - public data only.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
__version__ = "0.1.1"
|