PitBridge
Join the waitlist

NinjaTrader and AI agents

How to connect an AI agent to NinjaTrader 8

Connecting an AI agent to NinjaTrader 8 comes down to where the order logic runs and what checks it. This walks the three approaches, why an external MCP agent is the flexible one, and the real uvx quickstart with a guardrail that blocks any order past your limits.

On this page

Connecting an AI agent to NinjaTrader 8 is a solved problem in the trivial sense: something has to translate the agent’s intent into an order the platform accepts. The question worth answering is where that translation runs and what gets to inspect the order on the way through. Get that wrong and you have handed a language model a direct line to a futures account. This walks the three real approaches, why an external agent is usually the one you want, the risk that comes with it, and the actual uvx pitbridge setup that puts a hard limit between the model and the platform.

Three ways to automate NinjaTrader 8

There are three architectures in common use, and they differ in where the decision logic lives.

In-platform NinjaScript is the native path. You write a strategy in NinjaScript, NinjaTrader’s C# environment, and it runs inside the platform against live data, with no external process in the order path. This is the right tool for a mechanical strategy you can express in code. It is not an AI agent: the logic is compiled C#, not a model reasoning in a loop, and teaching it to reason over natural-language context or call out to a model is a fight against the grain.

An external agent talks to NinjaTrader 8 from outside, over a protocol the platform or a bridge exposes. This is where an AI agent fits: the model runs in its own runtime, reads account state through tools, and proposes orders. It brings its own reasoning and its own data, and it does not need to be rewritten in C#. The catch is that something now reaches into the platform from outside, so the boundary between the two is where all the safety has to live.

A cloud bridge is a hosted variant of the external approach. The agent talks to a vendor’s cloud, which relays the order to a small add-on inside your NinjaTrader. It is the fastest to set up because the vendor operates the moving parts, at the cost of putting a third party’s servers in the path of every order.

Propertyin-platform ninjascriptexternal agentcloud bridge
where the logic runscompiled C# inside NT8a model in its own runtimea model plus a vendor cloud
fits an AI agentno, it is C# strategy codeyes, the native fityes, hosted
order pathinside the platformyour machine to the platformthrough the vendor's servers
where risk checks can livein your strategy codein the local bridgesplit across the vendor and the add-on
setup costlearn NinjaScriptrun a local daemonsign up, grant access

in-platform ninjascript

where the logic runs
compiled C# inside NT8
fits an AI agent
no, it is C# strategy code
order path
inside the platform
where risk checks can live
in your strategy code
setup cost
learn NinjaScript

external agent

where the logic runs
a model in its own runtime
fits an AI agent
yes, the native fit
order path
your machine to the platform
where risk checks can live
in the local bridge
setup cost
run a local daemon

cloud bridge

where the logic runs
a model plus a vendor cloud
fits an AI agent
yes, hosted
order path
through the vendor's servers
where risk checks can live
split across the vendor and the add-on
setup cost
sign up, grant access
The three approaches differ in where the decision runs and what sits between it and the account. None is wrong; they solve different shapes of problem.

Why reach for an external agent at all

If NinjaScript already runs strategies natively, why go outside the platform? Because an AI agent is a different kind of driver. It reasons over live state instead of executing a fixed rule, it reads the book before it acts, and it can take instruction in plain language. Expressing that inside a compiled NinjaScript strategy means bolting a model onto an environment that was not built to host one.

This is also where the common search for a NinjaTrader Python API runs into a wall. NinjaTrader 8 automates through NinjaScript in C#, and it ships no official Python API. If your agent, your tooling, or your own scripts live in Python, or speak MCP, the platform has no native door for them. You need something outside NinjaTrader that the platform can talk to and that your code can drive. That is exactly the shape of a bridge: it speaks the agent’s protocol on one side and NinjaTrader’s on the other.

