DEV Community

shakti tiwari
shakti tiwari

Posted on

nse-bse-mcp Install Guide: NIFTY Option Chain Python mei Live

Step-by-step of getting live NSE option-chain data via MCP — the exact setup I used for the NSE research skill. No API key, no auth circus. Agar tum NIFTY/BANKNIFTY data chahte ho bina paid vendor ke, ye read karo.

What nse-bse-mcp gives

A local MCP server (HTTP :3000) exposing 57 NSE tools: nse_fno_historical, nse_option_chain, nse_filtered_option_chain, nse_compile_option_chain, nse_vix_historical, nse_download_fno_bhavcopy, nse_get_market_status. Ye sab NSE ke public endpoints wrap karte hain. No API key required.

Install (verified on macOS, node 22)

npx -y nse-bse-mcp
Enter fullscreen mode Exit fullscreen mode

Server http://localhost:3000/mcp pe start hota hai. Background mei run karo taaki terminal band hone par na mare:

nohup npx -y nse-bse-mcp > /tmp/nse-mcp.log 2>&1 &
Enter fullscreen mode Exit fullscreen mode

Health check:

curl -s -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Enter fullscreen mode Exit fullscreen mode

57 tools list aayenge. Agar empty aaye toh server nahi chala — log check karo.

Fetch live chain (Python)

import urllib.request, json

def fetch_snapshot(symbol="NIFTY"):
    payload = {"jsonrpc":"2.0","id":1,"method":"tools/call",
        "params":{"name":"nse_filtered_option_chain",
            "arguments":{"symbol":symbol,"strike_range":5,"max_items":50}}}
    req = urllib.request.Request(
        "http://localhost:3000/mcp",
        data=json.dumps(payload).encode(),
        headers={"Content-Type":"application/json",
                 "Accept":"application/json, text/event-stream"})
    resp = urllib.request.urlopen(req, timeout=20).read().decode()
    if "data:" in resp:
        resp = resp.split("data:")[-1]
    data = json.loads(resp)
    text = data["result"]["content"][0]["text"]
    s = text.strip()
    j = json.loads(s[s.find('{'):s.rfind('}')+1])
    chain = j.get("data") or j.get("_metadata",{}).get("data") or []
    rows = []
    for strike in chain:
        ce = strike.get("CE",{}); pe = strike.get("PE",{})
        rows.append((strike["strikePrice"], "CE", ce.get("openInterest"),
                     ce.get("impliedVolatility"), ce.get("lastPrice")))
        rows.append((strike["strikePrice"], "PE", pe.get("openInterest"),
                     pe.get("impliedVolatility"), pe.get("lastPrice")))
    return rows
Enter fullscreen mode Exit fullscreen mode

Real result (19-Aug-2026 09:31 IST)

NIFTY 50 = 24086.25 (Open, -0.28%)
42 rows (21 strikes × CE+PE)
Top OI strike: 24500 CE
Sample CE OI: 3761 | CE IV: 12.36% | CE last: 142.50
Enter fullscreen mode Exit fullscreen mode

Ye numbers NSE live feed se aaye hain. Mock nahi.

Gotchas (real bugs I hit)

  1. BANKNIFTY range:10 error — "Response is too large" deta tha kyunki BANKNIFTY mei zyada strikes hain. Fix: strike_range + max_items use karo (NIFTY mei range:10 chal gaya, BANKNIFTY mei nahi).
  2. BANKNIFTY response _metadata wrapper mei — NIFTY clean JSON deta hai, BANKNIFTY metadata mei. Parser dono handle kare (upar wala code karta hai).
  3. Expiry format"25-Aug-2026" JSON date nahi, parse fail. Normalize 2026-08-25 karo.
  4. CE/PE nested — structure {data:[{strikePrice, CE:{...}, PE:{...}}]}. Direct json.loads(text) fail hoga, iterate karo.

Store to DuckDB

import duckdb
con = duckdb.connect("options.duckdb")
con.execute("""CREATE TABLE IF NOT EXISTS market_raw (
    session_date DATE, symbol VARCHAR, strike DOUBLE, type VARCHAR,
    open_interest BIGINT, iv DOUBLE, last_price DOUBLE, spot DOUBLE)""")
rows = fetch_snapshot("NIFTY")
spot = 24086.25
con.executemany("INSERT VALUES (?,?,?,?,?,?,?,?)",
    [(date.today(), "NIFTY", r[0], r[1], r[2], r[3], r[4], spot) for r in rows])
Enter fullscreen mode Exit fullscreen mode

Comparison: free vs paid

| Source | Cost | Latency | Setup |
|--|||-|
| nse-bse-mcp | ₹0 | ~1-2s | npx command |
| NSE official API | ₹0 but unstable | varies | auth circus |
| Paid (TrueData etc) | ₹1500+/mo | <1s | subscription |
| Manual screenshot | ₹0 | manual | time sink |

Free MCP enough hai research/paper-mode ke liye.

FAQ

Q: API key chahiye? Nahi. NSE public data hai.
Q: Windows pe chalega? Haan, npx cross-platform hai.
Q: Kitni baar call kar sakte hain? NSE rate-limit hai, 5-min interval safe hai.
Q: BANKNIFTY bhi? Haan, strike_range:5, max_items:50 se 102 rows aate hain.

Common mistakes

  1. Background na chalaana — terminal band, server mara, "MCP down" error.
  2. BANKNIFTY = NIFTY treat karna — alag response format hai.
  3. Expiry format assume ISO — crash karega.
  4. Har second call — rate-limit ban.

What I learned

Data pipeline banane mei 80% time debugging format issues mei gaya, na ki logic mei. NSE ka response consistent nahi hai across symbols — defensive parser likhna padta hai.

My workflow

  • 09:30 launch recorder (5-min cron)
  • Har 5 min: NIFTY 42 + BANKNIFTY 102 rows append
  • 16:00 EOD snapshot
  • Sunday: features rebuild

Data via NSE public site. Research only, not live-trading.

Deep dive: response parsing why it's tricky

NSE MCP ek consistent API nahi deta. NIFTY ke liye nse_filtered_option_chain direct JSON deta hai jisme data array hai. BANKNIFTY ke liye same call _metadata wrapper deta hai jisme actual data _metadata.data mei hai, aur upar ek message hota hai "Response is too large — use filters." Matlb BANKNIFTY mei zyada strikes hain, isliye server ne truncate kar diya aur metadata mei wrap kar diya.

Isliye mera parser dono check karta hai:

chain = j.get("data") or j.get("_metadata",{}).get("data") or []
Enter fullscreen mode Exit fullscreen mode

Agar data nahi mila toh _metadata.data try karta hai. Fir CE/PE nested objects iterate karke rows banata hai.

Expiry handling

Option chain mei multiple expiries hoti hain. MCP default nearest expiry deta hai. Agar specific expiry chahiye:

arguments={"symbol":"NIFTY","expiryDate":"2026-08-25","strike_range":5}
Enter fullscreen mode Exit fullscreen mode

Dhyan rahe: format 25-Aug-2026 FAIL karega (string date JSON nahi). Use 2026-08-25 (ISO). Maine normalize function banaya hai jo DD-Mon-YYYY ko YYYY-MM-DD mei convert karta hai.

Error handling in production

try:
    rows = fetch_snapshot("NIFTY")
except urllib.error.URLError as e:
    print("MCP down, retrying in 60s")
    time.sleep(60)
    # ya launch script se restart karo
Enter fullscreen mode Exit fullscreen mode

Mera launch_recorder.py har run pe check karta hai ki server up hai; nahi toh npx -y nse-bse-mcp start kar deta hai. Isse Cron job 24x7 chalta hai bina manual intervention.

Rate limits aur etiquette

NSE public endpoints rate-limit karte hain. 5-minute interval pe 1 call safe hai. Agar 429 ya empty response aaye, backoff karo (exponential: 60s, 120s, 240s). Mass scraping mat karo — IP ban ho sakta hai.

Security

Server localhost pe hi rakho. 0.0.0.0 pe expose mat karo — koi bhi network se tumhara NSE data pull kar sakta hai. Firewall default block hai, usko mat kholo.

Real use case: my NSE research

Is setup se main daily 42 (NIFTY) + 102 (BANKNIFTY) rows collect karta hoon DuckDB mei. 4 weeks mei 20+ sessions build hote hain, tab signal gate real probability nikalta hai. Bina is data ke koi model blind hai.

Data via NSE public site. Research only, not live-trading.

Troubleshooting checklist

| Symptom | Cause | Fix |
||-|--|
| Empty tools/list | Server nahi chala | nohup npx -y nse-bse-mcp & |
| "too large" on BANKNIFTY | Range wide | strike_range:5, max_items:50 |
| _metadata in response | BANKNIFTY truncate | Parser handles it |
| Expiry parse error | 25-Aug-2026 format | Use 2026-08-25 |
| 429 empty | Rate limit | Backoff 60s+ |
| CE/PE missing | Nested structure | Iterate CE{} PE{} |

Comparison with Indian-Option-MCP

Doosra option: npx -y indian-option-mcp (stdio mode). Difference:

  • nse-bse-mcp: HTTP, 57 tools, option chain + futures + VIX + bhavcopy. Easier to call via curl/Python.
  • indian-option-mcp: stdio, NSE cookies, simpler but per-call spawn.

Main dono use karta hoon — nse-bse-mcp primary (HTTP stable), indian-option-mcp backup.

What this unlocks

Live NSE data milne se:

  1. Real OI/IV features bante hain (no fake data).
  2. Max pain, PCR, IV skew calculate kar sakte ho.
  3. Signal gate ko real feed milta hai.
  4. Backtest realistic ban jata hai.

Bina data ke ML sirf theory hai. Ye setup theory ko practice banata hai.

Data via NSE public site. Research only, not live-trading.

My honest setup notes

Maine ye setup 19-Aug-2026 ko banaya tha. Pehle 2 ghante sirf format bugs fix karne mei gaye — NIFTY clean tha, BANKNIFTY ne sab bigada. Lesson: hamesha dono symbols test karo ek hi function mei, mat assume karo ki ek kaam karega toh doosra bhi karega.

Ab ye Cron job pe hai: */5 9-15 * * 1-5 — market hours mei har 5 minute. Monday se Friday. Saturday/Sunday band (NSE closed). EOD snapshot 16:00 pe alag job karta hai.

Data DuckDB mei accumulate ho raha hai. Abhi 1 session tha, abhi NO_TRADE gate sahi reject kar raha hai. 4 weeks baad 20+ sessions honge, tab walk-forward validator pehli real signal degi.

Final recommendation

Agar tum NIFTY/BANKNIFTY par research kar rahe ho aur paid data afford nahi kar sakte, nse-bse-mcp best free option hai. 30 minute mei setup ho jata hai agar upar ke gotchas yaad rakho. Paid vendors tab consider karo jab live sub-second execution chahiye.

Data via NSE public site. Research only, not live-trading. SEBI compliance separate topic.

Quick start (copy-paste)

# 1. Start server
nohup npx -y nse-bse-mcp > /tmp/nse-mcp.log 2>&1 &
# 2. Verify
curl -s -X POST http://localhost:3000/mcp -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | head
# 3. Run fetch (use code above)
python3 fetch_nifty.py
Enter fullscreen mode Exit fullscreen mode

Bas. 10 minute mei live NSE data tumhare paas hai. Baaki articles mei hum isi data pe features aur signals banayenge.

Data via NSE public site. Research only, not live-trading.

Disclaimer

Sab kuch research purpose ke liye hai. Live trading ke liye SEBI registration aur risk management alag se chahiye. NSE data public source se aata hai, accuracy guaranteed nahi.

Agar setup mei atak gaye, comment karo — main exact error dekh kar fix bata dunga.

More From Shakti Tiwari

Top comments (0)