跳到主要内容

Commands

Every command available at the REPL, alphabetical. For the size/price grammar that fills the <size> / <price> slots below, see Sizing & prices. For chain operators (; / &), loops, and conditionals, see Workflow.

Web vs standalone — most commands run identically in the in-app web CLI and the standalone binary. Exceptions are flagged with standalone-only. See Web CLI subset for the full split.


Trading​

buy / sell   (aliases b, s)​

Place a market, limit, or best-priced order on the focused symbol, with optional reduce-only / post-only / bracket stop.

FormResult
buy $100Market buy $100 notional
buy 100$Same — suffix form
buy 50%bal50% of free balance
buy SYMBOL $100Symbol override (leading or trailing)
buy WIF,ENA $100Multi-symbol fan-out (comma list)
buy $100 at 50000Limit at absolute price
buy $100 at +100 / at 1%Limit at relative / percent offset
buy $100 at 50000 reduceReduce-only limit
buy $100 at 50000 poPost-only limit
buy $100 bestLimit at best bid (buy) / best ask (sell)
buy $100 stop 49500Bracketed entry with attached stop loss

at is required for a limit order. buy 100$ 50000 is not a limit — there is nothing for the price to attach to, so it would be a market order with a stray number. Any leftover bare number is rejected with "did you mean at <price>?" regardless of size. This used to apply only to numbers ≥ 100, which meant a coin quoted in cents silently market-filled instead. fatfinger checks fire per-order.

Source: packages/cli-core/src/commands/trading/BuyCommand.ts, SellCommand.ts.


stop​

Reduce-only stop loss or take-profit. Decided by trigger price vs mark.

at is optional — stop 18500 and stop at 18500 do the same thing.

FormResult
stop 18500Market stop for full focused position
stop at 18500Same, with the optional at
stop -1%Relative to entry
stop buy at +100Explicit side (when hedge-mode is ambiguous)
stop $500 at 1%Partial-size stop
stop sell 0.01 at -100 ETHUSDTSymbol override
stop at -1% trigger 18500Limit stop — trigger ≠ limit price

Source: StopCommand.ts.


be​

Move the protective stop to break-even. Alias: breakeven.

Break-even is the price at which closing what is LEFT of the position leaves you flat overall — your entry, moved by whatever the position has already banked. Take $1,000 of profit on a 1-contract long from $50,000 and break-even is $49,000: you can exit that much lower and still come out even. The same $1,000 moves a short's break-even UP.

This places the stop at your ENTRY price. It does not account for profit already banked, so on a position you have taken partial profit on it is not the same number as the chart's B/E line.

That is a data problem rather than a missing feature. The venues that report a per-position realised figure disagree about what it means — some report a lifetime total for the symbol, some keep reporting it after the position has closed, some fold funding and fees in, and on inverse contracts it is denominated in the base currency. Placing a stop on any of those would be worse than placing it at entry.

FormResult
beStop at your entry price
be +3%3% above entry
be -0.5%0.5% below entry
be +100Absolute offset, same directions
be ETHUSDTSymbol override

An offset is relative to entry, not to the mark, and it is a plain direction rather than a side-aware one: + is always up the price axis. On a LONG, be +3% is the one you want — it puts the stop above entry and locks a little in. On a SHORT the profitable side is DOWN, so the same buffer is be -3%; be +3% there widens the stop instead of tightening it.

It cancels stop losses only — your take-profits are left alone. Writing this by hand as cancel stops; stop $entry does not do the same thing: cancel stops means "everything that is not a limit or a market", which includes every rung of a TP ladder.

If you are underwater, be warns you. Break-even on a losing position sits on the far side of the market, so the order becomes a reduce-only take-profit rather than a stop — and the stop it replaced has already been cancelled. The command says so plainly when that happens; it does not report "Stop moved" and leave you to find out.

Fees are not included, because a live position does not carry them — so this is break-even on price, and the round trip still costs you the taker fee. The chart's B/E line in the web app reads accumulated fee data the CLI cannot see, so the two can differ slightly for that reason.

Source: BreakevenCommand.ts.


trail​

A trailing stop on the open position — the "runner" leg. The stop follows the market and never moves against you.

FormResult
trail 20%Stop 20% behind the current price
trail 500Absolute distance
trail 20% ETHUSDTSymbol override
when (price >= 0.0716) (trail 20%)Arm it once price gets there

Distance is measured from the CURRENT price, not from your entry — that is what a trailing stop means to the venue.

The whole position trails. Bybit implements this through its position-level trading-stop endpoint, which takes no amount, so a partial-size runner is not expressible. Size the runner by taking profit on the rest first.

Not every venue has trailing stops. On one that does not, this refuses by name rather than sending an order the venue will reject.

Source: TrailCommand.ts.


close   (alias c)​

FormResult
closeFull close, focused symbol
close SYM,SYM2Full close, named symbols
close long / shortHedge-side disambiguator
close longs / shortsAll long / short positions globally
close all / allposEvery open position
close 50% / close $100Partial close of focused
close longs 50%Partial close of every long globally

Global variants (longs, shorts, all, allpos) honor the whitelist. Source: CloseCommand.ts.


cancel   (alias x)​

Filters compose: side × kind × reduce-only × position-selector × range × id.

FormResult
cancelAll orders, focused symbol
cancel ETHUSDTAll orders, named symbol
cancel buys / sellsSide filter
cancel limits / stopsKind filter
cancel ro / xroReduce-only / excluding reduce-only
cancel buys ro ETHUSDTCompose filters
cancel top 3 / bottom 5Sorted by price (top = highest)
cancel first 2 / last 1Sorted by last update
cancel from 49000 to 50000Price-range, limits only
cancel <id> / <id-prefix>Specific order (prefix ≥ 3 chars)
cancel <id1>,<id2>,…Comma list — what cancel @capturedVar becomes

Source: CancelCommand.ts.


bump​

Shift open limit orders by a price delta. Stops are untouched.

FormResult
bump +10Shift every limit by +10, focused
bump ETHUSDT +10Symbol override
bump buy +10 / sell -5Side filter
bump top 3 +5Top-N price selector
bump 100 --buysLegacy flag form — still accepted

Source: BumpCommand.ts.


move   (alias mv)​

Move a specific limit order by ID (full or unique prefix).

FormResult
move <orderId> 50000Absolute
move <orderId> +10 / -5Relative offset

Source: MoveCommand.ts.


scale​

Ladder N limit orders between two prices, split evenly.

scale <buy|sell> <size> into <N> from <p1> to <p2> [reduce] [taker] [SYMBOL]
ModifierEffect
reduceReduce-only
takerDrop the default post-only TIF
cubic / icubicAccepted but distribution is still even (no-op today).

Examples:

scale buy 10 into 10 from 31000 to 32000
scale sell $1000 into 25 from 50000 to 48500 reduce
scale buy $1000 into 10 from -0.25% to -1% ETHUSDT

Source: ScaleCommand.ts.


swarm​

Fire N concurrent market orders summing to <size>.

swarm <buy|sell> <size> into <N> [reduce] [irregular] [SYMBOL]
ModifierEffect
irregularRandomise slice weights in [0.5x..1.5x]
reduceReduce-only

Errors before any order is sent if a slice would round to zero. Source: SwarmCommand.ts.


chase​

Passive limit at top of book that re-pegs to best bid / ask. Runs as a background task — list with chasers, kill with kill <id>.

FormResult
chase buy $100Chase on focused symbol
chase sell 50% reduceReduce-only chase
chase buy WIF,ENA $100Multi-symbol fan-out
chase sell %all% 20% reduceAll positions on the implied side
chase buy $100 to 1%Terminate-at distance (price-walk guard)
chase buy $100 to 49500 / to $50Same, abs / dollar form
chase cancelStop newest active chaser + cancel rest order
chase cancel keepStop chaser but leave the order in book

