TradeMCP
by Aaditya2502
README.md
# TradeMCP
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that exposes trading analytics — technical indicators, portfolio state, risk metrics, and backtest results — as tools an LLM agent can call. Built to demonstrate protocol-level MCP understanding, not just API wrapping.
The defining design choice: **read operations are open; write operations (placing trades) sit behind a human-in-the-loop approval gate.** Phase 1 (this repo) ships the read-only surface and the architecture that makes the read/write split clean.
---
## Why this exists
Most MCP portfolio projects wrap a public API in a decorator. This one is built around the questions that actually come up when you put an agent in front of something that can move money:
- What happens when the model sends a hallucinated symbol or malformed arguments?
- How do you stop an agent from doing something irreversible?
- How do you keep tool outputs small enough to not blow the context window?
- How do you swap simulated data for a live brokerage without rewriting the tools?
See **[DESIGN.md](./DESIGN.md)** for the full decision record.
---
## Architecture
```
┌──────────────┐ MCP (stdio / streamable HTTP) ┌────────────────────┐
│ LLM client │ ───────────────────────────────► │ TradeMCP server │
│ (Claude etc.)│ ◄─────────────────────────────── │ (server.py) │
└──────────────┘ tool calls / results └─────────┬──────────┘
│ depends on interface
▼
┌──────────────────────────────┐
│ MarketDataProvider (ABC) │
├──────────────────────────────┤
│ SimulatedProvider (default) │
│ KiteProvider (Phase 2) │ ← live AutoTrade Bot
└──────────────────────────────┘
```
| Module | Responsibility |
|---|---|
| `server.py` | Protocol/tool layer: validate input → call provider → format output |
| `data_provider.py` | Data layer behind an abstract interface (the swap point for live data) |
| `models.py` | Pydantic input schemas — the first line of defense against bad LLM input |
| `formatting.py` | Shared markdown/JSON formatting (context-efficient output) |
| `errors.py` | Centralized, *actionable* error messages |
The tool layer depends on the `MarketDataProvider` **interface**, never on a concrete data source. That dependency-inversion boundary is what lets the same server run on simulated data in CI and live data in production.
---
## Tools (Phase 1 — all read-only)
| Tool | Purpose |
|---|---|
| `trade_get_indicators` | Latest RSI / EMA / MACD / ATR + signal for a symbol |
| `trade_get_portfolio` | Holdings, cash, equity, unrealized P&L |
| `trade_get_portfolio_risk` | Concentration, beta, VaR, Sharpe, drawdown, circuit breakers |
| `trade_list_backtests` | Paginated list of backtest runs (discover run IDs) |
| `trade_get_backtest` | Full metrics for one run |
Every tool is annotated `readOnlyHint: true` and supports both `markdown` (default, human-readable) and `json` (structured) output.
---
## Quickstart
```bash
# 1. Install
pip install -e ".[dev]"
# 2. Run the test suite
pytest
# 3. Run the server (stdio transport, the default)
python -m trade_mcp.server
# Or over HTTP for remote clients:
TRADE_MCP_TRANSPORT=streamable_http TRADE_MCP_PORT=8000 python -m trade_mcp.server
```
### Inspect with the MCP Inspector
```bash
npx @modelcontextprotocol/inspector python -m trade_mcp.server
```
### Wire into Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"trade-mcp": {
"command": "python",
"args": ["-m", "trade_mcp.server"],
"cwd": "/absolute/path/to/trade-mcp/src"
}
}
}
```
Then ask: *"What's the RSI on Reliance, and how concentrated is my portfolio?"*
---
## Data is simulated (by design)
The default `SimulatedMarketDataProvider` returns deterministic data derived from a hash of each input, so demos and tests are fully reproducible with zero credentials. Wiring in the live [AutoTrade Bot](#) backend means implementing the five `MarketDataProvider` methods in a new class and changing one line in `server.py`.
---
## Roadmap
- [x] **Phase 1** — Read-only analytics surface, provider abstraction, tests
- [ ] **Phase 2** — `trade_place_order` behind a human approval gate (Telegram confirmation + audit log)
- [ ] **Phase 3** — Rate limiting, response caching, retries
- [ ] **Phase 4** — Multi-server client demonstrating tool discovery/orchestration
- [ ] **Phase 5** — Live `KiteMarketDataProvider` wrapping the real trading bot
---
## License
MIT
TDQS
A4.6/5.0
Scored across 5 tools
Disambiguation5/5
Each tool targets a distinct area: backtest details, indicators, portfolio snapshot, portfolio risk, and backtest listing. No overlap in functionality.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern prefixed with 'trade_' (e.g., trade_get_backtest, trade_list_backtests).
Tool Count5/5
5 tools cover the core analytical needs of a trading server: portfolio overview, risk assessment, indicators, and backtesting. Well-scoped.
Completeness4/5
The server focuses on read-only analytics; missing order placement or historical price data, but core portfolio, risk, indicators, and backtest coverage is solid.
Maintenance
ActivityInactive
ResponsivenessNo issues