Agent Cookbook12 copy-ready prompts for AI coding agents.12 prompts for AI agentsSee recipes
All Blog Posts
Build an Onchain Research Agent with Claude Code and the Dwellir MCP Server

Build an Onchain Research Agent with Claude Code and the Dwellir MCP Server

By Ben Chatwin 14min read

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.

TEXT
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 question

Prerequisites:

  • 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
Flow of the research agent: the /research command hands the question to a subagent that follows CLAUDE.md rules, the subagent makes read-only calls through the Dwellir MCP server, and the result is a report with a source row and read time for every number. Responses over 50 KB go through a script that uses DWELLIR_API_KEY.

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:

BASH
claude mcp add --transport http --scope project dwellir https://mcp.dwellir.com/mcp

That writes:

JSON
{
  "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.

TaskToolNotes
Find chains and endpoint IDslist_endpointsFilter by name, for example hyperliquid
Get a key referencelist_keysReturns non-secret key_ref values, never key values
List allowed read methodsrpc_methodsEVM, Substrate, Solana, Bitcoin, Starknet, Sui
Read chain staterpc_calleth_getLogs, eth_call, eth_getBalance and similar; broadcasts are rejected
Read Hyperliquid Infohyperliquid_infometa, spotMeta, perpDexs, clearinghouseState, spotClearinghouseState, openOrders, userFees, exchangeStatus
Sample a streamcapture_streamnewHeads, finalizedHeads, runtimeVersion, Hyperliquid l2Book; at most 20 messages or 15 seconds
Read Dwellir docssearch_docs, get_docsLets the agent check method parameters itself
Accountusage_summary, usage_history, key managementNot 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.

MARKDOWN
# 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.

MARKDOWN
---
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:

MARKDOWN
---
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.

TEXT
/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 flagged isDelisted. XYZ alone lists 114 live markets and holds 95% of the streaming open-interest caps on the four live HIP-3 DEXes.

DEXLive / listedLeverageOI capsWhat it lists
XYZ114 / 13410x to 50x$16.32BUS equities, indices, commodities, FX
Paragon30 / 3810x$720MEquities, US rates, crypto indices
EntropyIO10 / 135x to 25x$117MPre-IPO (OpenAI, Anthropic), equities
Kinetiq5 / 245x to 25x$77MUS 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 public api.hyperliquid.xyz/info endpoint and labelled the result.

Source: public Hyperliquid APIOpen interest24h 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 interest24.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.

Bar chart of the 10 HIP-3 perp DEXes on Hyperliquid on 13 October 2026: XYZ has 114 of 134 markets live, Paragon 30 of 38, EntropyIO 10 of 13, Kinetiq mkts 5 of 24, while HyENA, Kinetiq km, dreamcash, Felix, Ventuals and ABCDEx have every market delisted.

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.

TEXT
/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).

AccountAccount valuePositionsGross notionalLong / short
HLP parent 0xdfc2…f303$40,863,2170$0n/a
Child 0x0104…703a$3,182,095177$3.91M$2.0M / $2.0M
Child 0x31ca…974b$3,001,978177$3.93M$1.9M / $2.1M
Child 0xb0a5…9540$30,000,0000$0n/a
4 other children$3,000,9990$0n/a
MarketChild 0x0104… sizeChild 0x31ca… size
BTC+0.698-0.681
ETH+10.39-10.00
HYPE+166.7-157.5
SOL+338.2-328.2
HLP capital map on 13 October 2026: $80.05M in total, of which $40.86M sits in the parent vault and $30.00M in one child vault with no positions, $3.00M across 4 idle children, and $6.18M in 2 trading children whose positions mirror each other, long BTC, ETH, HYPE and SOL in one and short in the other, in 171 of 177 shared markets.

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:

PYTHON
"""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:

BASH
dwellir keys env research-agent
python3 scripts/hl_orders_summary.py \
  0x010461c14e146ac35fe42271bdc1134ee31c703a \
  0x31ca8395cf837de08b24da3f660e77761dfb974b
JSON
{"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:

NeedUseWhy
Discover endpoints, methods, docsMCPNo key handling, small responses
Point reads: balances, positions, one block, one market listMCP rpc_call, hyperliquid_infoFast, sourced, read-only by design
Large responses: thousands of orders, wide eth_getLogs rangesScript with DWELLIR_API_KEYKeeps raw data out of the context window
Continuous data: streams, gRPC, fills over timeProject code on Dwellir gRPC or the historical archiveMCP captures stop at 20 messages or 15 seconds
Trading or signingNot this agentThe 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 Transfer events on Arc in the last 1,000 blocks?" (eth_getLogs via rpc_call)
  • "What fee tier is this Hyperliquid wallet on, and how much has it traded in the last 14 days?" (userFees)
  • "Is the Base finalized head keeping pace with latest right now?" (capture_stream with finalizedHeads and newHeads)
  • "What does this HyperEVM contract return for totalSupply() at block 3,000,000?" (eth_call against 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.

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.

read another blog post