MCP tools & resources
25 tools in the tria_trade_* namespace plus 8 auto-context resources. Each tool's input schema is discoverable via the MCP tools/list request — the LLM sees the same shape you do.
Tools
| Category | Tools |
|---|---|
| Orders (7) | place_order, place_batch, cancel_order, cancel_all_orders, modify_order, order_status, open_orders |
| Positions (3) | positions, close_position, attach_tpsl |
| Account (4) | balances, margin_state, account, fills |
| Market data (5) | markets, orderbook, candles, recent_trades, ticker |
| Risk (1) | scheduled_cancel |
| Helpers (1) | generate_client_order_id |
| Streams (4) | start_stream, read_stream, stop_stream, list_streams |
Each maps 1:1 onto a TriaClient method — see the SDK reference for argument shapes and venue behavior. place_order requires a clientOrderId (use generate_client_order_id for an HL-compatible 0x + 32-hex value); for market-style execution use tif: "ioc" with a crossing price.
Provisioning tools (gated)
| Tool | Authorization | When registered |
|---|---|---|
tria_trade_provision_inspect | none (read-only) | always — survey setup state without master authority |
tria_trade_provision | TRIA_TRADE_HL_MASTER_KEY at startup | only when the master key is present |
The write tool is gated on purpose: a deployment where the operator hands a trading env to someone else never exposes master-wallet authority to the LLM. Most users skip both and use the npx tria-trade-provision CLI.
Resources (auto-context)
Read-only URIs that MCP clients auto-fetch into the LLM's context without spending a tool call:
| URI | Returns |
|---|---|
tria://markets/{venue} | MarketInfo[] — full market listing |
tria://account/{venue} | AccountSnapshot — balances + margin + leverage + builder + network |
tria://positions/{venue} | Position[] — open positions |
tria://open-orders/{venue} | OrderStatus[] — resting orders |
{venue} is hl or decibel; the list is conditional on the venues you configured. No caching and no change-notifications in v1 — each read fetches live; for event-driven flow use streams.
Stream-handle protocol
MCP is request/response — there's no server-push channel for tools. The server keeps a per-handle event buffer the LLM drains at its own pace:
start_stream({ kind: "fills", venue: "hl" })
→ { handle_id: "stream_a1b2…", kind, venue, started_at }
read_stream({ handle_id, max_events: 50 })
→ { events: [...], more: true, last_seq: 123 }
stop_stream({ handle_id })
→ { stopped: true, events_seen: 123 }
Stream kind: fills, orders, account, positions. Defensive caps: 8 concurrent streams per process, a 1000-event ring buffer per handle (oldest dropped, surfaced as eventsDropped), and a 10-minute idle TTL that auto-stops a handle if read_stream isn't called. After a context compact, call list_streams() to re-discover open handles.
For truly continuous monitoring over hours, use the raw SDK — the 10-minute idle TTL means an agent must read regularly to keep a handle alive.
Common workflows
Real prompts that work end-to-end in Claude Desktop:
- "What's BTC doing on HL right now?" →
ticker({venue:"hl", market:"BTC"}). - "Show my open positions across all venues" → reads the
tria://positions/hl+tria://positions/decibelresources (no tool call). - "Place a $15 BTC long with TP +5% and SL −5%" →
ticker→markets(precision) →generate_client_order_id→place_order(crossing IOC) →attach_tpsl. - "Cancel all my orders on Decibel" →
cancel_all_orders({venue:"decibel"}). - "Watch for fills on HL for a minute" →
start_stream→ wait →read_stream→stop_stream→ summarize. - "Close my BTC position and tell me the PnL" →
close_position→fills→ agent computes PnL.
The agent's chain-of-thought is visible in the client UI — you can interrupt at any step.