Source: ChaseCommand.ts.


chasers​

FormResult
chasersList active + recent chasers
chasers cancel <id>Cancel by id-prefix
chasers cancel allCancel all chasers

Source: ChasersCommand.ts.


twap​

Spread an order over time. Three forms accepted.

twap buy <size> [SYMBOL] into <N> over <minutes> [reduce] [chaser]
twap chase buy <size> into <N> over <M> [reduce] [timeout <pct> <action>] [fail <action>]
twap buy <size> duration=1h slices=10 # legacy key=value form

twap chase runs a chaser per slice. Defaults: timeout 50% market, fail market. Action ∈ {market, next}. <pct> ∈ (0, 100].

ManagementResult
twap listList all TWAPs
twap stop <id-prefix>Stop by id-prefix
twap stop allStop all TWAPs

Gotcha: reduce is parsed and gates fatfinger checks, but is not yet threaded through to slice placement. Treat twap … reduce as a fatfinger-bypass marker, not a hard guarantee per slice.

Source: TwapCommand.ts.


nuke​

Cancel + close everything. Up to 3 retries internally.

FormResult
nuke / nuke allCancel all orders + close all pos
nuke positionsClose all positions only
nuke ordersCancel all orders only

Source: NukeCommand.ts.


leverage   (alias lev)​

FormResult
leverageRead (only if a position is open)
lev 5Set 5x on focused symbol
leverage 10 ETHUSDTSet 10x on named symbol

Strings like -5, 5x, 2..5 are rejected loudly. Source: LeverageCommand.ts.


max​

Largest possible order size given free balance × current leverage. Falls back to 1x with a note if no position is open. Source: MaxCommand.ts.


orders   (alias o)​

FormResult
orders / oOpen + creating orders, focused symbol
orders --all / -aMulti-account view across all symbols

Source: OrdersCommand.ts.


positions   (alias ps)​

FormResult
positions / psFocused symbol
positions long / shortSide filter
positions --all / -aMulti-account view, all symbols

Source: PositionsCommand.ts.


position   (aliases p, pos)​

Card-style display for a single position (size, entry → mark, uPnL, liq, leverage). pos btc accepts fuzzy symbol match. show modifier is a no-op. Source: PositionCommand.ts.


margin   (aliases balance, bal)​

FormResult
margin / balAccount margin / balance
bal --allMulti-account view

Source: MarginCommand.ts.


spot​

Spot balances when the exchange exposes them. spot --all for multi-account. Source: SpotCommand.ts.


last-price / mark-price / index-price​

Read live price from the focused or named ticker(s).

Aliases (in order)Reads
last-price, lp, llast trade
mark-price, mp, mmark
index-price, ip, iindex

All accept a trailing comma-separated symbol list. Source: PriceCommand.ts.


echo   (alias say)​

Print args after variable substitution. echo @hi does ratchet a tracker on read; print @hi does not. Source: EchoCommand.ts.


chart   (standalone-only)​

ASCII candlestick chart with position + open-order overlays.

FormResult
chart1h, 30 candles, focused
chart 15mTimeframe override
chart 4h 50Timeframe + bar count (capped at 100)
chart 1d ETHUSDTSymbol override

Source: ChartCommand.ts.


Session​

symbol   (aliases sym, switch)​

Change the focused symbol: switch BTCUSDT. Bare instrument typed at the prompt (BTCUSDT<enter>) is shorthand for this.

A bare ticker is resolved for you — sym btc focuses BTCUSDT. The suffix picks the settlement currency, so sym btcusd focuses the inverse contract and sym btcusdc the USDC one. A symbol the exchange doesn't list is rejected here rather than accepted and failing on your next order.

Source: SymbolCommand.ts.

markets   (aliases mkt, m)​

List available markets in a 4-column grid. Source: MarketsCommand.ts.

check​

Say what a listed contract is a claim on. Venues like Bybit list tokenized equities, ETFs, metals, and FX pairs beside crypto perps on the same endpoints with the same symbol shape — SHOPUSDT looks exactly like SOLUSDT and does not trade like it.

FormExample output
check BTCUSDTBTCUSDT on bybit: crypto perpetual
check SHOPUSDTSHOPUSDT on bybit: tokenized equity (SHOP) — may require signing a trading agreement
check XAUUSDTXAUUSDT on bybit: tokenized commodity — may require signing a trading agreement

check is a READ, not an eligibility check. The venue decides whether a given account may open a position on a non-crypto contract based on calendars and agreements; only the instrument's class is public. If the symbol argument is omitted, the focused session symbol is used.

Order writes (buy, sell, stop, scale, close, be) run the same preflight automatically and refuse before touching the venue when the symbol is non-crypto. Bybit's symbolType is read today; other venues report "classifier not implemented" and never refuse.

Source: CheckCommand.ts.

status   (alias st)​

Account / exchange / symbol of the current session. Source: StatusCommand.ts.

connection   (aliases conn, ws)​

FormResult
connWS health, current account
conn --allMulti-account
conn reconnect / ws reconnectForce a fresh WS connection

Source: ConnectionCommand.ts.

help   (aliases ?, h)​

help for general index, help <cmd> for a specific command.

prompt​

Configure the REPL prompt format. See Output → Prompt. Source: PromptCommand.ts.

clear   (alias cls)​

Clear screen.

login, logout, auth   (standalone-only)​

OAuth flow. whoami shows the current logged-in user. Listens on port 9876 for the OAuth callback.

logs / log / clearlogs   (standalone-only)​

FormResult
logsPrint the log file path
logs clear / clearlogsWipe ~/.tealstreet/cli.log

audit   (standalone-only)​

Durable, append-only log of write-ops (orders / cancels / closes / leverage). Off by default. When on, each write-op appends a JSON line to ~/.tealstreet/audit.log with timestamp, account, the command, and the result (ok + order IDs, or the error) — including failed attempts.

FormResult
auditShow status + log path
audit onEnable the write-op audit log
audit offDisable
audit tail [N]Print the last N entries (default 20)

Reads (positions / orders / watch / etc.) are never logged — only exposure-affecting writes. Script-driven writes are captured too: script:<name> internal write ops (orders, cancels, updates, closes, leverage) are logged (prefixed [script]) along with the named invocation. Every write from one typed line shares a runId (shown as run=<id> by audit tail), so all the orders from a repeat 10 or a single script run group together. Fills are attributed back to the order that produced them: when a tracked order fills, a [fill] entry is logged with the same runId and a ← <originating command> pointer (unattributable fills — placed before auditing was on, or in a prior process — are skipped). The log is append-only but size-capped: past ~5 MB the live audit.log rolls to audit.log.1 (one backup) so disk use stays bounded; audit tail reads from the end and dips into the backup when needed. Source: audit-log.ts, script-adapter.ts.

Controls the persistent bottom status footer — a pinned line at the bottom of the terminal, above which your prompt and output live, showing always-on live data (connection, account, symbol, balance, PnL, clock, …). It updates in place ~once a second and is a glanceable companion to the transient top alert bar. On by default — footer off opts out (persisted). The setting + layout live in ~/.tealstreet/config.json (footer block — see config files).

FormResult
footerShow on/off state + the current segment layout
footer on / footer offEnable / disable the footer (persisted)
footer listList the configured segments with their indices
footer resetReset the layout to the default set
footer add <type> [right]Append a segment, optionally to the right-aligned group
footer add script <name> [right]Append a custom-script segment (see below)
footer remove <index>Remove the segment at the given index