The Model Context Protocol has become the standard way agents connect to tools, which makes an MCP server the natural front door for a trading account. The agent reads state with typed tools, proposes an order as a tool call, and reads the structured result. What a trading MCP server exposes, and why a proposal is not an execution, is covered in what a trading MCP server does.

The risk you are actually taking on

An agent with order access is a language model with a place_order tool, and a language model produces a distribution of outputs. Most of the time it does the sensible thing. The tail of that distribution includes an order for the wrong size, the wrong instrument, or the wrong side, reached through a plain mistake, a misread of the current position, an unusual market, or an input crafted to talk it past its instructions. Prompt injection is now routinely compared to SQL injection, because untrusted text and trusted instructions travel the same channel and the model cannot reliably tell them apart.

The tempting fix is to write the limits into the system prompt. Never exceed two contracts. Stop after a five hundred dollar loss. That configures behavior, it does not guarantee it. On the run where the model does not comply, a prompt limit does nothing, because the prompt was never the thing standing between the order and the account. Enforcement has to live below the model, in code the model cannot rewrite. Why a prompt is advice and an out-of-process check is a control is the whole subject of risk controls an LLM cannot override.

What a local-first guardrailed MCP bridge changes

A local-first bridge answers both problems at once: it keeps the order path on your machine, and it puts a deterministic checkpoint between the agent and the platform. The agent calls a tool, the call arrives at the daemon, a guardrail engine checks it against the limits you set, and only an allowed order continues to NinjaTrader 8. A blocked order comes back as a structured result with a reason code, not an exception that kills the session, so the agent can read why it stopped and move on.

PitBridge order pathAn order intent travels from the AI agent through the PitBridge daemon to the guardrail engine, which either allows it through to NinjaTrader 8 or blocks it with a stated reason.AI AGENTmcp / rest clientPITBRIDGE DAEMONlocalhost:8873GUARDRAIL ENGINE12 rules activeNINJATRADER 8Sim101ALLOW buy 2 MES. all rules pass.BLOCK buy 10 MES. size 10 > max_contracts_per_order 2.

Example decisions: ALLOW buy 2 MES, all rules pass. BLOCK buy 10 MES, size 10 exceeds max_contracts_per_order 2.

The order route: the agent proposes, the guardrail engine adjudicates, and only an allowed order reaches NinjaTrader 8. The block is shown as plainly as the allow.

Two properties make this a control rather than a suggestion. First, the checks are deterministic and run out of process: the same order and the same config always produce the same decision, and the model is not in the adjudication. Second, the agent’s surface is exactly nine tools, and none of them can weaken a limit. It has five reads and four order actions. There is no tool to release the kill switch, no tool to arm live trading, and no tool to change a threshold. Those live on an operator-only CLI the model never touches. The strongest safeguard here is an absence: the capability to raise its own limits is simply not in the agent’s world.

reads5

  • get_accounts
  • get_positions
  • get_orders
  • get_account_state
  • get_guardrail_status

Return state. They never change anything.

writes4

  • place_order
  • cancel_order
  • close_position
  • flatten_account

Request a change. Every place_order still passes the guardrail engine.

The nine tools an MCP client sees at connect time. There is no tool to lift the kill switch, arm live, or change a guardrail: those are operator-only on the CLI.

Local-first is the other half. The daemon, the guardrail engine, and your credentials run on your machine, and no order is relayed through a PitBridge server. On one Windows box the daemon and NinjaTrader run together on localhost. In paired mode the daemon runs on your Mac and the AddOn connects out to it from the Windows box over your own network. Either way, PitBridge’s own cloud is never in the order path. That property is the subject of the local-first trading bridge page.

The quickstart: uvx pitbridge

PitBridge is published on PyPI, so uvx resolves and runs it with no separate install step. The fastest look is the demo sandbox: with no config at all, the MCP server boots a safe paper account with every guardrail on and live execution locked, so an agent can read state before you configure anything.

