# MCP server for NSE market data

> Connect Claude, Codex or any MCP client to NSE end-of-day data: run screener scans, replay their hit rate, and read 30 years of split-adjusted history.

Canonical: https://patternsradar.com/docs/mcp

Endpoint: `https://api.patternsradar.com/mcp` (streamable HTTP). Authenticate with `Authorization: Bearer prdr_YOUR_KEY` — keys are free on every plan, and the same per-plan rate limits as the REST API apply. The agent does not need to know the query language: the `sift_reference` tool returns the complete machine-readable reference.

## What an agent can do with it

Once connected, these are ordinary prompts:

- “Find NSE stocks above their 200-day average where delivery percentage has been over 60% for a week.”
- “Backtest that scan — what did its matches do over the next 5 days?”
- “How has RELIANCE's delivery percentage trended this month?”
- “Save the ones that work to my account and alert me after each close.”

## Setup

Claude Code:

```bash
claude mcp add --transport http patternsradar \
  https://api.patternsradar.com/mcp \
  --header "Authorization: Bearer prdr_YOUR_KEY"
```

Codex (`~/.codex/config.toml`, or `.codex/config.toml` to scope it to one repo) — the key comes from the named environment variable, not the file:

```toml
[mcp_servers.patternsradar]
url = "https://api.patternsradar.com/mcp"
bearer_token_env_var = "PATTERNSRADAR_API_KEY"
```

opencode (`~/.config/opencode/opencode.json`, or `opencode.json` at a project root) — note the `mcp` key and `type: "remote"`, which differ from the generic block below:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "patternsradar": {
      "type": "remote",
      "url": "https://api.patternsradar.com/mcp",
      "enabled": true,
      "headers": {
        "Authorization": "Bearer {env:PATTERNSRADAR_API_KEY}"
      }
    }
  }
}
```

Any other MCP client (JSON config):

```json
{
  "mcpServers": {
    "patternsradar": {
      "type": "http",
      "url": "https://api.patternsradar.com/mcp",
      "headers": { "Authorization": "Bearer prdr_YOUR_KEY" }
    }
  }
}
```

TypeScript SDK:

```typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });

await client.connect(
  new StreamableHTTPClientTransport(new URL("https://api.patternsradar.com/mcp"), {
    requestInit: {
      headers: { Authorization: `Bearer ${process.env.PATTERNSRADAR_API_KEY}` },
    },
  }),
);

