# TradeStation MCP Server

[![PyPI version](https://img.shields.io/pypi/v/tradestation-mcp)](https://pypi.org/project/tradestation-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/tradestation-mcp)](https://pypi.org/project/tradestation-mcp/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/theelderwand/tradestation-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/theelderwand/tradestation-mcp/actions/workflows/ci.yml)

An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that exposes the full [TradeStation API](https://api.tradestation.com/docs/specification/) as tools for LLM-powered applications like Claude Desktop, VS Code Copilot, and other MCP clients.

## Features

- **36 MCP Tools** covering all three TradeStation API categories:
  - **Market Data** (17 tools): Quotes, historical bars, option chains, market depth, symbol search, streaming
  - **Brokerage** (11 tools): Accounts, balances, positions, orders, order history, streaming
  - **Order Execution** (8 tools): Place/confirm/replace/cancel orders, group orders (OCO/Bracket), routes
- **5 MCP Prompts** for common workflows: portfolio review, stock lookup, trade placement, options analysis, daily summary
- **Built-in OAuth2 Authentication**: Opens your browser for secure TradeStation login — no manual token management
- **Automatic Token Refresh**: Access tokens refresh automatically (they expire every 20 minutes)
- **Streaming Support**: Real-time market data and order updates via time-bounded collection windows
- **Smart Account Resolution**: Brokerage tools auto-detect your accounts when IDs aren't specified
- **Rich Tool Descriptions**: Domain-tagged descriptions ensure the LLM correctly routes "What's my balance?" to brokerage tools and "What's the stock price?" to market data tools

## Prerequisites

- **Python 3.10+**
- **TradeStation Account** with API access
- **TradeStation API Key** — [Get one here](https://api.tradestation.com/docs/faq#how-do-i-get-an-api-key)

## Installation

### From PyPI (recommended)

```bash
pip install tradestation-mcp
```

### From source (development)

```bash
# Clone the repository
git clone https://github.com/theelderwand/tradestation-mcp.git
cd tradestation-mcp

# Create and activate a virtual environment
python -m venv .venv

# Windows
.venv\Scripts\activate

# macOS/Linux
# source .venv/bin/activate

# Install in development mode with dev dependencies
pip install -e ".[dev]"
```

### Quick run with uvx (no install needed)

```bash
uvx tradestation-mcp
```

## Configuration

1. Copy the example environment file:
   ```bash
   copy .env.example .env
   ```

2. Edit `.env` with your TradeStation API credentials:
   ```env
   TS_CLIENT_ID=your_api_key_here
   TS_CLIENT_SECRET=your_api_secret_here
   TS_REDIRECT_PORT=3000
   ```

3. Make sure your API key has `http://localhost:3000` in its Allowed Callback URLs (this is a default for new keys).

## First Run — Authentication

On first launch, the server will:
1. Open your default browser to the TradeStation login page
2. You log in with your TradeStation credentials and authorize the application
3. The browser redirects back to `localhost:3000` where the server captures the auth code
4. Tokens are exchanged and saved to `~/.tradestation_mcp_tokens.json`

Subsequent launches will use the saved refresh token — no browser needed unless the refresh token is revoked.

## Usage with GitHub Copilot CLI

GitHub Copilot CLI stores MCP server configs in `~/.copilot/mcp-config.json`. You can set it up in two ways:

### Option A: Interactive (inside Copilot CLI)

1. Launch `copilot` (or `gh copilot`) in your terminal
2. Type `/mcp add`
3. Fill in the fields:
   - **Name**: `tradestation`
   - **Type**: `stdio`
   - **Command**: `tradestation-mcp`  (if installed via pip)
4. Press `Ctrl+S` to save

### Option B: Edit the config file directly

Create or edit `~/.copilot/mcp-config.json`:

```json
{
  "mcpServers": {
    "tradestation": {
      "type": "stdio",
      "command": "tradestation-mcp",
      "env": {
        "TS_CLIENT_ID": "your_api_key",
        "TS_CLIENT_SECRET": "your_api_secret"
      }
    }
  }
}
```

> **Note**: If you installed from source instead of pip, replace `"command": "tradestation-mcp"` with the full path to your Python executable and use `"args": ["-m", "tradestation_mcp.server"]`.

### Verify it works

Inside Copilot CLI, type `/mcp` to see your configured servers and confirm `tradestation` is listed. Then try:

```
Use the tradestation MCP server to get a quote for MSFT
```

### Allow tools without manual approval (optional)

```bash
copilot --allow-tool 'tradestation'
```

Or deny specific dangerous tools while allowing the rest:

```bash
copilot --allow-tool 'tradestation' --deny-tool 'tradestation(place_order)' --deny-tool 'tradestation(place_group_order)'
```

## Usage with Claude Desktop

Add to your Claude Desktop configuration (`%APPDATA%\Claude\claude_desktop_config.json` on Windows):

```json
{
  "mcpServers": {
    "tradestation": {
      "command": "tradestation-mcp",
      "env": {
        "TS_CLIENT_ID": "your_api_key",
        "TS_CLIENT_SECRET": "your_api_secret"
      }
    }
  }
}
```

## Usage with VS Code (Copilot / MCP)

Add to your VS Code `.vscode/mcp.json`:

```json
{
  "servers": {
    "tradestation": {
      "command": "tradestation-mcp",
      "env": {
        "TS_CLIENT_ID": "your_api_key",
        "TS_CLIENT_SECRET": "your_api_secret"
      }
    }
  }
}
```

## Tool Reference

### Market Data Tools

| Tool | Description | Example Query |
|------|-------------|---------------|
| `get_quote_snapshots` | Current price quotes | "What's the stock price of MSFT?" |
| `get_bars` | Historical OHLCV bars | "Show me AAPL daily chart for last month" |
| `stream_bars` | Live streaming bars | "Stream live 1-minute bars for TSLA" |
| `get_crypto_symbol_names` | List crypto pairs | "What crypto symbols are available?" |
| `get_symbol_details` | Symbol info/metadata | "What exchange does MSFT trade on?" |
| `get_option_expirations` | Option expiry dates | "When do AAPL options expire?" |
| `get_option_risk_reward` | Risk/reward analysis | "What's the max profit on this spread?" |
| `get_option_spread_types` | Available strategies | "What option spread types exist?" |
| `get_option_strikes` | Available strikes | "Show strikes for AAPL options" |
| `stream_option_chain` | Live option chain | "Show me the AAPL option chain" |
| `stream_option_quotes` | Live option pricing | "Stream greeks for these contracts" |
| `stream_quotes` | Live quote stream | "Stream live prices for MSFT,AAPL" |
| `stream_market_depth_quotes` | Level 2 data | "Show market depth for MSFT" |
| `stream_market_depth_aggregates` | Aggregated depth | "Show aggregated order book for SPY" |
| `suggest_symbols` | Symbol autocomplete | "Find symbols for Tesla" |
| `search_symbols` | Advanced symbol search | "Search for ES futures" |
| `stream_tick_bars` | Tick-based bars | "Show tick bars for MSFT" |

### Brokerage Tools

| Tool | Description | Example Query |
|------|-------------|---------------|
| `get_accounts` | List accounts | "What accounts do I have?" |
| `get_balances` | Current balances | "What's my account balance?" |
| `get_balances_bod` | Opening balances | "What was my balance at market open?" |
| `get_positions` | Current holdings | "What stocks do I own?" |
| `get_orders` | Today's orders | "Do I have any open orders?" |
| `get_orders_by_id` | Specific order lookup | "Show me order 123456789" |
| `get_historical_orders` | Past order history | "Show my trades from last week" |
| `get_historical_orders_by_id` | Specific past order | "Find historical order 123456789" |
| `stream_orders` | Live order updates | "Stream my order status updates" |
| `stream_orders_by_id` | Live specific order | "Watch order 123456789 for fills" |
| `stream_positions` | Live position updates | "Stream my portfolio P&L" |

### Order Execution Tools

| Tool | Description | Example Query |
|------|-------------|---------------|
| `confirm_order` | Preview order cost | "How much to buy 100 MSFT?" |
| `place_order` | Execute a trade | "Buy 100 shares of MSFT" |
| `confirm_group_order` | Preview group order | "Preview my bracket order" |
| `place_group_order` | Place OCO/bracket | "Place bracket order on AAPL" |
| `replace_order` | Modify open order | "Change my limit to $150" |
| `cancel_order` | Cancel open order | "Cancel order 123456789" |
| `get_activation_triggers` | Conditional triggers | "What trigger types are available?" |
| `get_routes` | Order routes | "What routes can I use?" |

## Security Notes

- **Token Storage**: Tokens are saved in plaintext at `~/.tradestation_mcp_tokens.json`. This file contains your refresh token which can be used to obtain new access tokens. Ensure your home directory has appropriate permissions.
- **Refresh Tokens**: By default, TradeStation refresh tokens do not expire. You can contact TradeStation Client Experience to enable rotation (30-minute expiry).
- **Order Safety**: The `place_order` tool description instructs the LLM to always call `confirm_order` first, but this is guidance — the tool itself does not enforce it.
- **Production API**: This server connects to TradeStation's production API. All orders are REAL.

## Troubleshooting

**"TS_CLIENT_ID environment variable is required"**
- Ensure your `.env` file exists or set the environment variables directly.

**Browser doesn't open for authentication**
- Manually visit the URL printed in stderr logs.
- Ensure port 3000 (or your configured port) is not in use.

**"Token refresh failed"**
- Delete `~/.tradestation_mcp_tokens.json` and restart to re-authenticate.

**"No brokerage accounts found"**
- Ensure your API key has the correct logins configured. Contact TradeStation Client Experience.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.

## License

[MIT](LICENSE)

## Links

- [Changelog](CHANGELOG.md)
- [Security Policy](SECURITY.md)
- [TradeStation API Docs](https://api.tradestation.com/docs/specification/)
- [Model Context Protocol](https://modelcontextprotocol.io/)
