# stock-research-mcp [Health: Active]

**Category:** 💰 Finance & Fintech  
**Repository:** https://github.com/Tapetide-hq/nse-bse-indian-stock-market-data-mcp  
**GitHub Stars:** 149  
**npm Downloads (last month):** 696  
**Views:** 7  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/stock-research-mcp

## Description
Indian stock market research: quotes, financials, technicals, screener, FII/DII and market insights.

## Tools
Capabilities this server exposes over MCP:

- **search_stocks** — Search ~8,000 Indian stocks by name, symbol, BSE code, or ISIN. Also matches common/brand names and post-rename aliases (e.g. 'Zomato'→ETERNAL, 'Infosys'→INFY). Listed companies rank first, then by match (exact symbol/code > prefix > word > contains), larger companies first within each; queries of 4+ characters tolerate typos. Each result's `symbol` is what the per-stock tools take as input.
- **get_company_profile** — Get detailed company overview — sector, about, pros/cons, fundamentals (PE, PB, market cap, ROE, ROCE, debt/equity), growth metrics, and current quote. Default response is ~3KB.

Use the 'include' param to add optional sections via parallel API calls:
- "technicals": RSI, SMA, EMA, MACD, Bollinger Bands, ATR, ADX (~20 indicators)
- "ratings": Analyst buy/hold/sell consensus with counts and percentages
- "peers": Comparable-company table — the stock's published peer cohort with price, day change, market cap, P/E, P/B, dividend yield, ROE, ROCE, ROA, OPM, debt/equity, TTM sales and net profit, and promoter holding, plus a per-column median across the cohort. The stock itself is included and flagged `is_self`, so it can be ranked against its own peers on any column. A `null` metric means the figure is not published for that company — never treat it as 0.

Example: include ["technicals", "ratings"] for a full analysis view.
- **get_stock_events** — Get stock events — news, corporate actions, or company filings.

Types:
- "news": Sentiment-tagged news (positive/negative/neutral), category, source URL
- "corporate_actions": Dividends, splits, bonuses, AGMs, rights issues with ex-date and LTP
- "filings": Results, presentations, concall transcripts/audio, annual reports, credit ratings, announcements. Rows carry doc_type and the exact filing date, latest quarter included.

