tradingcli
A local paper-trading MCP server for stocks, ETFs, crypto, FX, futures, and options — covering accounts, orders, positions, market data, watchlists, research, and admin tooling.
Accounts & cash — create, list, rename, set/get default, deposit, withdraw, view account details and multi-account summaries.
Positions & P&L — list/get/close positions (whole or partial), close all, mark-to-market P&L, and account activity (fills, transfers, dividends, splits, option events).
Order lifecycle — submit (market/limit/stop/stop-limit/trailing/bracket/OCO/OTO), get, replace, cancel, cancel all; preview and dry-run with risk checks; TIF, extended hours, client order IDs.
Options — buy/sell contracts, parse OCC symbols, browse option chains by expiry/strike.
Futures — list supported symbols with multipliers and margin.
Market data — bars, latest quote, snapshots, bulk quotes, symbol validation, search, news, movers, most actives, quotes streaming, market status, trading calendar.
Watchlists — create, list, get, add, remove, delete, and pull live quotes.
Performance & research — portfolio performance (return, CAGR, Sharpe, Sortino, vol, max DD) and backtesting of current holdings via backtesting.py.
Admin & audit — config get/set/list/delete, events polling, audit log, healthcheck, database backup, MCP catalog introspection.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tradingcli Run a backtest on my current holdings"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
📈 Trading CLI
Local, multi-account paper-trading engine for humans and AI agents. Live terminal dashboard, Alpaca-style orders, REST + MCP server. SQLite state, Yahoo Finance market data. Simulation only — never places live brokerage orders. 🚫💸
🧺 Assets | 🛠️ Engine |
Stocks / ETFs / crypto ( |
|
⚙️ Setup
Requires Python 3.10+ and Bun >=1.4.1 (the tradingcli-tui dashboard runs on Bun + OpenTUI).
# from source
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # or: pip install -e .
(cd tui && bun install) # TUI deps (Bun + OpenTUI)
# isolated tool install (uv)
uv tool install .🗄️ Database defaults to ~/.papertrade.db; override with PAPERTRADE_DB=/tmp/test.db or PAPERTRADE_DB=:memory: for isolated in-memory tests.
Related MCP server: tastytrade-mcp
🚀 Run
# first-run wizard + live TUI dashboard 🖥️ (Bun + OpenTUI)
python3 papertrade.py # or: tradingcli
# explicit dash
python3 papertrade.py dash # or: tradingcli dash (or: tradingcli-tui)
# legacy Rich dashboard
python3 papertrade.py dash --rich# headless snapshot for agents / scripting 🤖 (single JSON envelope, no TTY)
tradingcli-tui --headless --json snapshot
tradingcli-tui --headless --json snapshot -a mybook
tradingcli-tui --headless --json backtest -a mybook --lookback-days 1825👛 Accounts
python3 papertrade.py new mybook --cash 50000
python3 papertrade.py accounts --json
python3 papertrade.py use mybook💹 Trade → inspect
python3 papertrade.py buy AAPL 5 -a mybook
python3 papertrade.py positions -a mybook --json
python3 papertrade.py market --json🔄 Alpaca-style order lifecycle
python3 papertrade.py order submit AAPL --side buy --qty 10 --type limit --limit-price 185 -a mybook
python3 papertrade.py order submit AAPL --side sell --qty 10 --type trailing-stop --trail-percent 3 -a mybook
python3 papertrade.py order get --order-id 2 --json # pending limit from above
python3 papertrade.py order replace 2 --limit-price 184
python3 papertrade.py order cancel-all -a mybook
python3 papertrade.py order submit AAPL --side buy --qty 10 --type limit --limit-price 180 --dry-run --json
python3 papertrade.py position close AAPL --percent 50 -a mybook
python3 papertrade.py position close-all -a mybook🧷 Brackets, options, watchlists, research
# bracket / OCO / OTO — use --take-profit / --stop-loss / --stop-loss-limit
# options / chain / watchlists / research
python3 papertrade.py option get AAPL270115C00100000 --json
python3 papertrade.py option exercise AAPL270115C00100000 -a mybook
python3 papertrade.py chain AAPL 2027-01-15
python3 papertrade.py watchlist create Tech --symbols AAPL,MSFT,NVDA -a mybook
python3 papertrade.py watchlist quotes Tech -a mybook --json
python3 papertrade.py data bars AAPL --timeframe 1Day --limit 30 --json
python3 papertrade.py data snapshot AAPL --json
python3 papertrade.py data movers --json
python3 papertrade.py calendar --start 2026-07-01 --end 2026-07-31 --json
# backtest current holdings as a retrospective (see notes below)
python3 papertrade.py backtest -a mybook --lookback-days 1825 --commission-bps 10 --json🤖 Every command accepts one automation flag: --json / --csv / --quiet. --schema prints the command tree without touching market data; doctor checks DB integrity.
Press g in the TUI to open 📊 Backtesting & Graphs — live equity curve beside a backtesting.py current-holdings backtest (return, CAGR, vol, Sharpe, Sortino, costs, maxDD). Universe is the selected account's open positions; 6m / 1y / 2y / 5y / 10y / max presets or exact days. CAGR uses real calendar elapsed time; options appear as skipped (no point-in-time chain history); futures use continuous series without roll costs. Curves are time-weighted, so deposits/withdrawals don't masquerade as alpha. The result has intentional look-ahead/survivorship bias — it's a "what if we held today's book" retrospective, not an OOS strategy test. Yahoo adjusted closes are used; crypto top-of-book is indicative.
🕸️ Web UI (unsupported)
static/ excluded from the wheel; web_ui.py retained but unsupported — use the TUI, CLI --json, or MCP server instead.
🔌 MCP server (for Claude Code / Cursor / Hermes)
Preferred surface for AI agents — typed, idempotent, single DB contract.
python3 mcp_server.py # core — 60 tools (default, safe)
PAPERTRADE_MCP_PROFILE=advanced python3 mcp_server.py # 72 tools — adds destructive/specialist ops
PAPERTRADE_MCP_PROFILE=full python3 mcp_server.py # 79 tools — adds legacy aliases (buy/sell/quote/…)
PAPERTRADE_MCP_RESPONSE_FORMAT=json python3 mcp_server.py # force JSON contract
# or via entry point after pip install -e .
tradingcli-mcpcore responses use {"ok": true, "data": …} / {"ok": false, "error": {"code": "…", "message": "…"}}. mcp_catalog reports the active profile + tool list. Mutating tools take idempotency_key + agent for safe retries.
Client config 🔧 — copy .mcp.json to your client's MCP config and fix the path:
{
"mcpServers": {
"papertrade": {
"command": "python3",
"args": ["/absolute/path/to/Trading-CLI/mcp_server.py"],
"env": { "PAPERTRADE_MCP_PROFILE": "core" }
}
}
}For agents importing as a library instead of MCP, see docs/agent-guide.md.
✅ Verify
Tests are standalone scripts (no pytest needed):
python3 test_papertrade.py
python3 test_backtesting.py
python3 test_performance.py
python3 test_concurrency.py
python3 test_mcp_server.py
python3 test_mcp_profiles.py
python3 test_dashboard.py
python3 test_alpaca_parity.py
python3 test_cli.py
python3 test_edge_cases.py
python3 test_market_data.py
python3 test_mcp_features.py
python3 test_invariants.py
python3 test_tui_parity.py
python3 test_quote_cache.pybun test ./tui/tests/tradingcli config list
tradingcli config set myapp.threshold 42
tradingcli events --since-id 0 --limit 20 --json
tradingcli export -a mybook --format parquet --output mybook.parquet
tradingcli perf -a mybook --benchmark SPY --jsonYahoo Finance supplies market data. Historical quote/trade series and crypto top-of-book are explicitly marked aggregated/indicative — not exchange tick tapes or full depth.
Available Tools
60 toolsaccount_activityC
Unified account fills, orders, transfers, dividends, splits, and option events.
Inputs: account (required), end, limit, start, +1 more. Returns: result
account_createC
Create an account. Reuse idempotency_key safely when retrying the same mutation.
Inputs: name (required), cash, agent, idempotency_key. Returns: result
account_detailsC
Account balances, configured risk limits, and open-position count.
Inputs: account (required). Returns: result
account_listA
List all paper accounts and their cash balances.
Inputs: no named parameters. Returns: result
asset_searchB
Search Yahoo Finance for matching symbols, asset types, and exchanges.
Inputs: query (required), limit. Returns: result
audit_logA
Paginated mutation audit trail with agent and idempotency attribution.
Inputs: limit, offset, account. Returns: result
bulk_quotesA
Fetch up to 50 comma-separated live symbols concurrently.
Inputs: symbols (required). Returns: result
buy_optionA
Buy an option. expiry is YYYY-MM-DD, kind is 'C' or 'P', contracts x100 shares. Market order unless limit (premium) is given. Use option_chain to find valid expiries/strikes.
Inputs: kind (required), expiry (required), strike (required), account (required), +5 more. Returns: result
config_deleteC
Delete a config key.
Inputs: key (required), agent, idempotency_key. Returns: result
config_getC
Get a config value.
Inputs: key (required). Returns: result
config_listA
List all config keys.
Inputs: no named parameters. Returns: result
config_setC
Set a config value.
Inputs: key (required), value (required), agent, idempotency_key. Returns: result
database_backupA
Create a consistent online backup under ~/.papertrade_backups.
Inputs: no named parameters. Returns: result
depositB
Add cash to a paper account.
Inputs: amount (required), account (required), agent, idempotency_key. Returns: result
eventsA
Poll unified audit/order events since an id. For agents to replace polling with incremental sync.
Inputs: limit, account, since_id. Returns: result
futures_symbolsA
List supported futures symbols with their contract multiplier and initial margin.
Inputs: no named parameters. Returns: result
get_default_accountA
Return the account used when CLI/TUI calls omit an explicit account.
Inputs: no named parameters. Returns: result
healthcheckA
Check SQLite integrity, WAL mode, schema version, and core record counts.
Inputs: no named parameters. Returns: result
market_barsC
Historical OHLCV bars from Yahoo Finance.
Inputs: symbol (required), end, limit, start, +1 more. Returns: result
market_latest_quoteC
Latest bid, ask, and last indication.
Inputs: symbol (required). Returns: result
market_most_activesD
Current most-active equity screener.
Inputs: limit. Returns: result
market_moversC
Current day gainers and losers.
Inputs: limit. Returns: result
market_newsC
Recent symbol news headlines and links.
Inputs: symbol (required), limit. Returns: result
market_snapshotC
Combined latest quote, daily bar, previous close, and change.
Inputs: symbol (required). Returns: result
market_statusA
Holiday/early-close-aware NYSE status and next open/close time.
Inputs: no named parameters. Returns: result
mcp_catalogA
Describe the active catalog, response contract, profiles, and legacy aliases.
Inputs: no named parameters. Returns: result
option_chainA
List option expiries for an underlying, or near-the-money strikes for one expiry (YYYY-MM-DD).
Inputs: underlying (required), expiry. Returns: result
option_contractA
Parse and quote one OCC option contract.
Inputs: symbol (required). Returns: result
order_cancelB
Cancel one pending order by id; canonical counterpart to order_cancel_all.
Inputs: order_id (required), agent, idempotency_key. Returns: result
order_cancel_allA
Cancel every pending/held order, optionally restricted to one account.
Inputs: agent, account, idempotency_key. Returns: result
order_getA
Get one order by numeric id or by account plus client order id.
Inputs: account, order_id, client_order_id. Returns: result
order_replaceA
Replace selected fields on a pending order and return the new order id.
Inputs: order_id (required), qty, agent, trail, +5 more. Returns: result
ordersB
List paginated order history, including source agent and idempotency key.
Inputs: account (required), limit, offset. Returns: result
order_submitC
Submit market, limit, stop, stop-limit, trailing, bracket, OCO, or OTO orders.
Inputs: side (required), symbol (required), account (required), qty, +16 more. Returns: result
performanceB
Portfolio performance since inception: return, CAGR, Sharpe, Sortino, volatility, max drawdown. Reconstructs a daily equity curve from the trade/cashflow ledger and real historical prices.
Inputs: account (required). Returns: result
pnlA
Mark-to-market P&L report for an account: positions, unrealized P&L, cash, total equity.
Inputs: account (required). Returns: result
portfolio_backtestA
Backtest the account's current open positions and cash with backtesting.py.
The universe is read from this account's SQLite positions, options without reliable continuous history are reported as skipped, and results include the equity curve, return, CAGR, volatility, Sharpe, Sortino, and drawdown. The default window is five years; request up to 36500 calendar days. This is a current-holdings retrospective, not an out-of-sample strategy test.
Inputs: account (required), end, start, lookback_days, +1 more. Returns: result
position_closeB
Close all or part of one position by quantity or percentage.
Inputs: symbol (required), account (required), qty, agent, +2 more. Returns: result
position_close_allB
Liquidate every open position in an account at current market prices.
Inputs: account (required), agent, idempotency_key. Returns: result
position_getA
Get one live-marked position with market value and unrealized P&L.
Inputs: symbol (required), account (required). Returns: result
positionsA
List open positions (symbol, side, qty, avg cost, asset class) for an account.
Inputs: account (required). Returns: result
preview_orderA
Dry-run an order against cash, margin, short, naked-option, and leverage limits.
Inputs: qty (required), side (required), symbol (required), account (required), +1 more. Returns: result
quotes_streamA
Poll live quotes N times at an interval; returns list of snapshots for a simple stream without WebSocket.
Inputs: symbols (required), snapshots, interval_sec. Returns: result
rename_accountA
Rename a paper portfolio. Updates positions, orders, history, and the default pointer.
Inputs: new (required), old (required), agent, idempotency_key. Returns: result
risk_getA
Show the account's shorting, naked-option, leverage, and order-size limits.
Inputs: account (required). Returns: result
risk_setB
Change selected account risk limits; omitted fields retain their current values.
Inputs: account (required), agent, allow_short, clear_max_order, +4 more. Returns: result
sell_optionB
Sell/write an option (opens a short if not covering). Same params as buy_option.
Inputs: kind (required), expiry (required), strike (required), account (required), +5 more. Returns: result
set_default_accountA
Set the default portfolio used by the CLI and dashboard when no account is specified.
Inputs: name (required), agent, idempotency_key. Returns: result
summaryA
One-line-per-portfolio snapshot for all accounts: cash, equity, unrealized P&L, position count. Fast overview for deciding which account to act on.
Inputs: no named parameters. Returns: result
tickA
Check all pending limit orders against current prices and fill any that crossed.
Inputs: no named parameters. Returns: result
trading_calendarB
List NYSE sessions, including holidays and early closes.
Inputs: end, start. Returns: result
validate_symbolC
Validate a symbol and return its live price, class, multiplier, and margin.
Inputs: symbol (required). Returns: result
watchlist_addB
Add a symbol to a persistent watchlist.
Inputs: symbol (required), account (required), watchlist (required), agent, +1 more. Returns: result
watchlist_createB
Create a persistent named watchlist with comma-separated symbols.
Inputs: name (required), account (required), agent, symbols, +1 more. Returns: result
watchlist_deleteC
Delete a persistent watchlist.
Inputs: account (required), watchlist (required), agent, idempotency_key. Returns: result
watchlist_getC
Get one named watchlist or numeric watchlist id.
Inputs: account (required), watchlist (required). Returns: result
watchlist_listB
List an account's persistent watchlists.
Inputs: account (required). Returns: result
watchlist_quotesA
Return live quotes for every symbol saved in a watchlist.
Inputs: account (required), watchlist (required). Returns: result
watchlist_removeB
Remove a symbol from a persistent watchlist.
Inputs: symbol (required), account (required), watchlist (required), agent, +1 more. Returns: result
withdrawB
Remove cash from a paper account (fails if it would go negative).
Inputs: amount (required), account (required), agent, idempotency_key. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 60 tools
Most tools are grouped by resource with specific descriptions, but there is overlap between order_submit and buy_option/sell_option for option trades, and events/audit_log/account_activity all present similar history/log data. Helpful descriptions mitigate the ambiguity, but selection is not always obvious.
Naming is readable due to consistent resource prefixes like order_, watchlist_, market_, and config_, but the convention is mixed: order_submit is object_verb, validate_symbol is verb_object, and summary/positions/pnl/healthcheck are noun-only. The lack of a uniform pattern prevents a higher score.
At 60 tools, this server far exceeds the 3-15 well-scoped range and crosses the 50+ extreme mismatch threshold. Even for a trading CLI, the tool surface is overwhelming; it should be consolidated or split into focused sub-servers to keep agent selection tractable.
The tool surface covers account management, order lifecycle, positions, watchlists, market data, options and futures, risk management, performance/backtest, audit/events, config, and backup/admin. Common trading workflows have no obvious dead ends, making this a very complete server for its domain.
Maintenance
Related MCP Connectors
Trading MCP server for AI agents, with live market data, account reads and controlled execution.
MCP server for OpenMM — exposes market data, account, trading, and strategy tools to AI agents
Open-source MCP server for Zerodha Kite Connect. Portfolio, market data, backtesting, alerts.
Hosted MCP server for Indian market quotes, option-chain Greeks and multi-broker telemetry.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceFull-lifecycle algorithmic trading MCP server. AI strategy generation from plain English, backtesting, live bot deployment to 10+ brokers, portfolio monitoring, and prediction markets. Stocks, options, crypto, futures. 32 tools. Free tier.-
- AlicenseAqualityDmaintenanceMCP server for the tastytrade brokerage API, providing tools for account management, market data, and order execution.18MIT
- FlicenseBqualityDmaintenanceMCP server for Interactive Brokers via IB Gateway, enabling read access to account data and trading capabilities for paper accounts.11-
- AlicenseBqualityDmaintenanceA read-only-by-default MCP server for Interactive Brokers that exposes account, positions, PnL, market data, and trade history from a local TWS/IB Gateway session, with optional trading capabilities.15MIT