Ask a language model how many HIP-3 perp DEXes are live on Hyperliquid and you get an answer from its training data. That answer is months old, and it sounds confident. Onchain state changes every block, so a research agent needs two things a chat model lacks: a live read path to the chain and rules that stop it from filling gaps with guesses.
This guide builds that agent in Claude Code. The read path is the hosted Dwellir MCP server, which gives Claude read-only access to 150+ networks and the Hyperliquid Info API through browser login. You never paste an API key into the chat. The rules are a CLAUDE.md file, a subagent, and a /research command that writes a dated report with a source row for every number.
We then run two research questions against Hyperliquid mainnet and show the reports the agent writes.
What you build
The project is a handful of small files. Every one is shown in full below.
onchain-research-agent/
├── .mcp.json # Dwellir MCP server, project scope
├── CLAUDE.md # research rules every session loads
├── .claude/agents/onchain-researcher.md # the subagent and its tool list
├── .claude/commands/research.md # /research <question>
├── scripts/hl_orders_summary.py # for responses too large for MCP
└── reports/ # one Markdown report per questionPrerequisites:
- Claude Code installed and logged in
- A Dwellir account (you can create one during the MCP login)
- Python 3.10+ for the one helper script

Step 1: Connect the Dwellir MCP server
Add the server at project scope, so the configuration lives in .mcp.json and anyone who clones the repo gets it:
claude mcp add --transport http --scope project dwellir https://mcp.dwellir.com/mcpThat writes:
{
"mcpServers": {
"dwellir": {
"type": "http",
"url": "https://mcp.dwellir.com/mcp"
}
}
}Start claude in the project folder, approve the project server when prompted, then run /mcp, select dwellir and choose Authenticate. The browser opens the Dwellir dashboard. Choose Read only and select Authorize. A research agent does not need Manage keys, and a read-only grant cannot be upgraded during approval.
The server exposes these tools. The agent uses the first six.
| Task | Tool | Notes |
|---|---|---|
| Find chains and endpoint IDs | list_endpoints | Filter by name, for example hyperliquid |
| Get a key reference | list_keys | Returns non-secret key_ref values, never key values |
| List allowed read methods | rpc_methods | EVM, Substrate, Solana, Bitcoin, Starknet, Sui |
| Read chain state | rpc_call | eth_getLogs, eth_call, eth_getBalance and similar; broadcasts are rejected |
| Read Hyperliquid Info | hyperliquid_info | meta, spotMeta, perpDexs, clearinghouseState, spotClearinghouseState, openOrders, userFees, exchangeStatus |
| Sample a stream | capture_stream | newHeads, finalizedHeads, runtimeVersion, Hyperliquid l2Book; at most 20 messages or 15 seconds |
| Read Dwellir docs | search_docs, get_docs | Lets the agent check method parameters itself |
| Account | usage_summary, usage_history, key management | Not needed for research |
Every chain read is a normal request against your Dwellir plan, so research runs show up in your usage like any other traffic.
Step 2: Write the research rules
CLAUDE.md loads into every session in the project. The aim is to make the agent's output checkable: every number traces to a tool call and a read time, and missing data is reported as missing.
# Onchain research agent
This project answers questions about onchain state. Answers come from live data, never from memory.
## Data sources
- Use the `dwellir` MCP server for chain reads.
- Start every session with `list_endpoints` and `list_keys`. Use the returned
`endpoint_id` and `key_ref`. Never ask for or print an API key value.
- If a question needs data that the Dwellir tools do not return, say so in the
report. You may then use a public source with `curl`. Label every number from
that source.
## Rules for numbers
1. Every number in a report comes from a tool call made in this session.
2. Each report records when the data was read: a block number for EVM chains,
or the `time` field (ms) for Hyperliquid Info.
3. Hyperliquid Info returns sizes and prices as strings. Convert them before
you do arithmetic. Position value is in USDC.
4. If a call fails or a field is missing, write "not available" and give the
reason. Do not estimate.
5. Separate observations from interpretation.
## Report format
Write reports to `reports/YYYY-MM-DD-<slug>.md`: Question, Answer (3-5
sentences), Findings (tables), Interpretation, Gaps, Sources (one row per
tool call: tool, endpoint or URL, arguments, read time).Rule 4 matters most. Without it, a model that gets an error on one call will often fill the table with a plausible number. With it, the gap shows up in the report where you can see it.
Step 3: Add the subagent and the command
The subagent runs research in its own context window, so large tool responses do not crowd out your main session. Its tools line limits it to the Dwellir read tools plus file and shell access for reports and scripts.
---
name: onchain-researcher
description: Answers questions about live onchain state (wallets, markets, contracts,
Hyperliquid perp DEXes) with Dwellir MCP tools and writes a sourced report.
tools: mcp__dwellir__list_endpoints, mcp__dwellir__list_keys, mcp__dwellir__rpc_methods,
mcp__dwellir__rpc_call, mcp__dwellir__hyperliquid_info, mcp__dwellir__capture_stream,
mcp__dwellir__search_docs, mcp__dwellir__get_docs, Bash, Read, Write
model: sonnet
---
You are an onchain research analyst. Follow the rules in CLAUDE.md.
1. Restate the question as a list of data points you need.
2. Map each data point to a tool call. Call rpc_methods or get_docs if unsure.
3. Make the calls. Summarise raw responses larger than about 50 KB with a
short Python script instead of pasting them into the report.
4. Check each total against a second calculation where you can.
5. Write the report to reports/ and return the path and the short answer.
Never call write tools. This agent does not sign, trade, or move funds.The command is a thin wrapper, so you can type the question in one line:
---
description: Research a question about live onchain data and write a sourced report
argument-hint: <question>
---
Use the onchain-researcher subagent to answer this question:
$ARGUMENTS
When it finishes, show me the answer section and the report path.Run 1: Which HIP-3 perp DEXes are live?
HIP-3 lets builders deploy their own perpetual markets on HyperCore. The deployer list grows and shrinks, and models trained a few months ago cannot know the current state.
/research Which HIP-3 perp DEXes are live on Hyperliquid right now, what do they list, and how concentrated is HIP-3 activity?The agent called list_endpoints with hyperliquid and picked the HyperCore Info endpoint. It then called hyperliquid_info with perpDexs once, and with meta once per DEX using the dex argument. That is 12 Info requests. The report it produced (read at 2026-10-13 06:41 UTC):
Answer. Hyperliquid lists 10 HIP-3 perp DEXes next to the main DEX. Only 4 have live markets: XYZ, Paragon, EntropyIO and Markets by Kinetiq (
mkts). The other 6 have every market flaggedisDelisted. XYZ alone lists 114 live markets and holds 95% of the streaming open-interest caps on the four live HIP-3 DEXes.
| DEX | Live / listed | Leverage | OI caps | What it lists |
|---|---|---|---|---|
| XYZ | 114 / 134 | 10x to 50x | $16.32B | US equities, indices, commodities, FX |
| Paragon | 30 / 38 | 10x | $720M | Equities, US rates, crypto indices |
| EntropyIO | 10 / 13 | 5x to 25x | $117M | Pre-IPO (OpenAI, Anthropic), equities |
| Kinetiq | 5 / 24 | 5x to 25x | $77M | US indices, bonds, volatility |
The other six DEXes have no live markets: Felix Exchange (flx, 16 listed), HyENA (hyna, 25), dreamcash (cash, 17), Ventuals (vntl, 15), ABCDEx (abcd, 1) and a second Kinetiq DEX (km, 23) from the same deployer as the live one.
Gaps. The question asks how concentrated activity is. Open interest and volume per HIP-3 market are in
metaAndAssetCtxs, which the Dwellir MCP tool does not expose, and Dwellir's Info endpoint serves it only for the default perp DEX. Per CLAUDE.md, the agent fell back to the publicapi.hyperliquid.xyz/infoendpoint and labelled the result.
| Source: public Hyperliquid API | Open interest | 24h volume |
|---|---|---|
| Main DEX | $11.85B | $7.78B |
| XYZ | $3.74B | $2.86B |
| EntropyIO | $62M | $87M |
| Paragon | $17M | $4M |
| Kinetiq | $11M | $4M |
| HIP-3 share of total open interest | 24.4% |
Three things in this report would be hard to get from a chat model. Six of the ten DEXes have no live markets left. Kinetiq runs two DEXes with the same deployer address, one fully delisted. And the largest single HIP-3 market by open interest is xyz:SP500 at $392M. The agent got there by reading the isDelisted flag and the deployer field, data that changes faster than any training cutoff.
The 24.4% HIP-3 share also matches the roughly 25% that industry coverage reported for September, which is a useful sanity check on the fallback numbers.