~
$ uvx pitbridge mcp
# no config found: booting a safe paper DEMO sandbox.
# fake account, all 12 guardrails on, live locked.
# your agent can now call get_accounts and get_guardrail_status.

The demo needs no NinjaTrader install and cannot place a real order. It exists so an agent can see the tools and the guardrail engine before setup.

When you are ready to point it at your own account, scaffold a config, edit it, and verify it. Every step stays in paper mode until you deliberately unlock live.

~
$ uvx pitbridge init          # writes ~/.pitbridge/config.toml
$ uvx pitbridge doctor        # read-only PASS / WARN / FAIL self-check

init scaffolds a starter config; doctor checks config, accounts, guardrails, the deny-list, the kill switch, the live gate, and the version.

The config is one TOML file that names your account and its limits. The keys are real; the values are yours to set.

~/.pitbridge/config.toml
[daemon]
bind = "127.0.0.1"           # localhost only
port = 8873

[accounts.sim]
nt_account = "Sim101"        # the NinjaTrader account name
mode = "paper"               # read_only | paper | live

[accounts.sim.guardrails]
instruments = ["MES 09-26"]      # allowlist
max_contracts_per_order = 2      # reject any single order larger than this
daily_loss_halt = 500            # halt new entries after -$500
trading_window = { tz = "America/New_York", open = "09:30", close = "16:00" }

A real config.toml. Leave a key out and that check does not run. A reason code in a block names the exact key that refused an order.

Wire the runtime you already use

The bridge does not care which model is on the other end, because the guardrail engine checks every order regardless of the client. Claude Code registers the stdio server with one command.

~/your-project
$ claude mcp add pitbridge -- uvx pitbridge mcp
# custom config path? append: --config /path/to/config.toml

Claude Code one-liner. Claude Desktop and OpenClaw attach the same stdio server; see the quickstart for each.

For an agent runtime that speaks MCP over HTTP, such as Hermes or your own client, run the daemon and point the client at the local HTTP endpoint. It is the same nine tools, the same guardrail pipeline, and the same audit log as stdio.

~
$ uvx pitbridge run
# daemon up on 127.0.0.1:8873
# REST at /v1/*, WebSocket at /v1/ws, MCP over HTTP at /mcp
# point any MCP-over-HTTP client at:
#   http://127.0.0.1:8873/mcp

Streamable HTTP MCP has been served next to stdio since 0.2.0. On a localhost bind the agent token is optional; a non-localhost bind requires paired mode plus a token.

If you are the one reaching for a NinjaTrader Python API, this is the seam: uvx pitbridge run exposes a localhost REST route, so a Python script can POST an order to http://127.0.0.1:8873/v1/place_order and it travels the same guardrail pipeline as the agent’s tool call. The full per-runtime setup, including Claude Desktop, OpenClaw, and plain curl, is in the quickstart.

See a block, on purpose

The moment that proves the setup is a refused order. Ask the agent to check the account, buy two contracts, then buy ten. The first fills in paper; the second breaks the per-order cap you configured, and the engine refuses it before NinjaTrader sees anything.

agent tool calls
get_account_state                                              -> link_up: true, day_pnl: 0.0
place_order account=sim instrument="MES 09-26" side=BUY qty=2  -> SUBMITTED, then FILLED filled_qty=2
place_order account=sim instrument="MES 09-26" side=BUY qty=10 -> BLOCKED reason_code=MAX_CONTRACTS_PER_ORDER

Example agent tool calls against the local daemon. Real tool names and reason code. Fills are synthetic simulation fills, not live results. The block returns as a structured result the agent can read and explain.

A refused order is the system doing its job, not an error to hide. The whole decision, allow or block, is written to an append-only, hash-chained audit log, so pitbridge audit why <order_id> can explain any single order after the fact and pitbridge audit verify proves the log has not been edited.

Honest status: paper by default, live gated

