nt8-mcp

NinjaScript development loop for NinjaTrader 8: compile, inspect charts, read output and backtest

By Tristan (individual) Python Local · stdio Developer toolsFinance and payments

23 popularity score ★ 31

Connect your client

Local (from source)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

FirstTerminal
git clone https://github.com/tbraman-dev/nt8-mcp
pip install -e nt8-mcp/server
powershell -ExecutionPolicy Bypass -File nt8-mcp\scripts\install-addon.ps1
Claude CodeTerminal
claude mcp add nt8 -- nt8-mcp
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "nt8": {
      "command": "nt8-mcp",
      "args": []
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "nt8": {
      "command": "nt8-mcp",
      "args": []
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "nt8": {
      "type": "stdio",
      "command": "nt8-mcp",
      "args": []
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.nt8]
command = "nt8-mcp"
args = []
Gemini CLITerminal
gemini mcp add --scope user nt8 nt8-mcp

Settings 5

NT8BRIDGE_URL Optional: Address of the NT8Bridge AddOn. Default http://localhost:7891.
NT8_MCP_REQUIRE_PUSHED Optional: Set to 1 to make nt_install refuse files that are not committed and pushed in git. For nt_install.
Set together: sim desk
NT8MCP_LOCK_FILE Optional: Path of the lock file the Sim desk writes check. Default Documents\NinjaTrader 8\nt8mcp\nt8.lock. For nt_lock.
NT8MCP_DESK_LEGS Optional: Path of desk_legs.json, the expected legs read by nt_desk_status. The AddOn reads its own copy of this setting from NinjaTrader's environment for the grid allowlist. Default Documents\NinjaTrader 8\nt8mcp\desk_legs.json. For nt_desk_status.
NT8MCP_DECISIONS_DIR Optional: Folder of per-leg decision CSVs. Default Documents\NinjaTrader 8\nt8mcp\decisions. For nt_leg_decisions.

What it does

nt8-mcp connects an MCP client to a running NinjaTrader 8 desktop so an assistant can work on NinjaScript indicators and strategies itself. It has two parts: a Python stdio server and an AddOn (NT8Bridge) compiled into NinjaTrader, which listens on localhost:7891 and exposes charts, the compiler, output, logs, backtests, data stores and accounts.

With it an assistant can compile-check files offline against your Custom project, compile through NinjaTrader's own compiler without the Editor open, reload the assembly, read plot values, drawing anchors and bars off a chart, read Print() output, take screenshots, run headless backtests on the Backtest account, and run grid optimisation, walk-forward tests and PDF reports. It can also look up the real signatures of NinjaTrader types, lint NinjaScript and check local data coverage. Since 1.6.0 it can also open the NinjaScript Editor and switch, open, close or save workspaces without any dialog.

It is aimed at development rather than trading and is read-only unless you arm it. An empty orders.enabled file arms order entry, ATM strategies, strategies-on-Sim, the Sim desk repairs and replay controls, all limited to Simulator and Playback accounts and each needing a dry run and a confirm string used within 30 seconds. The desk writes, which now include disabling grid rows one by one or from a list, also check a local lock file that names the caller. A separate ops.enabled file, ignored after 24 hours, arms a reduce-only flatten. It is not affiliated with NinjaTrader, LLC.

From the code at v1.6.0: the server registers 96 tools spread over 23 tools_* modules, though one README paragraph still says 89. Each call to the AddOn times out after 5 seconds unless the tool sets a longer deadline (server/nt8_mcp/app.py). The NinjaTrader folder is always taken as Documents\NinjaTrader 8 under the user's home, with no setting to move it, and the server works with both the 1.x and 2.x releases of the mcp Python package.

What it needs

RuntimePython 3.10+
Runs onWindows
NinjaTrader 8FreeA free Simulator install is enough for the development tools; no broker account or data subscription needed
Also
  • NinjaTrader 8 desktop running with the NT8Bridge AddOn compiled in
  • The .NET SDK (dotnet on PATH) for nt_check only

Tested by its maker on NinjaTrader 8.1.8.2. Install the NT8Bridge AddOn with scripts\install-addon.ps1 and compile it once (F5 in the NinjaScript Editor). The optional extras parquet and report (pip install -e ".[parquet,report]") bring the packages nt_nrd_export and nt_report's PDF need.

Limits

  • Limit Not on PyPI. It is installed from a clone of the repository with pip install -e.
  • Platform Windows only, with the NinjaTrader 8 desktop running. The AddOn binds NinjaTrader internals by name, so an NT8 update can break features.
  • Not covered Order entry reaches Simulator and Playback accounts only. Live, funded and broker-demo accounts are refused.
  • Size cap Orders are capped at 10 contracts, 20 working orders per account and 60 submits a minute by default; config can raise these to 100, 100 and 600.
  • Limit nt_reload_assembly is refused while a live order-routing connection is up.
  • Size cap nt_optimize refuses more than 200 parameter combinations by default.
  • Limit nt_data_download needs a real data connection and no open positions or orders outside the Backtest account. Ranges over 10 days need big=True.
  • Not covered nt_grid_enable and nt_grid_disable are refused unless desk_legs.json exists and lists the row's strategy, account and instrument.
  • Not covered nt_workspace_close is refused for the only open workspace and for one that holds an enabled or running strategy.
  • Limit It never connects or disconnects the Playback connection, which must already be Connected for replay control.

Not on PyPI; installed from a clone. Order entry never reaches live, funded or broker-demo accounts, and caps orders at 10 contracts, 20 working orders per account and 60 submits per minute by default (config can raise them to 100/100/600). nt_reload_assembly is refused while a live order-routing connection is up. It never connects or disconnects the Playback connection. nt_optimize refuses above 200 combinations by default. nt_data_download needs a real data connection and no open positions or orders outside the Backtest account; ranges over 10 days need big=True. The AddOn binds NinjaTrader internals by name, so an NT8 update can break features.

Who it suits

NinjaScript developers on Windows who want an assistant to write, compile, check on a chart and backtest indicators and strategies without copying errors and screenshots by hand. It runs fully on your machine and is read-only by default. If you want an assistant to trade a real account, its own README points to ozmnf4/ninjatrader-mcp, anfs-pain/ninjatrader-mcp or NinjaTrader's official server (Tradovate cloud API), since this one only places orders on Simulator and Playback accounts. Not usable on macOS or Linux.

Tools 60 of 96

32 only read, 27 change things, 1 can delete or overwrite. A ? marks an optional parameter.

nt_health
Report AddOn and NinjaTrader versions, connections, open chart count and any blocking dialog
nt_windows
List open NinjaTrader windows with title, kind and position
nt_charts
List open charts with instrument, period and indicators
nt_chart_state
Return the full state of one chartchart?: string
nt_bars
Return the last n OHLCV bars of a chart (50 by default)chart?: stringn?: integer
nt_indicators
Return a chart's indicators, their inputs and recent plot valueschart?: stringname?: stringn?: integer
nt_drawings
List drawing objects on a chart with tag, type, owner and anchorschart?: string
nt_chart_reload changes
Reload NinjaScript on one chartchart?: string
nt_account
Read cash, P&L, positions and orders for one or all accountsname?: string
nt_bridge_log
Tail the AddOn's own request and error logn?: integer
nt_screenshot
Capture a chart window as a PNGchart?: string
nt_status
Check whether the running build is older than the source files on disk
nt_chart_indicator_add changes
Add an indicator to a chart and read the chart backindicator: stringchart?: stringinputs?: objectpanel?: integer
nt_chart_indicator_remove changes
Remove an indicator it added, or any one with force=Truechart?: stringindicator?: stringindex?: integerforce?: boolean
nt_chart_set_series changes
Change a chart's instrument or bar periodchart?: stringinstrument?: stringbars_period?: objectrestore?: boolean
nt_chart_scroll_to changes
Scroll a chart to a given timetime: stringchart?: string
nt_trade_shot
Scroll to one backtest trade's entry and screenshot itrun_id: stringtrade_index: integerchart?: string
nt_compile changes
Compile the NinjaScript tree with NinjaTrader's compiler and return structured errorstimeout_s?: integer
nt_reload_assembly changes
Compile and swap the running assembly at once; refused while a live order connection is uptimeout_s?: integer
nt_compile_f5 changes
Fallback that presses F5 in the NinjaScript Editor and waits for the rebuildtimeout_s?: integer
nt_editor_open changes
Open the NinjaScript Editor window so nt_compile_f5 can run; does nothing if one is open
nt_output
Read NinjaScript Print() output from the AddOn's buffersince?: integern?: integertab?: integercontains?: string
nt_log
Read NinjaTrader's own event log, filtered by level, name or textsince?: integern?: integerlevel?: stringname?: stringcontains?: string
nt_strategies
List strategies available to backtest with their inputs
nt_backtest changes
Run a headless backtest on the Backtest account and return summary and tradesstrategy: stringchart?: stringfrom_date?: stringto_date?: stringtick_replay?: booleaninputs?: objectinstrument?: stringbars_period?: objectwait_s?: integertemplate?: stringfill_resolution?: stringfill_resolution_type?: stringfill_resolution_value?: integerslippage_ticks?: numbercommission_template?: stringinclude_commission?: booleanfill_limit_on_touch?: booleaninclude_trade_history?: booleanmax_trades?: integersave_run?: boolean
nt_match
Compare NinjaTrader trades with a reference trade list and give a pass or failreference_csv: stringnt8_trades?: stringbacktest?: objectbacktest_id?: stringrun_id?: stringcolumns?: objectnt8_columns?: objectexit_map?: objectfrom_date?: stringto_date?: stringtick_size?: numberprice_tol_ticks?: numberentry_tol_min?: numbernt8_time_shift_min?: integersession_start?: stringbars_csv?: stringbars_time_is_close?: booleanbars_chart?: stringbars_n?: integernews_minutes?: array
nt_optimize changes
Grid-search strategy parameters over backtests, capped at 200 combinations by defaultstrategy: stringparams: objectchart?: stringinstrument?: stringbars_period?: objectfrom_date?: stringto_date?: stringtick_replay?: booleaninputs?: objectfill_resolution?: stringfill_resolution_type?: stringfill_resolution_value?: integerslippage_ticks?: numbercommission_template?: stringinclude_commission?: booleanfill_limit_on_touch?: booleanfitness?: stringtop_n?: integermin_trades?: integermax_combos?: integer
nt_walkforward changes
Run an anchored or rolling walk-forward of optimize plus out-of-sample testsstrategy: stringparams: objecttrain_days?: integertest_days?: integeranchored?: booleanfrom_date?: stringto_date?: stringchart?: stringinstrument?: stringbars_period?: objecttick_replay?: booleaninputs?: objectfill_resolution?: stringfill_resolution_type?: stringfill_resolution_value?: integerslippage_ticks?: numbercommission_template?: stringinclude_commission?: booleanfill_limit_on_touch?: booleanfitness?: string
nt_analyze
Break down a run's trades by month, weekday, hour, side, drawdown and streaksrun_id?: stringtrades?: array
nt_runs
List saved backtest runs from the run registrylimit?: integerstrategy?: string
nt_report changes
Build stats and an optional one-page PDF for a finished backtestid?: stringstatus_doc?: objectpdf_path?: string
nt_api_search
Search loaded NinjaTrader assemblies for types and members by keywordquery: stringlimit?: integer
nt_api
Show the real signatures of one NinjaTrader typetype_name: stringmember?: string
nt_data_coverage
Show which days of tick, minute, day and replay data are stored locallyinstrument: stringkind?: stringfrom_date?: stringto_date?: string
nt_data_probe
Find how far back the connected provider serves an instrumentinstrument: stringkind?: stringwait_s?: integer
nt_nrd_export changes
Decode Market Replay .nrd files to Parquet offlineinstrument_glob: stringout_dir: stringlevels?: arrayforce?: booleanreplay_dir?: string
nt_data_download changes
Download missing historical data from the connected provider into NinjaTrader's storeinstrument: stringfrom_date: stringto_date: stringkinds?: arraytypes?: arrayoverwrite?: booleanbig?: boolean
nt_connections
List configured connections and why each last droppedn?: integersince?: integer
nt_executions
List real fills on one accountaccount: stringfrom_date?: stringto_date?: stringinstrument?: stringn?: integer
nt_performance
Compute round-trip trades and metrics from an account's fillsaccount: stringfrom_date?: stringto_date?: stringinstrument?: stringn?: integer
nt_workspace
Show the loaded workspace and every window with each chart's indicators and strategies
nt_strategies_running
Read the Control Center Strategies gridmaterialize?: boolean
nt_window_shot
Capture any NinjaTrader window as a PNG without bringing it forwardwindow?: stringchart?: stringhwnd?: integerpath?: string
nt_workspace_switch changes
Make an already open workspace the active onename: string
nt_workspace_open changes
Open a workspace file from NinjaTrader's workspaces foldername: stringactivate?: boolean
nt_workspace_close changes
Close an open workspace and answer its save prompt; refused while it holds an enabled strategyname: stringsave?: boolean
nt_workspace_save_as deletes
Save an open workspace under a new name; replaces an existing file only with overwrite=Truename: stringnew_name: stringoverwrite?: boolean
nt_playback
Report the Market Replay connection's stateinstrument?: stringcoverage?: booleanbudget_s?: integer
nt_check
Compile-check .cs files against the Custom project in a scratch folderfiles?: array
nt_install changes
Copy .cs files into the right Custom subfolderfiles: array
nt_install_addon changes
Install or update the NT8Bridge AddOn files
nt_lint
Scan NinjaScript files for known hazardspaths: arrayrules?: array
nt_order_submit changes
Place one order on a Simulator or Playback account after a dry run and confirm (opt-in)account: stringinstrument: stringaction: stringorder_type: stringquantity: integerlimit_price?: numberstop_price?: numbertif?: stringconfirm?: stringissued_at?: number
nt_order_bracket changes
Place an entry with stop and targets on a Simulator or Playback account (opt-in)account: stringinstrument: stringaction: stringorder_type: stringquantity: integerlimit_price?: numberstop_price?: numberstop_loss_price?: numberstop_loss_ticks?: integertargets?: arraytif?: stringconfirm?: stringissued_at?: number
nt_strategy_start changes
Enable a strategy on a Simulator or Playback account (opt-in)strategy: stringaccount: stringinstrument: stringbars_period: objectinputs?: objectdays_to_load?: integerbreak_at_eod?: booleantrading_hours?: stringconfirm?: stringissued_at?: number
nt_flatten changes
Cancel orders and flatten positions on one account (opt-in ops module)account: stringinstrument?: stringconfirm?: stringissued_at?: number
nt_reconcile
Pair a backtest's trades with a replay run's fillsbacktest_id?: stringbacktest_run_id?: stringbacktest_trades?: arrayplayback_run_id?: stringplayback_executions?: arraytolerance_ticks?: numbertolerance_seconds?: numbertick_size?: number
nt_lock changes
Take, renew or release the local lock file the Sim desk writes check forcaller: stringminutes?: numberrelease?: boolean
nt_grid_disable changes
Disable one allowlisted Strategies grid row without removing it or flattening (opt-in)caller: stringstrategy_id: stringaccount: stringconfirm?: stringissued_at?: number
nt_grid_disable_all changes
Disable a list of grid rows under one plan and one confirm (opt-in)caller: stringids: arrayconfirm?: stringissued_at?: number

Similar servers