NinjaTrader 8 MCP Server
Trade, read positions and control charts in a running NinjaTrader 8 desktop through a NinjaScript Add-On
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
Opens the app, which asks before it adds the server.
git clone https://github.com/tbraman-dev/nt8-mcp
pip install -e nt8-mcp/server
powershell -ExecutionPolicy Bypass -File nt8-mcp\scripts\install-addon.ps1claude mcp add nt8 -- nt8-mcp{
"mcpServers": {
"nt8": {
"command": "nt8-mcp",
"args": []
}
}
}{
"mcpServers": {
"nt8": {
"command": "nt8-mcp",
"args": []
}
}
}{
"servers": {
"nt8": {
"type": "stdio",
"command": "nt8-mcp",
"args": []
}
}
}[mcp_servers.nt8]
command = "nt8-mcp"
args = []gemini mcp add --scope user nt8 nt8-mcpNT8BRIDGE_URL |
Optional: Address of the NT8Bridge AddOn. |
|---|---|
NT8_MCP_REQUIRE_PUSHED |
Optional: Set to 1 to make nt_install refuse files that are not committed and pushed in git. |
| Set together: sim desk | |
NT8MCP_LOCK_FILE |
Optional: Path of the lock file the Sim desk writes check. |
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. |
NT8MCP_DECISIONS_DIR |
Optional: Folder of per-leg decision CSVs. |
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.
| Runtime | Python 3.10+ |
|---|---|
| Runs on | Windows |
| NinjaTrader 8 | FreeA free Simulator install is enough for the development tools; no broker account or data subscription needed |
| Also |
|
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.
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.
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.
32 only read, 27 change things, 1 can delete or overwrite. A ? marks an optional parameter.
nt_healthnt_windowsnt_chartsnt_chart_statechart?: stringnt_barschart?: stringn?: integernt_indicatorschart?: stringname?: stringn?: integernt_drawingschart?: stringnt_chart_reload changeschart?: stringnt_accountname?: stringnt_bridge_logn?: integernt_screenshotchart?: stringnt_statusnt_chart_indicator_add changesindicator: stringchart?: stringinputs?: objectpanel?: integernt_chart_indicator_remove changeschart?: stringindicator?: stringindex?: integerforce?: booleannt_chart_set_series changeschart?: stringinstrument?: stringbars_period?: objectrestore?: booleannt_chart_scroll_to changestime: stringchart?: stringnt_trade_shotrun_id: stringtrade_index: integerchart?: stringnt_compile changestimeout_s?: integernt_reload_assembly changestimeout_s?: integernt_compile_f5 changestimeout_s?: integernt_editor_open changesnt_outputsince?: integern?: integertab?: integercontains?: stringnt_logsince?: integern?: integerlevel?: stringname?: stringcontains?: stringnt_strategiesnt_backtest changesstrategy: 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?: booleannt_matchreference_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?: arraynt_optimize changesstrategy: 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?: integernt_walkforward changesstrategy: 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?: stringnt_analyzerun_id?: stringtrades?: arraynt_runslimit?: integerstrategy?: stringnt_report changesid?: stringstatus_doc?: objectpdf_path?: stringnt_api_searchquery: stringlimit?: integernt_apitype_name: stringmember?: stringnt_data_coverageinstrument: stringkind?: stringfrom_date?: stringto_date?: stringnt_data_probeinstrument: stringkind?: stringwait_s?: integernt_nrd_export changesinstrument_glob: stringout_dir: stringlevels?: arrayforce?: booleanreplay_dir?: stringnt_data_download changesinstrument: stringfrom_date: stringto_date: stringkinds?: arraytypes?: arrayoverwrite?: booleanbig?: booleannt_connectionsn?: integersince?: integernt_executionsaccount: stringfrom_date?: stringto_date?: stringinstrument?: stringn?: integernt_performanceaccount: stringfrom_date?: stringto_date?: stringinstrument?: stringn?: integernt_workspacent_strategies_runningmaterialize?: booleannt_window_shotwindow?: stringchart?: stringhwnd?: integerpath?: stringnt_workspace_switch changesname: stringnt_workspace_open changesname: stringactivate?: booleannt_workspace_close changesname: stringsave?: booleannt_workspace_save_as deletesname: stringnew_name: stringoverwrite?: booleannt_playbackinstrument?: stringcoverage?: booleanbudget_s?: integernt_checkfiles?: arraynt_install changesfiles: arraynt_install_addon changesnt_lintpaths: arrayrules?: arraynt_order_submit changesaccount: stringinstrument: stringaction: stringorder_type: stringquantity: integerlimit_price?: numberstop_price?: numbertif?: stringconfirm?: stringissued_at?: numbernt_order_bracket changesaccount: stringinstrument: stringaction: stringorder_type: stringquantity: integerlimit_price?: numberstop_price?: numberstop_loss_price?: numberstop_loss_ticks?: integertargets?: arraytif?: stringconfirm?: stringissued_at?: numbernt_strategy_start changesstrategy: stringaccount: stringinstrument: stringbars_period: objectinputs?: objectdays_to_load?: integerbreak_at_eod?: booleantrading_hours?: stringconfirm?: stringissued_at?: numbernt_flatten changesaccount: stringinstrument?: stringconfirm?: stringissued_at?: numbernt_reconcilebacktest_id?: stringbacktest_run_id?: stringbacktest_trades?: arrayplayback_run_id?: stringplayback_executions?: arraytolerance_ticks?: numbertolerance_seconds?: numbertick_size?: numbernt_lock changescaller: stringminutes?: numberrelease?: booleannt_grid_disable changescaller: stringstrategy_id: stringaccount: stringconfirm?: stringissued_at?: numbernt_grid_disable_all changescaller: stringids: arrayconfirm?: stringissued_at?: number