Built-in segment types: connection, account, symbol, balance, pnl (focused-symbol uPnL $ + %), totalpnl, position, mark, last, funding, clock, version (the CLI version — in the default layout; footer remove it if you don't want it), text. All read already-streamed state — no extra API calls. Each segment can set group (left / right) and a color override in the config file.

script segments show the return value of one of your custom scripts: footer add script <name> runs the named script ~once a second and renders the string it returns. These runs are hard read-only — capabilities are forced so the script cannot place or cancel orders or call runCommand (any such call fails); only reads work. They're also silent (the script's print() output is suppressed — only the return value is used) and time-boxed (a slow or throwing script shows a small error token like !myfooter and never blocks the footer).

Example footer script (~/.tealstreet/scripts/risk.ts):

export const meta = { name: 'risk', targets: ['core', 'cli'], capabilities: { accounts: [], writes: [] } };
export default function (_args, api) {
const p = api.getPositions()[0];
return p ? `risk ${p.notional.toFixed(0)}` : 'flat';
}

Source: footer.ts, footer-segments.ts, scroll-region.ts, repl.ts (runFooterScript).

update   (standalone-only)​

update runs the binary updater. update --check / -c does a version check only.

exit / quit   (standalone-only)​

Stops monitors, listener, exchanges, then process.exit(0).


Accounts​

account   (aliases acc, use)​

FormResult
account mybybitSwitch focused account by name
account 1 / account -# 1By 1-indexed number
account enable acc1 acc2Start streaming for named accounts
account enable --allStart streaming for every account
account disable acc1 / --allStop streaming

Source: AccountCommand.ts.

accounts   (alias config)​

FormResult
accounts / accounts listList all configured accounts
accounts add -n <name> -e <ex> -k <key> -s <secret>Add — use --tealstreet-proxy [--proxy-region <region>] to match web "Use Tealstreet IPs"
accounts add -n <name> -e paradex -k <subkey-private-key> --paradex-address <addr> --subkey-address <addr>Add Paradex with the same credential fields as web
accounts import <json>Import from web export JSON
accounts remove <name> / --allRemove (tombstoned for 30 days)
accounts enable <name…> / disable <name…> / --allBulk streaming control
accounts enabled / streaming / activeList only streaming accounts
accounts helpFull reference

Manual account creation is validated by the shared safe-cex account contract used by web. Exchange-specific fields include --passphrase, --application-id, --api-key-index, --omni-key-seed, --paradex-address, --subkey-address, --subaccount, --grvt-signer-address, --grvt-trading-account-id, --vault, --tealstreet-tunnel, and --tealstreet-ws-route.

Source: AccountsCommand.ts.

exchanges   (alias ex)​

List supported exchanges with required credential fields. Source: ExchangesCommand.ts.


Tasks (in-process)​

tasks​

Unified list of in-process chasers, TWAPs and armed when triggers.

Triggers are listed first, and deliberately: bare kill takes the most recent active task, which has always meant the chaser or TWAP you just started.

kill   (aliases fuck, terminate)​

FormResult
killMost-recent active task (see below)
kill lastSame
kill <id-prefix>By id-prefix — this is how you drop a trigger
kill allEvery running task, triggers included

Because triggers are listed first, bare kill reaches a chaser or TWAP whenever one is running. It only ever targets a trigger when nothing else is active — name the id if you mean a specific one.

Source: KillCommand.ts. fuck / terminate are ichibot-parity aliases.


History​

history​

FormResult
historyLast 50 commands
history 100Last N — capped at 200

Source: HistoryCommand.ts.

Persisted to ~/.tealstreet/cli_history (standalone) or a jotai atom (web).


Variables, aliases, workflow​

Defined and detailed in their own pages — listed here for completeness:


Safety​

Defined in Safety. Listed here:

  • simulation / sim / dry-run
  • fatfinger / unfatfinger
  • budget — cumulative notional cap (budget $5000 / budget off / budget reset)
  • whitelist / unwhitelist

Watch modes   (standalone-only)​