Paging: max 50 per call; while meta.has_more, pass offset=meta.next_offset. from/to (filings only) bound the date; meta.total is for the filtered set.
- **get_stock_ownership** — Get ownership data for a stock — yearly dividend totals and mutual fund holdings. `dividends` is one row per year: {Year, Div (dividend per share in ₹ for that year), yield (%), exch}. There is NO ex-date and NO interim/final split here; for dated individual dividends use get_stock_events with type "corporate_actions". `dividends` is an empty string or null when none is on file. `mf_holdings` is a list of positional arrays, one per scheme: [scheme_id, scheme_name, amc_id, scheme_isin, shares_held, pct_of_scheme_aum, share_change_mom, pct_of_aum_change_mom (percentage points), an unlabelled change figure (do not interpret), months, slug]. shares_held, pct_of_scheme_aum and months are '|'-joined monthly series, newest first, aligned by position (e.g. months "2026-09|2026-08|…"). Empty string or null when no holdings are on file.
- **get_stock_quote** — Latest stock quote: LTP, change, change %, volume, market cap, PE, 52-week high/low. price_basis is live (traded today or in the last session), last_trade (an older session's price) or null (unknown). last_trade_date is the session the price traded in. NSE prices can lag the exchange by up to ~15 minutes. For multiple stocks, use get_batch_quotes instead.
- **get_batch_quotes** — Quotes for up to 20 stocks in one call, each with price_basis and last_trade_date as in get_stock_quote. NSE prices can lag the exchange by up to ~15 minutes.
- **get_price_history** — Get OHLCV price history as row-per-day format — date, open, high, low, close, volume, delivery %. Supports configurable lookback days and daily/weekly aggregation. Default 365 days (max 2000). Use this for price analysis, trend detection, and technical calculations. IMPORTANT: `days` is CAPPED at 2000, so a longer request is silently shortened unless you read `meta.window`. Always check `meta.window.truncated` before treating the series as the full requested history — when it is true, `meta.window.requested_days` tells you what you asked for and `meta.window.next_cursor` gives the `end_date` to pass on a follow-up call to page further back. For a full multi-year series, page with `end_date` until `truncated` is false.
- **get_financials** — Get financial statements for one company. Sections: `quarterly` (quarterly P&L, ~13 quarters), `profit_loss` (annual P&L), `balance_sheet`, `cash_flow`, `ratios` (all annual). Pass `section` for one statement with every period we hold; omit it to get all sections trimmed to the latest 5 periods each (use `periods` to widen, e.g. {"symbol":"TCS","section":"quarterly","periods":12}). Each section carries `periods` (oldest first), `data` {row: {period: value}}, `pct_changes`, `row_order`, and an `availability` array giving the point-in-time `available_from` date per period (the real result-declaration date where known, `basis:\"reported\"`, otherwise a regulatory-lag estimate, `basis:\"estimated\"`). Use `available_from` for backtests to avoid look-ahead bias. NOTE: `available_from` reflects original declaration timing only; the values are the latest reported figures and may include later restatements. One symbol per call; for many companies call once per symbol (get_batch_quotes is prices only). ETFs, index funds and bonds have no financial statements.
- **get_shareholding** — Get shareholding pattern — promoter, FII, DII, public holdings over time. Track institutional buying/selling trends quarter over quarter. Useful for understanding ownership changes. CAUTION: a move of more than 5 points in any bucket in a single quarter may be a filing reclassification rather than trading. When you see one, report the public/other buckets for the same quarters alongside it and do not describe the move as accumulation or exit without a second source.
- **get_forecasts** — Get analyst forecasts — EPS, revenue, EBITDA, net income, ROA, ROE, and price estimates. Both quarterly and annual periods with actuals vs estimates comparison, and each estimate's analyst range in `bands` (low/high). EPS actuals are restated for splits and bonuses; `meta.eps_adjustments` lists what was rescaled. Useful for understanding market expectations and earnings surprises.
- **get_market_pulse** — Get today's market snapshot — FII/DII net flows (buy/sell/net in crores), Nifty 50 valuations (PE/PB/DY), and the India VIX volatility gauge. This is the quick daily-overview tool. For the technical signal scanner (52-week highs/lows, RSI extremes, MACD, volume spikes) use get_market_data with dataset: "signals"; for top gainers/losers/most-active use get_trending_stocks.
- **get_fii_dii_detail** — Get detailed FII/DII institutional flow data:
- Daily cash market flows for last 30 trading days (buy/sell/net in crores)
- F&O participant positioning (FII/DII/Pro/Client long/short OI)
- Weekly, monthly, yearly aggregates
- Buy/sell streaks and 5d/30d/1yr cumulative net flows
- Optional: cumulative flow chart data with interval param

Essential for understanding institutional money flow in Indian markets.
- **get_fii_dii_flows** — Alias for get_fii_dii_detail. Get detailed FII/DII institutional flow data — daily cash market flows, F&O positioning, weekly/monthly/yearly aggregates, buy/sell streaks.
- **get_fpi_sectors** — Get FPI (Foreign Portfolio Investor) sector-wise investment data. Returns AUM share per sector, fortnight change, 1-year cumulative flow, and sparkline data. Sorted three ways: by AUM, by fortnight change, and by 1Y flow. Useful for understanding which sectors foreign investors are buying/selling.
- **get_market_news** — Get latest market-wide news across all categories. Returns sentiment-tagged articles (positive/negative/neutral) with category, source URL, and related stock symbols.

Categories include: companies, global, markets, ipo, government-policy-and-regulation, debt-markets, equity-markets, investment-ideas, technology, real-estate, infrastructure.

Use this for broad market news. For stock-specific news, use get_stock_events with type "news" instead.
- **get_market_data** — Get one of today's market-wide data feeds. Pass `dataset` to choose:
- deals — bulk & block deals for the last 7 days (symbol, name, client, buy/sell, qty, price, value), newest and largest first.
- fno_ban — F&O ban list: stocks at or above 80% of MWPL, with mwpl_pct and status (in_ban from the exchange's published ban list, else near_ban).
- deliveries — latest session's highest delivery-% stocks (>=50%, traded value >= Rs 1 Cr), indicating genuine buying over speculation.
- ipo — current and upcoming IPOs: dates, price band, issue size, and subscription by category.
- mtf — Margin Trading Facility: most-funded stocks with funded qty/value in Rs crore and change vs the previous session (market-wide book not available).
- slbm — Stock Lending & Borrowing: lent stocks with lending yield and traded qty. High yield = strong short-selling demand.
- signals — technical signals from the latest session: 52-week highs/lows, RSI extremes, MACD, volume spikes, 200-day trend.
For index PE/PB valuation history use market_valuations; for an index's constituent heatmap use market_heatmap; for a single stock's own deal history use get_stock_deals.
- **market_valuations** — Get index valuation metrics (PE, PB, Dividend Yield) over time. Default: Nifty 50, weekly data, 5 years. Useful for assessing whether the market is overvalued or undervalued relative to historical averages.

index_code accepts EITHER a slug (recommended, like market_heatmap) or a raw numeric code:
  nifty-50 (13), nifty-500 (19), nifty-bank (25), nifty-midcap-50 (51), nifty-it (27), nifty-next-50 (53).
- **market_heatmap** — Get a stock heatmap for an index — all constituent stocks with market cap, PE, PB, price changes (1d/1w/1m/3m/6m/1y/5y), volume, and sector.

Available indices: see the index parameter (Nifty broad, size and sector indices plus Sensex).
- **screen_stocks** — Screen Indian stocks by fundamental criteria using 325 financial ratios (valuation, profitability, growth, balance sheet, cash flow, shareholding, with 3Y/5Y/10Y history).
For technical screens (RSI, MACD, moving averages), use screen_stocks_technical instead.

QUERY SYNTAX: {Ratio Name} {operator} {value}[%]
  Operators: >, <, =, >=, <=   Connectors: AND, OR (each on its own line)
  Cross-field comparison is allowed: Current price > DMA 200
  Max length 1500 characters. Ratio names must be EXACT (case-insensitive); an invalid query is an error naming the bad token.

COMMON RATIO NAMES: Market Capitalization, Current price, Price to Earning, Price to book value, Dividend yield, Return on equity, Return on capital employed, OPM, EPS, Net profit, Sales, Sales growth 3Years, Profit growth 3Years, Debt to equity, Current ratio, Promoter holding, FII holding, Pledged percentage, DMA 50, DMA 200, RSI, Piotroski score, Altman Z Score, Number of equity shares.
Call get_screener_ratios (searchable, full 325-ratio catalog) for anything not listed — do not guess a name.

EXAMPLE: "Market Capitalization > 5000 AND\nPrice to Earning < 15 AND\nReturn on capital employed > 22"

Note: "last year" in a ratio name means the most recent annual result. To identify an unknown stock from partial financials, call read_me for the disambiguation procedure.
- **screen_stocks_technical** — Screen Indian stocks by technical indicators (RSI, MACD, moving averages, crossovers, volume, momentum) on real-time data.
For fundamental screening (PE, ROCE, Sales, Growth), use screen_stocks instead.

Each filter is { left: field, operation, right: number | field }.
Operations: "greater", "less", "equal", "in_range" (right is [min,max]), "crosses_above", "crosses_below" (crossover today).

FIELDS: close, open, high, low, volume, change, change_abs, market_cap_basic | SMA5/10/20/50/100/200, EMA5/10/20/50/100/200 | RSI, RSI[1], MACD.macd, MACD.signal, Stoch.K, Stoch.D, CCI20, ADX, AO, Mom, ATR | BB.upper, BB.lower | Pivot.M.Classic.R1/R2/S1/S2 | Recommend.All (-1..1), Recommend.MA, Recommend.Other | Perf.W, Perf.1M, Perf.3M, Perf.6M, Perf.Y, Perf.YTD | average_volume_10d_calc, average_volume_30d_calc, relative_volume_10d_calc | price_earnings_ttm, price_book_fq, dividend_yield_recent

⚠️ market_cap_basic is absolute ₹, NOT Cr (1 Cr = 10,000,000), so 5000 Cr = 50000000000.

EXAMPLE — oversold large-caps: [{"left":"RSI","operation":"less","right":30},{"left":"market_cap_basic","operation":"greater","right":50000000000}]
- **get_screener_ratios** — Search or list available financial ratios for the screen_stocks tool. Pass a keyword to search (e.g., 'cash flow', 'debt', 'promoter') or omit for the full catalog of 325 ratios. Returns the exact ratio names that screen_stocks queries accept.
- **get_trending_stocks** — Get trending stock summary — top gainers, losers, and high-volume stocks from Nifty 500. Quick snapshot of market movers today.
- **get_options_analytics** — Get derivatives analytics for a stock — implied volatility (ATM IV, IV rank, IV percentile), realized volatility, put-call ratio (OI and volume), max pain strike, 25-delta skew, and call/put open interest, broken down per expiry. Use for options strategy, volatility analysis, and gauging derivatives-market positioning.
- **get_stock_deals** — Get large-trade history for a stock — bulk deals, block deals, insider (designated-person) trades, and SAST (substantial acquisition) disclosures, with the counterparty name, buy/sell side, quantity, price, and value. Answers 'who has been buying or selling X?'. Optionally filter by deal type. `price` is as traded; `price_adjusted` is the same price on the split/bonus-adjusted basis of the daily closes, so compare a pre-split/bonus deal with the close using `price_adjusted`.
- **get_promoter_pledge** — Promoter share-pledge history for a stock: % of promoter holding pledged over recent quarters, plus recent pledge creation/release events. High or rising pledges are a governance red flag. NOTE: pct_total_shares_pledged is ALL pledged shares (any holder) as % of demat shares, not promoter-only; see `field_notes`.
- **get_credit_ratings** — Get credit-rating actions for a company — agency, rating, action (upgrade/downgrade/reaffirm), and outlook over time. A rating change is a forward-looking signal on credit/solvency risk. Use for risk assessment and debt-investor research.
- **get_earnings_call_summary** — Get AI-generated investor digests of a company's recent earnings (concall) transcripts and investor presentations — a structured summary plus key highlights, risks, management guidance, and headline metrics, grounded in the company's own filings. Use for qualitative fundamental research beyond the numbers.
- **get_india_vix** — Get the India VIX — the market's expected near-term volatility (the 'fear gauge'). Returns the latest value, daily change, and recent history. Rising VIX = rising fear/uncertainty; falling VIX = calm. Use for market-timing and risk context.
- **list_company_documents** — Index of a company's filings parsed to text (concall transcripts, annual reports, presentations, IPO documents): doc_id, type, period, date, num_pages, flags, and per-document links (raw PDF, full Markdown, summary Markdown). No prose. The doc_id is the input get_document_summary and read_document take; the links let the user open or download the document. Newest first.
- **get_document_summary** — Investor digest of ONE parsed filing: summary, highlights, risks, guidance, key metrics, plus links to the PDF and full Markdown. Pass doc_id from list_company_documents, or doc_type for the newest of that type. For the text itself use read_document or download links.markdown_url.
- **read_document** — Markdown text of a parsed filing by doc_id and page range, with <!-- page N --> markers to cite. Max 12 pages / 24000 chars per call (max_chars up to 60000); the result states pages_returned, next_pages, and links to the full Markdown and PDF. Annual reports run 100-400 pages: read the sections you need, or download links.markdown_url to search the whole file.
- **get_tapetide_score** — Get the Tapetide Score for ONE stock: a deterministic, non-LLM 0-100 composite from the latest complete scoring run, with the six pillar sub-scores and their weights, the percentile within that run (base: `percentile_universe`), confidence, coverage, and `governance` caps and red flags. There is no band field: band = Strong 66+, Good 55-65, Average 45-54, Weak 37-44, Poor <37 (as in screen_tapetide_scores). USE THIS for 'what is Tapetide's score for X', 'why is X rated Y', or as the rating input to a write-up. HOW TO READ IT: (1) the band matters more than the number: the distribution is narrow and a 1-3 point gap is noise; (2) a `null` pillar means the data is unavailable, NOT a zero: never average over it or call the company weak on it; (3) `status: "insufficient_data"` means no publishable score: say so, never substitute a number; (4) `governance.caps_applied` / `red_flags` mean an overlay limited the score, worth saying; (5) there is deliberately NO category label: describe the pillar numbers in your own words. Decision-support only. The Tapetide Score is data analysis, not investment advice. Tapetide is not a SEBI-registered research analyst or investment adviser. Bands are intentionally coarse; small point differences may not be meaningful.
- **screen_tapetide_scores** — List and rank stocks by the Tapetide Score, filtered by size bucket, band, score window, sector, minimum data-confidence and symbol/name search. Rows come back in the server's final order with score, band, pillars, sector, size, market cap and a next-page cursor. USE THIS for 'which large caps score highest', 'show me Strong-band pharma stocks', or any rank/filter-by-Tapetide-Score question — same data and ordering as the tapetide.com ranking page. IMPORTANT, or you will describe the results wrongly: (1) present rows by BAND, never as an ordinal '#1, #2, #3' leaderboard — nothing has ever scored above 77 and neighbouring scores are not meaningfully different; (2) the DEFAULT view is large+mid cap at confidence >= 75, a filtered slice and not the whole market, so state the active filters (`meta.counts`) alongside any ranking; (3) sizes:["all"] adds small/micro caps — flag their liquidity risk (market cap is a size proxy, not liquidity); (4) quote `meta.snapshot.score_date` and reuse `next_cursor` to stay on that run. These are stocks matching the given Tapetide Score criteria, NOT investment recommendations. Decision-support only. The Tapetide Score is data analysis, not investment advice. Tapetide is not a SEBI-registered research analyst or investment adviser. Bands are intentionally coarse; small point differences may not be meaningful.
- **get_option_chain** — Get the INDEX OPTION CHAIN with implied volatility, Greeks, bid/ask and open interest by strike. Use for any option-chain, IV, Greeks, open-interest, PCR or max-pain question — 'show me the NIFTY option chain', 'what is the ATM IV', 'where is max pain', 'put-call ratio', 'OI by strike'. Covers NIFTY, BANKNIFTY, FINNIFTY, MIDCPNIFTY ONLY — we do not collect a chain for individual stocks, so for a stock-option question say the chain covers index options only rather than implying we have no options data at all; get_option_iv_history DOES cover ~556 underlyings including stocks. IMPORTANT: this is an END-OF-DAY STAMPED snapshot, not a streaming live tick. Read `snapshot_ts` and state it (e.g. 'as of the 7 Aug close') — never imply an intraday real-time quote. `iv_pct` and `atm_iv_pct` are PERCENT (10.87 means 10.87%); `atm_iv_change` is percentage POINTS vs the prior session. NULLS ARE UNAVAILABLE, NEVER ZERO: a leg flagged `iv_unsolved` has null IV and Greeks (reason in `iv_status`), `illiquid` means no OI/volume so its premium is indicative only, and `pcr_undefined` means the put/call ratio cannot be computed. Render these as '—'; never state a 0% IV, a 0 delta or a PCR of 0. Also read `atm_offset` (strike steps from ATM) and `available_expiries`. Present the chain as data: report the numbers and what they describe. Do NOT recommend a strike, a strategy, or a direction to trade.
- **get_option_iv_history** — Get the HISTORICAL option-analytics time series for an underlying — ATM implied volatility, IV rank, IV percentile, realised vol, put-call ratio (OI and volume), max pain and 25-delta skew, one point per session. Use for 'is IV high right now', 'IV rank of RELIANCE', 'has volatility been rising', or any volatility-regime / IV-vs-realised comparison. Covers ~556 underlyings INCLUDING individual stocks (unlike get_option_chain, which is index-only). UNITS: every IV field is a PERCENT (10.55 means 10.55% annualised) — never multiply by 100 again. `iv_rank_pct` and `iv_percentile_pct` are percents too, not 0-1 scores, and they are DIFFERENT measures: rank is position in the trailing high-low band, percentile is the share of sessions below the current reading. Read `bar_interval` — ranges of 2y+ are rolled up WEEKLY, so counting points as trading days will be wrong; one call returns at most the 400 most recent bars, so quote the `from_date`/`to_date` returned rather than assuming full history. The response also states its own `coverage` and flags `spot_is_proxy` — respect both. Report the numbers and what they describe. Do NOT recommend a trade, a strike, or a volatility position.
- **get_index_performance** — Rank NSE indices by RETURN over recent completed weeks or months, using official NSE index closing levels. Returns per-period % plus cumulative % for each index, sorted best-to-worst. Covers ~140 indices: all sectoral (IT, Bank, Auto, Pharma, FMCG, Metal, Realty, Energy, Oil & Gas, PSU Bank, Private Bank, Media, Healthcare, Consumer Durables, Power, Insurance, Telecom, Chemicals, Cement, Capital Goods, NBFC, Retail and more), plus broad market/size, thematic and strategy/factor indices. USE THIS for 'rank sectoral indices by 3-week return', 'which sector performed best last month', 'top gaining sectors', or weekly close-to-close index returns — do NOT compute a sector return from its constituents, which is only an approximation. Only COMPLETED periods are counted; the in-progress week/month is excluded.
- **get_index_history** — Get the historical LEVEL series (OHLC + PE/PB/dividend yield) for a single NSE INDEX — Nifty 50, Nifty Bank, Nifty IT, Nifty Oil & Gas, India VIX, and ~140 more. Official NSE index data. Use for 'what did Nifty IT close at on <date>', 'Nifty Bank level history', 'India VIX over the last month', or index valuation trend. This is the INDEX counterpart of get_price_history (which handles individual stocks only). To rank or compare MULTIPLE indices by return, use get_index_performance instead.
- **get_adjustment_factors** — Get the split/bonus adjustment-factor timeline for a stock, so a raw (unadjusted) price series can be reconstructed from the adjusted one. Returns per-event factor and cumulative factor with ex-dates, plus the reconstruction formula in meta. USE THIS when a price move looks impossibly large and you need to know whether it was a corporate action rather than a real return, or when the user asks for raw/unadjusted prices, or asks how to adjust for splits and bonuses. CRITICAL: the response also carries `unquantified_events` — rights issues and demergers that are KNOWN but have NO reliable numeric factor (a rights adjustment needs the subscription price; a demerger is not a single number). Never invent a factor for those; tell the user those ex-dates should be excluded or treated with caution. NOTE: factors cover splits and bonuses only. The adjusted series is PRICE-return, not total-return — dividends are not included.
- **get_observation_status** — For every CALENDAR day in a lookback window, get why a price is or is not present: `traded`, `weekend`, `holiday`, `pre_listing`, `delisted`, or `no_print`. USE THIS when a price series has gaps and the user needs to know whether a missing day was a market holiday, a suspension, a pre-listing date, or genuinely missing data — and ESPECIALLY before computing returns over a gappy series. A missing price is NOT a zero return: `no_print` means a listed trading day with no print and should be treated as not-a-return (carry forward or mask), never as 0%. HONESTY LIMITS in the response's `classification_limits`: `no_print` deliberately does NOT distinguish an illiquid no-trade from a suspension from missing data (no per-day suspension feed exists, so a specific reason would be fabricated), and `pre_listing` can only be asserted where a listing date is known — its absence is not evidence the stock was trading.
- **get_index_membership_asof** — Was a stock a constituent of an index on a specific historical date? Returns a FOUR-STATE answer, never a bare yes/no: `present` (proven in range), `uncertain` (inside an unobserved bracket around a join/leave — plausible but NOT proven), `absent` (proven not a member, within coverage), or `out_of_coverage` (outside the observed window — we cannot answer). USE THIS for any 'was X in the Nifty 50/500 on <date>' question, and for point-in-time universe construction or survivorship-bias-aware backtests. Do NOT infer historical membership from today's constituent list — that is exactly the survivorship bias this tool exists to avoid. REPORT UNCERTAINTY HONESTLY: treat `uncertain` and `out_of_coverage` as NOT tradeable signal and say so; never silently collapse either into `absent`. The response states its own `meta.coverage` window plus `meta.freshness.lag_days` — trust answers only up to `coverage.answerable_through`.
- **resolve_identifier_asof** — Resolve a historical symbol or ISIN to the company that held it ON a given date. USE THIS when working with old data whose ticker may since have been renamed, reused, or reassigned — e.g. a 2018 holdings file, an old research note, or a backtest that must not treat one company as two securities (or worse, merge two different companies because a ticker was recycled after a delisting). Returns `present` | `uncertain` | `not_found` | `out_of_coverage` with certainty ranges; each match names the company by its latest known `symbol` and `isin`, which the other stock tools take. `uncertain` means the date falls in an open bracket around a rename/ISIN change — quarantine it rather than asserting the mapping. The response states its own coverage window; a date outside it returns `out_of_coverage` and must not be reported as 'no such symbol'.
- **get_identifiers_asof** — The REVERSE of resolve_identifier_asof: given a company's `symbol` and a date, return which symbol and ISIN that company held at that time. USE THIS to label historical output correctly — e.g. reporting a 2019 backtest position under the ticker it actually traded as then, rather than its current name. Also useful for explaining a rename to a user who is confused why a symbol they remember no longer resolves. Pass the symbol the company trades as today (resolve_identifier_asof maps an old ticker to it). Coverage bounds are stated in the response — outside them the answer is `out_of_coverage`, not 'no identifiers'.
- **read_me** — Returns the complete guide to this server — all tools organised by category, the SEBI disclaimer requirement, and usage patterns for common research tasks.
- **scan_movers** — Alias for get_trending_stocks. Top gainers, losers, and most-active stocks today.
- **get_live_quote** — Alias for get_stock_quote (same fields, incl. price_basis and last_trade_date). NSE prices can lag the exchange by up to ~15 minutes. Example: {"symbol":"RELIANCE"}.
- **get_stock_news** — Alias for get_stock_events with type:"news". Sentiment-tagged news for one stock. Example: {"symbol":"TCS"}.
- **get_corporate_actions** — Alias for get_stock_events with type:"corporate_actions". Dividends, splits, bonuses, AGMs for one stock. Example: {"symbol":"ITC"}.
- **run_preset_screen** — Not a standalone tool. For ready-made movers use get_trending_stocks; for custom fundamental screens use screen_stocks; for technical screens use screen_stocks_technical.
- **get_user_portfolio** — Get the authenticated user's current stock portfolio with live prices. Returns each holding's symbol, company name, quantity, average buy price, current market price, P&L (absolute + %), invested value, portfolio weight %, sector, industry, market cap, PE ratio, dividend yield, and company classification (large/mid/small cap), plus portfolio-level totals.

Returns an empty list when the user has not added any holdings. Holdings can be added with add_portfolio_stocks, including from a pasted broker CSV export.
- **add_portfolio_stocks** — Add one or more stocks to the user's portfolio, merging duplicates by weighted-average price. Accepts a single add, a bulk list, or holdings the user pasted from a broker CSV/table (parse it into the holdings array yourself). Example: "Add RELIANCE 10 shares at ₹1,350" → holdings:[{symbol:"RELIANCE",quantity:10,avg_price:1350}]. STRIP exchange suffixes before calling — -EQ, -BE, -SM, -ST, -BZ, -BL, -RE, -IV, -RR, .NS, .BO — and pass plain NSE symbols (APS-SM → APS; SME stocks are supported). When the user has stated symbol, quantity and price, add them directly. When you PARSED or inferred the holdings (broker CSV, a pasted table, a screenshot), show the parsed rows for confirmation first, and ask rather than guess a missing or ambiguous field. Use search_stocks if a symbol does not resolve. Call read_me for the full broker-CSV procedure.
- **update_portfolio_stock** — Update the quantity and/or average price of an existing stock in the user's portfolio.

Use cases:
• User says "I bought 10 more RELIANCE at ₹1,400" → you must calculate the new total qty and weighted avg price, then call this tool
• User says "Change my TCS quantity to 50" → direct update
• User says "I sold 5 shares of INFY" → reduce quantity (calculate new qty = old - 5)

IMPORTANT workflow for additional purchases:
1. First call get_user_portfolio to get current quantity and avg_price
2. Calculate: new_qty = old_qty + additional_qty
3. Calculate: new_avg = (old_qty × old_avg + additional_qty × purchase_price) / new_qty
4. Call this tool with the NEW total quantity and NEW weighted average price

For partial sells:
1. new_qty = old_qty - sold_qty (avg_price stays the same)
2. If new_qty = 0, use remove_portfolio_stocks instead

Both quantity and avg_price are required — always provide the final values.
- **remove_portfolio_stocks** — Remove one or more stocks from the user's portfolio entirely.

Use cases:
• User says "Remove INFY from my portfolio" → single delete
• User says "Remove all IT stocks" → you identify the symbols from get_user_portfolio, then delete them
• User says "Clear my portfolio" → remove all symbols

IMPORTANT: Always confirm with the user before removing stocks. This action cannot be undone.
For partial sells (reducing quantity), use update_portfolio_stock instead.
- **get_watchlist** — Get the user's stock watchlist — the stocks they are following, newest first. Returns symbol, company name, sector, industry and the live quote (price, change, change %, previous close; null when unpriced) for each stock, plus a gainers/losers/unchanged tally of the whole list in `movers`. Paged: up to 50 stocks per call; when `has_more` is true, call again with `offset: next_offset` to get the rest (do this before acting on "all" of a long watchlist).
- **add_to_watchlist** — Add one or more stocks to the user's watchlist. Idempotent — adding a stock that's already followed is a no-op.

Use cases:
• User says "Watch RELIANCE" → single add
• User says "Add all Nifty IT stocks to my watchlist" → you look up the symbols, then add them
• User says "Track TCS, INFY, WIPRO" → bulk add
- **remove_from_watchlist** — Remove one or more stocks from the user's watchlist.

Use cases:
• User says "Stop watching INFY" → single remove
• User says "Clear my watchlist" → remove all (get watchlist first, paging with next_offset until has_more is false, then remove all symbols)

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "stock-research-mcp": {
    "command": "npx",
    "args": ["-y","tapetide-mcp"],
    "env": {
      "TAPETIDE_TOKEN": ""
    }
  }
}
```

**Requires environment variables:** `TAPETIDE_TOKEN` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What stock-research-mcp does

stock-research-mcp provides MCP tools for researching Indian equities listed on the NSE and BSE. Its coverage spans approximately 8,000 stocks, from major index constituents to SME companies. The toolset combines live quote data, historical OHLCV series, financial statements, ownership information, corporate filings, market news, index statistics, derivatives data, and institutional-flow reports.

The server is suited to research workflows that need more than a single price lookup. Agents can resolve companies by name, symbol, BSE code, or ISIN, including renamed companies and brand aliases. They can then screen stocks across 326 fundamental ratios or apply technical conditions such as RSI, moving-average crossovers, MACD, Bollinger Bands, ADX, volume, and momentum.

## How it works

The hosted endpoint is available at `https://mcp.tapetide.com/mcp`. Remote clients connect over HTTP and authenticate with Google OAuth or a personal bearer token. Local clients can run a lightweight bridge through `npx` or `uvx`; that bridge forwards MCP JSON-RPC requests to the remote service rather than implementing the market-data logic locally.

The npm bridge reads MCP messages from standard input and writes responses to standard output. It supports common Content-Length and newline-delimited JSON framing, handles the remote server's SSE responses, and preserves the MCP session identifier between requests. The Python package provides the same bridge through `uvx` or `pip`. Remote tools and updates are therefore available without rebuilding the local bridge.

## Setup and configuration

For a local npm setup, use Node.js 18 or newer and configure the server with the `TAPETIDE_TOKEN` environment variable:

```json
{
  "mcpServers": {
    "tapetide": {
      "command": "npx",
      "args": ["-y", "tapetide-mcp"],
      "env": { "TAPETIDE_TOKEN": "your_token_here" }
    }
  }
}
```

A Python setup uses Python 3.10 or newer with `uvx tapetide-mcp` and the same token variable. URL-capable clients can use the hosted endpoint with an `Authorization: Bearer YOUR_TOKEN` header. Chat-based remote connections use Google sign-in instead. The repository also provides setup paths for Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Codex CLI, Gemini CLI, Zed, and Cline, including a Gemini CLI extension and a Claude Code plugin.

## Tools and capabilities

- Resolve symbols and company identities with `search_stocks`.
- Screen on fundamental ratios, technical indicators, sectors, industries, and cross-field conditions.
- Retrieve quotes individually or in batches of up to 20 stocks.
- Read daily or weekly price history for up to 2,000 sessions per request, with publication timestamps on financial periods.
- Inspect quarterly and annual profit and loss, balance sheet, cash flow, ratios, forecasts, shareholding, promoter pledges, credit ratings, dividends, and mutual-fund ownership.
- Analyze FII/DII and FPI flows, market news, India VIX, index performance, valuations, heatmaps, and daily market datasets.
- Examine index option chains, implied-volatility history, expiry aggregates, Greeks, open interest, PCR, max pain, and skew.

## Limitations and notes

A free account provides 50 tool calls per day. Authentication is required for local token-based use, while remote chat access uses Google OAuth. Option-chain data is described as a stamped end-of-day snapshot, so it is distinct from the live quote tools. The local npm and Python packages act as transport bridges; tool execution and market-data logic remain on the remote service.

_Full upstream README: https://allmcps.com/mcp/stock-research-mcp/readme_

