Skip to main content

How to Connect Crush to NinjaTrader 8 with CrossTrade MCP

Crush is Charm's open-source coding agent with a clean TUI. JSON config, type: 'http' for remote MCP. No native OAuth, use a bearer token in headers.

OAuth scope: mcp:tradeMulti-model harness

Prerequisites

RequirementDetail
CrossTrade subscriptionElite
CrossTrade NT8 Add-Onv1.13.0 or higher
NinjaTrader 8Running, broker connected
AccountSim101 for first runs
OAuth scopemcp:trade
Install commandbrew install charmbracelet/tap/crush
Config file~/.config/crush/crush.json (global) or .crush.json / crush.json (project root)
CrossTrade MCP server
https://app.crosstrade.io/v1/api/mcp
Transport: streamable-http. Auth: OAuth 2.1 + PKCE. Request scope mcp:trade. Read plus write. Place/cancel orders, deploy strategies, compile NinjaScript.

Step 1: Install Crush​

The connection path from Crush to a NinjaTrader 8 account. The client speaks the Model Context Protocol to the CrossTrade MCP server, which is hosted rather than local. Authorisation happens once over OAuth and issues a scoped token. From there the server calls through to the CrossTrade NT8 Add-On inside your running NinjaTrader, and results travel back the same way as plain language.

Four hops, authorised once. Read-only is the scope to start with.

# Homebrew
brew install charmbracelet/tap/crush

# npm
npm install -g @charmland/crush

# Go
go install github.com/charmbracelet/crush@latest

# Windows (Winget)
winget install charmbracelet.crush

On first launch Crush prompts for an LLM provider API key, or you can pre-set env vars (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.).

Step 2: Add CrossTrade MCP​

Edit ~/.config/crush/crush.json (or .crush.json / crush.json in your project root — checked in priority order):

{
"mcp": {
"crosstrade": {
"type": "http",
"url": "https://app.crosstrade.io/v1/api/mcp",
"timeout": 120,
"disabled": false,
"headers": {
"Authorization": "Bearer $CROSSTRADE_API_KEY"
}
}
}
}
Crush uses type: "http"

Crush's transport values are "stdio", "http", or "sse". Not "remote" (OpenCode) or "streamable_http" (Goose). Schema fields: type (required), url, headers, timeout, disabled, disabled_tools, enabled_tools, env.

Env var expansion: $VARNAME syntax in header values is supported.

Step 3: Get a bearer token​

Crush doesn't have a native browser OAuth flow. To get a token:

  1. Authorize CrossTrade via Claude Code, Cursor, OpenCode, or any OAuth-capable client.
  2. Copy the issued token from your AI Clients page.
  3. export CROSSTRADE_API_KEY=... in your shell rc.

Step 4: First prompt​

Confirm CrossTrade MCP. ListAccounts, GetConnections. One-line status per account.

FAQ​

Why no OAuth?​

Crush's MCP client is bearer-only as of this writing. Watch github.com/charmbracelet/crush for updates.

Schema autocomplete?​

Crush doesn't auto-generate $schema references. Add "$schema": "https://charm.land/crush/schema.json" to the top of crush.json for IDE completion.

OAuth handshake

The first tool call surfaces an authorization URL. Open it in a browser, approve mcp:trade, and return to the harness. The access token is stored by the harness (keychain, config file, or memory depending on the client).

See CrossTrade MCP OAuth for the full flow, and 403/408 troubleshooting if the handshake fails.

Verify the connection

Smoke-test before doing anything stateful:

Call GetMcpCapabilities and McpSelfTest. Then ListAccounts and GetConnections.
Report add-on version, NT8 version, and which accounts are linked.

If you authorized mcp:trade, also confirm Sim101 is the default account before any order placement.

Funded-account safety
The mcp:trade scope grants order placement. The scope does not protect a funded account; your prompt and account selection do. Default to Sim101 during setup. For funded accounts, verify the firm's automation policy first.

Troubleshooting

SymptomLikely causeFix
403 insufficient_scopeToken authorized at mcp:read but tool requires mcp:tradeReauthorize the connection and select mcp:trade
OAuth callback failsSystem browser blocked the redirect or popupCopy the auth URL manually, complete it, paste the code back
Tools list is empty after connectServer registered but session did not refreshRestart the harness or trigger a tool list refresh
Add-on offline errorNT8 not running, or add-on not loadedConfirm NT8 is open and the CrossTrade NT8 add-on (v1.13.0+) is installed
type: "remote" rejectedCrush uses type: "http" (not "remote" like OpenCode, not "streamable_http" like Goose)Use type: "http"; valid values are "stdio", "http", "sse"
No OAuth flow startsCrush docs do not describe a native browser OAuth flowObtain a CrossTrade token via another client's OAuth flow and paste it in headers as a Bearer token