AliasLong formsShows
wawatch account, watch accMargin + positions + orders combo
wpwatch positions, watch posLive positions table
wowatch orders, watch ordLive orders table
wmwatch margin, watch balance, watch balLive margin
—watch chart   (shorthand watch c …)Live ASCII chart
—watch chaseLive chaser status panel

All of wa/wp/wo/wm accept --all / -a for multi-account view. Exit: Escape or Ctrl+X. Refresh: 1000 ms.

See Output → Watch modes for terminal-recovery quirks.


Listener subsystem   (standalone-only)​

Detailed in Operations → Listener and Hooks & webhooks. Listed here:

  • hook / hooks / hook create / hook revoke / hook rotate / hook show
  • clients / clients list / clients revoke

Cross-trade   (standalone-only)​

Detailed in Operations → Cross-trade. Top-level binary surface:

FormResult
tealstreet cross-trade listList configs in ~/.tealstreet/cross-trade.json.
tealstreet cross-trade add --master <a> --copier <b> [--symbol] [--mode] [--enabled]Add a single-copier config. --mode ∈ LimitSlippage | Market | Chase (Chase skipped on CLI).
tealstreet cross-trade enable <id> / disable <id> / remove <id>Mutate by id prefix (8 chars matches one row).
tealstreet cross-trade runForeground daemon. Boots accounts, runs the engine, blocks until SIGINT.
tealstreet cross-trade statusRead the heartbeat and print running/not + uptime + active configs.

Recording   (standalone-only)​

Detailed in Operations → Recording. REPL surface:

FormResult
record <exchange>Start orderbook recording
record start <exchange>Same — explicit
record stop <exchange>Stop recording
record listList configured recordings
record stats [exchange]DB stats

Alias: rec.


Import / export​

FormResult
exportWrite vars + aliases to ~/.tealstreet/cli-export.json
importRead same — replaces current vars + aliases

Distinct from tealstreet account export/import, which dumps credentials.


Scripts   (standalone-only)​

Scripts live in ~/.tealstreet/scripts/ — one .ts file per script. Open the directory in your editor for full IntelliSense via the seeded tsconfig.json + types.d.ts. Full layout in Operations → Config files → Scripts.

FormResult
script:<name>   (e.g. script:hello)Run the loaded script. The script: prefix is required — bare <name> is never resolved to a script. Args after the name are parsed and handed to the script as args. Composes with retry N, @<x> = , set ec, chain operators, and webhooks.
script reload   (or scripts reload)Re-scan ~/.tealstreet/scripts/ and rebuild the in-memory registry. Edits to script files don't auto-reload — run this after saving.

Grammar: script:<name> with no space after the colon. script: foo is a parse error. script: with no name is a parse error. Invoking a name the loader didn't find errors loudly — it does NOT fall through to the regular command dispatcher.

Why a prefix? Eliminates every name-collision case. Filenames like ~/.tealstreet/scripts/buy.ts are legal; the builtin buy keeps working. Future CLI upgrades adding new builtins never silently shadow existing user scripts.


The tealstreet binary​

The CLI is also a standard command-line tool. With no args, it starts the REPL. With a subcommand, it runs one-shot.

Top-level flags​

FlagEffect
-v / --versionPrint version and exit
--updateTrigger updater
--check-updateVersion-check only
--disable-allStart REPL with all exchanges disabled

Subcommands​

SubcommandAliasesPurpose
interactive (default)iLaunch REPL. -a <name>, --simple, --disable-all accepted
exec <command…>—One-shot. -a <account>, -s <symbol> for context scoping
buy / sell / close / cancel / scale / chase / nuke / balance / stop—Shorthand wrappers around exec <verb> …. All accept -a / -s
login / logout / authwhoami (for auth)Sign in through the browser, sign out, show who is signed in
account (group)accountslist / add / remove / default / symbol / exchanges / import / export
cross-trade (group)crosstradeManage and run the cross-trade engine (configs at ~/.tealstreet/cross-trade.json)
tasks list / tasks clear—Persisted tasks from ~/.tealstreet/tasks.json (see warning below)
record (group)—start / stop / list / stats
update—-c / --check for check-only
logslog-c / --clear, -n <N> lines
mcp—Run as an MCP server over stdio — see MCP server below

tealstreet tasks is different from REPL tasks. Top-level reads persisted task records from ~/.tealstreet/tasks.json. REPL tasks lists live chasers + TWAPs from memory. Don't conflate them.

One-shot exec commands that start TWAPs keep the process alive until those TWAPs finish, then disconnect the exchange session.

Source: apps/cli/src/index.ts.


MCP server   (standalone-only)​

tealstreet mcp runs the CLI as an MCP server over stdio, so an AI assistant (Claude Code, Claude Desktop, …) can read, write, and validate your scripts, inspect local account state, and read Tealstreet data tools.

Register it with your MCP client — for Claude Code:

claude mcp add tealstreet-scripts -- tealstreet mcp

You must be logged in. Run tealstreet login (or login inside the REPL). The MCP server exits immediately with not logged in on stderr rather than starting and letting each tool fail separately, since an assistant would otherwise keep retrying instead of telling you to log in. If your MCP client reports the server as failed, check your login first — tokens expire.

Tools​

ToolPurpose
list_scriptsEvery script on disk, including ones that currently fail to load
read_scriptOne script's source — works even when the script is broken
get_api_typesThe exact TypeScript surface available to scripts (core / cli / web / mobile / all)
validate_scriptTypecheck + capability check without writing. Fast, local, free
write_scriptCreate or replace a script. Validates first and refuses to write invalid source
delete_scriptDelete a script
export_scriptsExport your own scripts as a portable JSON bundle (backup / moving machines)
list_accountsConfigured accounts — names and exchanges only, never credentials
get_positions / get_orders / get_balance / get_ticker / get_tickers / get_markets / get_orderbookLive reads for an account, returned as JSON
run_scriptDry run only — see below
list_market_data_sourcesPublic Tealstreet data sources and publicdata exchange health
get_public_tickers / get_public_tickerPublic ticker snapshots from Tealstreet publicdata
get_top_movers / get_top_volume / get_top_fundingPublic market top lists from Tealstreet publicdata
get_exchange_proxy_candlesHistorical candles through data.tealstreet.io's public candle service
get_recent_newsPublic normalized TealNews items through news.tealstreet.io's recent-news endpoint
get_safe_cex_markets / get_safe_cex_marketSafe-cex market metadata through data.tealstreet.io's public candle service
get_mcp_context_dsl_referenceSelf-contained mcp-context/v1 DSL, scope, refresh, callback and dashboard reference
list_mcp_context_planes / plan_mcp_context_queryPlan composable mcp-context/v1 dashboard queries into bounded MCP tool steps
get_polymarket_events / search_polymarket_eventsPublic Polymarket prediction-market events and search
get_polymarket_midpoints / get_polymarket_order_book / get_polymarket_price_historyPublic Polymarket CLOB data, with bounded book depth
screen_prediction_markets / get_prediction_eventPrediction markets filtered by implied probability, window and liquidity; one event with normalized probabilities
find_prediction_arbitrage / get_prediction_resolution_calendarMutually exclusive sets buyable below 1.00 at the ask; where settlements cluster
get_prediction_liquidity_profileSpread, resting depth and exitable size for one outcome token
get_hyperliquid_leaderboardCrawled Hyperliquid leaderboard rows, when analytics DB env vars are configured
get_onchain_address_portfolioPublic positions held by one address at one venue, in a venue-neutral shape with a bounded max-loss summary
get_prediction_address_exposureOne public Polymarket address as exposure: holdings, worst case, same-market offsets and a resolution calendar
get_hyperliquid_address_positions / get_hyperliquid_address_fills / get_hyperliquid_address_value_curveCrawled public Hyperliquid address analytics (take a public address), when analytics DB env vars are configured

What it will refuse​

write_script runs the same checks as validate_script and will not write a file that fails any of them:

  • Value imports. import { OrderSide } from '@tealstreet/script-api-core' typechecks but fails at load, because scripts run from a directory with no node_modules. Use import type for types and api.constants.* for values.
  • Undeclared capabilities. Every api.exchange.* method the body calls must appear in meta.capabilities.writes. closePosition additionally requires placeOrder.
  • Top-level calls. Code outside the default-exported function runs when the CLI loads the scripts directory, not when the script is invoked. Declarations (types, helper functions, const config) are fine.

This is stricter than editing a file by hand on purpose: a script an assistant wrote is code you have not read.

run_script is dry-run only​

run_script executes a script against live market data but every write — placeOrder, cancelOrder, runCommand, everything — is recorded and returned as an intent rather than executed. Nothing this server can do places a real order.

You get back the full list of what the script would have done, which is the useful part; a mechanism that simply refused at the first write would tell you about one action and nothing else.

To actually run a script, run script:<name> yourself in the REPL.

Two caveats worth knowing:

  • Dry run bounds a script's api.* calls. It is not a sandbox — scripts execute with full runtime globals, so a script that reaches outside the API entirely is unaffected. run_script therefore refuses to run source that doesn't validate.
  • The server connects accounts on demand and never writes active back to your config, so it cannot disturb a REPL running alongside it.

There is no import tool, on purpose​

export_scripts exists; a matching import does not. Exporting your own scripts is a backup. Installing scripts written by someone else is a different proposition entirely: scripts currently run on the same boundary as code you wrote yourself, reaching fetch, localStorage and your session. Third-party scripts wait for the worker sandbox.

If you want to move a bundle to another machine, paste each script through write_script — it validates first, and you see what it declares before it lands.

Notes​

  • Local only. stdio transport, no network listener. It does not expose your accounts to anything but the MCP client you launched it from.
  • Data reads may call Tealstreet services. Public market tools make outbound HTTPS calls to Tealstreet publicdata. Hyperliquid analytics tools read a Postgres analytics database only when you set HYPERLIQUID_ANALYTICS_DATABASE_URL or HYPERLIQUID_ANALYTICS_POSTGRES_*; otherwise they return a configuration error.
  • Context-query tools plan, they do not execute. Start with get_mcp_context_dsl_reference when an MCP client needs the self-contained DSL, scope semantics, callback contract, refresh metadata and dashboard piping instructions. plan_mcp_context_query compiles the allowlisted mcp-context/v1 DSL into MCP tool steps plus dashboard widget metadata (queryHash, refresh policy and required scopes) so an agent can pipe results into an MCP dashboard or refresh it on a polling interval. The stdio runtime rejects hosted-only private planes.
  • Credentials are never exposed. list_accounts returns an explicit allowlist (name, exchange, testnet, connected) — never the stored keys.
  • Script writes, deletions, and dry runs are recorded in the audit log tagged [mcp], so agent activity is distinguishable from your own after the fact. A dry-run entry carries the number of write intents the script attempted — that count is what makes a run worth reviewing later.
  • Scripts are not executed by this server — write them here, run them from the REPL with script:<name>.

Source: apps/cli/src/mcp/.


Multi-symbol fan-out​

Most trading commands accept a leading comma-separated symbol list:

buy WIFUSDT,ENAUSDT $100
chase sell %all% 20% reduce
last-price BTC,ETH,SOL

%all% (in chase … reduce only) expands to every position on the implied side. See Recipes → Fan out across symbols.


Notes on accepted-but-no-op surface​

A few keywords are accepted by the parser but don't yet have runtime effect. Treat them as "doesn't break the command":

  • scale … cubic / … icubic — accepted, distribution still even.
  • twap … reduce — accepted; gates fatfinger but not slice placement.
  • import payload's binds field — read but discarded (reserved for hotkeys).