Everything above runs against a paper or simulation account. In the open core mode = "live" is intentionally impossible: arm-live refuses because the live-execution provider ships separately as a paid, closed component, and there is no agent tool to change that. Live execution has been in production on a funded futures account since 30 July 2026, behind an operator-run arm step. The upside is that you can exercise the entire safety kernel, every reason code, on a Mac before any real money is in scope. When you do want live execution, the pricing page explains exactly what the paid unlock is.

Before a funded or prop account

Start on a NinjaTrader simulation account such as Sim101, in read-only or paper mode, and watch how the agent behaves across a full session before you consider anything funded. If that account is with a prop firm, one more rule applies: PitBridge enforces the limits you configure, but it does not know or bypass your firm’s automation policy. Some firms prohibit agent or automated order entry outright, some allow it with conditions, and the rules change. Confirm your firm’s written policy yourself and map it into your config. This is the subject of prop firm rules in software.

Connecting an AI agent to NinjaTrader 8 the safe way is not about trusting a well-behaved model. It is about making it impossible for the model to leave the limits you set. The NinjaTrader 8 MCP bridge is the front door, the guardrails page lists exactly what the engine refuses, and the security model covers where each part runs. If you want checks like these between your agent and your account, tell us your platform on the waitlist. PitBridge is trading infrastructure, not financial advice: it enforces the limits you configure and does not promise any trading outcome. Futures trading carries a substantial risk of loss.

Read the pillar: NinjaTrader 8 MCP bridge

Questions

How do I connect an AI agent to NinjaTrader 8?

Run a local bridge that both speaks to your agent and speaks to NinjaTrader 8. With PitBridge you run uvx pitbridge mcp, register it in your MCP client such as Claude Code, and the agent gets nine tools. Every order it proposes passes a guardrail engine on your machine before it reaches the platform.

Does NinjaTrader 8 have a Python API?

No. NinjaTrader 8 automates through NinjaScript, its C# environment, and ships no official Python API. To drive it from Python or an AI agent you need a bridge outside the platform. The PitBridge daemon is Python and exposes a localhost REST route and an MCP server, so a Python script or an agent can propose orders that route through the guardrails into NinjaTrader 8.

Is it safe to let an AI place orders?

Only if a control the model cannot reach sits between it and the account. A system prompt telling the model to respect a limit is advice it can ignore or be tricked past. PitBridge runs the limits as a deterministic engine in a separate process, and the agent has no tool to weaken a limit, release the kill switch, or arm live. It can propose an order; the daemon decides. Start on a simulation account and watch it before anything funded.

Does my data leave my machine?

No. The daemon, the guardrail engine, and your credentials run on your own machine, and no order is relayed through a PitBridge server. In paired mode the daemon runs on your Mac and the AddOn runs next to NinjaTrader 8 on your Windows box over your own network. PitBridge's own cloud is never in the order path.

Does it work with prop accounts?

PitBridge enforces the limits you configure on any account you point it at, but it does not know or bypass any prop firm's automation policy. Some firms prohibit agent or automated order entry, some permit it with conditions, and rules change. You are responsible for reading your firm's written rules and mapping them into your config. Verify with the firm before you connect anything to a funded account.

Do I need NinjaTrader installed to try it?

No. With no config at all, uvx pitbridge mcp boots a safe paper demo sandbox with a fake account and all guardrails on, so an agent can read state and see the tools. To exercise the full order flow on a Mac you run the daemon against a bundled fake AddOn that gives synthetic fills. Real routing into NinjaTrader 8 is Windows plus the C# AddOn.

How is this different from CrossTrade?

CrossTrade offers a hosted MCP server on its Elite plan, where agent instructions route through CrossTrade's cloud to reach the platform. PitBridge is local-first: the MCP server, the checks, and your keys stay on your machine, and the MCP is free. The comparison page lays out the sourced differences, including what CrossTrade does that PitBridge does not.

PitBridge is in development. NinjaTrader 8 is first.

Tell us your platform and we email you when your setup is supported. Nothing else.