NSE MCP Explorer

Architecture

Decision summary

Decision Choice Why
Language TypeScript end-to-end The official MCP TypeScript SDK has a first-class Streamable HTTP client; one language lets the UI and backend share types, the tool catalog, argument validation and analytics.
Backend Node.js + Express 5 (one small process) NSE’s CORS policy blocks browsers, so a backend must be the MCP client. Express is the most familiar choice for readers of an educational repo.
Frontend React 19 + Vite, no UI/chart libraries Small, readable components. Charts are ~200 lines of SVG — enough for line/volume/bar/range views without a dependency.
Analytics Pure TypeScript functions (shared/analytics.ts) NSE already aggregates server-side (SMA, volume stats, 52W range, comparisons). What’s missing — corporate-action adjustment, EMA/RSI/volatility/drawdown series, relative volume — is small and runs in both browser and server. Python/Pandas was evaluated and rejected: responses are ≤ ~40 KB and the computations are simple, so a second runtime would add setup cost with no benefit.
Python Example only (examples/python) Shows the official mcp Python SDK for developers who prefer it; tested against the mock.
Offline/testing Mock MCP server built with the same SDK, replaying recorded NSE responses NSE availability is intermittent; tests must not depend on it, and new users should be able to explore offline.
AI agent Optional, Anthropic SDK manual tool-use loop Demonstrates MCP’s core value (model chooses tools from tools/list) without becoming a separate product. Disabled unless ANTHROPIC_API_KEY is set.
Storage None Nothing to persist. A 60-second in-memory cache avoids re-hitting NSE.

Component diagram

┌──────────────────────── Browser ────────────────────────┐
│ React UI (web/src)                                      │
│  Learn · Dashboard · Explorer · Examples · Insights ·   │
│  Integrate · Agent · Protocol log                       │
└───────────────┬─────────────────────────────────────────┘
                │ JSON over HTTP  (/api/*)
┌───────────────▼──────────── Node backend (server/src) ─────────────────────┐
│ app.ts            Express routes, error mapping                            │
│ analytics/recipes multi-tool compositions (deep dive, unusual volume, …)   │
│ agent/agent.ts    optional Claude tool-use loop over discovered tools      │
│ mcp/hub.ts        NseMcpHub: routing, validation, limiter, cache, stats    │
│ mcp/connection.ts one MCP Client + StreamableHTTPClientTransport per server│
│ mcp/wiretap.ts    fetch wrapper that records every JSON-RPC exchange       │
└───────────────┬───────────────────────────────┬────────────────────────────┘
                │ MCP (JSON-RPC over Streamable HTTP)
   ┌────────────▼────────────┐       ┌──────────▼──────────────┐
   │ cm-market-mcp           │       │ nse-bhavcopy-redis-mcp  │
   │ mcp.nseindia.in/cmmkt   │       │ …/bhavcopy/cm/mcp       │
   └─────────────────────────┘       └─────────────────────────┘
          (or mock/server.ts replaying mock/fixtures/nse-fixtures.json)

shared/  ← imported by both sides
  types.ts      API contracts
  catalog.ts    server list, tool metadata (category, example args, view), param options
  mcpResult.ts  parse CallToolResult (JSON / number / soft error), validate arguments
  analytics.ts  candles, CA adjustment, SMA/EMA/RSI, volatility, drawdown, gaps, RVOL

Request lifecycle (Explorer → NSE)

  1. UI builds a form from the tool’s live inputSchema, validates with validateArguments and POSTs /api/tools/:name/execute.
  2. NseMcpHub.execute finds the tool (from tools/list), re-validates/coerces arguments, checks the 60 s cache.
  3. A per-server limiter (concurrency 2, ≥ 250 ms between starts) runs McpConnection.callTool.
  4. The connection lazily performs initialize → notifications/initialized → tools/list on first use; reconnects and retries (max 2) on session loss (HTTP 404) or connection reset. Timeouts are not retried.
  5. The wiretap records the JSON-RPC request and SSE response body.
  6. parseToolResult turns the text block into JSON / number / text and detects soft errors.
  7. The response carries: status, duration, parsed data, the raw CallToolResult, and the wire exchange. The UI renders a tailored view (ResultViews.tsx) chosen by the catalog’s view.

Design principles

Extending

Security