@axon-trading/mcp
v1.2.2
Published
Axon MCP server — local non-custodial perp trading terminal for AI agents. Drop-in for Claude Code, Claude Desktop, Cursor, Codex, Cline, Continue, Zed, Windsurf, OpenClaw. Trade Hyperliquid perps through ~35 typed Model Context Protocol tools. Keys stay
Maintainers
Keywords
Readme
@axon-trading/mcp
🤖 MCP server for the Axon trading daemon — the trading terminal for AI agents. Drop-in for Claude Code, Claude Desktop, Cursor, Codex, Cline, Continue, Zed, Windsurf, OpenClaw. Exposes ~35 typed Model Context Protocol tools — open_perp, close_perp, get_positions, kill_switch_on, hl_deposit, marketplace_search, marketplace_vote, and more — so any MCP-compatible runtime can drive a real Hyperliquid wallet through chat. The user's keys never leave their local machine. Every order signed locally; non-custodial by construction.
Drop-in:
axon install <runtime>writes the right config for your agent runtime in one command. No JSON wrangling. No manual paste. The MCP server auto-spawns when your runtime starts.
✨ What's new in 1.0.0
- 📦 Marketplace tools —
marketplace_search(query, tags?, venues?, sort?)returns signed strategies;marketplace_vote({ strategyId, value })casts a daemon-signed vote against the marketplace-api. Both wrap the same HTTP path the dashboard uses. - 📜 Strategy lifecycle tools —
install_strategy,uninstall_strategy,list_strategies,get_strategy_runs,run_strategy. Signature verification on install pins against the build-time-embedded Strykr ed25519 pubkey forkind: "strykr"manifests. - 🛡️ x402 hardening surfaces — paid-strategy purchases via the marketplace now run pre-sign validation (recipient, amount, USDC contract, validity window, manifest-hash binding). Six new typed rejection codes propagate to the agent for clean error handling.
- 🔄 Update detection — agents can probe
/v1/health.updateAvailableviaaxon statusto know if the daemon is behind a newer release. - 🪜 One-click install for: Claude Code, Claude Desktop, Cursor, Codex, Cline, Zed, Windsurf. (Continue.dev still requires manual YAML.)
Full changelog: CHANGELOG.md.
Works With
| Agent runtime | Auto-install |
|---|---|
| Claude Code (Anthropic CLI) | axon install claude-code |
| Claude Desktop (Anthropic) | axon install claude-desktop |
| Cursor (AI-first editor) | axon install cursor |
| Codex CLI (OpenAI) | axon install codex |
| Cline (VS Code extension) | axon install cline |
| Zed (collab editor) | axon install zed |
| Windsurf (Codeium agent) | axon install windsurf |
| Continue.dev | manual (YAML config) |
| OpenClaw | use the packages/adapters/openclaw/ adapter — wraps the same SDK |
| LibreChat / OpenWebUI / any MCP runtime | manual (any MCP-compatible) |
Built for: Claude Code • Claude Desktop • Cursor • Codex • Cline • Continue • Zed • Windsurf • OpenClaw • LangChain agents (via @axon-trading/sdk) • LangGraph • AutoGPT • CrewAI • custom MCP-compatible runtimes
Perfect For
- 🤖 AI trading agents — give Claude / Codex / Cursor / etc. real execution authority on Hyperliquid in 60 seconds
- 🔐 Self-custody users — agents can place orders but cannot withdraw funds, modify policy, or disarm the kill switch
- 🏢 Per-agent compartmentalization — bind each runtime to a different wallet (Codex on testnet, Claude Desktop on production)
- 📊 Read-heavy research — every read tool (positions, balances, OHLCV, audit log) is non-signing and safe to call freely
- 🛡️ Compliance-first ops — every MCP call is recorded in the daemon's hash-chained audit log with the calling clientId
Table of Contents
- Works With
- Perfect For
- Features
- Prerequisites
- Installation
- Quick Start
- Tool Reference
- Pending-Action Pattern
- Per-Runtime Setup
- Identity + Per-Agent Bindings
- Error Handling
- Examples
- Troubleshooting
- Security model
- FAQ
- License
Features
- 🎯 MCP standard — protocol-conformant; works with any MCP-compatible runtime
- 🔌 Auto-discovery — reads
~/.axon/agent.envto find the daemon URL + bearer token (rotated every daemon boot) - 🔁 Auto-retry — transparent retry on transient daemon-restart errors
- 🛡️ Policy-enforced — every tool call goes through the daemon's policy engine; agents can't bypass leverage caps, daily limits, or the kill switch
- 📜 Audited — every tool invocation is recorded in the local hash-chained audit log with the calling clientId
- 🔐 Passphrase-safe — operations that need the user's passphrase return a browser confirmation URL; the passphrase NEVER crosses the LLM transcript
- 📊 ~30 tools — trading, market data, wallet management, funding, operations
- 🪪 Per-agent identity — the runtime's clientId (e.g.
claude-desktop/0.5) is automatically attached to every call
Prerequisites
- The Axon daemon installed and running:
npm install -g @axon-trading/cli && axon - An MCP-compatible agent runtime (see Works With)
- Node.js ≥ 20
Installation
In most cases you don't install this package directly. The Axon CLI's install subcommand writes the right MCP config for your runtime:
# Install Axon CLI (which bundles the MCP adapter)
npm install -g @axon-trading/cli@next
# Wire MCP into your runtime
axon install claude-desktop # or claude-code, cursor, codex, cline, zed, windsurf
# Restart your runtime — Axon's tools are now availableDirect install (uncommon)
If you want the standalone MCP binary on your PATH:
npm install -g @axon-trading/mcp@next
which axon-mcpThen in your runtime's MCP config:
{
"mcpServers": {
"axon": {
"command": "axon-mcp"
}
}
}Or via the bundled CLI subcommand
{
"mcpServers": {
"axon": {
"command": "axon",
"args": ["mcp"]
}
}
}Quick Start
# 1. Start the daemon
axon # demo mode by default
# OR for live trading:
axon --live
# 2. Wire your AI runtime
axon install claude-desktop
# 3. Restart the runtime
# (quit + reopen your AI client)
# 4. In chat:
"Show me my Hyperliquid balance and any open positions"The agent calls get_balance + get_positions automatically and reports back.
Tool Reference
Trade tools
| Tool | What | Passphrase? |
|---|---|---|
| open_perp | Open a long/short perp position | No (agent key signs) |
| close_perp | Close a position (full or partial) | No |
| cancel_order | Cancel an open limit order | No |
| update_leverage | Change leverage on an existing position | No |
Read tools (no signing, no side effects)
| Tool | Returns |
|---|---|
| get_balance | USDC + ETH on-chain + HL margin |
| get_positions | Open positions across venues |
| get_markets | Symbol list with tick / size / max-leverage |
| get_ticker | Latest mark price + spread |
| get_ohlcv | Historical candles |
| get_trade_history | Filled trades + open orders, normalized |
| get_audit_events | Hash-chained audit log (filterable) |
| inspect_bridge_balance | Cross-references on-chain USDC vs HL margin |
| run_doctor | Full system health check |
Wallet tools
| Tool | Passphrase? | Notes |
|---|---|---|
| list_wallets | No | All known wallets + active flag |
| set_active_wallet | No | Change daemon's default signing wallet |
| rename_wallet | No | Rename for UI clarity |
| delete_wallet | Yes (browser) | Returns confirmationUrl |
| bind_agent | No | Per-runtime wallet binding |
| set_default_binding | No | Default for unbound agents |
| list_agent_bindings | No | Read all current bindings |
| transfer_usdc | Yes (browser) | Wallet-to-wallet USDC |
| generate_wallet | Yes (browser) | New wallet, mnemonic shown ONCE |
| import_wallet | Yes (browser) | From BIP-39 mnemonic |
| import_wallet_from_pk | Yes (browser) | From raw private key |
Funding tools
| Tool | Passphrase? | Notes |
|---|---|---|
| hl_deposit | Yes (browser) | Owner EOA → HL via Bridge2 EIP-2612 permit |
| hl_spot_to_perp | Yes (browser) | Move USDC between HL spot ↔ perp wallets |
| approve_builder | Yes (browser) | One-time HL builder-fee approval |
Operations tools
| Tool | Passphrase? | Notes |
|---|---|---|
| kill_switch_on | No | Agents CAN arm. Cancels every order, halts new ones. |
| kill_switch_off | Yes (browser) | Only humans can disarm |
| set_mode | Yes (browser) | demo / testnet / live |
| audit_verify | No | Verify hash chain integrity |
| list_anchors | No | On-chain audit anchors |
| settle_now | No | Force a settlement-anchor commit |
| get_policy | No | Read current policy (read-only for agents) |
| await_pending_action | No | Poll a pending action token until completion |
Pending-Action Pattern
For passphrase-gated tools, the response shape is:
{
"ok": true,
"pending": true,
"token": "pa_<32hex>",
"confirmationUrl": "http://127.0.0.1:47890/confirm/pa_<32hex>",
"pollUrl": "/v1/pending/pa_<32hex>",
"expiresAt": 1700000300000
}Agent flow:
- Display
confirmationUrlto the user — tell them to open it in a browser and enter their passphrase. - Poll via
await_pending_action(token). - Resolve with the final result (success or rejection like
BAD_PASSPHRASE).
The passphrase never crosses the LLM transcript or the MCP boundary.
Tools that use this pattern: hl_deposit, hl_spot_to_perp, approve_builder, kill_switch_off, set_mode, transfer_usdc, generate_wallet, import_wallet, import_wallet_from_pk, delete_wallet.
Per-Runtime Setup
Axon's CLI auto-installs MCP for the most common runtimes. The actual configs it writes:
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (Mac) or %APPDATA%\Claude\claude_desktop_config.json (Win):
{
"mcpServers": {
"axon": { "command": "axon", "args": ["mcp"] }
}
}Claude Code
~/.claude.json:
{
"mcpServers": {
"axon": { "command": "axon", "args": ["mcp"] }
}
}Cursor
~/.cursor/mcp.json:
{
"mcpServers": {
"axon": { "command": "axon", "args": ["mcp"] }
}
}Codex CLI (TOML)
~/.codex/config.toml:
[mcp_servers.axon]
command = "axon"
args = ["mcp"]Cline (VS Code)
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json (Mac path; analogous on Win/Linux):
{
"mcpServers": {
"axon": { "command": "axon", "args": ["mcp"] }
}
}Zed
In Zed's settings JSON (under the assistant block):
{
"context_servers": {
"axon": { "command": "axon", "args": ["mcp"] }
}
}Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"axon": { "command": "axon", "args": ["mcp"] }
}
}Continue.dev (YAML)
~/.continue/config.yaml:
mcpServers:
- name: axon
command: axon
args: [mcp]Identity + Per-Agent Bindings
When Claude Desktop, Cursor, Codex, etc. spawn axon-mcp as a subprocess, the MCP handshake reports the runtime's identity (clientInfo.name + clientInfo.version — e.g. claude-code/0.5). The MCP adapter forwards this to the daemon as x-axon-client: claude-code/0.5 on every HTTP request.
This identity drives:
- Per-agent wallet bindings: bind
claude-code/0.5to wallet A,cursor-vscode/1.0to wallet B - Per-agent notional caps: policy can limit each clientId's daily trading volume separately
- Audit log attribution: every intent in the audit log carries the calling clientId
The user manages bindings via the dashboard's Wallets → Agent Bindings panel, OR via MCP tools:
"Bind the cursor agent to my testnet-sandbox wallet"
→ bind_agent({ clientId: "cursor-vscode/1.0", walletId: "wal_..." })
Error Handling
Every tool returns either a typed success result OR a RejectionResult:
{ "ok": false, "code": "HL_INSUFFICIENT_MARGIN", "message": "...", "hint": "..." }Branch on code, NOT message. Codes are stable across versions.
Common rejection codes
| Code | What to do |
|---|---|
| KEYSTORE_LOCKED | Tell user to unlock via dashboard. Agents cannot unlock. |
| ONBOARDING_REQUIRED | First-time user. Tell them to run axon and complete the wizard. |
| WALLET_BINDING_MISMATCH | Show bound vs active wallet; offer to rebind. |
| HL_INSUFFICIENT_MARGIN | Reduce size, deposit more, or use lower leverage. |
| HL_BUILDER_FEE_NOT_APPROVED | Call approve_builder({}). |
| HL_AGENT_NOT_APPROVED | Tell user to run axon hl revoke-agent and retry. |
| KILL_SWITCH_DENIED | Tell user to disarm in dashboard. |
| WC_RELAY_UNAVAILABLE | Connected wallet flow needs the dashboard, not MCP. |
| POLICY_PER_AGENT_CAP | Daily notional cap reached for this clientId. |
| EXPIRED | Pending action token expired. Re-call to get a fresh one. |
Full reference: docs/REJECTION_CODES.md.
Examples
Open a position from chat
"Open a $100 long on BTC with 5x leverage"
Agent calls:
{"tool": "get_markets", "args": {"venue": "hyperliquid"}}
{"tool": "open_perp", "args": {
"venue": "hyperliquid",
"symbol": "BTC",
"side": "long",
"leverage": 5,
"sizeUsd": 100
}}Reply:
Opened 0.0015 BTC long on Hyperliquid at $67,492.50 (5× leverage, $100 notional). View on HL
Close a position
"Close my ETH position"
Agent flow:
{"tool": "get_positions", "args": {}}
// finds: { venue: "hyperliquid", symbol: "ETH", size: 0.5, side: "long", ... }
{"tool": "close_perp", "args": {
"venue": "hyperliquid",
"symbol": "ETH",
"sizeBase": 0.5
}}Deposit USDC to HL
"Deposit $50 to my Hyperliquid account"
{"tool": "hl_deposit", "args": {"amount": 50}}Returns { pending: true, confirmationUrl, token, ... }. Agent displays the URL; user opens + enters passphrase. Agent then polls:
{"tool": "await_pending_action", "args": {"token": "pa_<32hex>"}}Inspect a stuck deposit
"I bridged USDC 10 minutes ago but my HL balance hasn't updated"
{"tool": "inspect_bridge_balance", "args": {}}Returns:
{
"hlPerpAccountValue": 100.0,
"hlSpotBalances": [{"coin": "USDC", "total": 0}],
"bridgeContractBalance": 50.0,
"pendingDeposits": [{"txHash": "0x...", "amount": 50, "ageSec": 600}]
}Agent explains the credit timing.
Recent activity summary
"What did I trade today?"
{"tool": "get_trade_history", "args": {"limit": 20}}
{"tool": "get_audit_events", "args": {"limit": 50, "kinds": ["intent_filled"]}}Troubleshooting
Tool returns { "code": "DAEMON_UNREACHABLE", "fix": "..." } (rc.5+)
The daemon isn't running. The fix field carries the exact command — relay it verbatim to the user:
axon # start the daemon in a terminalIf they don't have the CLI:
npm install -g @axon-trading/cli@next
axonThe MCP adapter has a 15-second cold-start grace window on the first tool call per process — gives the daemon time to finish booting if the user just spawned axon seconds ago.
Tool returns { "code": "DAEMON_NOT_INSTALLED", "fix": "..." } (rc.5+)
The user never installed the Axon CLI on this machine. The structured response includes:
details.state: "no-cli"→ install + boot:npm install -g @axon-trading/cli@next && axondetails.state: "cli-no-creds"→ CLI is installed; justaxondetails.state: "cli-creds-stale"→ restartaxonto regenerateagent.env
Always show the user the literal command from details.fix. Don't paraphrase it — that command line is what they need to copy + paste.
"MCP server failed to start"
- Daemon not running: open a terminal and run
axon. The MCP server connects to the daemon's HTTP API; without it, MCP can't operate. axonnot on PATH: re-runnpm install -g @axon-trading/cli. Or use the full path:"command": "/usr/local/bin/axon".- Permission errors: ensure your runtime can spawn subprocesses. Some sandboxed environments (Flatpak, snap) restrict that.
"I don't see any Axon tools" / axon doctor says everything is fine but MCP fails
axon doctor (rc.5+) checks daemon reachability whenever an MCP runtime is configured. If you see all green there but the agent still can't reach Axon's tools:
- Restart your agent runtime so it re-spawns the MCP subprocess.
- Run
axon install --verifyto confirm the runtime config still resolves to a working binary. - Run
axon doctoragain — the rc.5+ output now shows daemon reachability as a dedicated row.
"fetch failed" on every tool call
The daemon restarted and the bearer token rotated. The MCP adapter retries automatically once. If persistent, restart your AI runtime so it re-spawns the MCP subprocess (which re-reads ~/.axon/agent.env).
KEYSTORE_LOCKED on every call
The daemon is running but locked. Tell the user to open http://127.0.0.1:47890 and enter their passphrase. Agents cannot unlock.
The agent says "I don't see Axon's tools"
- Did you restart your AI runtime after running
axon install? - Run
axon install --verifyto confirm the config is still valid. - Check the runtime's MCP server logs (varies per runtime).
- Try
axon-mcp --helpdirectly in a terminal to confirm the binary works.
Tool returns a result the agent doesn't display
LLM agents sometimes refuse to display large structured output verbatim. Ask the agent to summarize: "Summarize my open positions", "What's my net exposure?".
Security model
The MCP adapter is a thin shell around the SDK. It enforces nothing on its own — every constraint lives in the daemon:
- ✅ Agents cannot read the keystore (only the daemon decrypts it)
- ✅ Agents cannot disarm the kill switch (only humans, via dashboard)
- ✅ Agents cannot modify policy (read-only via
get_policy) - ✅ Passphrase-gated actions use browser confirmation; passphrase never crosses MCP
- ✅ Bearer-token auth on every call; token rotates on daemon restart
- ✅ Per-clientId attribution in audit log + per-agent notional caps
Full threat model: docs/security-model.md.
FAQ
Why MCP instead of a regular OpenAI / Anthropic tool definition?
MCP is the emerging standard for agent-tool wiring across providers. By going MCP-first, Axon works with any compliant runtime — you're not locked into a single LLM vendor.
Can the same MCP server serve multiple agent runtimes?
Yes. The Axon daemon is process-singleton; multiple agent runtimes spawn their own axon-mcp subprocesses, all of which connect to the same daemon. Each subprocess identifies as its parent runtime, enabling per-agent bindings + caps.
How do I add custom tools?
Right now the tool list is fixed by the daemon's HTTP API. To add a custom tool, you'd need to (1) add the tool to the daemon, (2) add the SDK method, (3) register it in the MCP adapter, (4) open a PR. For one-off custom logic, build a separate MCP server alongside this one — your runtime's config can register multiple mcpServers.
Is there a hosted MCP?
No. The whole point is non-custodial. A hosted MCP would mean the keys live on someone else's machine.
Does this work with the Claude API directly (not Claude Desktop)?
Indirectly. The MCP standard isn't yet wired into Anthropic's web API. If you're driving Claude programmatically, use the SDK (@axon-trading/sdk) instead of MCP.
What happens if I have multiple wallets?
Every agent uses the daemon's "active wallet" by default. Use bind_agent to override per-runtime: e.g., claude-desktop → production wallet, cursor → testnet sandbox.
Why does kill_switch_on not require passphrase but kill_switch_off does?
Safety asymmetry: agents should be able to halt trading immediately if something feels wrong (one-tool call). Disarming requires the human, by design — the kill switch is a circuit breaker, not a toy.
Why isn't there a deposit-from-other-chain tool?
Cross-chain deposits require a wallet signature on the source chain — and Axon doesn't hold keys for MetaMask / Phantom / Coinbase / etc. The dashboard surfaces the LI.FI / Jumper hosted bridge for that flow. Bridge-then-deposit is a two-step manual process today.
License
Proprietary. © 2026 Strykr Labs. All rights reserved. See LICENSE for the full proprietary notice and TRADEMARKS.md for trademark policy. Licensing inquiries: [email protected].
Source: https://github.com/Strykr-Labs/Axon-Agent-Trading
Docs: https://github.com/Strykr-Labs/Axon-Agent-Trading/tree/main/docs
Companion packages: @axon-trading/cli · @axon-trading/sdk
