traderspost-mcp
by AdairBear
README.md
# TradersPost MCP Server
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that gives Claude direct access to [TradersPost](https://traderspost.io) webhook trading.
Send trade signals, inspect strategy configs, query trade history, and monitor positions — all without leaving Claude Code or Claude Desktop.
> **Why this exists:** TradersPost doesn't expose a full REST management API. This MCP server wraps their webhook system and, optionally, a local [prop_futures_relay](https://github.com/AdairBear/prop_futures_relay) installation to give Claude a complete trading management interface.
---
## What It Does
17 MCP tools covering the full trading workflow:
| Category | Tools |
|----------|-------|
| Strategy management | `tp_list_strategies`, `tp_get_strategy`, `tp_toggle_strategy` |
| Signal submission | `tp_send_signal` |
| Trade history (SQLite) | `tp_get_recent_trades`, `tp_get_fills`, `tp_get_trade_stats` |
| Position state | `tp_get_positions`, `tp_get_daily_pnl` |
| Health & status | `tp_get_relay_health`, `tp_get_strategy_health`, `tp_system_status`, `tp_eval_status` |
| Control (destructive) | `tp_flatten_all`, `tp_flatten_strategy`, `tp_pause_engine`, `tp_resume_engine` |
### Response envelope
Every tool returns one shape. `ok` reflects **semantic** success, not the HTTP status —
a TradersPost HTTP 200 with `success: false` is a rejection and returns `ok: false`.
```jsonc
// success
{ "ok": true, "data": { /* result */ }, /* ...extras */ }
// failure
{ "ok": false, "code": "machine_code", "detail": "human readable", /* ... */ }
```
Plus two MCP resources:
- `traderspost://signal-format` — webhook payload reference
- `traderspost://active-accounts` — account config summary
---
## Modes
### Relay mode (recommended)
Point `RELAY_DIR` at a local [prop_futures_relay](https://github.com/AdairBear/prop_futures_relay) installation. The server reads `account_config.yaml`, state JSON files, and `trading_system.db` for full functionality.
### Standalone mode
Set `TP_WEBHOOK_<STRATEGY>` env vars directly. Signal sending works; strategy management and trade history tools return empty results.
---
## Installation
**Requirements:** Python 3.10+
```bash
git clone https://github.com/AdairBear/traderspost-mcp.git
cd traderspost-mcp
pip install -r requirements.txt
```
Or install dependencies directly:
```bash
pip install "mcp[cli]" httpx pyyaml python-dotenv
```
---
## Configuration
### Claude Code (`.claude/settings.json`)
**Relay mode** — with a local prop_futures_relay installation:
```json
{
"mcpServers": {
"traderspost": {
"command": "python",
"args": ["/path/to/traderspost-mcp/traderspost_mcp.py"],
"env": {
"RELAY_DIR": "/path/to/prop_futures_relay"
}
}
}
}
```
**Standalone mode** — webhook URLs only:
```json
{
"mcpServers": {
"traderspost": {
"command": "python",
"args": ["/path/to/traderspost-mcp/traderspost_mcp.py"],
"env": {
"TP_WEBHOOK_MY_STRATEGY": "https://traderspost.io/trading/webhook/...",
"RELAY_URL": "https://relay.yourdomain.app"
}
}
}
}
```
### Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`)
```json
{
"mcpServers": {
"traderspost": {
"command": "python",
"args": ["/path/to/traderspost-mcp/traderspost_mcp.py"],
"env": {
"RELAY_DIR": "/path/to/prop_futures_relay"
}
}
}
}
```
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `RELAY_DIR` | No | Path to a local `prop_futures_relay` installation. Enables strategy config, state files, and SQLite access. |
| `TP_WEBHOOK_*` | Yes (per strategy) | TradersPost webhook URLs. In relay mode, the strategy's `webhook_ref` field names these. In standalone mode, use `TP_WEBHOOK_<STRATEGY_UPPER>`. |
| `RELAY_URL` | No | Base URL of your running relay (e.g. `https://relay.yourdomain.app`). Required for health check tools. |
Copy `.env.example` to `.env` and fill in your values:
```bash
cp .env.example .env
```
The server auto-loads `.env` from `RELAY_DIR` first, then from its own directory.
---
## Tool Reference
### `tp_list_strategies`
List all configured strategies with their status, ticker, account, and webhook configuration.
```
Returns: JSON with strategy list, account summary, and aliases.
Note: webhook URLs are never exposed — only whether they're configured.
```
### `tp_get_strategy`
Get full configuration for a specific strategy including account rules and session window.
```
Args:
strategy (str): Strategy key, e.g. "sil_crusher_tradovate_44942793"
```
### `tp_toggle_strategy`
Enable or disable a strategy in `account_config.yaml`.
```
Args:
strategy (str): Full strategy key
enabled (bool): True to enable, False to disable
Note: Modifies local config only — restart or redeploy the relay for changes to take effect.
```
### `tp_send_signal` ⚠️
Send a trade signal to TradersPost. **Dry-run by default — pass `live=True` to place a real order.**
```
Args:
strategy (str): Strategy key (or standalone env var suffix)
ticker (str): Instrument — "MNQ", "SIL", "MGC", "ES", etc.
action (str): "buy", "sell" (entries), "exit", "cancel" (exits)
quantity (int): Number of contracts (default: 1)
sentiment (str, optional): "bullish", "bearish", or "flat"
order_type (str, optional): "market", "limit", or "stop"
take_profit (float, optional): Take profit price level
stop_loss (float, optional): Stop loss price level
live (bool): True = REAL order. Default False = dry-run preview only.
test (bool, optional): Force dry-run. If True, overrides live=True (safety wins).
```
**Replay safety:** every attempt is logged to a JSONL audit file (`TP_ATTEMPT_LOG`)
before the POST. An identical *live entry* (buy/sell) within `TP_DEDUP_WINDOW_SEC`
(default 30s) is refused to prevent a timeout-retry duplicate order.
**Exits are sacred:** `exit`/`cancel` are never deduplicated, fire even on a disabled
strategy, and a rejected exit always fails loud (`ok: false`).
### `tp_get_recent_trades`
Query recent trade signals and TradersPost HTTP responses from SQLite.
```
Args:
limit (int): Max records 1-100, default 20
strategy (str, optional): Filter by strategy
account_id (str, optional): Filter by account
days (int, optional): Lookback window in days
```
### `tp_get_fills`
Query actual fill data (execution prices, slippage) from the fills table.
```
Args: Same as tp_get_recent_trades
```
### `tp_get_trade_stats`
Aggregate statistics: signal success rates, slippage summary, per-strategy breakdown.
```
Args:
strategy (str, optional): Filter by strategy
account_id (str, optional): Filter by account
days (int): Lookback period, default 30
```
### `tp_get_positions`
Get current position state from relay state JSON files, or falls back to relay API.
```
Returns: Per-strategy state: FLAT / IN_POSITION / PENDING_ENTRY / PENDING_EXIT / HALTED
```
### `tp_get_daily_pnl`
Get today's estimated P&L from the relay's daily loss tracker.
```
Returns: Per-account estimated P&L and remaining loss budget.
Note: Estimated from signals, not confirmed broker fills.
```
### `tp_get_relay_health`
Check relay health via the `/health` endpoint.
```
Requires: RELAY_URL env var
Returns: Relay version, uptime, component status
```
### `tp_get_strategy_health`
Get per-strategy status (signal counts, last signal time, halts) from the running relay.
```
Requires: RELAY_URL env var
Returns: Per-strategy status from /health/strategies
```
---
## Usage Examples
### Check what's configured
```
"Show me all configured strategies and which ones have webhooks set up"
→ Claude calls tp_list_strategies()
```
### Dry-run a signal
```
"Send a test buy signal for SIL, 1 contract, to the sil_crusher_tradovate_44942793 strategy"
→ Claude calls tp_send_signal(strategy="sil_crusher_tradovate_44942793", ticker="SIL",
action="buy", quantity=1, test=True)
```
### Monitor performance
```
"How many signals has sil_crusher sent this week and what's the success rate?"
→ Claude calls tp_get_trade_stats(strategy="sil_crusher_tradovate_44942793", days=7)
```
### Emergency disable
```
"Disable the MNQ strategy immediately"
→ Claude calls tp_toggle_strategy(strategy="coord_mnq_gmr_tradovate_44942793", enabled=False)
```
### Check positions and P&L
```
"What positions are currently open and what's today's P&L?"
→ Claude calls tp_get_positions() and tp_get_daily_pnl()
```
---
## Security Notes
- Webhook URLs are read from environment variables and **never** appear in tool responses or logs
- `tp_send_signal` is marked `destructiveHint: true` — Claude will confirm before calling it
- `test=True` returns the TradersPost trade plan without executing any orders — use it first
- `tp_toggle_strategy` only modifies local config — the running relay is not affected until redeployed
---
## Architecture
```
Claude (MCP client)
↓ stdio
traderspost_mcp.py (MCP server)
├── account_config.yaml (strategy config — RELAY_DIR mode)
├── data/state/*.json (position state — RELAY_DIR mode)
├── trading_system.db (trade history — RELAY_DIR mode)
├── TP_WEBHOOK_* env vars (webhook URLs — always)
└── RELAY_URL/health (live relay status — optional)
↓ httpx POST
TradersPost webhook
↓
Broker (Tradovate, etc.)
```
---
## Requirements
- Python 3.10+
- `mcp[cli]` >= 1.0 (FastMCP)
- `httpx` >= 0.24
- `pyyaml` >= 6.0
- `python-dotenv` >= 1.0 (optional, for .env auto-loading)
---
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues