# DalalOS: Indian Stock Market Research (NSE/BSE) (remote · mcp.dalalos.in)

Filing-grounded Indian stock research (NSE/BSE): financials, ratios, screens. Sourced and dated.

- Trust score: 79/100 (medium)
- Change this week: +5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- remote · `mcp.dalalos.in`: 79/100 (this document), [markdown](https://verifymcp.io/servers/in-dalalos-mcp/mcp.md), [page](https://verifymcp.io/servers/in-dalalos-mcp/mcp)

## Channel facts

- Endpoint: `https://mcp.dalalos.in/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Endpoint Security**: 95/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC is configured correctly; the domain's records validate against the full chain to the root.
  - The authorisation server supports Client ID Metadata Documents, the current MCP client-registration mechanism.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 59/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 23601 tokens (~342/item across 69 items; 69 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 33/100
  - Stability observed for 10 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 78/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 22% of tool parameters carry a description.
  - Structured output schemas are declared (1% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 70 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the DalalOS: Indian Stock Market Research (NSE/BSE) MCP server?

DalalOS: Indian Stock Market Research (NSE/BSE) is a hosted endpoint at https://mcp.dalalos.in/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http in-dalalos-mcp 'https://mcp.dalalos.in/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "in-dalalos-mcp": {
      "url": "https://mcp.dalalos.in/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "in-dalalos-mcp": {
      "type": "http",
      "url": "https://mcp.dalalos.in/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.in-dalalos-mcp]
url = "https://mcp.dalalos.in/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "in-dalalos-mcp": {
      "type": "remote",
      "url": "https://mcp.dalalos.in/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add in-dalalos-mcp --url 'https://mcp.dalalos.in/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  in-dalalos-mcp:
    url: "https://mcp.dalalos.in/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "in-dalalos-mcp": {
      "Transport": "http",
      "Url": "https://mcp.dalalos.in/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add in-dalalos-mcp -t streamable-http -u 'https://mcp.dalalos.in/mcp'
```

### Other

```json
{
  "mcpServers": {
    "in-dalalos-mcp": {
      "type": "http",
      "url": "https://mcp.dalalos.in/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 79, 0)

- [functional regression] Tool coverage: 28% → 22%
- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-11-04 (score 79, +2)

- [security improvement] DNSSEC: fail → pass
- [functional improvement] Tool coverage: 0% → 28%
- [functional] Schema quality: good → excellent
- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-11-03 (score 77, +1)

- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-11-02 (score 76, 0)

- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-11-01 (score 76, +1)

- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-10-31 (score 75, 0)

- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-10-30 (score 75, +1)

- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

### 2026-10-29 (score 74, 0)

- [functional regression] Tool coverage: 11% → 2%
- [functional] This server's schema is too large to store in full, so we cannot compare its tools day to day

## MCP tools (69)

### `ping` (~37 tokens)

Connection check

Use this only to confirm the DalalOS connection is working.

DalalOS health check. Returns a success envelope to confirm the server is reachable.

### `get_filing_extract` (~644 tokens)

Filing summary

Use this when the user asks for the contents or a summary of one specific BSE filing of an Indian company, using a news_id from get_stock_events. It may queue processing and use a small daily allowance.

Get the cached PDF-extraction for one BSE corporate filing. Accepts NSE symbol, ISIN,
    or BSE code + a BSE news_id. Obtain the `news_id` from get_stock_events, which lists a
    security's recent filings each carrying its `news_id`.

    Returns cached grounded facts + a factual summary extracted from the filing PDF. On a cache
    miss for any filing that has an attached PDF, calling this tool ENQUEUES on-demand extraction.
    It waits (up to ~30 seconds) only when the queue estimate says the result can be ready in
    that time; otherwise it returns at once with `status="pending", queued=true`,
    `retry_after_seconds` and, when known, an `eta_seconds` estimate from the current queue and
    recent run times — call again after that long to retrieve the facts. Extraction often takes a
    few minutes, so to read several filings of one company use get_filing_extracts (up to 10
    news_ids per call) rather than polling this tool per filing. Extraction works for ANY filing
    with a PDF, not a fixed doc-type list — EXCEPT financial-results
    filings, which return `not_queued` reason `results_available_via_financials` (+ a `see_instead`
    pointer) because their figures come from XBRL via get_financials / get_financial_trends, not
    PDF extraction. Every `pending` response carries a `reason_code` that stays consistent across
    repeat polls of the same news_id: `on_demand_processing` (this tool's own trigger enqueued it,
    or moved an already-queued automatic job up to on-demand priority, and it is still
    queued/running — keep polling), `auto_backfill_processing` (already being processed by
    automatic extraction, not this tool — keep polling), or `awaiting_auto_backfill` (not yet
    queued, but eligible for a future sweep). Other cache-miss statu…

Input parameters:

- `news_id` (string, required)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_filing_extracts` (~446 tokens)

Several filing summaries

Use this when the user wants summaries of several filings of one Indian company at once (up to 10 news_ids from get_stock_events). It may queue processing and use allowance.

Get the cached PDF-extractions for several BSE filings of ONE company in one call. Accepts
    NSE symbol, ISIN, or BSE code + a list of up to 10 BSE news_ids (from get_stock_events).

    Use this instead of calling get_filing_extract once per filing. Each entry in `filings` (in
    request order) is exactly what get_filing_extract returns for that filing: extracted facts
    with verbatim source quotes when cached, otherwise `pending` / `not_queued` / `failed` with
    the same `reason_code` values. Every uncached filing with a PDF is ENQUEUED for on-demand
    extraction in this one call (each enqueue counts against the caller's per-day on-demand cap;
    once the cap is reached the rest return `not_queued` reason `on_demand_quota_exceeded`).
    This tool never waits. When some filings are still `pending`, the response lists them in
    `pending_news_ids` with one shared `retry_after_seconds`: call this tool again after that
    long with just `pending_news_ids`. `counts` tallies the entries by status. To keep the
    response small, a cached filing past the size budget comes back as a stub listed in
    `omitted_for_size`; fetch it with get_filing_extract (it is cached, so no new extraction). A
    news_id that is not this company's filing returns `status="request_error"` without failing
    the batch. Raw disclosed facts with verbatim source quotes only — no verdicts, targets, or
    recommendations.

Input parameters:

- `news_ids` (array, required)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_market_fii_dii_flow` (~325 tokens)

FII and DII market flow

Use this when the user asks what FIIs and DIIs have been buying or selling in Indian equities day by day across the whole market. Not for a company's ownership percentage; use get_shareholding.

Market-wide DAILY FII/DII net cash-flow (Rs crore), NSE cash (Capital Market) segment.

    NOT the shareholding data: get_shareholding gives per-company QUARTERLY FII/DII holding
    PERCENTAGES; this gives market-wide DAILY net buy/sell/net value in Rs crore -- e.g. "FIIs
    net sold Rs 2,340 Cr, DIIs net bought Rs 1,890 Cr" for a given trading day. `from_date`/
    `to_date` are optional ISO dates (default: trailing ~30 days); `segment` is "cash" only.
    For NSE participant-wise F&O positioning, use `get_fo_participant_activity`. Raw
    figures; `net = buy - sell` is the only computation, with no interpretation added.
    The envelope's `source` reflects actual per-call provenance: recent
    dates are NSE-live (`source="nse"`), older dates come from a one-time historical backfill by
    a secondary public source,
    since NSE publishes no bulk cash-history archive (each row's `source` names its origin), and
    a query
    window spanning both returns `source="mixed"`.

Input parameters:

- `from_date`
- `segment` (string)
- `to_date`

### `get_stock_fii_flow` (~377 tokens)

Stock FII flow (historical)

Use this when the user asks about daily FII transaction flow in one Indian stock in the historical CDSL data, which stops at March 2025.

Per-stock DAILY FII/FPI transaction flow (raw Rs) -- daily series + trailing-30d summary.

    Accepts NSE symbol, ISIN, or BSE code. `days` (1..1825, default 90) bounds the daily
    `series`; `summary` is always the trailing-30d figure (the SAME single-source helper
    get_company_profile's compact `fii_activity` field uses). A distinct FII/FPI surface from
    get_market_fii_dii_flow (market-wide) and get_shareholding (quarterly holding %) -- this is
    per-STOCK daily transaction flow, aggregated from CDSL's trade-wise disclosure.

    COVERAGE CAVEAT: CDSL-only (NSDL's per-stock data is not ingested), and CDSL stopped
    publishing after March 2025 -- every response carries a `coverage_note`.
    `net = buy - sell` is the only computation (SEBI-RA line: no direction calls, no "smart
    money" framing).

    Renamed from `get_fii_activity` so the name carries "flow" like its
    get_sector_fii_flow/get_market_fii_dii_flow siblings ("activity" gave no scope cue).
    `get_fii_activity` is kept as a deprecated back-compat alias for this release.

Input parameters:

- `days` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_watchlist` (~232 tokens)

Show watchlist

Use this when the user asks what is on their DalalOS watchlist, a saved list of stock symbols (not brokerage holdings).

Get the caller's DalalOS watchlist: bare stock symbols, no quantity/cost-basis.

    Use this whenever the user asks what's on their (DalalOS) watchlist, or before adding/
    removing symbols to check current state. This is DalalOS's own watchlist, tied to the
    caller's DalalOS account.

    Requires an authenticated caller (API key or OAuth session tied to a DalalOS account) --
    unauthenticated or auth-disabled deployments get an `unauthorized`/`not_configured` error
    envelope instead of data. Each entry is decorated with `name`/`sector`/`market_cap` (best
    effort, via the same lookup `get_company_profile` uses) alongside the bare `symbol` and
    `added_at`; a symbol that no longer resolves (delisted, renamed) still returns as a bare row
    rather than failing the whole call.

### `add_to_watchlist` (~424 tokens)

Add to watchlist

Use this when the user asks to add, watch or track Indian stocks in their DalalOS watchlist. Changes only the user's own saved list.

Add one or more stocks to the caller's DalalOS watchlist, accepting a pasted list.

    Use this when the user says "watch X", "track X", "add X to my watchlist", or asks to save
    stocks they just searched/screened/analyzed via DalalOS for later. This writes to DalalOS's
    own watchlist, tied to the caller's DalalOS account.

    `symbols` accepts a list of strings or a single string, and any entry may itself be a
    DELIMITED PASTE -- commas, newlines, semicolons, tabs or pipes -- so a CSV or pasted
    list of symbols can be handed over as-is. Each fragment is resolved by exact identifier
    (NSE symbol, ISIN, BSE code) first, then by company name, so "Gandhar Oil" becomes
    GANDHAR. Capped at 200 resolved symbols per call.

    Fragments are never guessed at. The response splits three ways: `watchlist` (added),
    `unmatched` (no match), and `ambiguous` (two or more plausible matches, returned WITH their
    candidates so you can ask the user which they meant rather than picking one). Space-separated
    company names cannot be split reliably -- "GANDHAR OIL SAVITA OIL" is one fragment, not two --
    so ask the user for one per line or comma-separated if a paste comes back unmatched.

    Re-adding a symbol already on the watchlist is a no-op, not an error. Requires an
    authenticated caller; see `get_watchlist` for the auth error shape.

Input parameters:

- `symbols` (required): List of NSE symbols, ISINs or BSE codes, e.g. ["TCS", "INFY"]. Always send it as `symbols`.

### `remove_from_watchlist` (~280 tokens)

Remove from watchlist

Use this when the user asks to remove stocks from their DalalOS watchlist. Changes only the user's own saved list.

Remove one or more stock symbols from the caller's DalalOS watchlist in a single call.

    Use this when the user says "stop watching X", "remove X from my watchlist", or "clear my
    watchlist" (call get_watchlist first, then pass every returned symbol here in one call).
    This is DalalOS's own watchlist, tied to the caller's DalalOS account.

    `symbols` accepts either a list of strings (mirrors `add_to_watchlist`, capped at
    200 symbols per call) or a single bare string (kept for one release for
    backward compatibility with older single-symbol callers). A partial match -- some symbols
    on the watchlist, some not -- never fails the call: the response reports
    `{"removed": [...], "not_found": [...]}` so the caller can see exactly which symbols were
    actually removed. Requires an authenticated caller; see `get_watchlist` for the auth error
    shape.

Input parameters:

- `symbols` (required): List of NSE symbols, ISINs or BSE codes, e.g. ["TCS", "INFY"]. Always send it as `symbols`.

### `submit_dalalos_feedback` (~555 tokens)

Send DalalOS feedback

Use this when the user asks to report a problem with DalalOS data or tools, or to request a feature, or agrees after you offer to report a likely DalalOS issue. Not for questions about a company; it sends a report to the DalalOS team and does not change any data.

Submit a user-approved report about DalalOS data, tools, documentation, or a feature request. Use this when the user asks to report feedback or agrees after you offer. Include only details needed to understand the issue; do not send full conversations, credentials, account information, contact details, portfolio holdings, or unrelated private data. Clearly distinguish a suspected issue from a verified fact: a reported discrepancy is stored as a claim, since units, periods or source timing may explain it. Never report a failure of this feedback tool itself, and do not offer to report the same issue twice in one conversation.

Fields: `category` (data_inaccurate, data_outdated, data_missing, tool_error, unexpected_result, feature_request, documentation, other), `summary` (max 160 chars), `details` (what happened or what is needed, max 2000 chars) and `request_id` (a fresh UUID you generate per report; reuse it only to retry the same report) are required. Optional context: `related_tool` (the DalalOS tool involved), `security_identifier` with `security_identifier_type` (nse_symbol, bse_code or isin; give both or neither), `metric`, `observed_value` and `expected_value` (with units, max 200 chars each), `as_of_date` (date or reporting period), `source_reference` (a short citation or URL; it is stored, never fetched). No source, exact value or identifier is required.

Requires an authenticated caller. Feedback is free and does not use monthly credits. On success returns `report_id` and `status` "received" (the report was saved; it has not been verified, prioritised or fixed). Tell the user the report supports future improvements, that the team will not reply to individual reports for now, and give them the rep…

Input parameters:

- `as_of_date`
- `category` (string, required)
- `details` (string, required)
- `expected_value`
- `metric`
- `observed_value`
- `related_tool`
- `request_id` (string, required)
- `security_identifier`
- `security_identifier_type`
- `source_reference`
- `summary` (string, required)

### `search_stocks` (~246 tokens)

Find an Indian stock

Use this when the user names an Indian company, NSE symbol, BSE code or ISIN and you need to identify the listed security before calling another tool. Not for US or other non-Indian stocks.

Find Indian stocks by company name, NSE symbol, BSE code, or ISIN.

    Returns matching securities with their ISIN, internal company_id, name, and both
    exchange codes. Use this first when a ticker is unknown or ambiguous, then pass a returned
    `nse_symbol` / `isin` / BSE code as the `query` argument to any other per-stock tool.
    Tolerant matching: a company-name/symbol typo still surfaces a suggestion, a truncated/
    partial ISIN or BSE code matches via prefix, and a former/retired name or symbol (e.g. a
    pre-rename company name) resolves to the security's current identity, with `resolved_via`
    on the result naming which kind of resolution fired.

Input parameters:

- `limit` (integer)
- `query` (string, required): Company name or part of it, or an NSE symbol, ISIN or BSE code.

### `get_stock_quote` (~427 tokens)

Stock quote (end-of-day)

Use this when the user asks for the price, trading volume, 52-week range, PE or PB of an Indian company listed on NSE or BSE. Prices are end-of-day, not live. Not for non-Indian stocks or live intraday prices.

Get the latest end-of-day quote (price, OHLC, volume) for an Indian stock.

    Accepts an NSE symbol, ISIN, or BSE code. Prices are EOD from the NSE bhavcopy. Carries
    `currency` ("INR") and a mechanically-computed `vwap` (turnover / volume for the latest
    bar, None when either is missing/zero). P/E and P/B may be null with a `valuation_notes`
    explanation (e.g. negative shareholders' equity, or a proven loss) rather than a
    misleading ratio. A `ratios_caveat` field and/or a `week52_adjustments` list appear when a
    split, bonus, or other corporate action in the trailing 52 weeks affects the comparability
    of the 52-week range or valuation ratios. `recent_dividends` / `upcoming_dividends` /
    `dividend_yield` carry realized cash-dividend history and trailing yield. Always check
    these fields before restating a figure as clean.

    A `bse_reported` sub-object, when present, carries BSE's OWN published ROE/operating margin/
    net margin — a DIFFERENT, BSE-computed figure (not necessarily TTM or the same
    consolidated/standalone basis) from this project's XBRL-derived ratios elsewhere. It is a
    cross-check/fallback signal only — never treat it as the same number as a computed `roe`.

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_batch_quotes` (~167 tokens)

Quotes for several stocks

Use this when the user wants end-of-day prices or ratios for several Indian stocks at once (up to 20), for example to line up peers.

Get EOD quotes for up to 20 Indian stocks in one call (peer benchmarking).

    Each item carries the same fields as get_stock_quote (currency, vwap, bse_reported, any
    valuation_notes/ratios_caveat/dividend fields) plus `status` and `error` keys, so an
    unresolved or uncached symbol is reported per-item rather than failing the whole batch.

Input parameters:

- `symbols` (array, required): List of up to 20 NSE symbols, ISINs or BSE codes, e.g. ["TCS", "INFY"]. Always send it as `symbols`.

### `get_financials` (~885 tokens)

Company financials

Use this when the user asks how an Indian company listed on NSE or BSE has performed financially: revenue, profit, margins, balance sheet, cash flow or growth, quarterly or annual. Not for non-Indian companies; for a period-by-period growth series use get_financial_trends.

Get consolidated financials (P&L + balance sheet), TTM, and computed margins.

    Accepts an NSE symbol, ISIN, or BSE code. `period_type` is "quarterly" (default) or
    "annual". Banks/NBFCs/insurers return an interest-income template (NII / interest
    income) instead of Revenue / EBITDA. Returns raw line items and mechanically-computed
    ratios only — no valuation verdicts. Also includes a `growth` section (annual YoY plus
    3y/5y CAGR for revenue / net income / EBITDA / EPS) — a single summary block layered on
    top of these levels, NOT a per-period series; for a period-by-period QoQ/YoY growth,
    margin-delta, and reportable-segment trend series instead, see `get_financial_trends`.
    The `growth` section here is sign-aware (a loss base/endpoint is
    Not Meaningful rather than a garbage %), EPS share-adjusted across splits/bonuses, with a
    `base_effect` flag when a tiny prior-year base inflates the YoY. A `null` inside a present
    growth metric (as opposed to the metric being absent, which means <2 annual periods are
    cached) means the growth figure is Not Meaningful for that metric this period — most
    commonly because the prior-year base (or a CAGR endpoint) was a loss, making a percentage
    change mathematically undefined or misleading; it is not a data gap. When that is the
    cause, a sibling `*_not_meaningful_reason` field (e.g. `yoy_not_meaningful_reason:
    "prior_period_loss"`) makes it explicit rather than leaving the `null` to be misread as
    "no data available".

    Also carries three multi-period histories (independent of `period_type`/`limit` — always
    the full annual history): `interest_coverage_history` (per-year interest-coverage trend,…

Input parameters:

- `limit` (integer)
- `period_type` (string)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_company_profile` (~391 tokens)

Company profile

Use this when the user asks what an Indian company listed on NSE or BSE is: its sector, industry, market cap and a headline financial summary.

Get a company profile: identity, sector/industry, market snapshot, and TTM summary.

    Assembled from cached security master + quotes + financials. Accepts NSE symbol, ISIN, or
    BSE code. `fundamentals` is None when no financials are cached yet; `market` is None when
    no quote is cached. When present, `market` carries `currency` ("INR") and, only when a
    split/bonus fell inside the trailing 52 weeks, `week52_adjustments` — the same treatment
    get_stock_quote gives its own snapshot. Both `market` and `fundamentals` may carry caveat
    fields (e.g. `market.valuation_notes`, `fundamentals.ttm.basis_note`,
    `fundamentals.latest_period_income.non_recurring_items_note`) when a figure is suppressed
    or driven by a one-off/non-recurring item — always surface these alongside the figure they
    annotate rather than the bare number.

    `market.bse_reported`, when present, carries BSE's OWN published ROE/operating margin/net
    margin — a DIFFERENT, BSE-computed figure (not necessarily the same period or
    consolidated/standalone basis) from `fundamentals`' XBRL-derived ratios. Cross-check/
    fallback signal only — never the same number as the computed `roe`/margins.

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_company_report` (~373 tokens)

Company report

Use this when the user wants a sourced overview of an Indian company listed on NSE or BSE: identity, key facts, recent disclosures and calculations in one report, each linked to its source.

Get a source-linked, read-only canonical company report for one security.

    Accepts an NSE symbol, ISIN, BSE code, or company name. `days` (1-365, default 90) is the
    reporting window that selects which recent disclosures are in scope. Returns the validated
    `company_report_v1` model as the envelope `data`: company identity, source-linked `facts`
    with `citations`, mechanically-computed `calculations`, evidence-referenced `claims`,
    materiality-bucketed `events`, and a `coverage` block that names any missing reviewed mapping
    rather than implying non-disclosure.

    This is DalalOS's own consolidated report over its cached exchange filings + reviewed
    exposure/peer mappings. Read-only: assembled
    entirely from cache, no upstream fetch and no LLM call. Every number in a claim references
    the fact/calculation supporting it, and NO verdict, target price, or buy/sell language can
    appear — the canonical validator rejects such a report before it is ever built (SEBI
    research-analyst boundary). An unresolvable query (or a required input with nothing cached)
    returns `reason_code="not_found"`; an out-of-range `days` returns `invalid_argument`.

Input parameters:

- `days` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_peer_comparison` (~762 tokens)

Peer comparison

Use this when the user compares an Indian company listed on NSE or BSE with similar companies on valuation, margins, returns or debt (PE, PB, debt-to-equity, ROE). For an explainable peer set rather than a table use get_relevant_peers.

Compare a stock against its sector/industry peers on valuation metrics.

    Auto-identifies the peer group and returns a side-by-side table (Mkt Cap, PE, PB,
    Revenue TTM, net / EBITDA margin, ROE, ROA, ROCE, interest coverage, D/E, the EV bundle
    — EV, EV/EBITDA, EV/EBIT and the EV-based earnings yield — plus the cash-flow ratios
    P/CF, P/FCF and FCF yield), sourced entirely from cache. EBITDA-margin and the EV bundle
    are DELIBERATELY general-only (None for banks/NBFCs/insurers — an intentional validity-
    matrix decision: EBIT/EBITDA are not meaningful add-backs for a financial's P&L). Cash-flow
    ratios are NOT gated that way and populate for any peer disclosing an annual cash flow —
    including banks/NBFCs/insurers. The one exception is bank capex specifically: P/FCF and FCF
    yield are structurally unavailable for BANK peers whose only cached annual filing predates
    a capex-mapping fix (banks tag capex under a different XBRL concept than the general
    template; the mapping now covers it, but existing cached rows need a backfill re-scrape to
    pick it up) — P/CF (which doesn't need capex) is unaffected either way.

    Each row also carries `piotroski_f_score` (0-9, general-only; None for banks/NBFCs/
    insurers) and `altman_z_score` (general-only; None for banks/NBFCs/insurers, and for a
    general filer whenever any of the five classic-formula inputs is undisclosed for that
    security). The explanatory text for WHY a score is None is never repeated per row — it is
    deduplicated across the whole peer set and surfaced once at
    `data.notes.{piotroski_f_score,altman_z_score}` (a list of the distinct reasons actually
    present in the table). A row with an implausible figure (e.g. a corrupte…

Input parameters:

- `limit` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_shareholding` (~442 tokens)

Shareholding pattern

Use this when the user asks who owns an Indian company listed on NSE or BSE: promoter, FII, DII, mutual fund and public holding percentages by quarter. Not for daily buying or selling; for daily FII/DII flow use get_market_fii_dii_flow or get_stock_fii_flow.

Get the promoter / FII / DII / public shareholding-pattern time series for a stock.

    Accepts an NSE symbol, ISIN, or BSE code. `limit` caps the most-recent quarterly periods
    (max 12). Returns raw reported ownership percentages — no verdicts. Sourced from cache;
    returns an empty series with a note when no shareholding data is cached yet. `breakdown`
    (when the underlying filing's raw payload was cached) carries the full BSE-SHP
    institutional sub-category split as `breakdown.institutions`, a list of
    `{"category": ..., "pct": ...}` — e.g. Mutual Funds, Insurance Companies, Alternate
    Investment Funds, Provident/Pension Funds, Sovereign Wealth Funds, Foreign Portfolio
    Investors Category I / II — separately from the headline `fii_pct`/`dii_pct` aggregates.
    Category label strings are BSE's own text as filed (may contain formatting artifacts like
    a trailing "/" or doubled spaces), not normalized. Omitted entirely for a period whose raw
    payload wasn't cached. `breakdown.named_institutional_holders` lists individual FII/FPI,
    insurance, and mutual-fund holders BSE's filing names once they cross the Reg 31 reporting
    threshold — `{"name": ..., "category": ..., "pct": ...}` per holder — so a caller can see
    who specifically holds a stake, not just the category total.

Input parameters:

- `limit` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_price_history` (~324 tokens)

Price history

Use this when the user wants past share prices of an Indian company listed on NSE or BSE over a period, daily, weekly or monthly, for example to chart or compare a move.

Get the OHLC + volume price-history series for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. `days` (1..1825) bounds the lookback window.
    Set `adjusted=True` for split/bonus-adjusted closes; default is raw close. `interval`
    is 'daily' (default), 'weekly', or 'monthly' (weekly/monthly resample the adjusted
    daily series). EOD from the NSE bhavcopy. `currency` is always "INR". Each bar carries
    `sma_50` and `sma_200`, computed from daily split/bonus-adjusted (both modes) closes before resampling, plus a
    mechanically-computed `vwap` (turnover / volume, None when either is missing/zero); vwap
    is not rescaled by the split/bonus adjustment factor (turnover/volume are raw flow
    figures, identical in raw and adjusted mode).

Input parameters:

- `adjusted` (boolean)
- `days` (integer)
- `interval` (string)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_valuation_history` (~181 tokens)

Valuation history

Use this when the user asks how an Indian stock's PE or price-to-sales ratio has changed over time.

Get point-in-time P/E and price-to-sales history for an Indian stock.

    Each point uses only the TTM filing that was public on that trade date. `days` accepts
    1..1825; `interval` is daily, weekly, or monthly. P/S is null where the filing lacks a
    usable top line or disclosed share count. Cache-only, mechanically computed, no verdicts.

Input parameters:

- `days` (integer)
- `interval` (string)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_returns` (~310 tokens)

Stock returns

Use this when the user asks how much an Indian stock has returned over a period (1 week to max), or about its volatility or drawdown.

Get mechanical return statistics over standard windows for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. Returns period returns (1W/1M/3M/6M/1Y/YTD/max),
    CAGR, annualized volatility, max drawdown, and 52-week high/low — all computed from the
    split/bonus-adjusted close series. A null return is always explained by exactly one of two
    fields: `incomplete_windows` (not enough price history for that window yet) or
    `corporate_action_flagged_windows` (a rights issue/demerger/spin-off/merger/bare
    consolidation fell inside the window, so the window mixes a mechanical value transfer with
    ordinary price movement and is nulled rather than reported — see `corporate_action_caveat`
    when present). If the query only resolved via a rename/merger/demerger-successor alias,
    the envelope carries `resolved_via` naming which kind fired. Descriptive statistics only;
    no verdicts.

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_technical_indicators` (~659 tokens)

Technical indicators

Use this when the user asks for moving averages, RSI, MACD, Bollinger Bands, beta or circuit-limit data for an Indian stock.

Get moving averages, RSI, MACD, Bollinger Bands, beta, and circuit-filter band/hit-days
    for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. Moving averages (sma_50/sma_100/sma_200), `rsi_14`
    (Wilder's 14-period RSI), `macd` (12/26/9 EMA line/signal/histogram), `bollinger_bands`
    (20-day, 2-stdev middle/upper/lower + percent_b), and `beta` (regressed against NSE's own
    Nifty 50 daily close series over the trailing ~1Y of paired trading days; `beta_benchmark`
    names it) are all mechanically computed from the split/bonus-adjusted daily close series.

    `circuit_band_pct`/`circuit_band_as_of`/`circuit_hit_days` use the RAW (unadjusted) close
    series and are NSE's own per-security circuit-filter data, not derived from bhavcopy. NSE
    publishes only a CURRENT snapshot with no historical archive, so this pipeline's own daily
    captures are the only source of band history and only exist from whenever this deployment
    started capturing them:
    * `circuit_band_pct` is null for TWO DIFFERENT reasons — check `circuit_band_as_of` to tell
      them apart. `circuit_band_as_of` present + `circuit_band_pct` null means this security
      genuinely has NSE's "No Band" designation (no static daily price band applies — typically
      a large/liquid, F&O-eligible name; this is a complete, real answer, NOT missing data).
      `circuit_band_as_of` null means no band has been captured for this security AT ALL yet
      (also named in `insufficient_history`) — do not conflate the two.
    * `circuit_hit_days` is a list of `{trade_date, close, prev_close, pct_change, band_pct}`
      for RAW-close days that plausibly touched that day's captured band (a small tolerance
      absorbs NSE's tick-size rounding of the actual limit price off the raw percentage) — a
      descriptive flag that trading was likely constrained tha…

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_delivery_trends` (~155 tokens)

Delivery volume trend

Use this when the user asks how much of an Indian stock's traded volume was taken for delivery, and how that has trended.

Get the delivery-volume / delivery-percentage trend for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. `days` (1..1825) bounds the lookback window.
    Returns the raw delivery quantity and delivery % time series from the NSE bhavcopy.

Input parameters:

- `days` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_dividends` (~239 tokens)

Dividend history

Use this when the user asks whether and when an Indian company paid or declared a dividend, or about its dividend yield.

Get the cash-dividend history for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. `years` (1..15, default 5) bounds the window.
    Returns disclosed dividend amounts per share with ex-dates. Raw disclosures only.

    `annual_totals` (fiscal-year, Apr-Mar buckets) also carries a dividend-YIELD HISTORY: each
    bucket's `fy_end_price_date`/`fy_end_price` (the closing price on/before that FY's 31 March
    year-end) and `dividend_yield` (that FY's total dividend / that FY-end close) — None when no
    price history reaches that far back yet.

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).
- `years` (integer)

### `get_brsr` (~335 tokens)

BRSR sustainability disclosures

Use this when the user asks about an Indian company's BRSR (Business Responsibility and Sustainability Report) or ESG disclosures.

Get BRSR (Business Responsibility & Sustainability Report) ESG disclosures for a stock.

    Accepts NSE symbol, ISIN, or BSE code. `years` (1..10, default 3) caps fiscal years returned,
    newest first. Each year gives curated KPIs grouped as `emissions` (Scope 1/2 + intensity),
    `energy`, `water`, `waste`, `social` (female board/KMP %, LTIFR, fatalities, POSH complaints,
    CSR spend, ...), `governance`, and `meta` — each `{value, unit}`, raw as filed with SEBI.
    `include_raw=True` returns the full ~800-concept BRSR map exactly as disclosed over REST only; MCP omits it (about 150k characters per year).

    SEBI's mandatory ESG filing for the top 1000 listed companies (LODR Reg 34(2)(f)). Raw
    disclosed figures only — never an ESG score, rating, or verdict (SEBI-RA line). Coverage
    starts from whenever the nightly refresh began ingesting the company's BRSR.

Input parameters:

- `include_raw` (boolean)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).
- `years` (integer)

### `get_bulk_block_deals` (~309 tokens)

Bulk and block deals

Use this when the user asks about bulk or block trades in an Indian stock on the NSE.

Get NSE bulk/block trade disclosures for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. `deal_type` optionally narrows to "bulk" or "block"
    (omitted returns both); `days` (1..1825, default 90) bounds the trailing window; `limit`
    (1..500, default 100) caps rows returned, newest first.

    Each row is a raw disclosed (symbol, counter-party, direction) record: `client_name`,
    `buy_sell` ("BUY"/"SELL"), `quantity`, `price`, and `remarks` (bulk only). NSE's feed reports
    one row per counter-party + direction, not a matched buyer/seller pair — there is no official
    "buyer paired with seller" record. Only NSE's most-recently-published trading day is fetched
    upstream (no reachable historical bulk/block archive), so coverage starts from whenever the
    nightly refresh job began running, not further back.

Input parameters:

- `days` (integer)
- `deal_type`
- `limit` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_insider_trades` (~452 tokens)

Promoter and insider trades

Use this when the user asks which promoters, directors or company insiders bought, sold or pledged shares of Indian listed companies, market-wide or for one company. Not for bulk or block deals by funds; use get_bulk_block_deals.

Get disclosed insider trades (SEBI PIT) in Indian listed companies: buys, sells and pledges by
    promoters, directors, KMP and designated persons, market-wide or for one stock.

    Omit `symbol` for the whole market, or pass an NSE symbol, ISIN or BSE code. The window is the
    TRADE date: `days` back from today (1..365, default 30), or `from_date`/`to_date` (ISO
    dates). `category`: promoters (default; promoter, promoter group, promoter-and-director) |
    directors_kmp | designated | relatives | all. `side`: trades (default, buys and sells) | buy |
    sell | pledge | all. `min_value_inr` drops smaller trades. Equity only unless
    `include_derivatives`. `group_by`: trade (default, newest first) | company (per-company
    buy, sell and net value in rupees, largest first). `limit` (1..500, default 100).

    Sources, both from BSE: System-Driven Disclosures (depository-generated, the complete record
    for these people, published 7-14 days after the trade) and company Form C (next day, adds
    `mode` such as market or off_market, and the holding before). A trade in both is counted
    once. Every response carries a `coverage_note`; the latest two weeks fill in as reports
    arrive. Disclosed facts only, no view on why anyone traded.

Input parameters:

- `category` (string)
- `days` (integer)
- `from_date`
- `group_by` (string)
- `include_derivatives` (boolean)
- `limit` (integer)
- `min_value_inr`
- `side` (string)
- `symbol`
- `to_date`

### `get_derivatives_positioning` (~264 tokens)

Futures and options positioning

Use this when the user asks about open interest, put-call ratio or futures and options positioning for an Indian stock or an index such as NIFTY or BANKNIFTY.

Get NSE F&O (futures & options) positioning for one underlying.

    Accepts an NSE symbol, ISIN, or BSE code for a stock, OR a raw F&O underlying/index name
    (e.g. "NIFTY", "BANKNIFTY") that has no security-master row of its own.

    Returns the latest trading day's aggregate: `futures_oi`/`futures_oi_change`, `call_oi`/
    `put_oi`, `pcr` (put_oi / call_oi — a mechanically-computed ratio, not a signal),
    `total_volume`, and `in_ban_list`. Raw NSE bhavcopy figures only — no OI-buildup
    interpretation or bullish/bearish framing (SEBI-RA line).

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_fo_participant_activity` (~225 tokens)

F&O participant activity

Use this when the user asks how FIIs, DIIs, proprietary traders or clients are positioned in NSE futures and options across the whole market.

Get NSE participant-wise (FII/DII/Pro/Client) F&O open interest & volume — market-wide.

    `days` (1..366, default 10) bounds the trailing window. Each row is one (trade_date,
    client_type) pair with raw long/short contract counts across futures-index, futures-stock,
    options-index-call/put, and options-stock-call/put, for both `oi` and `volume`.

    This is a DIFFERENT, derivatives-side signal from `get_market_fii_dii_flow`
    (market-wide daily CASH-segment net flow) — it is the highest-confidence official
    substitute for FII/DII derivatives positioning (NSE's cash-market feed does not cover
    F&O). Raw counts only — no "smart money"/positioning-bias interpretation (SEBI-RA line).

Input parameters:

- `days` (integer)

### `get_fno_ban_list` (~196 tokens)

F&O ban list

Use this when the user asks which Indian stocks are in the NSE futures-and-options ban period today.

Get the full NSE F&O securities-in-ban list for the most-recently-published trading day.

    Market-wide, not per-underlying — no `query` argument. This is the whole-list companion to
    `get_derivatives_positioning`'s per-symbol `in_ban_list` flag: use this tool when you want
    everything currently banned in one call, rather than checking symbols one at a time.

    Returns `ban_date` (the snapshot's date) and `symbols` (one entry per banned name, each with
    `nse_symbol` and `isin` — None for index names, which carry no security-master row). Raw
    NSE-published ban list verbatim — no "avoid these" framing or interpretation (SEBI-RA line).

### `get_corporate_actions` (~247 tokens)

Corporate actions

Use this when the user asks about an Indian company's past splits, bonuses, dividends or other corporate actions. For upcoming events across the market use get_market_calendar.

Get the disclosed corporate-action timeline for ONE STOCK, HISTORICAL (splits, bonuses,
    dividends, etc.) — the per-stock, backward-looking sibling of get_market_calendar (whole-
    market, any window, all event types merged) and get_upcoming_results (whole-market, forward-
    only results convenience). Use this tool, not get_market_calendar, when you want one
    company's corporate-action history rather than a market-wide view.

    Accepts NSE symbol, ISIN, or BSE code. `years` (1..20, default 5) bounds the window.
    `types` optionally filters to a subset of action types. Newest first; raw disclosures.

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).
- `types`
- `years` (integer)

### `get_stock_events` (~420 tokens)

Recent company announcements

Use this when the user asks what an Indian company has announced or filed on the exchange recently: results, orders, board meetings, fundraising, acquisitions or other disclosures.

Get recent BSE corporate announcements (SEBI Reg-30 disclosures) for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. `days` (1..365, default 30) bounds the trailing
    window over filing date; `category` optionally narrows to one BSE category (e.g.
    "Board Meeting", or "Insider Trading / SAST" for SAST stake-change and pledge letters and
    trading-window notices; promoter/director buy-sell trades are in get_insider_trades).
    Returns disclosure metadata — subject, headline,
    category, filing time, and a link to the source PDF on BSE. Metadata only; the filings
    themselves are not parsed or summarised. Quarterly results aren't here — use get_financials
    for those. Capped at 200 rows; `truncated: true` means more filings matched the window than
    were returned (narrow `days`/`category` to see the rest) — `total_scanned` reports the true
    match count, uncapped.

    Each event includes a `news_id` (the BSE filing GUID). To read the extracted facts and a
    factual summary of a specific filing, pass that `news_id` to get_filing_extract.
    

    When filing prefetch is enabled, an MCP call may enqueue background extraction for
    eligible listed filings and count accepted jobs against the caller's per-day on-demand cap.
    The listing response does not wait for extraction.

Input parameters:

- `category`
- `days` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `search_company_disclosures` (~239 tokens)

Search past filings

Use this when the user needs historical detail from an Indian company's earlier filings, for example a prior order value or commissioning date.

Search this company's already cached official filings, page by page.

    Use after get_stock_events/get_filing_extract when you need historical context, such as a
    prior commissioning date, original order announcement, customer, project, or tender. This is
    cache-only: it never downloads a filing or triggers extraction. Results retain a source page
    and original BSE attachment URL; `coverage` tells you how much page-preserving history is
    indexed and explicitly reports parsed legacy filings that cannot be searched reliably yet.

Input parameters:

- `document_types`
- `from_date`
- `limit` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).
- `search_text` (string, required): Words to find in the company's indexed filings, e.g. "fraud".
- `to_date`

### `get_event_context` (~279 tokens)

Filing event context

Use this after get_filing_extract when the user wants the earlier state behind an order, capacity or similar event in a filing.

Return cached prior-state context for a canonicalized filing event.

    Use after get_filing_extract for an order, capacity or other supported event. The result
    retains source quotes and reports only deterministic historical links; it does not infer
    price correlation, business causality, or an investment conclusion. Cache-only: no fetches,
    extraction requests, or writes occur on this tool path.

    ``event_family`` additionally carries the persisted family TIMELINE — every cached filing in
    this disclosure thread, in filing order — and ``open_questions`` lists the factual follow-ups
    still unanswered by those filings (e.g. a required contract value the company has not
    disclosed), each with the filing that raised it and, once answered, the filing that resolved
    it. Both are raw, source-linked groupings of the company's own disclosures: never a verdict,
    target, forecast or recommendation.

Input parameters:

- `news_id` (string, required)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_company_operating_metrics` (~177 tokens)

Operating metrics and order book

Use this when the user asks for an Indian company's disclosed operating figures such as order book, order inflow, capacity or other business KPIs over time.

Return cached, source-grounded operating KPI history for one company.

    Coverage distinguishes company-disclosed values from ``not_disclosed`` fields. It never
    infers a current order book from a new order and never fetches or writes on this read path.

Input parameters:

- `from_date`
- `latest_only` (boolean)
- `limit` (integer)
- `metrics`
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).
- `to_date`

### `get_company_macro_exposures` (~193 tokens)

Macro exposure signals

Use this when the user asks how an Indian company is exposed to a macro factor such as crude oil, rates or currency, with official context signals.

Return cached company macro pathway evidence and eligible official context signals.

    Signals are emitted only when an active, reviewed, sourced company exposure passes the
    factor policy against a complete official PPAC Indian Basket or FBIL USD/INR window. This is
    conditional context only: it never states that a macro move caused or will cause an earnings,
    price, or investment outcome. Missing evidence is returned as explicit coverage, not inferred.

Input parameters:

- `as_of_date`
- `factors`
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_company_exposures` (~291 tokens)

Company factor exposures

Use this when the user asks which macro or commodity factors an Indian company depends on, based on reviewed exposure mappings.

Return one company's REVIEWED macro-factor exposures, labelled via the factor catalog.

    Cache-only, read-only: the company's reviewed ``company_exposures`` rows joined to the
    ``factor_registry`` catalog, so each exposure carries its factor label/description/dimension
    alongside the disclosed pathway (directness/direction/lag/mechanism) and source evidence.

    This is a DIFFERENT tool from ``get_company_macro_exposures`` (two similarly-named tools): this
    one is the plain, raw per-company evidence listing — no ``as_of_date``/factor filter, no live
    PPAC/FBIL macro window, no eligibility signals. ``get_company_macro_exposures`` is the
    signal-eligibility tool that evaluates those exposures against a complete official macro
    window. Neither ever claims a macro move caused or will cause an earnings/price/investment
    outcome (SEBI-RA line). A company with no reviewed exposures returns an empty success envelope.

Input parameters:

- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_relevant_peers` (~196 tokens)

Relevant peers

Use this when the user asks who an Indian company's real peers or competitors are and why. For a valuation table of peers use get_peer_comparison.

Return an explainable peer set for operating, financial, or valuation comparison.

    Uses reviewed, provenance-backed business tags and overrides plus cached factual metrics. The
    existing get_peer_comparison table remains the broader SEBI-classification comparison. This
    tool may return fewer peers when business-model evidence is insufficient; it never presents a
    same-industry label as proof of comparability, and returns no investment conclusion.

Input parameters:

- `event_context`
- `limit` (integer)
- `purpose` (string)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `list_announcement_buckets` (~131 tokens)

Announcement categories

Use this when the user wants to browse market-wide disclosure types, such as order receipts or fundraises, before calling get_announcement_bucket.

List the market-wide BSE announcement discovery buckets (id + label).

    Each bucket groups a real-world disclosure type (e.g. "order-receipts", "fundraise",
    "credit-rating", "acquisitions", "management-changes") across the WHOLE market — the inverse
    of get_stock_events, which is scoped to one company. Pass a bucket id to
    get_announcement_bucket to fetch its recent filings.

### `get_announcement_bucket` (~291 tokens)

Companies by announcement type

Use this when the user asks which Indian companies recently announced a given kind of disclosure, for example order wins or fundraises, across the whole market.

Get every company that filed a matching BSE announcement in a trailing window, market-wide.

    `bucket` is one of the ids from list_announcement_buckets (e.g. "order-receipts",
    "fundraise"). `days` (1..90, default 7) bounds the trailing window over filing date. Returns
    newest first across the WHOLE universe (not one security). Metadata only — the raw disclosed
    subject/headline plus a link to the source BSE filing; no PDF parsing, no verdicts. Capped
    at 200 rows; `truncated: true` means more announcements matched the window than were
    returned (narrow `days` to see the rest) — `total_scanned` reports the true match count,
    uncapped. Each event carries its `news_id` — pass it to get_filing_extract for that filing's
    extracted facts.
    

    When filing prefetch is enabled, an MCP call may enqueue background extraction for
    eligible listed filings and count accepted jobs against the caller's per-day on-demand cap.
    The listing response does not wait for extraction.

Input parameters:

- `bucket` (string, required)
- `days` (integer)

### `screen_stocks` (~1338 tokens)

Stock screener

Use this when the user asks for Indian stocks matching numeric criteria such as PE, PB, market cap, ROE, margins or debt, optionally within an index such as NIFTY 50. For OR logic or arithmetic between metrics use screen_by_query.

Screen the Indian security universe by user-supplied mechanical criteria.

    All `filters` keys are optional and AND-combined. `sort_by`/`order` order the result set;
    `limit` (1..100) caps it. Returns matching securities with the screened metrics — data
    only, no recommendations. An unknown filter key returns a `bad_request` error that lists
    every accepted key verbatim, so a rejected call is always self-correcting.

    RANGE filters (take a `_min` and/or `_max` suffix, e.g. `pe_min: 10, pe_max: 20`):
      market_cap, price, pe, pb, deliv_pct, week52_high, week52_low, turnover, num_trades
      (quote-level) — deliv_pct is a PERCENTAGE (50 = 50%); week52_high/week52_low are rupee
      price levels comparable to `price`; turnover is a rupee traded-value, num_trades a count.
      promoter_pct, pledged_pct — PERCENTAGES (pass 50 for "50%"), from shareholding data.
      roe, roa, roce, net_margin, dividend_yield, earnings_yield, fcf_yield, ebitda_margin,
      operating_margin, quarterly_net_margin_delta_yoy — FRACTIONS (pass 0.15 for "15%").
      interest_coverage, ev, ev_to_ebitda, ev_to_ebit, price_to_cash_flow, price_to_fcf,
      debt_to_equity, price_to_sales, piotroski_f_score (0-9) — plain multiples/scores, no
      unit conversion needed.
      revenue_growth, net_income_growth, quarterly_revenue_growth_yoy,
      quarterly_net_income_growth_yoy, return_1d/1w/1m/3m/6m/1y — FRACTIONS (0.20 = 20% growth
      or return); unlike the margin/yield group above, these may legitimately exceed 1.0
      (>100%) for high-growth or multi-bagger names.
      pct_off_52w_low — derived, FRACTION: (price - week52_low) / week52_low, e.g.
      `pct_off_52w_low_max=0.05` for "within 5% of its 52-week low".
      num_shareholders (a…

Input parameters:

- `filters` (object, required): Object of criteria, AND-combined, e.g. {"market_cap_min": 50000, "pe_max": 20}. Range filters take a `_min` or `_max` suffix.
- `limit` (integer)
- `order` (string)
- `sort_by` (string)

### `screen_by_query` (~641 tokens)

Screener query

Use this when the user's screen needs OR logic, arithmetic between two metrics or a screen expression that screen_stocks filters cannot express.

Screen the Indian security universe with one free-form DalalOS screen expression.

    Reach for this instead of screen_stocks when the ask needs OR, arithmetic between two
    metrics, or a comparison screen_stocks' fixed `<metric>_min`/`_max` keys cannot express — e.g.
    `Return on capital employed > 22% AND (Debt to equity < 0.5 OR Interest Coverage Ratio > 8)`.
    screen_stocks stays the right tool for a plain AND-combined set of range filters.

    `dialect` picks the vocabulary and is never guessed: "screener" (default) reads common screener
    ratio names in the units a screener page DISPLAYS — `> 22%` against a ratio stored as a fraction,
    market cap in crore — while "dalalos" reads canonical DalalOS metric ids in the units the
    cache stores. The metric catalogue for both is GET /v1/ratios; an unrecognised name comes
    back as an explicit error naming the phrase, never a silent substitution.
    Query syntax and metric names: https://dalalos.in/docs/screener and
    https://dalalos.in/docs/screener/ratios.

    Operators: AND, OR, = != > < >= <=, + - * /, and COALESCE, IF, LEAST, POWER, ABS,
    SQRT, LOG. Missing values follow SQL three-valued logic: a bare comparison against an
    unknown value does NOT match, `COALESCE(<metric>, 0) > x` does, and `A > x OR B > y` can
    still match on the right side alone. Division by zero is a missing value, not an error.

    Paging is pinned to one published metrics generation. Each response reports it as
    `pagination.snapshot_id`; pass that value back as `snapshot_id` on the next page. If a
    metrics refresh published a new generation in between, the call fails with
    `snapshot_expired` and the current generation rather than mixing rows from two of them —
    restart from `offset` 0. `sort_by` is a sortable metric id; ordering puts unknown values
    la…

Input parameters:

- `columns`
- `definitions`
- `dialect` (string)
- `include_condition_counts` (boolean)
- `limit` (integer)
- `offset` (integer)
- `only_latest_results` (boolean)
- `order` (string)
- `query` (string, required): One boolean expression over metric names, e.g. "market_cap > 5000 and roce > 20".
- `scope`
- `snapshot_id`
- `sort_by` (string)

### `get_sector_overview` (~148 tokens)

Sector overview

Use this when the user asks how an Indian sector or industry looks in aggregate: number of companies, market cap, valuation and returns.

Get an aggregate market overview by sector (or a finer SEBI grain).

    Omit `sector` to list all groups; pass one to drill in. `grain` is "sector" (default),
    "igroup" (SEBI Industry), or "isubgroup" (SEBI Basic Industry, the finest grain). Returns
    count, total market cap, and median/mean PE and median PB per group — computed from
    cached quotes. Aggregates only.

Input parameters:

- `grain` (string)
- `sector`

### `list_index_constituents` (~173 tokens)

Index constituents

Use this when the user asks which stocks are in an Indian index such as NIFTY 50 or NIFTY Bank.

List the constituent stocks of an Indian market index (e.g. NIFTY 50, NIFTY 500).

    `index` is matched exactly to a known index name — get the valid names from list_indices.
    `limit` (1..500) caps the returned constituents. Returns the member securities with
    identifiers (each `nse_symbol`/`isin` can be passed as the `query` to any per-stock tool).

Input parameters:

- `index` (string, required): NSE index name, e.g. "Nifty 50", "Nifty Bank" or "Nifty IT" (not a slug).
- `limit` (integer)

### `list_indices` (~36 tokens)

Available indices

Use this when the user needs the list of Indian market indices DalalOS covers.

List the market indices for which constituent membership is cached.

### `get_market_heatmap` (~246 tokens)

Index heatmap

Use this when the user wants valuation and returns across the stocks in an Indian index at a glance. Not for ranking by return; use get_top_movers.

Get valuation + multi-horizon returns for the constituents of an Indian market index.

    `index` is matched exactly to a known index name (e.g. NIFTY 50, NIFTY 500) — get the valid
    names from list_indices. `limit` (1..500) caps the returned constituents, sorted by market
    cap desc. Each row carries
    market_cap/pe/pb plus precomputed 1d/1w/1m/3m/6m/1y returns, and any Tier-C
    structural-event flags on those returns (`return_flags`) or a lack of price history
    (`incomplete_windows`) — the two are mutually exclusive and together explain every null
    return. Mechanical facts only — no rankings.

Input parameters:

- `index` (string, required): NSE index name, e.g. "Nifty 50", "Nifty Bank" or "Nifty IT" (not a slug).
- `limit` (integer)

### `get_top_movers` (~322 tokens)

Top gainers and losers

Use this when the user asks which Indian stocks gained or lost the most, or traded the most, in the last completed session.

Raw ranked gainers/losers/most-active for an index over one completed EOD session.

    `index` defaults to 'NIFTY 500' — get valid names from list_indices. `metric` picks the raw
    sort field: 'pct_change' (day % change, default), 'change' (absolute price change, Rs),
    'turnover' (traded value, Rs), or 'volume' (traded quantity). `direction` is 'desc' (default
    — top gainers / most active) or 'asc' (top losers). `limit` (1..100, default 20) caps the
    rows. This is the same mechanical fact NSE's own top-gainers/losers page publishes — a
    caller-chosen sort key over already-public EOD numbers, nothing more.
    Distinct from get_market_heatmap, which is deliberately NOT sortable by return 
    and instead always sorts by market cap — use get_market_heatmap for a valuation+returns
    snapshot, use this tool when the question is specifically "what moved most today".

Input parameters:

- `direction` (string)
- `index` (string): NSE index name, e.g. "Nifty 50", "Nifty Bank" or "Nifty IT" (not a slug).
- `limit` (integer)
- `metric` (string)

### `list_preset_screens` (~107 tokens)

Preset screens

Use this when the user asks what ready-made screens are available, before calling run_preset_screen.

List the fixed, nightly-precomputed preset screens (name/description/cache freshness).

    Presets are FIXED mechanical filter combinations (never live-queried, never ranked or
    labelled as a recommendation) — a discovery starting point a caller can further filter via
    screen_stocks itself. Use run_preset_screen(name) to fetch one preset's actual results.

### `run_preset_screen` (~118 tokens)

Run a preset screen

Use this when the user wants the latest result of a named ready-made screen from list_preset_screens.

Return the last nightly-precomputed result for one registered preset screen.

    `name` must be one of the names returned by list_preset_screens. A preset that has never
    been computed yet returns an empty result with reason_code "no_data". Cache-only — this is
    the stored output of an equivalent screen_stocks(filters=...) call, not a live query.

Input parameters:

- `name` (string, required)

### `get_upcoming_results` (~296 tokens)

Upcoming results

Use this when the user asks which Indian companies report results soon, optionally by sector. For a past window or other event types use get_market_calendar.

List companies with an upcoming board-meeting / results date — WHOLE-MARKET, FORWARD-ONLY.

    This is a forward-only, sector-filterable CONVENIENCE view over the same results_calendar
    data get_market_calendar also reads — equivalent to get_market_calendar(date_from=today,
    date_to=today+days, types=["results"]) plus the sector narrowing get_market_calendar doesn't
    offer, not a competing source. Prefer get_market_calendar instead when you need a past window
    or multiple event types together. For ONE company's historical corporate-action timeline
    (splits/bonuses/dividends), use get_corporate_actions instead.

    `days` (1..90, default 14) is the forward window; `sector` optionally filters; `limit`
    (1..200) caps the results. Each entry carries the meeting date and security identifiers.
    A disclosed meeting is never dropped just because its bse_code doesn't join cleanly to
    the securities master; such rows keep the raw bse_code and add a `note` explaining why
    isin/nse_symbol/name/sector are null.

Input parameters:

- `days` (integer)
- `limit` (integer)
- `sector`

### `get_index_valuation` (~379 tokens)

Index valuation

Use this when the user asks for an Indian index's PE, PB or dividend yield over time, for example whether NIFTY 50 is expensive relative to its history.

NSE's own daily OHLC + P/E + P/B + Div Yield time series for one named index.

    `index` is matched case-insensitively against NSE's own published index names (e.g.
    "Nifty 50", "Nifty Bank", "Nifty IT", "Nifty Auto", "Nifty FMCG", "India VIX" — use
    get_india_vix for a VIX-specific shape). `from_date`/`to_date` are optional ISO dates
    (default: trailing ~30 days; window capped at 1825 days). Sourced from NSE's own daily
    `ind_close_all` file, which carries NSE's ALREADY-COMPUTED P/E, P/B, Div Yield for every
    index it publishes — sector indices (Nifty Bank, Nifty IT, ...) give an official NSE
    sector-valuation band, a DIFFERENT figure from get_sector_overview's peer-derived
    median_pe/median_pb (this project's own aggregate over its tracked universe, grouped by a
    different taxonomy) — the two are independent, neither validates the other. An unrecognized
    `index` returns `reason_code: "no_data"` with `available_indices_hint` (every index name
    NSE publishes) — see also list_index_valuations. Raw NSE-published figures only.

Input parameters:

- `from_date`
- `index` (string, required): NSE index name, e.g. "Nifty 50", "Nifty Bank" or "Nifty IT" (not a slug).
- `to_date`

### `list_index_valuations` (~99 tokens)

Indices with valuation data

Use this when the user needs the names of Indian indices that have PE, PB and dividend-yield history.

List every NSE index name tracked (headline, broad-market, sector/thematic, India VIX).

    Each entry carries `{index_name, latest_trade_date, latest_close}`. Powers
    get_index_valuation's `available_indices_hint` and lets you discover NSE's exact
    index-name spelling before calling it.

### `get_india_vix` (~149 tokens)

India VIX

Use this when the user asks about the India VIX, the NSE volatility index, today or over a period.

NSE's daily India VIX (volatility index) OHLC time series.

    `from_date`/`to_date` are optional ISO dates (default: trailing ~30 days; window capped at
    1825 days). Each row is `{trade_date, open, high, low, close, points_change, pct_change}` —
    VIX has no P/E, P/B, dividend yield, volume, or turnover, so those keys are omitted rather
    than returned null.

Input parameters:

- `from_date`
- `to_date`

### `get_market_ranking` (~293 tokens)

Market ranking by day

Use this when the user asks which Indian stocks had the most volume, turnover, trades, delivery percentage or the largest move on a given trading day. For today's movers within one index use get_top_movers.

Rank NSE securities on one trading day by a published number: volume, turnover, trades,
    delivery % or % change.

    `date` is an ISO date (default: the newest stored day). `metric`: volume (default) | turnover |
    num_trades | deliv_pct | pct_change. `direction`: desc (default) | asc. `limit` 1..100 (default
    25). `instrument_class`: equity (default, mainboard) | sme | fund_unit | all, so fund units and
    bonds do not crowd a volume list. `series` narrows to one NSE series such as EQ or BE. pct_change
    is (close - prev_close) / prev_close rounded to two places, the rule NSE uses to count advances
    and declines. Source: every row of NSE's daily bhavcopy. A sort of published numbers, not a
    recommendation. For movers within one index use get_top_movers.

Input parameters:

- `date`
- `direction` (string)
- `instrument_class` (string)
- `limit` (integer)
- `metric` (string)
- `series`

### `get_security_history` (~254 tokens)

Daily history, any NSE series

Use this when the user wants the raw daily NSE rows for a security, including SME stocks, bonds, G-secs, SGBs or fund units, with delivery and trade counts.

Daily NSE bhavcopy rows for one security in any series it trades in.

    `symbol` is an NSE symbol or ISIN; SME stocks, bonds, G-secs, SGBs, T-bills and fund units work
    too, which get_price_history does not carry. `series` narrows to one (EQ, BE, SM, GB...). Window: `days`
    back from the newest stored day (default 30, max 1825) or `from_date`/`to_date`. Each row: open,
    high, low, close, last, prev_close, volume, turnover, trades, delivery quantity and %. Prices are
    as NSE published them that day, NOT adjusted for splits or bonus issues (`adjusted: false`); use
    get_price_history for an adjusted series. Raw rows, no commentary.

Input parameters:

- `days`
- `from_date`
- `series`
- `symbol` (string, required)
- `to_date`

### `get_market_cap_history` (~212 tokens)

NSE market capitalisation

Use this when the user asks for NSE's own market cap and shares in issue, for one company over time or the largest companies on a day.

NSE's own market capitalisation, shares in issue and face value, from the daily PR bundle.

    With `symbol`: that security over `days` (default 30) or `from_date`/`to_date`. Without it: the
    `limit` (1..100) largest by market cap on `date` (default newest day) plus NSE's published listed,
    permitted and total market cap for the day. `market_cap` is rupees as NSE published it; it is not always
    issue size x close and is not corrected. History starts 2024-02-01. Facts as published, no valuation
    view.

Input parameters:

- `date`
- `days`
- `from_date`
- `limit` (integer)
- `symbol`
- `to_date`

### `get_price_band_hits` (~200 tokens)

Price band hits

Use this when the user asks which Indian stocks hit their upper or lower circuit on a day, or how often a stock has.

NSE's official list of securities that hit their price band (circuit) on a day.

    `date` (default newest day) lists every hit; `symbol` returns that security's hits over `days`
    (default 90, max 1825). `direction`: upper | lower | all (default). `limit` 1..500 (default 200).
    The list is the exchange's own record, which OHLC alone cannot reproduce: a stock can touch its band
    intraday and close inside it. A security can appear as both upper and lower in one day. From
    2010. Facts only.

Input parameters:

- `date`
- `days`
- `direction` (string)
- `limit` (integer)
- `symbol`

### `compare_indices` (~207 tokens)

Compare indices

Use this when the user wants several Indian indices compared on return, volatility and drawdown over the same period.

Compare 2 to 10 NSE indices over the same window: return, volatility, drawdown.

    `indices` are NSE index names, e.g. ["Nifty 50", "Nifty Bank"] (case-insensitive; a miss lists the valid
    names). Window: `days` back from the newest stored day (default 365, max 1825) or `from_date`/
    `to_date`. Per index: price return %, annualised volatility of daily returns (x sqrt 252), maximum
    drawdown, best and worst day, from NSE's own daily closes. Arithmetic on published closes; no
    recommendation. For one index's OHLC and P/E use
    get_index_valuation.

Input parameters:

- `days`
- `from_date`
- `indices` (array, required)
- `to_date`

### `get_stock_vs_index` (~229 tokens)

Stock against an index

Use this when the user asks how an Indian stock's return compared with an index such as Nifty 50 over a period.

One stock's return beside an NSE index's over the same window.

    `symbol` is an NSE equity symbol, `index` an NSE index name (default "Nifty 50"). Window: `days`
    (default 365, max 1825) or `from_date`/`to_date`. Returns each side's return %, annualised volatility,
    max drawdown, best and worst day, and `difference_pct` (stock minus index, percentage points). The
    stock's return compounds NSE's own close/prev_close, so splits and bonuses do not break it. Price
    returns, no dividends. Arithmetic only.

Input parameters:

- `days`
- `from_date`
- `index` (string): NSE index name, e.g. "Nifty 50", "Nifty Bank" or "Nifty IT" (not a slug).
- `symbol` (string, required)
- `to_date`

### `get_market_breadth` (~265 tokens)

Market breadth

Use this when the user asks how many Indian stocks advanced, declined or were unchanged on a trading day.

Whole-market advance/decline/unchanged breadth: how many NSE-listed securities moved
    up/down/flat on a trading day.

    `from_date`/`to_date` are optional ISO dates (default: trailing ~30 days; window capped at
    366 days). Each row is `{trade_date, advances, declines, unchanged, total}`, sourced from
    NSE's own live market-data feed. NSE publishes no bulk historical archive for this figure,
    so history only extends as far back as this server has been capturing it — an empty result
    for a genuinely old date is expected, not a bug. Raw counts only — no "risk-on/risk-off" or
    breadth-based market-direction commentary (SEBI-RA line).

    `universe` (all_series | equity_sme | equity) switches to counts DERIVED from NSE's daily
    bhavcopy, with history as deep as that table; `all_series` matches NSE's own
    published figure. Omit it for the live capture.

Input parameters:

- `from_date`
- `to_date`
- `universe`

### `get_macro_indicators` (~407 tokens)

Indian macro indicators

Use this when the user asks for official Indian macro data: CPI inflation, WPI, IIP, GDP or the crude-oil basket price.

Official macro/sector indicators: MOSPI CPI, WPI, IIP (monthly), GDP (annual), and PPAC's
    Indian Basket crude-oil price (monthly).

    `dataset` is required: `"cpi"` (headline Consumer Price Index by sector/division), `"wpi"`
    (headline Wholesale Price Index — overall + food index only), `"iip"` (Index of Industrial
    Production by category), `"gdp"` (GDP level + growth rate, current/constant prices, one
    row per published estimate vintage — First/Second Advance, Provisional, Revised), or
    `"crude_basket"` (PPAC's Indian Basket crude-oil monthly average price, USD/bbl). Any other
    value is a `bad_request`. `from_period`/`to_period` bound the window (`"YYYY-MM"` for
    cpi/wpi/iip/crude_basket, the fiscal-year string e.g. `"2024-25"` for gdp); `series_contains`
    substring-filters `series_key` (e.g. `"Food"`, `"Manufacturing"`, `"GDP Growth Rate"`; a
    no-op for crude_basket, which has only one series). `limit` (1..2000, default 200) caps the
    result, newest period first. Raw published index values/growth percentages/commodity prices
    only (SEBI-RA line) — no directional commentary ("inflation is high", "oil is expensive").

Input parameters:

- `dataset` (string, required): Required. One of: cpi, wpi, iip, gdp, crude_basket.
- `from_period`
- `limit` (integer)
- `series_contains`
- `to_period`

### `get_fx_reference_rates` (~273 tokens)

FX reference rates

Use this when the user asks for official FBIL reference rates of the rupee against USD, GBP, EUR, JPY or AED, for example the USD to INR rate.

Daily FBIL INR reference rates (USD/GBP/EUR/JPY/AED/IDR against INR).

    `currency_pair` optionally filters to one pair (e.g. `"USD/INR"`, case-insensitive).
    `from_date`/`to_date` are optional ISO dates (default: trailing 30 days). Each row is
    `{rate_date, currency_pair, unit_base, rate, source}` — `rate` is always "INR per
    `unit_base` units of the foreign currency" (unit_base is 1 for USD/GBP/EUR/AED, 100 for JPY,
    10000 for IDR — FBIL's own published denomination, never silently rescaled). FBIL's public
    feed only serves a rolling ~2-day window with no bulk history archive found, so a fresh
    deploy accretes this table forward one scheduled refresh at a time — a wide window may
    legitimately return far fewer rows than the window implies.

Input parameters:

- `currency_pair`
- `from_date`
- `to_date`

### `get_sector_fii_flow` (~357 tokens)

FII flow by sector (historical)

Use this when the user asks about daily FII flow by sector in the historical CDSL data, which stops at March 2025. For current sector flows use get_sector_fpi_investment.

Daily FII/FPI net flow (raw Rs), aggregated by sector -- the sector-wise breakdown.

    Scope-keyed alongside its siblings: get_market_fii_dii_flow is market-wide
    with no sector dimension; get_stock_fii_flow is per-stock; get_shareholding is per-company
    QUARTERLY holding %. This is DAILY, per-sector, TRANSACTION flow, joined from the
    stock-level fii_fpi_stock_flow table against securities.sector (the same sector field
    get_company_profile/get_sector_overview use). `from_date`/`to_date` are optional ISO dates
    (default: trailing ~30 days, capped at 366); `sector` optionally narrows to one sector name.
    `net = buy - sell` is the only computation (SEBI-RA line).

    COVERAGE CAVEAT: sourced from CDSL's Trade-Wise Equity Data of FII/FPI ONLY -- NSDL's
    per-stock trade data is not ingested, so this is a PARTIAL view of FII/FPI activity by
    sector, not the whole market's figure (every response carries a `coverage_note` saying so).
    CDSL stopped publishing after March 2025, so nothing later exists here: for current
    sector-level FPI flow across both depositories use get_sector_fpi_investment (fortnightly).

Input parameters:

- `from_date`
- `sector`
- `to_date`

### `get_sector_fpi_investment` (~478 tokens)

FPI investment by sector

Use this when the user asks which Indian sectors foreign portfolio investors are buying or selling, using fortnightly NSDL data.

Fortnightly FPI net investment and assets under custody by sector, from NSDL's
    Fortnightly Sector-wise FPI Investment data. Covers every FPI across BOTH depositories
    (NSDL and CDSL), 2012 onward -- the current sector-level FPI source; get_sector_fii_flow's
    CDSL feed stopped publishing after March 2025.

    Scope-keyed alongside its siblings: get_market_fii_dii_flow is market-wide DAILY cash
    flow; get_sector_fii_flow / get_stock_fii_flow are DAILY CDSL-only transaction flow;
    get_shareholding is per-company QUARTERLY holding %. This is FORTNIGHTLY, per NSDL sector.

    `from_date`/`to_date` are optional ISO dates matched to each fortnight's period_end
    (default trailing ~6 months; capped at 5 years unless `sector` is given); `sector` narrows
    to one NSDL label (case-insensitive; 'Grand Total' is NSDL's all-sector row); `instrument`
    picks one column (default equity; also debt_general, debt_vrr, debt_far, hybrid, aif,
    total, mf_equity, mf_debt, mf_hybrid, mf_solution_oriented, mf_other); `include_subsectors`
    adds pre-2022 nested sub-sector rows, which are already included in their parent. Each row
    is `{period_start, period_end, taxonomy, sector, row_kind, parent_sector, instrument,
    net_inr_cr, net_usd_mn, auc_inr_cr, auc_usd_mn}` as NSDL published it (INR crore / USD million;
    null = not published). Sector labels switch to BSE's Common Industry Classification from
    2022-04-30 (`taxonomy` marks it) and are NSDL's own, not securities.sector. No computation
    beyond row selection.

Input parameters:

- `from_date`
- `include_subsectors` (boolean)
- `instrument` (string)
- `sector`
- `to_date`

### `get_fii_activity` (~181 tokens)

Stock FII flow (deprecated alias)

Deprecated alias of get_stock_fii_flow; use get_stock_fii_flow for per-stock daily FII transaction flow.

DEPRECATED — renamed to `get_stock_fii_flow`; use that instead.

    Kept as a thin back-compat alias for this release only (no removal date committed yet):
    delegates to the exact same query function as `get_stock_fii_flow`, so the response is
    byte-for-byte identical for the same arguments. See `get_stock_fii_flow`'s docstring for the
    full parameter/behavior description.

Input parameters:

- `days` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_market_calendar` (~478 tokens)

Market calendar

Use this when the user asks what events are scheduled or happened across Indian markets in any date window: results, board meetings, dividends, splits.

Get a unified, WHOLE-MARKET calendar of disclosed events across all NSE/BSE securities,
    over an ARBITRARY window (past or future).

    Use this instead of get_upcoming_results when you need a past window or multiple event types
    together; use get_upcoming_results instead when you just want a forward results window with a
    sector filter (a scoped convenience over the same results data this tool also reads). For ONE
    company's historical corporate-action timeline, use get_corporate_actions instead — that tool
    is per-stock; this one is market-wide.

    `date_from`/`date_to` are ISO dates (YYYY-MM-DD); `date_to` must be on or after `date_from`
    and the window is capped at 180 days. Both are optional: `date_from` defaults to today and `date_to` to 30
    days after `date_from`. `types` optionally filters to a subset of `results,
    dividend, split, bonus, demerger, ipo` (plus the remaining corporate-action disclosure
    types: consolidation, rights, buyback, spinoff, merger, distribution, other) — an unknown
    type is a bad_request. Each event is `{date, type, isin, nse_symbol, name, detail}`, merged
    from results_calendar (results) and corporate_action_events (everything else) and sorted
    chronologically; `limit` (1..2000, default 150) caps the merged result; at most 300 events are returned per call, so narrow `types` or page by date. `ipo` is a stub —
    no IPO data source exists yet, so it always returns zero rows with an explanatory note.
    Raw disclosed facts only — no verdicts, no importance ranking beyond your own type filter.

Input parameters:

- `date_from`: ISO date YYYY-MM-DD. Defaults to today.
- `date_to`: ISO date YYYY-MM-DD, on or after date_from, at most 180 days later. Defaults to 30 days after date_from.
- `limit` (integer)
- `types`

### `get_ipos` (~321 tokens)

IPOs

Use this when the user asks about Indian IPOs: upcoming, open, awaiting listing or recently listed.

List IPO/public-issue records: upcoming, open, listing pending, or recently listed.

    `status` optionally filters to `upcoming`, `open`, `listing_pending`, or `listed` (omitted returns all four);
    an unknown value is a bad_request. Unlike most fields, `status` is derived at READ TIME from
    dates versus today (IST) and a listed-security match. A passed planned listing date without that evidence is `listing_pending`, never `listed`. `limit`
    (1..500, default 100) caps the result. Each entry carries price band, face value, lot size,
    issue size, open/close/listing dates, issue price, listing price (once listed), category-wise
    subscription x-times (QIB/NII/Retail/Employee) where disclosed, a DRHP/prospectus link, and a
    mechanically-computed `listing_gain_pct` = (listing_price - issue_price) / issue_price
    (null pre-listing). Sourced from BSE (api.bseindia.com) and SEBI public-issue filings —
    official sources only. No Grey Market Premium (GMP) field anywhere: GMP has no official
    exchange source, so it is deliberately excluded (SEBI-RA line — raw facts and mechanical
    arithmetic only, never a verdict).

Input parameters:

- `limit` (integer)
- `status`

### `get_financial_trends` (~355 tokens)

Financial trends

Use this when the user asks for quarter-on-quarter or year-on-year growth and margin trends of an Indian company period by period.

Get multi-period growth and margin trends for an Indian stock.

    Levels-vs-deltas division: this tool returns a PER-PERIOD time series (QoQ/YoY growth,
    `net_margin_delta`, `fcf_growth`, and per-period reportable-segment breakdowns, one row
    per displayed period) — not the latest levels or a summary growth/CAGR block. For the
    current P&L/balance-sheet levels, TTM, and a single summary `growth` section (annual YoY
    plus 3y/5y CAGR), see `get_financials` instead.

    Accepts NSE symbol, ISIN, or BSE code. `period_type` is "quarterly" (default) or
    "annual"; `limit` (1..12) caps the periods, newest first. Returns level fields plus
    QoQ/YoY growth and margins — mechanically computed, no verdicts. Each period carries
    `source` (`"bse-xbrl"` post-listing vs `"drhp"` pre-listing/prospectus-restated for a
    newly-listed company); the envelope's own `source` is the shared value or `"mixed"`.

Input parameters:

- `limit` (integer)
- `period_type` (string)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_pledge_trend` (~215 tokens)

Promoter pledge trend

Use this when the user asks how much of an Indian company's promoter holding is pledged and how that has changed.

Get the promoter share-pledge percentage trend for an Indian stock.

    Accepts NSE symbol, ISIN, or BSE code. `limit` (1..16) caps the most-recent periods.
    Returns the reported pledged-percentage time series. Raw disclosures only. Each period
    carries `pledge_disclosed`: false means this quarter's pledge field wasn't present in the
    underlying filing (a null `pledged_pct` reads as "not disclosed", not "zero pledge") — a
    real 0.0 is only reported when `pledge_disclosed` is true.

Input parameters:

- `limit` (integer)
- `query` (string, required): One company: NSE symbol, ISIN or BSE code, e.g. TCS, INE467B01029 or 532540. Always send it as `query` (not `symbol`).

### `get_data_freshness` (~104 tokens)

Data freshness

Use this when the user asks how recent DalalOS data is, or when a figure looks stale.

Report cache freshness: last successful refresh per data domain and overall health.

    Every scraper-backed domain (including fii_dii and the ipos family) carries a staleness
    threshold matched to its real refresh cadence, so a domain whose scraper job silently stops
    running gets flagged stale rather than reporting `max_age_hours: null` forever.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/in-dalalos-mcp/mcp#diagnostics

## Score history

- 2026-11-05: 79
- 2026-11-04: 79
- 2026-11-03: 77
- 2026-11-02: 76
- 2026-11-01: 76
- 2026-10-31: 75
- 2026-10-30: 75
- 2026-10-29: 74
- 2026-10-28: 74
- 2026-10-27: 73
- 2026-10-26: 73

## Common questions

### What is the DalalOS: Indian Stock Market Research (NSE/BSE) MCP server?

DalalOS: Indian Stock Market Research (NSE/BSE) is an MCP server listed in the public MCP registry as in.dalalos/mcp. Filing-grounded Indian stock research (NSE/BSE): financials, ratios, screens. Sourced and dated. This page covers its hosted endpoint (https://mcp.dalalos.in/mcp).

### Is the DalalOS: Indian Stock Market Research (NSE/BSE) MCP server safe to use?

DalalOS: Indian Stock Market Research (NSE/BSE) scores 79 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the DalalOS: Indian Stock Market Research (NSE/BSE) MCP server expose?

DalalOS: Indian Stock Market Research (NSE/BSE) exposes 69 tools: ping, get_filing_extract, get_filing_extracts, get_market_fii_dii_flow, get_stock_fii_flow, and 64 more. Their descriptions and schemas cost roughly 22,007 tokens of context every time the server is loaded.

### Does the DalalOS: Indian Stock Market Research (NSE/BSE) MCP server require authentication?

Yes. DalalOS: Indian Stock Market Research (NSE/BSE) asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the DalalOS: Indian Stock Market Research (NSE/BSE) MCP server still maintained?

DalalOS: Indian Stock Market Research (NSE/BSE) is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://mcp.dalalos.in/mcp
- Repository: https://github.com/BeyondNoww/DalalOS-Indian-Stock-Research
- Website: https://dalalos.in/
- Changelog RSS feed: https://verifymcp.io/servers/in-dalalos-mcp/mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/in-dalalos-mcp/mcp.json
- HTML version of this page: https://verifymcp.io/servers/in-dalalos-mcp/mcp
