NSE has launched its own Model Context Protocol (MCP) server. In simple words, NSE now gives AI assistants and AI agents a standard plug to fetch NSE market data: 5 years of daily (end-of-day) history, plus a live snapshot of the current trading day. No login and no API key are needed to connect.
In this tutorial we will connect to NSE MCP from Python, see all the tools it offers, call a tool directly, and finally build a small AI agent that answers stock market questions in plain English. The code is kept short and beginner friendly. We will use Agno as the agent framework and OpenAI’s gpt-5.6-luna as the model.

What is MCP?
MCP (Model Context Protocol) is an open standard that lets an AI model talk to external tools and data sources in a common way. NSE describes it like a USB-C port for AI: instead of writing custom code for every data source, any MCP aware app (Claude, ChatGPT, or your own Python agent) can plug into the NSE server and discover what it can do.
An MCP server publishes a list of tools. Each tool has a name, a description and a JSON schema for its inputs. The AI model reads these descriptions, decides which tool to call, and the MCP client runs the call and hands the result back to the model.
The Two NSE MCP Endpoints
NSE runs two separate MCP servers. Both use the Streamable HTTP transport and need no authentication.
| Server name | Endpoint | What it gives you |
|---|---|---|
| nse-bhavcopy | https://mcp.nseindia.in/bhavcopy/cm/mcp | End-of-day (Bhavcopy) data for the last 5 years, updated daily with the previous trading day’s final numbers |
| cm-market | https://mcp.nseindia.in/cmmkt/mcp | Live snapshot of the current trading day (NSE says 1 to 3 minutes behind real-time; in our test the data refreshed every 5 minutes) |
This is the same configuration NSE shows for Claude Desktop:
{
"mcpServers": {
"nse-bhavcopy": {
"url": "https://mcp.nseindia.in/bhavcopy/cm/mcp",
"transport": "streamable-http"
},
"cm-market": {
"url": "https://mcp.nseindia.in/cmmkt/mcp",
"transport": "streamable-http"
}
}
}
Note: in the Claude Connectors section of the NSE page, the live server URL is printed as msc.nseindia.in. The correct host is mcp.nseindia.in, as shown above and in the Claude Desktop config.
The Tools: 26 in Total
NSE says 15+ tools. When we actually connect and list them (Step 1 below), we get 13 tools on each server, 26 in total.

nse-bhavcopy (historical data)
| Tool | What it does |
|---|---|
get_stock_history | Daily OHLCV price history for a stock |
get_ltp_by_date | Closing price of a stock on a specific date |
get_52_week_high_low | 52-week high and low with dates |
moving_average | Simple moving average of close prices over N days |
get_volume_analysis | Volume trend for a stock over N trading days |
compare_stocks | Compare returns and drawdown of several stocks |
get_bulk_quote | Latest end-of-day snapshot for many stocks in one call |
get_top_movers | Top gainers or losers on a given date |
get_top_by_volume | Most actively traded stocks on a given date |
get_market_breadth | Advance and decline numbers for a date |
get_corporate_actions | Dividends, splits, bonus and other corporate actions |
search_symbols | Find a symbol by company name or partial symbol |
nse_lookup_symbol | Look up ticker symbols by keyword (no prices) |
cm-market (live data)
| Tool | What it does |
|---|---|
nse_get_market_movers | Main tool for live top gainers and losers |
nse_get_gainers | Top N gainers across all indices |
nse_get_losers | Top N losers across all indices |
cm_get_live_gainers | Raw gainers data grouped by index (NIFTY, BANKNIFTY and more) |
cm_get_live_losers | Raw losers data grouped by index |
cm_get_stock_quote | Live quote for one stock by exact symbol |
cm_get_live_market_data | Live market data for a chosen index or variation |
cm_get_equity_stocks | Live data for all equity series stocks (EQ, BE and others) |
cm_get_sme_stocks | Live data for SME segment stocks |
cm_get_call_auction_stocks | Live data for call auction session stocks |
cm_get_bond_stocks | Live data for bonds and debt instruments |
cm_get_data_status | How fresh the live market data is |
cm_get_allstocks_status | How fresh the all-stocks data cache is |
What Time Series Data Does NSE MCP Give You?
This is the first question most traders ask: can I get intraday candles? The short answer is no. NSE MCP gives you daily time series for the last 5 years and a live snapshot of today. There are no 1 minute, 5 minute or any other intraday candles, either live or historical. We tested both servers to confirm this.
| Data | Available? | Server and tool | Details |
|---|---|---|---|
| Daily OHLCV history | Yes, about 5 years | nse-bhavcopy: get_stock_history | One bar per trading day: open, high, low, close, previous close, volume, traded value. In our test (1 October 2026) data started on 1 October 2021. |
| Today’s live snapshot | Yes | cm-market: cm_get_stock_quote | Today’s open, high, low, last traded price, change, volume and value so far. One snapshot per call, not a series. |
| Intraday candles (1m, 5m, 15m and so on) | No | None | None of the 26 tools accepts an interval or a time range for intraday data. |
| Tick data and order book depth | No | None | Mentioned on the NSE page, but not exposed by any tool at the time of writing. |
A few details worth knowing when you work with the daily series:
- History comes in chunks:
get_stock_historyreturns at most 3 months per call. The response includes anext_end_datefield. Pass it asendDatein the next call to page backwards. An AI agent handles this paging on its own. - Latest bar is the previous trading day: the bhavcopy server is updated once a day after market close. For today’s numbers, use the cm-market tools.
- Live data refresh:
cm_get_data_statusreported a crawl interval of 5 minutes in our test. Before the market opens, the live quote still shows the previous session. - Prices are not adjusted: RELIANCE trades near 1,187 today but shows around 2,400 in late 2021 because of the 2024 1:1 bonus. If you calculate long range returns or moving averages, adjust for splits and bonus issues first.
get_corporate_actionsgives you the dates. - Going past 5 years: asking for data before the window returns a “Symbol not found” error, not an “out of range” message. The symbol is fine, the date is simply too old.
- Delivery quantity: the
deliveryQtyfield was 0 in every row we checked, so delivery based analysis is not possible yet.
If you need intraday candles, you can build your own by calling cm_get_stock_quote every 5 minutes and storing the results, or use a broker API for proper intraday history.
Why Agno?
Agno is an open source Python framework for building AI agents. You could talk to MCP servers with the raw mcp SDK and write your own tool calling loop, but Agno removes almost all of that work:
- Built-in MCP support:
MCPTools(url=..., transport="streamable-http")connects to a server, discovers every tool and converts it into a tool the model can call. One line per server. - The tool calling loop is handled for you: the agent sends the question to the model, runs the tool calls the model asks for, sends back the results and repeats until there is a final answer.
- Model agnostic: we use OpenAI here, but switching to Claude, Gemini or a local model is a one line change.
- Memory with one setting: add a SQLite database and
add_history_to_context=Trueand the agent remembers earlier questions, so follow-ups like “which of them had more volume?” just work. - Beginner friendly output:
print_responseshows the question, every tool call and the final answer in the terminal, which makes it easy to learn what the agent is doing.
The result is a complete NSE market assistant in about 50 lines of Python.
Prerequisites
- Python 3.10 or above (we used 3.12)
- An OpenAI API key
- Basic familiarity with running a Python script
Create a project folder, a virtual environment, and install the packages:
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # Mac / Linux
pip install "agno[mcp]" openai python-dotenv "sqlalchemy[asyncio]"
Create a .env file in the same folder with your OpenAI key and the model name:
OPENAI_API_KEY=sk-your-openai-key
OPENAI_MODEL=gpt-5.6-luna
Step 1: List All NSE MCP Tools
This script connects to both servers and prints every tool. It does not use any AI model, so no API key is needed for this step. It is a good first check that your machine can reach NSE MCP.
# list_tools.py
# Step 1: connect to both NSE MCP endpoints and print every tool they expose.
# No LLM and no API key needed for this step.
import asyncio
import logging
from agno.tools.mcp import MCPTools
# Hide a harmless warning printed when the NSE server closes the session
logging.getLogger("mcp.client.streamable_http").setLevel(logging.ERROR)
NSE_SERVERS = {
"nse-bhavcopy": "https://mcp.nseindia.in/bhavcopy/cm/mcp", # end-of-day data, last 5 years
"cm-market": "https://mcp.nseindia.in/cmmkt/mcp", # live market data (1-3 min delay)
}
async def main():
for name, url in NSE_SERVERS.items():
async with MCPTools(url=url, transport="streamable-http") as mcp:
print(f"\n=== {name} ({len(mcp.functions)} tools) ===")
for tool_name, tool in mcp.functions.items():
desc = (tool.description or "").strip().split("\n")[0]
print(f"- {tool_name}: {desc}")
if __name__ == "__main__":
asyncio.run(main())
Output (trimmed):
=== nse-bhavcopy (13 tools) ===
- get_top_by_volume: Get the top N most actively traded NSE stocks on a specific date, sorted descending.
- get_top_movers: Get the top N gaining or losing NSE stocks on a specific date.
- get_volume_analysis: Analyse trading volume trends for an NSE stock over N trading days.
...
=== cm-market (13 tools) ===
- cm_get_sme_stocks: Get latest live data for NSE SME (Small & Medium Enterprises) stocks (series: SM, ST).
- cm_get_live_market_data: Get live NSE market data for a specific variation type.
- nse_get_market_movers: PRIMARY TOOL for: "What are the top gainers today?", "top losers today?" ...
...
Step 2: Call a Tool Directly
Before handing the tools to an AI model, it helps to see the raw data. Here we print the input schema of get_52_week_high_low and then call it for RELIANCE.
# call_tool.py
# Step 2: call one NSE MCP tool directly, without any AI model.
# Useful to see the raw data the agent will receive.
import asyncio
import logging
from agno.tools.mcp import MCPTools
logging.getLogger("mcp.client.streamable_http").setLevel(logging.ERROR)
BHAVCOPY_URL = "https://mcp.nseindia.in/bhavcopy/cm/mcp"
async def main():
async with MCPTools(url=BHAVCOPY_URL, transport="streamable-http") as mcp:
# See the inputs a tool expects
print(mcp.functions["get_52_week_high_low"].parameters)
# Call the tool and print the raw result
result = await mcp.session.call_tool("get_52_week_high_low", {"symbol": "RELIANCE"})
print(result.content[0].text)
if __name__ == "__main__":
asyncio.run(main())
Output:
{'type': 'object', 'properties': {'symbol': {'type': 'string', 'description': 'NSE stock symbol in uppercase. Example: RELIANCE, TCS, INFY'}}, 'required': ['symbol'], 'additionalProperties': False}
{"symbol":"RELIANCE","last_close":1187.0,"52w_high":1611.8,"52w_high_date":"2026-01-05","52w_low":1181.7,"52w_low_date":"2026-09-30","position_in_range_pct":1.23,"from_52w_high_pct":-26.36,"from_52w_low_pct":0.45,"trading_days":245}
The tool returns clean JSON. This is exactly what the AI model receives when it calls the tool.
Step 3: Build the NSE Market Agent
Now the fun part. We give both MCP servers to an Agno agent and let the model decide which tools to use.
# nse_agent.py
# Step 3: a simple AI agent that answers stock market questions using NSE MCP.
import asyncio
import logging
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.tools.mcp import MCPTools
# Use the key and model from .env, even if another key is set in your system
load_dotenv(override=True)
logging.getLogger("mcp.client.streamable_http").setLevel(logging.ERROR)
# The two official NSE MCP endpoints (no authentication required)
BHAVCOPY_URL = "https://mcp.nseindia.in/bhavcopy/cm/mcp" # historical end-of-day data
LIVE_URL = "https://mcp.nseindia.in/cmmkt/mcp" # live market data
async def main():
# Connect to both NSE MCP servers
async with MCPTools(url=BHAVCOPY_URL, transport="streamable-http") as bhavcopy, \
MCPTools(url=LIVE_URL, transport="streamable-http") as live:
agent = Agent(
name="NSE Market Assistant",
model=OpenAIResponses(id=os.getenv("OPENAI_MODEL", "gpt-5.6-luna")),
tools=[bhavcopy, live],
instructions=[
"You are a helpful assistant for Indian stock market data from NSE.",
"Always use the NSE tools to fetch data. Never guess numbers.",
"Use the live tools for today's prices and the bhavcopy tools for history.",
"Show numbers in a small markdown table when it helps.",
"End with: Data from NSE MCP, for educational use only.",
],
add_datetime_to_context=True, # so the agent knows today's date
db=SqliteDb(db_file="nse_chat.db"), # stores the chat so the agent can remember it
add_history_to_context=True, # remember earlier questions in this chat
markdown=True,
)
print("NSE Market Assistant. Type 'exit' to quit.")
while True:
question = input("\nYou: ").strip()
if question.lower() in ("exit", "quit"):
break
if question:
await agent.aprint_response(question, stream=True)
if __name__ == "__main__":
asyncio.run(main())
How it works:
load_dotenv(override=True)loads the key and model from.env.override=Truemakes sure the.envvalues win, even if an oldOPENAI_API_KEYis set in your system environment.MCPTools(url=..., transport="streamable-http")opens a connection to each NSE server. Usingasync withcloses the connections automatically when you exit.OpenAIResponsesuses OpenAI’s Responses API, which is the API that newer reasoning models such as luna use for tool calling.instructionstell the agent to always fetch data from the tools instead of guessing numbers.add_datetime_to_context=Truetells the model today’s date, so “last 1 month” means the right dates.db=SqliteDb(...)plusadd_history_to_context=Truegives the agent memory of the conversation.
Run it with python nse_agent.py and start asking questions. Here is a real session (output simplified):
You: Compare TCS, INFY and WIPRO over the last 1 month
Tool Calls
compare_stocks(symbols=['TCS', 'INFY', 'WIPRO'], months=1)
Stock Start price End price Return Max drawdown
WIPRO 181.70 158.50 -12.77% 13.71%
TCS 2,369.00 2,050.60 -13.44% 14.21%
INFY 1,156.00 994.10 -14.01% 14.01%
You: Which of them had the highest average volume in the last 10 days?
Tool Calls
get_volume_analysis(symbol=TCS, days=10)
get_volume_analysis(symbol=INFY, days=10)
get_volume_analysis(symbol=WIPRO, days=10)
Stock Average volume
WIPRO 27,506,465 shares
INFY 10,032,097 shares
TCS 3,402,629 shares
Notice the second question never mentions TCS, INFY or WIPRO. The agent remembered them from the first question, picked the get_volume_analysis tool on its own and called it once for each stock.
Questions to Try
- What are the top 5 gainers in NIFTY right now?
- Give me the live quote of HDFCBANK.
- What was the market breadth yesterday? How many stocks advanced and declined?
- Show the 20 day moving average of INFY and tell me if the last close is above it.
- Which stocks had the highest traded volume on 30 September 2026?
- Has ITC announced any dividend in the last 1 year?
A Few Practical Notes
- Model choice: luna models need the Responses API for tool calling. At the time of writing, Agno 3.0.11 recognises
gpt-5*models as reasoning models, sogpt-5.6-lunaworks out of the box.gpt-6-lunafailed with a missing reasoning item error during tool calls on this Agno version, so stick togpt-5.6-lunauntil Agno adds support. - Harmless warning: without the logging line in the scripts you will see
Session termination failed: 501on exit. The NSE server simply does not support the optional session close request. It does not affect results. - Live vs historical: as covered in the time series section, the agent should use the cm-market tools for today’s prices and the bhavcopy tools for history, which is why we mention this in the instructions.
- Data freshness: the live server has a
cm_get_data_statustool. Ask the agent “how fresh is the live data?” if numbers look stale. - Educational use only: NSE states that MCP data is for informational and educational purposes, not for real-time trading, commercial deployment, or training AI models.
Where to Go Next
- Add a web UI using Agno’s AgentOS, or wrap the agent in a Streamlit app.
- Add more MCP servers (for example a news MCP) to the same agent with another
MCPToolsline. - Ask the agent to produce a daily end-of-day market summary and email it to yourself.
Disclaimer
This post is for educational purposes only and is not investment advice. Data is accessed through NSE’s public MCP service and is subject to NSE’s terms of use. Output generated by AI models may contain errors, so always verify important numbers from the source.