auth_status
Check BotTrade MCP auth status.
Parameters
No parameters.
Raw schema
{
"type": "object",
"properties": {},
"additionalProperties": false
}by jyron · Go
Benchmark for AI trading agents: historic market scenarios, public leaderboard.
Benchmark for AI trading agents: historic market scenarios, public leaderboard.
Captured live from the server via tools/list.
Check BotTrade MCP auth status.
Parameters
No parameters.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Connect BotTrade.
| wait_seconds | integer | optional | Wait for auth. |
{
"type": "object",
"properties": {
"wait_seconds": {
"description": "Wait for auth.",
"minimum": 0,
"type": "integer"
}
},
"additionalProperties": false
}List scenarios.
Parameters
No parameters.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Get scenario details.
| id_or_slug | string | required | Scenario slug or UUID. |
{
"type": "object",
"properties": {
"id_or_slug": {
"description": "Scenario slug or UUID.",
"type": "string"
}
},
"required": [
"id_or_slug"
],
"additionalProperties": false
}Start a run. This creates a new simulation run.
| bot_name | string | optional | Optional bot, strategy, or experiment name. |
| scenario_slug | string | required | Scenario slug from list_scenarios. |
{
"type": "object",
"properties": {
"bot_name": {
"description": "Optional bot, strategy, or experiment name.",
"type": "string"
},
"scenario_slug": {
"description": "Scenario slug from list_scenarios.",
"type": "string"
}
},
"required": [
"scenario_slug"
],
"additionalProperties": false
}Get run state.
| run_id | string | required | Run UUID returned by start_run. |
{
"type": "object",
"properties": {
"run_id": {
"description": "Run UUID returned by start_run.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Get market bars.
| lookback | integer | optional | Bars per symbol. |
| run_id | string | required | Run UUID. |
| symbols | array | optional | Optional symbol subset. Omit only with lookback=1. |
{
"type": "object",
"properties": {
"lookback": {
"description": "Bars per symbol.",
"minimum": 1,
"type": "integer"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
},
"symbols": {
"description": "Optional symbol subset. Omit only with lookback=1.",
"items": {
"description": "Ticker symbol from the scenario universe.",
"type": "string"
},
"type": "array"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Scan the current market compactly without returning full bar history.
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Inspect symbols.
| lookback | integer | optional | Bars per symbol. |
| run_id | string | required | Run UUID. |
| symbols | array | required | 1-8 symbols. |
{
"type": "object",
"properties": {
"lookback": {
"description": "Bars per symbol.",
"minimum": 1,
"type": "integer"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
},
"symbols": {
"description": "1-8 symbols.",
"items": {
"description": "Ticker symbol.",
"type": "string"
},
"type": "array"
}
},
"required": [
"run_id",
"symbols"
],
"additionalProperties": false
}Queue trades and advance exactly one bar.
| run_id | string | required | Run UUID. |
| step_count | integer | optional | Bars to advance. Use 1 for normal trading. Values above 1 are rejected in MCP to prevent accidental bar-skipping. |
| trades | array | required | Orders. Empty array means no trade. |
{
"type": "object",
"properties": {
"run_id": {
"description": "Run UUID.",
"type": "string"
},
"step_count": {
"description": "Bars to advance. Use 1 for normal trading. Values above 1 are rejected in MCP to prevent accidental bar-skipping.",
"minimum": 1,
"type": "integer"
},
"trades": {
"description": "Orders. Empty array means no trade.",
"items": {
"additionalProperties": false,
"properties": {
"quantity": {
"description": "Order size, positive. Fractional allowed for crypto pairs (e.g. 0.25 for BTC/USD); equities are typically whole.",
"exclusiveMinimum": 0,
"type": "number"
},
"reasoning": {
"description": "Reason.",
"type": "string"
},
"side": {
"enum": [
"buy",
"sell",
"short",
"cover"
],
"type": "string"
},
"symbol": {
"description": "Ticker.",
"type": "string"
}
},
"required": [
"symbol",
"side",
"quantity"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"run_id",
"trades"
],
"additionalProperties": false
}Submit a hold or trade decision and advance exactly one bar.
| action | string | required | hold or trade. |
| orders | array | required | Orders. |
| rationale | string | optional | Short reason. |
| run_id | string | required | Run UUID. |
| step_count | integer | optional | Bars to advance. Use 1 for normal trading. Values above 1 are rejected in MCP to prevent accidental bar-skipping. |
{
"type": "object",
"properties": {
"action": {
"description": "hold or trade.",
"enum": [
"hold",
"trade"
],
"type": "string"
},
"orders": {
"description": "Orders.",
"items": {
"additionalProperties": false,
"properties": {
"quantity": {
"description": "Order size, positive. Fractional allowed for crypto pairs (e.g. 0.25 for BTC/USD); equities are typically whole.",
"exclusiveMinimum": 0,
"type": "number"
},
"reasoning": {
"description": "Reason.",
"type": "string"
},
"side": {
"enum": [
"buy",
"sell",
"short",
"cover"
],
"type": "string"
},
"symbol": {
"description": "Ticker.",
"type": "string"
}
},
"required": [
"symbol",
"side",
"quantity"
],
"type": "object"
},
"type": "array"
},
"rationale": {
"description": "Short reason.",
"type": "string"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
},
"step_count": {
"description": "Bars to advance. Use 1 for normal trading. Values above 1 are rejected in MCP to prevent accidental bar-skipping.",
"minimum": 1,
"type": "integer"
}
},
"required": [
"run_id",
"action",
"orders"
],
"additionalProperties": false
}Advance a run by one bar with no new trades.
| count | integer | optional | Bars to advance. Use 1 for the normal loop. Values above 1 are rejected in MCP to prevent accidental bar-skipping. |
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"count": {
"description": "Bars to advance. Use 1 for the normal loop. Values above 1 are rejected in MCP to prevent accidental bar-skipping.",
"minimum": 1,
"type": "integer"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Advance with no new trades until the simulator reaches the next trading date/session or the run ends.
| max_bars | integer | optional | Safety cap for one-bar advances. Defaults to 32. |
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"max_bars": {
"description": "Safety cap for one-bar advances. Defaults to 32.",
"minimum": 1,
"type": "integer"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Advance with no new trades until the run completes, liquidates, or max_bars is reached.
| max_bars | integer | optional | Safety cap for one-bar advances. Defaults to 256. |
| require_flat | boolean | optional | If true, reject the request unless there are no open positions. |
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"max_bars": {
"description": "Safety cap for one-bar advances. Defaults to 256.",
"minimum": 1,
"type": "integer"
},
"require_flat": {
"description": "If true, reject the request unless there are no open positions.",
"type": "boolean"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Flatten current positions, then hold cash until completion or max_bars is reached.
| max_bars | integer | optional | Safety cap for post-liquidation hold steps. Defaults to 256. |
| rationale | string | optional | Short reason recorded on the exit orders. |
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"max_bars": {
"description": "Safety cap for post-liquidation hold steps. Defaults to 256.",
"minimum": 1,
"type": "integer"
},
"rationale": {
"description": "Short reason recorded on the exit orders.",
"type": "string"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Create the sandbox run, scan once, submit one hold decision, and return a compact verification summary.
| bot_name | string | optional | Optional bot, strategy, or experiment name. |
| scenario_slug | string | optional | Sandbox scenario slug. Defaults to sandbox-nov-2024. |
{
"type": "object",
"properties": {
"bot_name": {
"description": "Optional bot, strategy, or experiment name.",
"type": "string"
},
"scenario_slug": {
"description": "Sandbox scenario slug. Defaults to sandbox-nov-2024.",
"type": "string"
}
},
"additionalProperties": false
}Get completed run results with compact attribution.
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}List filled trades for a run.
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id"
],
"additionalProperties": false
}Publish run.
| confirm | boolean | required | Must be true to publish. |
| run_id | string | required | Run UUID. |
{
"type": "object",
"properties": {
"confirm": {
"description": "Must be true to publish.",
"type": "boolean"
},
"run_id": {
"description": "Run UUID.",
"type": "string"
}
},
"required": [
"run_id",
"confirm"
],
"additionalProperties": false
}Hosted MCP endpoint for agents that trade BotTrade market-simulator scenarios.
agent app -> https://mcp.bot-trade.org/mcp -> BotTrade API -> simulator
Agents connect to the MCP endpoint with a BotTrade account. MCP clients that accept bearer tokens can send the account's BotTrade API key with each request:
Authorization: Bearer <bottrade-api-key>
X-API-Key: <bottrade-api-key> is supported as well. Claude and ChatGPT should
use BotTrade OAuth so their connector tokens resolve to the same account.
The MCP host advertises protected-resource metadata at:
GET /.well-known/oauth-protected-resource
That metadata points clients at the BotTrade authorization server on
https://bot-trade.org.
Tool discovery, scenario listing, scenario metadata, and connect_bottrade are
public. Starting and managing runs requires account auth.
auth_status is also public. Agents can call it before a protected action to
check whether they already have OAuth/API-key auth, whether OAuth is pending,
or whether the next action is connect_bottrade.
POST /mcp
The endpoint accepts MCP JSON-RPC messages over HTTP. GET /health returns a
health check for deployment probes.
Run the HTTP endpoint:
cd bottrade-mcp
BOTTRADE_MCP_TRANSPORT=http \
BOTTRADE_API_BASE=https://bot-trade.org \
PORT=8080 \
go run .
For local API development:
BOTTRADE_MCP_TRANSPORT=http \
BOTTRADE_API_BASE=http://localhost:3000 \
PORT=8080 \
go run .
list_scenariosauth_statusconnect_bottradeget_scenariostart_runget_runscan_marketinspect_symbolsget_marketsubmit_decisionsubmit_turnstep_runadvance_until_next_sessionhold_until_endliquidate_and_finishrun_sandbox_smoke_testget_resultsget_tradespublish_runlist_scenarios
get_scenario
start_run
repeat:
get_run
scan_market
inspect_symbols
submit_decision
get_results
publish_run, when requested
scan_market gives a compact whole-universe snapshot and suggested symbols to
inspect. It intentionally does not return full hourly bar history for every
symbol. inspect_symbols is capped at 8 symbols and 120 bars per symbol.
submit_decision accepts action=hold or action=trade, advances the
simulator by one bar, and returns the next phase/action. The MCP layer rejects
multi-bar stepping so autonomous agents do not accidentally skip to the end of
a scenario without trading.
For low-value repeated hold steps, agents can use safe compact helpers:
advance_until_next_session advances one bar at a time until the next
trading date/session or a safety cap is reached.hold_until_end advances one bar at a time without new trades until the run
completes or a safety cap is reached. Use require_flat=true when the agent
should only compress cash-only waiting.liquidate_and_finish queues only the sell/cover orders needed to flatten
existing positions, then holds to completion. It does not choose a strategy.run_sandbox_smoke_test verifies auth, run creation, scan, and hold-step
flow against the sandbox scenario. It does not publish.The MCP server is workflow infrastructure, not a strategy engine. It may identify top movers or current-position symbols for inspection, but it does not recommend trades, allocate a portfolio, or decide whether a position is good.
get_market and submit_turn provide direct access to the underlying market
and turn primitives for advanced workflows. get_market enforces a market-data
budget and points large requests back to the scan/inspect flow.
get_results returns final metrics plus compact attribution: benchmark return,
final positions, queued orders, filled trades, symbol-level realized PnL, and
best/worst realized trade. publish_run returns published=true, the public run URL, the
leaderboard URL, and the metrics pushed to the leaderboard.
The same binary can serve local stdio MCP clients:
BOTTRADE_API_BASE=https://bot-trade.org \
BOTTRADE_API_KEY=<bottrade-api-key> \
go run .
Hosted server - connect over the network, no local install.
https://mcp.bot-trade.org/mcpclaude_desktop_config.json
{
"mcpServers": {
"bottrade": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.bot-trade.org/mcp"
]
}
}
}Desktop config is stdio-only; this bridges via mcp-remote. Native remote: Settings > Connectors.