Run 2: What is HLP doing right now?
The second question targets a single wallet: the Hyperliquidity Provider (HLP) vault, the protocol's own market-making vault.
/research What is the HLP vault (0xdfc24b077bc1425ad1dea75bcb6f8158e10df303) doing right now? Where is its capital and what positions does it hold?clearinghouseState on the HLP address returned $40.86M of account value and zero positions. The parent vault does not trade. The agent then needed the vault's child accounts. Vault relationships are not among the Info types the MCP tool supports, so it read them from the public vaultDetails endpoint, labelled the source, and called clearinghouseState on each of the 7 child addresses through Dwellir.
Answer. HLP holds $80.05M across the parent and 7 child vaults (read 06:42 UTC). Only 2 child vaults hold positions: $6.18M of account value, 7.7% of the total, running about $3.9M of gross notional each across 177 markets at 20x cross margin. The two strategies hold opposite sides: in 171 of 177 shared markets one is long where the other is short, at a median size ratio of 1.00. The rest of the capital sits idle in the parent ($40.86M) and one child ($30.00M).
| Account | Account value | Positions | Gross notional | Long / short |
|---|---|---|---|---|
HLP parent 0xdfc2…f303 | $40,863,217 | 0 | $0 | n/a |
Child 0x0104…703a | $3,182,095 | 177 | $3.91M | $2.0M / $2.0M |
Child 0x31ca…974b | $3,001,978 | 177 | $3.93M | $1.9M / $2.1M |
Child 0xb0a5…9540 | $30,000,000 | 0 | $0 | n/a |
| 4 other children | $3,000,999 | 0 | $0 | n/a |
| Market | Child 0x0104… size | Child 0x31ca… size |
|---|---|---|
| BTC | +0.698 | -0.681 |
| ETH | +10.39 | -10.00 |
| HYPE | +166.7 | -157.5 |
| SOL | +338.2 | -328.2 |

The agent separated the interpretation from these numbers, as the rules require. Two mirrored books at near-equal size mean HLP's net exposure across both strategies is close to flat. Each strategy on its own is directional per market. The data does not show why the two are split this way, and the report says so instead of guessing.
When MCP is the wrong tool
The open-orders step in Run 2 shows where an MCP tool stops being the right interface. openOrders for one of HLP's active children returned about 430 KB of JSON, roughly 3,800 resting orders. That is far more than you want in a model's context, and it is above Claude Code's default limit for a single MCP tool response (configurable with MAX_MCP_OUTPUT_TOKENS).
The subagent rules cover this case: summarise large responses with a script. Save this as scripts/hl_orders_summary.py. It reads DWELLIR_API_KEY from .env, which the Dwellir CLI writes without printing the value:
"""Summarise Hyperliquid open orders for one or more addresses.
Reads DWELLIR_API_KEY from the environment or from .env.
Usage: python3 scripts/hl_orders_summary.py 0xADDRESS [0xADDRESS ...]
"""
import collections
import json
import os
import pathlib
import sys
import urllib.request
def api_key():
if os.environ.get("DWELLIR_API_KEY"):
return os.environ["DWELLIR_API_KEY"]
env = pathlib.Path(".env")
if env.exists():
for line in env.read_text().splitlines():
if line.startswith("DWELLIR_API_KEY="):
return line.split("=", 1)[1].strip().strip('"')
sys.exit("DWELLIR_API_KEY not set. Run: dwellir keys env research-agent")
def info(payload):
url = f"https://api-hyperliquid-mainnet-info.n.dwellir.com/{api_key()}/info"
req = urllib.request.Request(url, data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=30) as resp:
return json.load(resp)
for address in sys.argv[1:]:
orders = info({"type": "openOrders", "user": address})
sides = collections.Counter(o["side"] for o in orders) # B = bid, A = ask
coins = {o["coin"] for o in orders}
notional = sum(float(o["sz"]) * float(o["limitPx"]) for o in orders)
print(json.dumps({
"address": address,
"open_orders": len(orders),
"bids": sides.get("B", 0),
"asks": sides.get("A", 0),
"markets": len(coins),
"resting_notional_usd": round(notional),
}))Run it on the two active HLP children:
dwellir keys env research-agent
python3 scripts/hl_orders_summary.py \
0x010461c14e146ac35fe42271bdc1134ee31c703a \
0x31ca8395cf837de08b24da3f660e77761dfb974b{"address": "0x0104...703a", "open_orders": 3814, "bids": 1909, "asks": 1905, "markets": 174, "resting_notional_usd": 3245517}
{"address": "0x31ca...974b", "open_orders": 3388, "bids": 1692, "asks": 1696, "markets": 174, "resting_notional_usd": 3000459}Each active HLP strategy keeps about 3,400 to 3,800 orders resting across 174 markets, almost exactly balanced between bids and asks. The model only sees two lines of output.
Use this split as the general rule for the project:
| Need | Use | Why |
|---|---|---|
| Discover endpoints, methods, docs | MCP | No key handling, small responses |
| Point reads: balances, positions, one block, one market list | MCP rpc_call, hyperliquid_info | Fast, sourced, read-only by design |
Large responses: thousands of orders, wide eth_getLogs ranges | Script with DWELLIR_API_KEY | Keeps raw data out of the context window |
| Continuous data: streams, gRPC, fills over time | Project code on Dwellir gRPC or the historical archive | MCP captures stop at 20 messages or 15 seconds |
| Trading or signing | Not this agent | The MCP server rejects broadcasts by design |
More questions to try
The same setup works on any chain the Dwellir catalog covers. Questions that fit the tools well:
- "Which address emitted the most USDC
Transferevents on Arc in the last 1,000 blocks?" (eth_getLogsviarpc_call) - "What fee tier is this Hyperliquid wallet on, and how much has it traded in the last 14 days?" (
userFees) - "Is the Base
finalizedhead keeping pace withlatestright now?" (capture_streamwithfinalizedHeadsandnewHeads) - "What does this HyperEVM contract return for
totalSupply()at block 3,000,000?" (eth_callagainst the archive HyperEVM endpoint)
Troubleshooting
The agent says it has no Dwellir tools. Run /mcp and check that dwellir shows as connected. Project-scope servers need approval the first time you start Claude Code in the folder.
hyperliquid_info returns "unsupported Hyperliquid Info query". The tool accepts 8 query types. For userFills, candles, or funding history, use project code against the Hyperliquid Info endpoint or the historical archive.
rpc_call rejects a method. Only registered read methods run. Ask the agent to call rpc_methods to see the list for the chain.
A response is "too large; narrow the query". The MCP server caps upstream responses at 1 MB. Narrow the block range or use a script.
Next steps
Two runs and about 20 Dwellir requests took Claude Code from "what does my training data say" to two reports where every number has a source row: the HIP-3 DEX list with six dead deployments, and HLP's two mirrored strategy vaults. The setup takes a few minutes: one claude mcp add command, one browser login, and four text files.
- Connect the server: Dwellir MCP documentation
- Get the full toolkit, including the Hyperliquid skill and CLI: Dwellir Agent Toolkit
- For research that needs fills, trades or order book history over time: Hyperliquid historical data
If you are building a research or analytics product on Hyperliquid data and need more than point reads, talk to the Dwellir team about dedicated endpoints and archive access.


