omx
OMX exposes a guardrailed Hyperliquid perps execution interface for AI agents: quote, preview, submit, monitor, cancel, and stop orders, plus account and policy visibility.
get_quote— top of book, mid, data age, and policy-band depth for an allowed coin.preview_order— dry-run market/limit/TWAP/POV/chase intents: planned children, policy decisions, fee bound, approval requirement.submit_order— send an intent with idempotentclient_intent_id; above threshold/budget it queues for human approval.approval_statusandorder_status— track queued approvals and intent fills, average price, slippage, fees, block reasons.cancel_order— cancel the agent's own intent and resting children.kill_switch— stop new orders and cancel resting OMX orders; agents can turn it on, not off.account_summaryandpolicy_limits— equity, P&L, positions, open orders, remaining budget, limits, thresholds, builder fee.Cannot change policy limits, withdraw/transfer funds, or clear the kill switch; human approval/daemon confirmations govern exceptions.
OMX: Hyperliquid execution for AI agents (MCP)
OMX is a non-custodial execution engine for Hyperliquid perpetuals. It runs on your own machine, turns an order intent (market, limit, TWAP, POV, chase) into child orders, checks every child against a pre-trade policy you configure, and writes every decision to a hash-chained audit log. A command line and an MCP server let a human or an AI agent drive it inside those limits.
OMX makes no claim about trading performance or profit. It is execution plumbing with guard rails.
You worry about | What OMX does |
Your keys | Signs only with a Hyperliquid API (agent) wallet you create in your own account; never asks for your main key or seed. The config holds the key file's path, not the key. No withdrawal or transfer code. |
Limits | Every child order is checked locally: coin allowlist, liquidity and depth, price band and slippage, per-coin and account notional (resting orders included), leverage, daily loss, data age. The engine refuses any child the policy rejects. No MCP tool can change limits; they come from the config the daemon loaded. An agent that also has shell or file access as your OS user could edit that file, so run such agents under another OS user (trust boundary). |
Human approval | An agent intent above |
Stopping it | Any agent or human can trip the kill switch; it cancels resting OMX orders. Only a human can clear it ( |
Audit | Every decision goes to a hash-chained log; |
Fees | Optional 1 bp builder fee, charged only after you approve it in your own wallet; |
Path: the keyless demo, then paper trading on live Hyperliquid books (also keyless), then testnet, then mainnet with small size.
Try it now: no key, no account
One click installs the MCP server in demo mode (a simulated venue in its own process; nothing real can be traded):
Or one line:
claude mcp add omx -- uvx omx-hyperliquid # Claude Code
codex mcp add omx -- uvx omx-hyperliquid # OpenAI Codex CLI
gemini mcp add omx uvx omx-hyperliquid # Gemini CLIClaude Code plugin:
/plugin marketplace add Lumen-Founder/omx-hyperliquid-mcp, then/plugin install omx@omx.Gemini CLI extension:
gemini extensions install https://github.com/Lumen-Founder/omx-hyperliquid-mcp.Any other MCP client (Claude Desktop, Cline, Windsurf, Zed, JetBrains, ...):
{"mcpServers": {"omx": {"command": "uvx", "args": ["omx-hyperliquid"]}}}. Claude Desktop keeps it inclaude_desktop_config.json(Settings > Developer > Edit Config; Windows%APPDATA%\Claude\, macOS~/Library/Application Support/Claude/); Cursor in~/.cursor/mcp.json. Pin a version with"omx-hyperliquid@0.1.7".No
uv? Windows:powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"; macOS / Linux:curl -LsSf https://astral.sh/uv/install.sh | sh; then open a new terminal. Orpip install omx-hyperliquidand useomx-hyperliquidas the command.
With no --config, no OMX_CONFIG and no ./omx.toml, omx-hyperliquid runs
the demo (--demo forces it). The engine, policy checks, approval threshold,
agent budget, kill switch and audit log are the real code; prices are a
random-walk model, not Hyperliquid data. Every answer carries "demo": true.
State lives in a temporary directory that is deleted on exit. A config that is
named but missing is an error, never a silent demo.
Then ask the agent to quote ETH, preview a small TWAP and submit it (for
example buy 0.1 ETH over 10 s in 5 slices), and poll order_status until it
is done. An intent above 1,000 USD returns an approval_id and waits for a
human; the demo has no approval step, so it stays pending and expires. After
kill_switch every new order is refused. In real use only a human clears it,
with omx unkill (it asks you to type I UNDERSTAND); the demo has no
unkill, so restart the server to start fresh.
Paper trading on live Hyperliquid books
omx-hyperliquid --paper (or omx-mcp --paper, omx paper) runs the same
tools with simulated fills against Hyperliquid mainnet's live public order
books. No key, no account, no config, no daemon: it only reads public market
data (/info l2Book, allMids, metaAndAssetCtxs) and never signs or sends an
order. The paper account starts at 10,000 USD (--paper-equity 2500 to change
it); taker orders walk the real book at Hyperliquid's base-tier fees (0.045 %
taker, 0.015 % maker), resting orders fill only when the book trades through
their price, and the default policy limits apply (including Hyperliquid's 10
USD minimum order). Every answer carries "paper": true. Fills are a model,
not Hyperliquid's matching engine; see docs/PAPER.md.
claude mcp add omx-paper -- uvx omx-hyperliquid --paperAny other client: {"command": "uvx", "args": ["omx-hyperliquid", "--paper"]}.
Codex CLI waits 10 s for a server to start by default, and the first uvx run
downloads the dependencies; if it times out, add startup_timeout_sec = 60
under [mcp_servers.omx] in ~/.codex/config.toml.
Set up your own account
pip install omx-hyperliquid # or: uv tool install omx-hyperliquid
omx setup # one guided terminal session, testnet first
omx --config <path printed by setup> daemon # in its own terminal, keep it open
omx mcp-config # prints the settings for your MCP clientomx setup walks you through the network (testnet first), your main
account's public address, an API wallet key (typed into a hidden prompt and
saved to a file only your user can read, or a key file you already saved), the
eligibility questions, agent limits, the builder-fee choice, then read-only
checks. It never asks for your main wallet key or seed phrase, and refuses a
key whose address is your main account. omx mcp-config prints the settings
for Claude Code, Codex, Gemini, VS Code, Cursor or Claude Desktop, filled in
with your config's absolute path. See docs/SETUP.md and the
Quick start for each step by hand.
Agent frameworks: omx-integrations has copy-and-run examples for the OpenAI Agents SDK, LangChain, the Claude Agent SDK, PydanticAI and CrewAI, each checked against this server with the framework's own MCP client (demo mode by default).
Status (v0.1.7): pre-1.0. The full path (agent intent -> policy -> signed order with a builder code -> fill -> kill switch -> audit verify) has been run end to end on Hyperliquid testnet. OMX has not had an external security audit. Start on testnet, then mainnet with small size. MIT licensed, no warranty.
Related MCP server: tv-recommender-mcp-server
Eligibility
OMX is not available to persons or entities residing, located, incorporated or
with a registered office in the United States, Ontario (Canada) or sanctioned
territories, nor to citizens of sanctioned territories, per the Hyperliquid
Terms of Use. Using a VPN or proxy, or a false residency statement, to get
around this is a breach; OMX offers no way around a block. OMX does not offer
outcome markets. omx eligibility asks these questions and refuses to trade
when the answer is blocked; it stores only country/region codes and yes/no
answers.
Non-custodial model
Your funds stay in your own Hyperliquid account. OMX has no withdrawal or transfer code path.
You create an API / agent wallet in your own account. It can place and cancel orders but cannot withdraw. OMX signs with that key only.
OMX never asks for your MAIN wallet key or seed phrase. The builder-fee approval (if any) is signed by you in your own wallet.
The config holds the agent key's file PATH or env var NAME, never the key. A config containing anything shaped like a private key is rejected, and so is a command-line argument shaped like one.
Install
pip install omx-hyperliquid # PyPI; gives the `omx`, `omx-mcp` and `omx-hyperliquid` commandsFrom a checkout (development, tests):
python -m venv .venv
.venv/Scripts/python -m pip install -e ".[test]" # Windows; .venv/bin/python elsewhere
.venv/Scripts/python -m pytest -q testsThe commands below also work as python -m omx.cli ... from a checkout.
Requires Python 3.11+ (tomllib; developed on 3.12). The MCP server uses the
official mcp Python SDK 2.x. The live Hyperliquid venue also needs
eth_account for signing.
Quick start (testnet)
OMX runs as one long-lived process, omx daemon, which owns the engine (the
only thing that talks to Hyperliquid and holds the agent key), the audit-log
writer and the approval executor. The CLI and the MCP server are thin clients
that talk to it through files in state_dir/ipc/.
Create an agent wallet at app.hyperliquid-testnet.xyz (API page) and save its key in a file only your user can read, e.g.
secrets/hl_agent_testnet.key.Write the config and answer the eligibility questions:
python -m omx.cli --config omx.toml init --account 0xYOUR_MAIN_ADDRESS --key-path secrets/hl_agent_testnet.keyconfig.example.tomlshows every field. Eligibility must be renewed everyeligibility_ttl_days(default and maximum 30):omx eligibility.Start the daemon in its own terminal and leave it running while you trade:
python -m omx.cli --config omx.toml daemonIt steps every working intent every 200 ms (TWAP/POV/chase slices are sent only while it runs). Only one daemon can run per
state_dir, and only one per account (a per-account lock in%LOCALAPPDATA%\omx\locks, orlock_dirin the config). It refuses to start without a valid eligibility attestation; there is no bypass for trading. It re-checks eligibility every 10 minutes and turns cancel-only when the check fails.daemon --cancel-onlystarts without the check and only cancels resting OMX orders (for an expired or blocked user). Approvals,unkill,eligibilityandaudit repairsent to the daemon are shown in its terminal with what they would do and the request id the CLI printed; they run only after you type theconfirm <code>line it prints there. Keep that terminal interactive (a real console, not< NULor a pipe; seedocs/SECURITY.md).In another terminal, dry run, then send:
python -m omx.cli --config omx.toml preview ETH buy 0.05 --algo twap --duration-s 300 --slices 5 python -m omx.cli --config omx.toml submit ETH buy 0.05 --algo twap --duration-s 300 --slices 5 python -m omx.cli --config omx.toml status <intent_id>preview,submit,status,cancelandapprovals approveneed the daemon; without it (heartbeat older than 5 s) they stop with a message telling you to startomx daemon. After a daemon restartstatusof an older intent answersunknown(check the audit log and the venue), neverrejected.Stop everything at once:
python -m omx.cli --config omx.toml kill --reason "...". It always writes thestate_dir/KILLfile first (no new orders from any OMX process), then cancels resting OMX orders through the daemon, or, if no daemon is running, through a one-shot cancel-only engine it builds for this (no eligibility check). Either way it exits with code 3 and aWARNINGif the sweep failed or an order could not be cancelled.--allcancels every open order on the account, not only OMX ones; the scope is stored in the KILL file and honoured by the next daemon. Clearing it (unkill) asks you to typeI UNDERSTAND.submitprints the intent id; after a timeout check it withstatus <id>and retry with--intent-id <id>(the daemon refuses an id it already took).AI agents:
python -m omx.cli --config omx.toml mcp(usually started by your MCP client, seedocs/AGENTS.md). It holds no key and no engine and needs the daemon running.
Stopping the daemon (Ctrl+C) does not set the kill switch and cancels
nothing: resting OMX orders stay on the venue and sliced intents stop sending.
On the next start the engine cancels orphan OMX orders from the previous run.
To cancel immediately, use omx kill.
Other commands: cancel, approvals list|approve|reject, audit verify,
audit repair, fees, mcp, eligibility, approve-builder, doctor. audit verify tells a torn last
line from a crash (TRUNCATED_TAIL, exit 4) apart from tampering (BROKEN,
exit 3); audit repair moves only a torn tail aside, after you type
REPAIR AUDIT.
Controls
Every child order passes all of these before it can leave your machine:
Coin allowlist
Liquidity floor (24 h traded notional) and resting depth near mid
Price band vs mid, intent limit price, per-intent slippage cap
Per-coin worst-case notional (position plus all same-side resting orders)
Account-wide worst-case notional
Worst-case leverage vs equity
Daily loss limit (deposits and withdrawals kept out of P&L)
Market-data freshness
Kill switch (a file in
state_dir; any process can trip it;omx killalso cancels resting OMX orders)Hash-chained audit log (
omx audit verify)
Plus a per-child notional cap, reduce-only checks, and for AI agents: an
on/off switch, an agent coin subset, a per-intent human-approval threshold, a
daily agent notional budget, approvals that expire, and no ability to unkill
or change limits. See docs/SECURITY.md, docs/FEES.md, docs/AGENTS.md.
Builder fee
OMX is open source (MIT) and costs nothing to install or run. The maintainers
are paid through an optional Hyperliquid builder fee on mainnet fills. When omx/config.py names a default builder for the network
(DEFAULT_BUILDER), omx init sets it at 1 bp (0.01 % of filled notional).
--no-builder sends no builder code, --fee-tenths-bps sets a lower fee, and
--builder-address uses your own. Nothing is charged until you approve the
fee from your own wallet (omx approve-builder), and you can revoke it at any
time. omx fees shows the exact rate and the exact max rate you would
approve, before you approve anything. Details in docs/FEES.md.
Enforcement. With [builder] address and fee_tenths_bps > 0 set, the
engine itself attaches {"b": address, "f": fee} to every order it sends.
Intents (CLI, MCP, approvals) have no builder field, so no caller can set or
remove it; a child order carrying any other builder is refused. The builder
address must differ from the account and from the agent wallet. The daemon
reads maxBuilderFee for (account, builder) at start and every 10 minutes
(every 60 s while blocked). While the approved maximum is below the configured
fee it is in BUILDER_NOT_APPROVED: new intents are refused with that reason
and the hint omx approve-builder; working intents finish or can be
cancelled; omx kill always works.
Approve in your browser, no key in OMX:
python -m omx.cli --config omx.toml approve-builder # approves the configured fee
python -m omx.cli --config omx.toml approve-builder --max-fee-rate 0.02% # a higher maximum
python -m omx.cli --config omx.toml approve-builder --revoke # maxFeeRate 0%It serves one page on 127.0.0.1 (random port and path) and opens your
browser (--no-browser only prints the URL; --timeout-s stops it, default
900). The page uses your browser wallet (window.ethereum): it checks that the
selected account is account_address, asks the wallet to sign
HyperliquidTransaction:ApproveBuilderFee, sends the signed approval from the
browser straight to Hyperliquid's /exchange and re-reads maxBuilderFee.
OMX's Python process never receives a key or the signature.
Check the setup: python -m omx.cli --config omx.toml doctor prints
OK / FAIL (with the fix) / SKIP for: config, key file, agent address (never the
key), endpoint, account exists, account mode, account value, agent approved for
the account, builder approval vs configured fee, builder account value >= 100
USDC, builder account mode, eligibility, daemon running. It only reads /info,
and only when you run it.
Account modes: OMX reads the account's Hyperliquid userAbstraction at
start and every 10 minutes. Standard accounts (disabled / default) use the
perp account value as equity. Unified accounts (unifiedAccount, the default
for users) keep one USDC balance in the spot clearinghouse, so OMX takes equity
from the spot USDC total. The docs do not say whether total already holds
the open positions' unrealized P&L; a testnet measurement (2026-11-05, 9 of 9
intervals: total moved with the unrealized P&L to 1e-6) shows it does, so the
equity is total itself. Positions always come from the
perp clearinghouse state. portfolioMargin, dexAbstraction or an unreadable
mode refuse new intents with ACCOUNT_MODE_UNSUPPORTED (kill and cancels still
work). Switching to Manual / Standard is optional; builder addresses must be
standard to accrue fees. python tools/measure_account_mode.py --config omx.toml --samples 10 --interval 30 (read-only, no key) prints both candidate equities
and, with an open position whose P&L moves, which one the venue uses.
Test wallets: python tools/new_test_wallet.py --out secrets/testnet_builder.key
creates a new throwaway key (never overwrites a file, restricts it to your
user) and prints only its address. Use it for test wallets only (a testnet
builder, a Base Sepolia payer), never for real funds.
Available Tools
9 toolsaccount_summaryB
Equity, day P&L (flows excluded), positions, open orders and remaining agent budget.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden; it does add one genuine detail — that P&L excludes flows — which is real context beyond structured fields. However, it says nothing about whether the summary is a point-in-time snapshot, whether the call is read-only, or any rate/permission constraints, leaving the safety profile unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence fragment with zero filler, and the most decision-relevant item (equity, P&L) is front-loaded. It is arguably under-specified rather than bloated, which is a different flaw already captured elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and a zero-param read tool needs little documentation. Still, in a trading-agent toolset with siblings covering limits, approvals and order status, the description should say what question this tool answers and when to prefer it, which it does not.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema baseline of 4 applies and there is nothing for the description to compensate for. No parameter meaning is lost.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description is a noun phrase enumerating returned data (equity, day P&L, positions, open orders, agent budget) rather than a verb+resource statement. It implies a read-only account snapshot and is roughly consistent with the name account_summary, but it never states the action, and offers nothing to distinguish it from siblings like policy_limits or order_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance at all: nothing says whether this should be called before preview_order/submit_order, or how it relates to policy_limits and order_status. The agent must infer usage purely from the listed fields.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
approval_statusB
State of a queued approval: pending, approved, rejected, expired, executed or failed.
| Name | Required | Description | Default |
|---|---|---|---|
| approval_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it does add real value by enumerating the state machine outcomes (pending, approved, rejected, expired, executed, failed), which implicitly tells the agent that pending is non-terminal and the others are terminal. It does not state that the operation is a read-only lookup, whether the result can change on re-poll, or what happens for an unknown or expired approval_id.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence, front-loaded with the resource and immediately followed by the value list. Every word earns its place; nothing is padded or repeated from the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, and the presence of an output schema removes the need to explain return values, so the short description is close to sufficient. It still leaves the agent without a source for approval_id and without confirmation that this is a non-mutating lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter approval_id has 0% schema description coverage and the description says nothing about it — not its format, nor where the agent obtains it (e.g. from a prior submit response). With low schema coverage the description was expected to compensate, and it does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource and the exact information returned ('state of a queued approval') and enumerates the possible values, so an agent can tell this is a status lookup rather than a mutation like submit_order or cancel_order. It lacks an explicit verb (e.g. 'returns'/'checks') and never mentions the sibling order_status, so differentiation is implied by the resource name rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance: nothing says to call this after submitting an approval, to poll while status is pending, or when to prefer order_status or get_quote instead. The only usage hint is implicit in the word 'queued'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_orderC
Cancel an intent this agent (same client name) created, and its resting children.
| Name | Required | Description | Default |
|---|---|---|---|
| intent_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose two useful behaviors: an authorization-like ownership restriction (same client name) and a cascading effect on resting children. It does not say whether cancellation is irreversible, what happens to partially filled intent, what error occurs if the intent belongs to another client, or whether the call is idempotent — significant gaps for a destructive mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the ownership constraint front-loaded and no filler. Slightly undermined by unexplained internal jargon ('resting children') that costs an agent a beat to interpret.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, but for an unannotated destructive mutation the description is thin: no irreversibility, failure modes, or idempotency, and it leaves the sole required parameter undefined.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter with 0% schema description coverage, so the description must compensate. It refers to 'an intent' generically but never explains what intent_id is, its format, or where the agent obtains it, leaving the only required argument undocumented in both places.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: cancel an intent and its resting children, with the scope qualifier that only intents created by this agent (same client name) qualify. That ownership qualifier helps separate it from kill_switch, though the description never names the sibling or clarifies the jargon 'resting children'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the ownership constraint (this is for your own intents, not everything), but there is no explicit when-to-use vs. when-not, and no pointer to alternatives such as kill_switch for a global stop or order_status for checking what remains.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_quoteB
Top of book, mid, data age and depth within the policy band for an agent-allowed coin.
| Name | Required | Description | Default |
|---|---|---|---|
| coin | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the burden, and it does add real context: data age signals staleness and 'within the policy band' implies the returned depth is filtered by policy limits. However, it never states that the call is a read-only operation, what happens when the coin is not agent-allowed, or any rate/latency characteristics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the returned fields and ends with the scoping constraint; nothing is redundant. As a sentence fragment it reads slightly terse, but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return field semantics are already covered, and the tool takes only one parameter. What remains missing is the accepted coin identifier format and the failure mode for disallowed coins, which for a pre-trade pricing call an agent will likely hit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single 'coin' parameter, so the description should clarify identifier format. 'Agent-allowed coin' usefully hints at a whitelist constraint on valid values, but it does not say whether a symbol, exchange-qualified pair, or internal ID is expected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names concrete data fields (top of book, mid, data age, depth) so the agent knows exactly what is returned, and 'for an agent-allowed coin' scopes the resource. It stops short of an explicit verb and does not distinguish itself from preview_order, which plausibly returns overlapping pricing data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of prerequisites, and no comparison to siblings such as preview_order or policy_limits. The agent must infer that this is a pre-trade read rather than a validation step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kill_switchA
Stop all new orders and cancel resting ones. Agents can turn it on, never off.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose the two facts that matter most: the action is destructive (cancels resting orders) and irreversible for agents (cannot be switched off). It omits the blast radius — whether it is account-wide or global — and whether open positions or fills are affected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the effect and followed by the constraint. Every clause adds information and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the core effect and irreversibility are covered. For an irreversible destructive halt with no annotations, however, the description leaves out scope, human override, and what exactly 'resting ones' covers.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needs to explain the single required 'reason' parameter, and it says nothing about it. The name is largely self-explanatory, which prevents a 1, but there is no guidance on format, whether it is logged, or why it is required for an already-irreversible action.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb plus resource and scope: 'Stop all new orders and cancel resting ones.' That clearly separates it from the single-order sibling cancel_order and from submit_order, even though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Agents can turn it on, never off' is a strong implicit warning that this is a last-resort action, which guides usage. But it never states the conditions that should trigger it versus cancel_order for a single order, nor any prerequisite such as approval_status or policy_limits checks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
order_statusC
Fill progress, average price, cost vs arrival mid, fees and block reasons of an intent.
| Name | Required | Description | Default |
|---|---|---|---|
| intent_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden: it never states that this is a read-only lookup, whether results are live or cached, or what happens with an unknown intent_id. The enumerated fields largely restate what the existing output schema already documents, so little behavioral context is added.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One compact sentence with no padding, which is appropriately sized. However, it is a verbless fragment dense with domain jargon ('cost vs arrival mid', 'block reasons') that an unfamiliar agent cannot parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one param) and has an output schema, so return values need not be explained. Still, with zero annotations and zero parameter documentation, the definition should say more about read-only semantics, data freshness, and overlap with approval_status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single required intent_id, and the description only implies the linkage via 'of an intent'. It does not say where an intent_id comes from, whether order/transaction IDs are also accepted, or what format is expected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description is a noun-phrase list of returned fields ('Fill progress, average price, cost vs arrival mid, fees and block reasons') with no verb, so the agent must infer that this reads status for an intent. The scope cue 'of an intent' is useful, but nothing distinguishes it from the close sibling approval_status. Purpose is inferable but not stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites (e.g., an intent_id must already exist from preview_order/submit_order), and no routing to alternatives such as approval_status or get_quote. The agent is left to guess the call site from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
policy_limitsA
Read-only view of the policy limits, agent thresholds and builder fee.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does declare the key safety trait: this is a read-only, non-mutating view. It also discloses the exact content returned (limits, thresholds, fees) rather than being a bare tautology, though it says nothing about permissions, rate limits, or whether limits are account-specific.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the mode (read-only) and the resource set are packed in without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and with zero input parameters the description only needs to convey purpose and safety — both of which it does. Nothing an agent needs before calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing to disambiguate and the baseline of 4 applies. The description does not need to compensate for any schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read-only view') and enumerates the exact resources exposed: policy limits, agent thresholds, and builder fee. This clearly distinguishes it from siblings like account_summary or approval_status, though it does not explicitly name those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied — an agent can infer this is the place to look up limits before submitting or previewing an order, but the description never states when to call it versus account_summary or approval_status, nor any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_orderA
Dry run: planned child orders, policy decisions, fee bound, and whether a human must approve. side: buy|sell. algo: market|limit|twap|pov|chase. size in base units. Sends nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| algo | No | twap | |
| coin | Yes | ||
| note | No | ||
| side | Yes | ||
| size | Yes | ||
| slices | No | ||
| limit_px | No | ||
| pov_rate | No | ||
| post_only | No | ||
| duration_s | No | ||
| reduce_only | No | ||
| max_slippage_bps | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full behavioral burden and does disclose the key trait: it sends nothing. It also says the response includes planned child orders, policy decisions, fee bound, and whether human approval is required, though it omits auth or rate-limit details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then gives compact parameter hints. Every sentence carries useful information, with no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return-value explanation is not strictly required, and the description does state the high-level preview contents. Still, for a complex 12-parameter trading tool with no annotations and zero schema descriptions, the description leaves substantial parameter and interaction detail unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 12 parameters, and the description only explains side values, algo values, and that size is in base units. It adds important enum and unit information missing from the schema, but leaves nine parameters such as slices, limit_px, pov_rate, duration_s, and max_slippage_bps undocumented beyond their titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb phrase, 'Dry run,' with the resource 'order,' and explicitly lists the preview outputs: planned child orders, policy decisions, fee bound, and human-approval need. It distinguishes itself from submit_order by stating 'Sends nothing,' so an agent can select it without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Dry run' framing and 'Sends nothing' clearly imply this is the safe preview path to use before submit_order. However, the description does not explicitly name submit_order as the alternative or state any conditions for when not to use the preview.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_orderA
Submit an intent. Above the approval threshold or the daily agent budget it is queued for a human and an approval_id is returned instead; check it with approval_status. ALWAYS pass a fresh client_intent_id (8..40 chars, A-Z a-z 0-9 _ -) and REUSE it when you retry after a timeout or error: a repeated id returns the existing intent (status "duplicate", intent_id "ag-<client_intent_id>") and never sends a second order.
| Name | Required | Description | Default |
|---|---|---|---|
| algo | No | twap | |
| coin | Yes | ||
| note | No | ||
| side | Yes | ||
| size | Yes | ||
| slices | No | ||
| limit_px | No | ||
| pov_rate | No | ||
| post_only | No | ||
| duration_s | No | ||
| reduce_only | No | ||
| client_intent_id | No | ||
| max_slippage_bps | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the approval-threshold and daily-budget queueing behavior, the existence of human approval, and the idempotency model including the 'duplicate' status and 'ag-<client_intent_id>' id format. It leaves out permission/auth requirements, whether orders are live or simulated, and rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The queueing/approval consequence is front-loaded, followed by the idempotency contract, with no filler sentences. The indentation is cosmetic noise but the content is dense and every clause conveys a distinct rule.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema means return shape needn't be explained, and the approval and duplicate-response behaviors are covered well. But for a 13-parameter mutation with zero schema descriptions and no annotations, the description is not complete enough: an agent still cannot tell what units size is in, what algo/slices/pov_rate do, or how limit_px vs post_only interact.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 13 parameters, and the description only documents client_intent_id (format constraints plus retry semantics). Core trading parameters like coin, side, size, algo, slices, pov_rate, limit_px, post_only, reduce_only and max_slippage_bps get no explanation at all, so the biggest gap in the definition remains unaddressed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ('Submit an intent') and immediately explains the queuing outcome, so an agent understands this places an order intent. It names approval_status as the follow-up tool, though it never distinguishes itself from preview_order or get_quote, leaving sibling routing partly to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit operational guidance: check a returned approval_id with approval_status, always supply a fresh client_intent_id, and reuse that id on retry after a timeout or error. What is missing is when to prefer preview_order or get_quote before calling this, so it stops short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
account_summary - First observed
approval_status - First observed
cancel_order - First observed
get_quote - First observed
kill_switch - First observed
order_status - First observed
policy_limits - First observed
preview_order - First observed
submit_order
TDQS
Scored across 9 tools
Each tool targets a distinct stage of the order lifecycle: pricing (get_quote), simulation (preview_order), execution (submit_order), approval state (approval_status), fill state (order_status), cancellation (cancel_order), and account/policy inspection. The boundary between preview_order and submit_order is explicitly clarified by the dry-run wording and 'Sends nothing' note. No two tools appear interchangeable.
Action tools follow a clean verb_noun snake_case pattern (get_quote, preview_order, submit_order, cancel_order), while read-only query tools use noun phrases (approval_status, order_status, account_summary, policy_limits). The split is readable and largely principled, though kill_switch and the noun-phrase group slightly break the single-pattern convention.
Nine tools is well-scoped for a trading execution agent, covering the full workflow without redundant operations. Each tool maps to a necessary step: quote, preview, submit, approval, status, cancel, kill switch, account, and policy.
The surface covers the core lifecycle including pre-trade simulation, approval handling, idempotent submission, cancellation, and emergency stop, with account and policy visibility. Minor gaps exist around amending orders and listing historical fills/open orders as dedicated operations, but these are workable via order_status and account_summary.
Maintenance
Related MCP Connectors
Description of my MCP server mega cool capabilities, lesgo
Related MCP Servers
- AlicenseCqualityDmaintenancetest server to see how clients handle a lot of tools3MIT
- MIT
- -
- -