quant-research-mcp
by Kumudadp
README.md
# quant-research-mcp
A small [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that exposes
market-data and quant-research tools — get a stock price, pull price history, compute a moving
average, and backtest an SMA-crossover strategy — to any MCP client (Claude Code, Claude
Desktop, etc.).
## What's in here
```
quant-mcp-server/
├── server.py # MCP server: defines the 4 tools, thin wrappers only
├── market_data.py # Data access: yfinance, with a deterministic offline fallback
├── quant.py # Pure calculation logic: SMA, crossover backtest (no MCP/network)
├── test_quant.py # Unit tests for quant.py (pytest)
├── requirements.txt
└── README.md
```
Logic is split into three layers on purpose: `quant.py` has zero dependency on MCP or the
network, so it's trivially unit-testable; `market_data.py` isolates the flaky, external part
(a live API call) behind one function; `server.py` is just the MCP glue. This is the same
separation you'd want in a production trading tool — you never want your strategy math coupled
to your data feed.
### The 4 tools
| Tool | What it does |
|---|---|
| `get_stock_price(ticker)` | Latest close price |
| `get_price_history(ticker, period)` | Daily OHLCV history |
| `compute_moving_average(ticker, window, period)` | Simple moving average, latest value + tail |
| `backtest_sma_crossover(ticker, short_window, long_window, period)` | Backtests a long/flat SMA-crossover strategy: total return, Sharpe, max drawdown, trade count, vs. buy-and-hold |
If Yahoo Finance is unreachable (no internet, rate-limited, bad ticker), every tool falls back
to a deterministic synthetic price series instead of crashing — and always tags the response
with `"source": "synthetic-fallback"` so it's never mistaken for real data. This matters more
than it sounds: an MCP tool that just throws a stack trace at the model produces a worse agent
experience than one that degrades gracefully and says so.
---
## 1. Set up the project
```bash
git clone <your-repo-url> quant-mcp-server # or just use this folder directly
cd quant-mcp-server
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
Run the tests (no network needed, all against `quant.py` directly):
```bash
pytest test_quant.py -v
```
Run the server standalone, just to confirm it starts:
```bash
python server.py
```
It'll sit there waiting for an MCP client to connect over stdio — that's expected, not a hang.
Ctrl+C to stop.
---
## 2. Install Claude Code (if you haven't)
```bash
curl -fsSL https://claude.ai/install.sh | bash
```
(macOS/Linux/WSL. For native Windows or other install methods — Homebrew, winget, apt/dnf —
see the [Claude Code docs](https://code.claude.com/docs).) Then authenticate:
```bash
claude
```
and follow the login prompt once.
---
## 3. Register this server with Claude Code
From inside the project folder:
```bash
claude mcp add quant-research --scope project -- python /absolute/path/to/quant-mcp-server/server.py
```
- `--scope project` writes the config to `.mcp.json` in this folder (shareable/commit-able,
vs. `--scope user` which is global to your machine).
- Everything after `--` is the exact command Claude Code runs to start your server — swap in
your venv's Python if you want to guarantee the right interpreter, e.g.
`.venv/bin/python server.py`.
Verify it's registered:
```bash
claude mcp list
```
Then start Claude Code in this directory:
```bash
claude
```
On first use in a session it'll ask you to approve the project's MCP server — approve it, then
just talk to it:
> "What's the current price of AAPL?"
> "Backtest a 20/50 SMA crossover on MSFT over the last year and tell me if it beat buy-and-hold."
> "Compute the 50-day moving average for TSLA and tell me if the price is above or below it."
Claude Code will decide on its own which tool(s) to call based on the docstrings in
`server.py` — that's the whole point of MCP: you don't write any glue code connecting your
prompt to the tool, the client figures it out from the tool descriptions.
---
## 4. (Optional) Also connect it to Claude Desktop
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`
on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
```json
{
"mcpServers": {
"quant-research": {
"command": "python",
"args": ["/absolute/path/to/quant-mcp-server/server.py"]
}
}
}
```
Restart Claude Desktop and the tools show up the same way.
---
## Possible extensions
Ideas for taking this further:
- **Portfolio backtesting**: `backtest_portfolio(tickers, weights, ...)` that runs the
crossover strategy across several tickers and combines the equity curves.
- **Risk metrics**: value-at-risk, beta vs. a benchmark index, volatility — extends
`quant.py`, stays fully unit-testable.
- **A second real data source** (e.g. Stooq or Alpha Vantage) as a fallback before synthetic
data, so degradation goes "best → good → synthetic" instead of straight to synthetic.
- **Docker packaging**, registered with Claude Code via `docker run` instead of `python` —
closer to how this would actually be deployed.
- **A `resources` endpoint** (MCP supports these alongside tools) exposing something like a
cached watchlist.
## Design notes
Built to explore two things together: using Claude Code as an agentic development workflow,
and building an MCP server other agents can call. The layered structure (calculation logic /
data access / MCP wrapper) and the graceful-fallback behavior were deliberate choices, not
defaults — the goal was a small tool that fails informatively rather than silently, which
matters more in a production data pipeline than the strategy logic itself does.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues