Ask ChatGPT or Claude "what was Reliance's operating margin last quarter?" and you get one of two answers: a polite "I don't have live data," or a confident, wrong number. The reasoning is great. The data access is nonexistent β these models are blind to anything past their training cut-off, and they have zero native window into NSE/BSE.
So I built an MCP server to fix it, and open-sourced it. This is the build story + a quick-start if you want to plug it into your own setup.
The Model Context Protocol is an open standard that lets AI assistants call external tools through a consistent interface. Instead of guessing, the model issues a structured request β get_stock_quote
for RELIANCE
β gets real data back, and reasons over it. One protocol, and Claude, ChatGPT, Cursor, Gemini, and Grok can all hit the same data source.
It's basically USB-C for AI tools.
search_stocks screen_stocks (326 fundamental filters)
screen_stocks_technical get_company_profile get_financials
get_stock_quote get_price_history get_shareholding
get_fii_dii_detail market_ipo market_fno_ban
get_user_portfolio add_to_watchlist ...and 21 more
Coverage: all ~8,200 NSE + BSE stocks, fundamentals, technicals, institutional flows, market data, and portfolio tracking. (It's a research tool, not a broker β it doesn't place trades.)
The big one: remote-first, on the edge.
βββββββββββββββββββ JSON-RPC / HTTPS ββββββββββββββββββββββββ
β AI Assistant β ββββββββββββββββββββΊ β Cloudflare Worker β
β (Claude, etc.) β ββββββββββββββββββββ β (stateless MCP) β
βββββββββββββββββββ ββββββββββββββββββββββββ
β
D1 (users, tokens, usage)
KV (rate limits, auth codes)
Most MCP servers ship as local stdio processes you have to install and run. That's a friction wall for non-developers. I wanted someone to paste one URL into claude.ai and be done β so the server runs as a Cloudflare Worker. Globally distributed, no servers to babysit.
The MCP SDK's WebStandardStreamableHTTPServerTransport
in stateless mode maps perfectly onto Workers β any request hits any edge location and is served identically:
const server = createServer(env, ph, userId);
const transport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: undefined, // stateless
enableJsonResponse: true,
});
await server.connect(transport);
MCP clients vary wildly. Chat apps (Claude.ai, ChatGPT) expect a full OAuth flow with Dynamic Client Registration (RFC 7591) plus discovery endpoints (RFC 8414, RFC 9728). Code editors often just want a bearer token.
The trick that makes the OAuth handshake "just work": return a 401
with a WWW-Authenticate
header on the first initialize
. That's the signal that kicks off the client's built-in OAuth flow.
if (!authHeader?.startsWith("Bearer ") && !isPublicMethod) {
return Response.json(
{ error: "authentication_required" },
{ status: 401, headers: {
"WWW-Authenticate":
`Bearer resource_metadata="${metadataUrl}", scope="openid email"`,
}},
);
}
So the server accepts both short-lived HMAC access tokens and long-lived personal tokens, distinguished by prefix (tpt_rt_β¦
). One auth surface, two credential types. tools/list
and ping
stay public so registries can discover the catalog without auth.
Two independent layers:
UPSERT
reserves a unit The part I'm happiest with: failed calls get refunded. The MCP SDK throws InvalidParams
whenever a tool argument fails schema validation β and LLMs hallucinate bad arguments constantly. Charging a user's quota because their model fumbled an argument would be infuriating.
if (quotaConsumed && userId) {
quotaConsumed = false; // guard against double-refund
if (hasError) {
ctx.waitUntil(refundRateLimitV2(env.DB, userId, date, month));
} else {
ctx.waitUntil(trackToolCall(env.DB, userId, src));
}
}
For stdio-only clients there's a tiny npm package β ~300 lines, zero runtime deps. No business logic: it reads JSON-RPC from stdin, forwards to the Worker over HTTPS, writes responses to stdout. It auto-detects message framing (Content-Length vs newline-delimited JSON, which differ across clients) and refreshes the access token before expiry. All tool logic lives on the server, so new tools ship instantly without anyone running npm update
.
No install (claude.ai, ChatGPT, Gemini, Grok) β paste the URL, sign in with Google:
https://mcp.tapetide.com/mcp
Local via npm (Cursor, Windsurf, Claude Desktop):
{
"mcpServers": {
"tapetide": {
"command": "npx",
"args": ["-y", "tapetide-mcp"],
"env": { "TAPETIDE_TOKEN": "your_token_here" }
}
}
}
Then just ask:
"Find mid-caps where FII holding rose last quarter, ROE above 15%, and RSI under 40."
npx
command for reach..well-known
discovery endpoints precisely.Free and open source under MIT. Source, all 34 tools, and setup guides:
π https://github.com/Tapetide-hq/nse-bse-indian-stock-market-data-mcp
If you build something on top of it or have ideas for tools you'd want, I'd love to hear it in the comments.