const result = await client.callTool({
  name: "run_scan",
  arguments: {
    source: "close > ema(21) and delivery_pct > 60",
    universe: 500,
  },
});
console.log(result);
```

## Tools

### run_scan

Run a Sift screener query against NSE equities and return the matches. Call sift_reference first if unsure of the syntax.

Parameters:

- `source` (string, required): The Sift query to run.
- `universe` (number, default 500): Liquidity universe: 100, 500 or 2000.
- `as_of` (string): Run as of this session (`YYYY-MM-DD`); defaults to the latest.
- `limit` (number, default 100, max 500): Maximum rows to return.

Returns: `{ok, as_of, count, matches, truncated}` — each match trimmed to symbol, name, close, change_pct, volume, turnover, rsi_14 and delivery_pct, far narrower than the HTTP rows, to spare the model's context.

### hitrate

Replay a Sift query across past sessions and report what its matches did over user-chosen forward horizons: win rate, payoff, excess return vs an index, a monthly breakdown and an equity-curve approximation. A sketch, not a backtest: no costs or slippage, and everything it reports describes past matches, never a prediction.

Parameters:

- `source` (string, required): The Sift query to replay.
- `universe` (number, default 500): Liquidity universe: 100, 500 or 2000.
- `sessions` (number, default 250): How many past sessions to replay.
- `horizons` (number[], default [1, 5, 20]): Forward windows in trading days, each 1–60, at most 4.
- `entryMode` (string, default "close"): `close` (signal bar) or `nextOpen` (next session's open).
- `benchmark` (string, default "NIFTY 50"): A NIFTY index name for excess returns, or `none`.
- `detailHorizon` (number, default the largest horizon): Which horizon the monthly and equity-curve detail describes.
- `stopLossPct` (number, default none): Simulate a stop-loss this many percent below entry; with a stop or target set, each trade exits at whichever of stop, target or horizon close comes first.
- `targetPct` (number, default none): Simulate a profit target this many percent above entry.
- `full` (boolean, default false): Include the per-session equity-curve points, histogram bins and per-trade list. Off by default — they are chart and audit data, and large.

Returns: The same shape as `POST /v1/hitrate`: sessions, totals, per-horizon buckets with payoff, exit-breakdown and benchmark stats, the monthly breakdown, and drawdown numbers. Curve points, histogram bins and trades only with `full`.

### search_symbols

Find NSE symbols by ticker or company name.

Parameters:

- `query` (string, required): Ticker or company name, whole or partial.
- `limit` (number, default 10, max 50): Maximum results.

Returns: `{results}` — the same hits as `GET /v1/search`.

### get_symbol

Identity and latest session for one NSE symbol: name, ISIN, listing dates, liquidity tier, last close and average delivery percentage.

Parameters:

- `symbol` (string, required): The NSE ticker, e.g. `RELIANCE`.

Returns: `{ok, symbol, stats}` — stats included best-effort; `{ok: false, error}` for an unknown ticker.

### get_bars

Recent OHLCV bars for one symbol, most recent last.

Parameters:

- `symbol` (string, required): The NSE ticker, e.g. `RELIANCE`.
- `timeframe` (string, default "1d"): `1d`, `1w` or `1mo`.
- `limit` (number, default 120, max 1000): How many most-recent bars to return.

Returns: `{ok, bars, count}`.

### market_meta

What the market database covers: first and last session, row counts, and how many symbols. Call this to find out how fresh the data is.

Returns: The same shape as `GET /v1/meta`.

### list_saved_scans

List the scans saved to the authenticated account.

Returns: `{scans}` — id, name, source and universe for each.

### save_scan

Save a Sift query to the account. Saving under a name that already exists replaces that scan rather than creating a second one.

Parameters:

- `name` (string, required): What to call the scan; saving over an existing name revises it.
- `source` (string, required): The Sift query.
- `universe` (number, default 500): Liquidity universe: 100, 500 or 2000.

Returns: `{ok, scan}` — the same plan quota as the HTTP route applies; an agent with a key is not a way around a limit.

### delete_scan

Delete a saved scan by name.

Parameters:

- `name` (string, required): The name of the saved scan to delete, matched case-insensitively.

Returns: `{ok}`, or `{ok: false, error}` when no scan has that name.

### sift_reference

The Sift query language: every field, indicator, window, operator and pattern that can appear in a scan. Read this before writing a query.

Returns: The full machine-readable reference: syntax, examples, fields, indicators, window functions, operators, patterns, universes and notes — generated from the same catalog the compiler reads.

## Common questions

### What is the PatternsRadar MCP server?

A Model Context Protocol endpoint that gives AI agents — Claude Code, Codex, or anything speaking MCP over HTTP — direct access to NSE end-of-day data: running Sift screener scans, replaying their historical hit rate, and reading price, volume and delivery data for 3,500+ instruments.

### Is the MCP server free to use?

Yes. API keys are free on every plan, including Free, and the MCP endpoint is metered by the same per-plan rate limits as the REST API. Paid plans raise the limits; they do not gate the capability.

### Does the agent need to know the Sift query language?

No. The sift_reference tool returns the complete machine-readable language reference — fields, indicators, operators, patterns, examples — generated from the same catalog the compiler reads. An agent calls it once and writes valid scans from then on.

### Is the data real-time?

No — end-of-day only, by design. The dataset updates once per session after the NSE close. There is no intraday feed, so an agent asking mid-session sees the previous close.
