Skip to main content
Glama
README.md
# quant-mcp — an MCP server for market analysis

**Built by [Ismaël LADJOHOUNLOU](https://ismael-portfolio-liard.vercel.app/en)** · Model Context Protocol · TypeScript · read-only by design

A [Model Context Protocol](https://modelcontextprotocol.io) server that gives an AI agent
typed access to market data, indicators, backtesting and position sizing. It runs over stdio,
works with Claude Desktop, Claude Code and the MCP inspector, and it is built around the
three things that separate a useful MCP server from a demo:

1. **It fits in a context window.** No tool returns five thousand rows. Long series are
   truncated to the most recent values and the response states the total, so a call never
   pushes the user's original question out of the conversation.
2. **Its errors are recoverable by the model.** An unknown symbol comes back as
   `isError: true` with the list of valid symbols, not as a protocol exception. The model
   fixes its own call and continues.
3. **Its results carry their caveats.** A backtest answer ships the execution model that
   produced it — next-bar fills, costs both sides, stop-before-target — so the model cannot
   quote a return figure without the assumptions that make it meaningful.

The data is **generated deterministically from a seed**, not downloaded. Every number in this
README is reproducible with `npm test`, and nothing here predicts a real market.

## Try it

```bash
npm install
npm test        # 24 tests, including a real MCP client driving a real handshake
npm run inspect # the official inspector, no model required
```

Wire it into a client with three lines of JSON: see [docs/USAGE.md](docs/USAGE.md) for Claude
Desktop, Claude Code, and how to point it at your own CSV history.

## The tools

| Tool | What it does | Guarantee it makes |
|---|---|---|
| `list_symbols` | The instruments available and where they come from | Says whether data is generated or operator-supplied |
| `get_ohlc` | Recent candles for a symbol and timeframe | Bounded response, states how much was left out |
| `indicator` | SMA, EMA, RSI, ATR, Bollinger | Values aligned with candles, `null` before the lookback fills, so nothing is silently shifted by a bar |
| `backtest` | MA cross, RSI reversion or breakout, with metrics, trades and equity curve | Next-bar execution, costs both sides, stop wins a bar that touches both; assumptions returned with the result |
| `position_size` | Risk and stop distance to contracts | Refuses a zero stop; flags notional above 20x equity |

Plus two resources (`quant://symbols`, `quant://methodology`) and two prompts
(`analyse_symbol`, `review_backtest`). The review prompt is the interesting one: it makes the
model re-run with doubled costs and check whether the equity curve rests on a few outliers
**before** it endorses a strategy.

## Why the backtest can be trusted

The engine enforces the four rules that decide whether a backtest means anything, instead of
leaving them to the caller's discipline:

- **A signal from bar *i* fills at the open of bar *i + 1*.** Filling at the close that
  produced the signal is look-ahead, and it is the single most common reason a strategy looks
  profitable on a chart and is not in production. A test walks every trade and asserts the
  fill sits on the next bar's open.
- **Costs are charged on entry and exit.** A test runs the same strategy at zero cost and at
  20 bps and asserts the expensive one ends poorer, with the same trade count — which is how
  you know the costs are applied to the money and not to the signals.
- **A bar touching both stop and target is a stop.** Without tick data the order inside the
  bar is unknowable, and assuming the favourable one is how a win rate gets inflated.
- **Size comes from risk.** Position size is the risked fraction of equity divided by the
  stop distance, which is a multiple of ATR.

Read them in [`src/engine/backtest.ts`](src/engine/backtest.ts), or ask the server for
`quant://methodology`.

## Security

An MCP server runs with the user's privileges, and the thing choosing which tool to call is
a model reading text that may have come from anywhere. The mitigation with the best ratio of
effectiveness to effort is to not ship a dangerous tool: **this server is read-only**. No
filesystem writes, no network calls, no child processes, no trading API, no `eval`. A
prompt injection that reaches it cannot make it destroy anything, because there is nothing
destructive to call.

The full threat model, and the line to hold if you extend it, is in
[docs/SECURITY.md](docs/SECURITY.md).

## Tests

```bash
npm test
```

24 tests in two layers.

**Protocol** — a real `Client` from the SDK, connected over an in-memory transport, doing a
real handshake: capabilities, tool listing with schemas, every tool called, truncation
asserted, schema violations caught before the handler runs, resources read, prompts rendered.
Testing the handler functions directly would pass while the server was unusable by any actual
client. CI goes one step further and pipes raw JSON-RPC into the built binary over stdio.

**Engine** — SMA and EMA against hand computations, RSI bounded and 100 on an unbroken
advance, ATR reflecting a gap rather than just the bar range, determinism of the generated
series, no look-ahead in fills, costs strictly reducing equity, and metrics agreeing with the
equity curve they are derived from.

## Author

**Ismaël LADJOHOUNLOU** — data engineer, algorithmic trading and automation developer.

- Portfolio: <https://ismael-portfolio-liard.vercel.app/en>
- GitHub: <https://github.com/GeneralTradingSarl>
- Upwork: <https://www.upwork.com/freelancers/~01498331f7c7800fc0>
- Related: [Sluice](https://github.com/GeneralTradingSarl/sluice) (streaming pipeline with
  backpressure and exactly-once) · [QuantSwap](https://github.com/GeneralTradingSarl/QuantSwap)
  (DEX with a reorg-safe indexer) · [Cascade](https://github.com/GeneralTradingSarl/Cascade)
  (Instagram to WhatsApp automation)

Available for MCP server, agent tooling and integration work.

## Licence

MIT © 2026 Ismaël LADJOHOUNLOU. See [LICENSE](LICENSE).

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

Each tool covers a distinct aspect of the quant workflow: symbol discovery, OHLC data, indicator calculation, backtesting, and position sizing. There is no meaningful overlap or ambiguity between them.

Naming Consistency3/5

Naming is readable but not uniform: list_symbols and get_ohlc follow a verb_noun pattern, while backtest, indicator, and position_size are single verbs or noun phrases. The inconsistency is noticeable but not confusing.

Tool Count5/5

Five tools is well-scoped for a quantitative analysis server. Each tool serves a necessary step in the analysis workflow without redundancy or bloat.

Completeness4/5

The set covers the core workflow: discover symbols, retrieve data, compute indicators, run backtests, and size positions. Minor gaps exist around strategy persistence or more granular risk controls, but they do not create dead ends for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues