QuantData MCP Server
by zzulanas
README.md
# QuantData MCP Server
[](LICENSE)
[](https://www.python.org/downloads/)
[](https://pypi.org/project/quantdata-mcp/)
[](https://pypi.org/project/quantdata-mcp/)
## THIS IS AN UNOFFICIAL MCP SERVER I AM NOT AFFILIATED WITH QUANTDATA IN ANY WAY
MCP server that gives AI agents (Claude Code, Claude Desktop, etc.) access to real-time and historical options market data from [QuantData](https://quantdata.us).
> π New to this? Start with the [Getting Started Guide](GETTING_STARTED.md) for a step-by-step walkthrough.
**Supports any optionable ticker** β SPX, SPY, QQQ, AAPL, TSLA, and more. Not just 0DTE.
**Available data:** GEX/DEX/CEX/VEX exposure walls, exposure term structure, net drift, max pain (instantaneous + per-expiration), IV rank, IV skew, IV term structure, volatility drift (ARV vs IV), trade side statistics, open interest (per strike, per expiration, over time, day-over-day change), net flow, consolidated + unconsolidated order flow, contract OHLCV, and contract statistics.
**Documentation:** see [GETTING_STARTED.md](GETTING_STARTED.md) for a click-by-click walkthrough.
## Quick Start
### 1. Install
You need **Python 3.11+** installed. Check with `python3 --version`.
- **Mac:** `brew install python` (or download from [python.org](https://www.python.org/downloads/))
- **Windows:** Download from [python.org](https://www.python.org/downloads/) (check "Add to PATH" during install)
Install from PyPI:
```bash
# With pip
pip install quantdata-mcp
# With uv (faster)
uv pip install quantdata-mcp
# Or install as a global tool with uv
uv tool install quantdata-mcp
```
> **Don't have uv?** Install it with `curl -LsSf https://astral.sh/uv/install.sh | sh` (Mac/Linux) or `irm https://astral.sh/uv/install.ps1 | iex` (Windows). It's a faster alternative to pip.
> **Want the bleeding edge?** Install from GitHub: `pip install git+https://github.com/zzulanas/quantdata-mcp.git`
### 2. Get Your Credentials
You need two values from your QuantData account. Open your browser:
1. Go to [v3.quantdata.us](https://v3.quantdata.us) and **log in**
2. Open **DevTools** (F12 or right-click β Inspect) β **Network** tab
3. Refresh the page
4. Click on any chart or page on QuantData β you'll see API requests appear
5. Click any request to `core-lb-prod.quantdata.us`, or filter by /api in the top
6. In the **Request Headers**, find and copy:
- **`authorization`** β your auth token (starts with `eyJ...`)
- **`x-instance-id`** β your instance ID (a UUID like `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`)
Should look like these:
<img width="2093" height="1146" alt="Screenshot 2026-03-27 at 8 49 30 PM 1" src="https://github.com/user-attachments/assets/51856fbb-7f22-458e-8478-8906f8792a54" />
### 3. Run Setup
```bash
quantdata-mcp setup \
--auth-token "eyJhbGci..." \
--instance-id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```
This creates a dedicated page on your QuantData account with 19 data tools and saves your config to `~/.quantdata-mcp/config.json`.
> **Upgrading from a previous install?** Just upgrade the package β the server auto-registers any new tool definitions (e.g. the 8 Tier-1 additions in this release) on first start. Existing tool IDs and page layout are preserved. Re-running `quantdata-mcp setup` is no longer required when a release adds new tools; only run it again if you need to refresh an expired auth token.
### 4. Add to Claude
#### Claude Code
Add to your project's `.mcp.json` (or global `~/.claude/mcp.json`):
```json
{
"mcpServers": {
"quantdata": {
"command": "quantdata-mcp",
"args": ["serve"]
}
}
}
```
Restart Claude Code. You should see `quantdata` in your MCP servers.
#### Claude Desktop
Add to your Claude Desktop config file:
- **Mac:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"quantdata": {
"command": "quantdata-mcp",
"args": ["serve"]
}
}
}
```
> **Note:** `quantdata-mcp` must be on your system PATH. If it's not found, use the full path:
> ```bash
> which quantdata-mcp # find the path
> ```
> ```json
> { "command": "/Users/you/.local/bin/quantdata-mcp", "args": ["serve"] }
> ```
>
> Or use `uvx` to run without worrying about PATH:
> ```json
> {
> "command": "uvx",
> "args": ["--from", "git+https://github.com/zzulanas/quantdata-mcp.git", "quantdata-mcp", "serve"]
> }
> ```
Restart Claude Desktop. The QuantData tools will appear in your tool list.
## Available Tools
### Market Overview
| Tool | Description |
|------|-------------|
| `qd_get_market_snapshot` | Full overview: GEX + DEX walls, drift, max pain, trade stats |
| `qd_set_page_date` | Switch ticker, session date, and/or expiration for analysis |
### Exposure (Greeks)
| Tool | Description | Key Settings |
|------|-------------|--------------|
| `qd_get_exposure_by_strike` | GEX/DEX/CEX/VEX wall data by strike | `greek_type`, `representation_mode` (per 1%, per $1, raw), `is_net`, `time_minutes` |
| `qd_get_exposure_by_expiration` | Greek exposure term structure across expirations | `greek_type`, `representation_mode`, `is_net`, `strikes` filter |
### Premium Flow
| Tool | Description | Key Settings |
|------|-------------|--------------|
| `qd_get_net_drift` | Cumulative call vs put premium flow | `aggregation` (1minβ1hr), `moneyness`, `strikes` filter |
| `qd_get_net_flow` | Call/put premium flow over time | `aggregation`, `data_mode` (premium/volume), `moneyness`, `trade_side`, `strikes` |
### Order Flow & Trade Stats
| Tool | Description | Key Settings |
|------|-------------|--------------|
| `qd_get_order_flow` | Consolidated order flow β individual large trades (40+ filters) | bool flags (`is_unusual`, `is_golden_sweep`, `is_opening_position`, ...), thresholds (`min_premium`, `min_size`, `min_volume`, `min_iv`, `max_dte`, ...), greek floors (`min_delta`, `min_gamma`, `min_theta`, ...), multi-selects (`sentiment_type`, `trade_type`, `sector`, `industry`, ...) |
| `qd_get_unconsolidated_flow` | Raw per-trade order flow β every trade, no sweep/block rollup. Mirrors `qd_get_order_flow`'s 40+ filters (no `is_golden_sweep`; sorted by premium DESC). | Same filter set as `qd_get_order_flow` minus `is_golden_sweep` and `trade_consolidation_type` |
| `qd_get_trade_side_stats` | Trade aggression: AA/A/M/B/BB breakdown | `data_mode`, `moneyness`, `strikes` |
| `qd_get_contract_statistics` | Total premium, trade count, volume by call/put | `moneyness`, `trade_side`, `strikes` |
`qd_get_order_flow` is the most filter-rich tool β it now exposes the full
QuantData order-flow filter set (40+ flat kwargs grouped into bool flags,
GTE/LTE thresholds, greek thresholds, and multi-select lists). Example β
bullish opening-position sweeps in tech with $10K+ premium:
```python
qd_get_order_flow(
ticker="SPY", is_unusual=True, is_opening_position=True,
sentiment_type=[SentimentType.BULLISH], min_premium=10000,
trade_type=["AUTO"], sector=["TECHNOLOGY"], last_n=20,
)
```
### Volatility & Pricing
| Tool | Description | Key Settings |
|------|-------------|--------------|
| `qd_get_iv_rank` | IV rank vs historical range | `lookback_period`, `maturity`, `contract_type` |
| `qd_get_volatility_skew` | IV across strikes per expiration (the "smile" / "smirk") | `contract_type`, `expirations`, `near_n` |
| `qd_get_term_structure` | Expected move + IV grid across expirations | `contract_type`, `expirations`, `moneyness`, `min_delta`, `max_delta` |
| `qd_get_volatility_drift` | Realized vs implied volatility (ARV vs IV) over time | `last_n` |
| `qd_get_contract_price` | OHLCV price data for a specific contract | `strike` (required), `contract_type`, `aggregation` |
### Open Interest & Max Pain
| Tool | Description | Key Settings |
|------|-------------|--------------|
| `qd_get_max_pain` | Max pain strike + distance from current price | β |
| `qd_get_max_pain_over_time` | Max pain strike for each expiration of the chain | β |
| `qd_get_oi_by_strike` | Open interest distribution with near-ATM filtering | `near_strike` |
| `qd_get_oi_by_expiration` | Total call/put OI summed per expiration | `strikes` |
| `qd_get_oi_over_time` | Call/put OI per session date β track build-up over time | `strikes`, `chart_type`, `last_n` |
| `qd_get_oi_change` | Day-over-day OI change β biggest gainers / losers | `min_pct_change`, `contract_type`, `strikes`, `expirations`, `top_n` |
### Common Parameters
All tools accept these parameters for ticker/date control:
| Parameter | Description | Default |
|-----------|-------------|---------|
| `ticker` | Any optionable symbol (SPX, SPY, QQQ, AAPL, TSLA, etc.) | `SPX` |
| `date` | Session date YYYY-MM-DD | Today |
| `expiration_date` | Expiration date YYYY-MM-DD | Same as `date` (0DTE) |
### Filter Parameters
Tools that support filtering accept these optional parameters:
| Parameter | Values | Description |
|-----------|--------|-------------|
| `moneyness` | `OTM`, `ITM`, `ATM` | Filter by moneyness (pass a list to combine) |
| `trade_side` | `AA`, `A`, `M`, `B`, `BB` | Filter by trade aggression |
| `strikes` | Dollar values, e.g. `[5600.0]` | Filter to specific strikes |
| `contract_type` | `CALL`, `PUT` | Filter to calls or puts only |
| `min_premium` | Dollar amount, e.g. `50000` | Minimum premium threshold (order flow only) |
### Example Usage
Ask Claude things like:
- *"What are the biggest GEX walls right now?"*
- *"Show me yesterday's DEX walls at 10:30 AM"*
- *"Pull up the trade side stats β are puts or calls more aggressive today?"*
- *"Compare the GEX profile at open vs close for last Thursday"*
- *"Show me AAPL gamma exposure for the April 17 monthly expiration"*
- *"What's the OTM-only net drift for SPX today?"*
- *"Show me the order flow β just calls with premium over $50K"*
- *"Get the OHLCV for the SPX 6600 call today"*
- *"What's the IV rank with a 30-day lookback?"*
- *"Show the GEX term structure across all expirations"*
### Multi-Ticker Support
All tools work with any optionable ticker. Just pass `ticker="AAPL"` (or whatever symbol).
**Important:** SPX, SPY, and QQQ have **daily** expirations (0DTE works by default). For equity options like AAPL or TSLA, you **must** set `expiration_date` to a valid expiration (e.g. monthly 3rd Friday) or you'll get empty data.
```
> Show me TSLA GEX walls for the April 17 monthly
> qd_get_exposure_by_strike(ticker="TSLA", expiration_date="2026-04-17")
```
### Historical Data + Time Scrubber
All tools support historical analysis. Set context once via `qd_set_page_date` and subsequent calls inherit it (the page filter is sticky as of v0.3.0):
```
> Switch to RKLB on 2026-05-08, then show me the gamma walls
> qd_set_page_date(date="2026-05-08", ticker="RKLB", expiration_date="2026-05-15")
> qd_get_exposure_by_strike() # inherits RKLB / 5/8 / 5/15
> qd_get_max_pain() # still RKLB / 5/8 / 5/15
```
**Persistent intraday scrubber** β set a tool to a specific moment of the trading day and the chart in your QuantData browser updates live:
```
> Show me the GEX walls at 11:00 AM yesterday
> qd_set_tool_time("exposure_by_strike", "11:00") # accepts "9:30", "1:30 PM", "16:00"
> qd_get_exposure_by_strike() # data scrubbed to 11:00 AM
> qd_reset_to_live("exposure_by_strike") # back to most recent
```
**Note:** `date` must be a valid trading day (not weekends or market holidays).
### Filter Groups (v0.3.0)
QuantData's filter groups are server-side, persistent, named filter sets that attach to tools. Once attached, the filter is AND'd onto every fetch β visible and editable in the QuantData web UI alongside what the LLM is doing.
```
> Save a filter group that excludes complex spreads, tied trades, and floor trades.
Apply it to net_drift.
> qd_save_filter_group(
name="clean_signal",
conditions=[
{"field": "IS_COMPLEX", "op": "==", "value": False},
{"field": "IS_TIED", "op": "==", "value": False},
{"field": "IS_FLOOR", "op": "==", "value": False},
{"field": "IS_CANCELLED", "op": "==", "value": False},
],
)
> qd_apply_filter_group("net_drift", "clean_signal")
```
After this, every `qd_get_net_drift(...)` call automatically AND's those four conditions. Edit incrementally with `qd_add_filter_clause`, `qd_update_filter_clause`, `qd_remove_filter_clause`. Discover community filters with `qd_search_public_filter_groups`. Field/operator catalog: `qd_list_filter_fields`.
## How It Works
QuantData doesn't have an official API. This server uses reverse-engineered REST endpoints from their web app. Each user has "tools" (chart widgets) on "pages" β the setup command creates a dedicated page with all 19 data types so the MCP server can query them.
**Architecture:**
```
Claude --> MCP (stdio) --> quantdata-mcp server --> QuantData REST API
```
Your credentials and tool IDs are stored locally at `~/.quantdata-mcp/config.json`.
## Commands
```bash
quantdata-mcp setup --auth-token <TOKEN> --instance-id <ID> # One-time setup
quantdata-mcp serve # Start MCP server (used by Claude)
```
## Requirements
- Python 3.11+
- Active [QuantData](https://quantdata.us) subscription
## Troubleshooting
**"Config not found" error:** Run `quantdata-mcp setup` first.
**Auth errors (401):** Your token expired. Get a new one from the Network tab and re-run setup. Your existing page and tools will be reused:
```bash
quantdata-mcp setup --auth-token "NEW_TOKEN" --instance-id "SAME_ID"
```
**Empty data:** Make sure you have an active QuantData subscription and the market was open on the date you're querying. For non-index tickers (AAPL, TSLA), make sure you set `expiration_date` to a valid options expiration.
**"No such file or directory" in Claude Desktop:** Use the full path to `quantdata-mcp` (see step 4 above).
## Contributing
Contributions are welcome β bug reports, new tools wrapping additional QuantData widgets, formatter improvements, and docs all help. See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev environment setup, the recipe for adding a new MCP tool, and the conventions to follow when sending a PR.
## License
MIT β see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues