Skip to main content
Glama

Valuein — SEC EDGAR Fundamentals & Smart-Money Data

Point-in-Time Universe

get_pit_universe
Read-onlyIdempotent

Use this tool to answer questions about historical index membership — e.g. "Was Company X in the S&P 500 on date Y?" (S&P 500 members on a date, including former members, from 1996) or "Which companies were in the Russell 2000 on 2010-01-01?" Use this INSTEAD OF search_companies when the question involves a specific historical date or whether a company was an index member in the past — search_companies only returns current membership and cannot answer historical questions.

Returns a survivorship-free universe valid on a given as_of_date (only companies that existed and were members on that exact date — no hindsight; [) interval semantics). To check one company, pass ticker (a ticker or, better, a CIK) + index + the target date: present = was a member, absent = was not.

⚠️ HISTORICAL DEPTH AND PROVENANCE DIFFER BY INDEX — read this before using a result for a backtest. • SP500 — membership history from 1996, reconstructed and incomplete before about 2007. Those years hold fewer members than the index had, and many changes are dated to a window, not a day. Long-delisted registrants are included. Check _meta.pit_safe and each row's confidence before relying on a date. • RUSSELL1000 / RUSSELL2000 / RUSSELL3000 — back to 2000-09-30, medium confidence. Reconstructed from the N-PORT and N-CSR portfolio filings of funds that track each index, plus publicly available constituent lists and public reports of index changes. Three consequences you must carry into any conclusion: OBSERVATION SPACING VARIES — roughly one to four observations a year from 2000 through 2006, monthly from 2007 on — so a join or leave date is only as precise as the interval between observations and is never exact to the day in the early years; a tracking fund only PROXIES its index, so a few holdings sit outside the index and a sampled fund can miss some members; and there is NO data before 2000-09-30 — an earlier as_of_date returns zero rows because we do not carry it, which is not a statement that the index was empty. • Known gap: 2016-12-30 → 2017-07-31. No holdings observation exists anywhere in that 213-day window, so Russell membership cannot be observed inside it. Departures collapse onto 2016-12-31 and arrivals onto 2017-07-31, which means the June 2017 reconstitution appears to happen on 31 July. Treat Russell results dated inside that window as interpolated.

Returns per company: CIK, ticker, name, sector, industry, SIC code, enriched, and per-row confidence (high/medium/low). The CIK is always present and is the identifier to carry forward; every other identity field is nullable. enriched: false means index_membership names this member but the company has no row in references (it delisted before SEC's current-only ticker map was written) — its identity is UNKNOWN, not absent, and it is still a member. ticker is separately null when the company was not listed under any ticker on the as_of_date.

⚠️ A RESPONSE IS USUALLY A PAGE, NOT THE UNIVERSE. universe_size always reports the FULL matched membership count; returned_rows reports what THIS response carries; complete is true only when they are equal, and survivorship_free is true only when complete is — a slice of a universe is not a survivorship-free universe. A response carries one page of at most limit rows (default 100, never more than 250 inlined), starting at offset; whenever rows remain after it the response carries a truncation envelope, so call again with offset = its next_offset (same other arguments) until the pages sum to universe_size. To get the whole universe in one read, use get_compute_ready_stream, the Python SDK, or the Bulk Data API. Index rows are ordered by CIK — deliberately uncorrelated with whether a company survived to today, so a truncated page is an arbitrary sample rather than a list of survivors. _meta.pit_safe is true only when EVERY matched row is high-confidence — so it is false for any Russell query by construction. That flag is the one to branch on: when it is false, treat the universe as approximate, whatever the index. sector is SIC-derived (GICS-aligned, not licensed GICS) — a screening bucket, not an authoritative label.

Use as the first step of a quantitative backtest before get_compute_ready_stream. Returns an empty array (with error detail) if the date is out of range or has no coverage. Available on every plan — sample returns the subset covered by the sample bucket.

Input Schema

NameRequiredDescriptionDefault
indexNoIndex filter. 'sp500' (~500 large caps; reconstructed history from 1996, incomplete before ~2007, check pit_safe), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry fund-derived history back to 2000-09-30 at medium confidence, with observation spacing that widens before 2007. Omit for no index filter (sector-only or full universe queries).
limitNoRows per page (1–3500; at most 250 are inlined per call). Defaults to 100. `universe_size` always states the full matched count; when more rows remain after this page the response carries a `truncation` envelope — call again with `offset` = its `next_offset`. Universe is deduped to one row per CIK (SP500 ~505, Russell 3000 ~3050).
offsetNoZero-based row offset where this page starts. Pass the previous response's `truncation.next_offset` to fetch the next page. Defaults to 0.
sectorNoSector filter (case-insensitive substring) over the SIC-derived, GICS-aligned label (not licensed GICS — see tool description). E.g. 'Technology', 'Energy'.
tickerNoCheck ONE company: a ticker or a CIK (SEC identifier), e.g. 'AAPL' or '0000320193'. Returns that company's row if it was a member on as_of_date, none if it was not. A ticker matches the symbol listed ON that date, and a since-delisted member can carry no ticker at all (enriched=false), so prefer the CIK for historical checks. Omit to list the universe.
is_activeNoFilter to active (currently trading) companies only. Omit to include all. WARNING: setting this to true on a HISTORICAL query reintroduces survivorship bias — companies that were active on as_of_date but later went bankrupt or got acquired will be filtered out. Leave unset for true PIT backtests.
as_of_dateNoHistorical date (YYYY-MM-DD) for survivorship-free construction. Index queries use index_membership join/leave dates (entrants after the date excluded, later-removed members kept); sector queries use security valid_from/valid_to. Omit for the current universe.
include_share_classesNofalse (default) collapses to one row per CIK (index-provider convention — BRK counts once, not BRK-A + BRK-B). true returns every share-class row (GOOG and GOOGL separately) — for security-level analysis only.

Output Schema

NameRequiredDescriptionDefault
noteYes
_metaYesProvenance envelope — data lineage for every MCP response
indexYes
sectorYes
completeYes
coverageYes
companiesYes
as_of_dateYes
truncationNoPresent only when the inline-row cap withheld rows. Page with `next_offset` (keep the same `limit`) or pull the full set via get_compute_ready_stream.
coverage_gapYes
returned_rowsYes
universe_sizeYes
limit_truncatedYes
survivorship_freeYes
confidence_summaryYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / index / description
      Previous value: -"Index filter. 'sp500' (~500 large caps, curated history back to 1996), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry fund-derived history back to 2000-09-30 at medium confidence, with observation spacing that widens before 2007. Omit for no index filter (sector-only or full universe queries)."New value: +"Index filter. 'sp500' (~500 large caps; reconstructed history from 1996, incomplete before ~2007, check pit_safe), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry fund-derived history back to 2000-09-30 at medium confidence, with observation spacing that widens before 2007. Omit for no index filter (sector-only or full universe queries)."
  2. Changed1 schema field changed
    • changedOutput schema / properties / _meta / properties / cost_usd / properties / basis / description
      Previous value: -"payg_charge = real charge (agent-pay or your balance). payg_rate_card = indicative price, not billed."New value: +"payg_charge = real pay-per-call charge (a card or MPP payment through agent-pay). payg_rate_card = indicative price, not billed."
  3. Changed2 schema fields changed
    • changedOutput schema / properties / _meta / properties / cost_usd / properties / basis / description
      Previous value: -"payg_charge = real agent-pay charge. payg_rate_card = indicative price, not billed."New value: +"payg_charge = real charge (agent-pay or your balance). payg_rate_card = indicative price, not billed."
    • changedOutput schema / properties / _meta / properties / cost_usd / properties / billed / description
      Previous value: -"true = this amount was actually charged via PAYG for this call. false = indicative PAYG-equivalent value; your plan already covers this call for free."New value: +"true = this amount was actually charged via PAYG for this call. false = indicative PAYG-equivalent value only: no charge was made for this call (it was within your plan)."
  4. Changed3 schema fields changed
    • removedInput schema / properties / as_of_basis
      Removed value: -{
      -  "default": "effective",
      -  "description": "Which date column drives historical construction. 'effective' (default) = effective_date/removal_date (first trading day; passive replication). 'announcement' = announcement_date/removal_announcement_date (S&P's public-announcement day; for inclusion-arb backtests) — rows with NULL announcement_date (mostly pre-2015) are skipped.",
      -  "enum": [
      -    "effective",
      -    "announcement"
      -  ],
      -  "type": "string"
      -}
    • removedOutput schema / properties / as_of_basis
      Removed value: -{
      -  "type": [
      -    "string",
      -    "null"
      -  ]
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "_meta",
      -  "as_of_date",
      -  "as_of_basis",
      -  "index",
      -  "sector",
      -  "universe_size",
      -  "returned_rows",
      -  "complete",
      -  "limit_truncated",
      -  "survivorship_free",
      -  "coverage_gap",
      -  "coverage",
      -  "confidence_summary",
      -  "note",
      -  "companies"
      -]New value: +[
      +  "_meta",
      +  "as_of_date",
      +  "index",
      +  "sector",
      +  "universe_size",
      +  "returned_rows",
      +  "complete",
      +  "limit_truncated",
      +  "survivorship_free",
      +  "coverage_gap",
      +  "coverage",
      +  "confidence_summary",
      +  "note",
      +  "companies"
      +]
  5. Changed3 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum companies to return (1–3500). Defaults to 100 — which is SMALLER THAN EVERY INDEX, so the default call returns a slice, reports `limit_truncated: true` and withholds `survivorship_free`. `universe_size` always states the full matched count whatever you set here. Raising it is NOT sufficient on its own: at most 250 rows are inlined per call, so a large limit still returns a page (`complete: false`) until you walk it with `offset`. Universe is deduped to one row per CIK, so for a usable backtest universe set this near the index size (SP500 ~505, Russell 3000 ~3050) and page with `offset`."New value: +"Rows per page (1–3500; at most 250 are inlined per call). Defaults to 100. `universe_size` always states the full matched count; when more rows remain after this page the response carries a `truncation` envelope — call again with `offset` = its `next_offset`. Universe is deduped to one row per CIK (SP500 ~505, Russell 3000 ~3050)."
    • changedInput schema / properties / offset / description
      Previous value: -"Zero-based row offset for paging a large universe. At most 250 rows are inlined per call; when more match, the response carries a `truncation` envelope — pass its `next_offset` here (keeping the same `limit`) to fetch the next page. Defaults to 0."New value: +"Zero-based row offset where this page starts. Pass the previous response's `truncation.next_offset` to fetch the next page. Defaults to 0."
    • addedInput schema / properties / ticker
      Added value: +{
      +  "description": "Check ONE company: a ticker or a CIK (SEC identifier), e.g. 'AAPL' or '0000320193'. Returns that company's row if it was a member on as_of_date, none if it was not. A ticker matches the symbol listed ON that date, and a since-delisted member can carry no ticker at all (enriched=false), so prefer the CIK for historical checks. Omit to list the universe.",
      +  "maxLength": 10,
      +  "minLength": 1,
      +  "pattern": "^([A-Za-z][A-Za-z0-9.\\-]{0,9}|\\d{1,10})$",
      +  "type": "string"
      +}
  6. Changed23 schema fields changed
    • changedInput schema / properties / as_of_basis / description
      Previous value: -"Which dates decide membership: effective (default, when a change took effect) or announcement (when it was announced), e.g. announcement."New value: +"Which date column drives historical construction. 'effective' (default) = effective_date/removal_date (first trading day; passive replication). 'announcement' = announcement_date/removal_announcement_date (S&P's public-announcement day; for inclusion-arb backtests) — rows with NULL announcement_date (mostly pre-2015) are skipped."
    • changedInput schema / properties / as_of_date / description
      Previous value: -"Date the membership applies to, YYYY-MM-DD; omit for the current universe, e.g. 2022-12-30."New value: +"Historical date (YYYY-MM-DD) for survivorship-free construction. Index queries use index_membership join/leave dates (entrants after the date excluded, later-removed members kept); sector queries use security valid_from/valid_to. Omit for the current universe."
    • changedInput schema / properties / include_share_classes / description
      Previous value: -"true returns one row per share class instead of one per company; defaults to false, e.g. true."New value: +"false (default) collapses to one row per CIK (index-provider convention — BRK counts once, not BRK-A + BRK-B). true returns every share-class row (GOOG and GOOGL separately) — for security-level analysis only."
    • changedInput schema / properties / index / description
      Previous value: -"Index to list: sp500, russell1000, russell2000 or russell3000; omit for no index filter, e.g. sp500."New value: +"Index filter. 'sp500' (~500 large caps, curated history back to 1996), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry fund-derived history back to 2000-09-30 at medium confidence, with observation spacing that widens before 2007. Omit for no index filter (sector-only or full universe queries)."
    • changedInput schema / properties / is_active / description
      Previous value: -"true keeps only companies still trading today, which drops members that later delisted; omit to keep all, e.g. true."New value: +"Filter to active (currently trading) companies only. Omit to include all. WARNING: setting this to true on a HISTORICAL query reintroduces survivorship bias — companies that were active on as_of_date but later went bankrupt or got acquired will be filtered out.  Leave unset for true PIT backtests."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum number of members to return, 1 to 3500; defaults to 100, e.g. 505."New value: +"Maximum companies to return (1–3500). Defaults to 100 — which is SMALLER THAN EVERY INDEX, so the default call returns a slice, reports `limit_truncated: true` and withholds `survivorship_free`. `universe_size` always states the full matched count whatever you set here. Raising it is NOT sufficient on its own: at most 250 rows are inlined per call, so a large limit still returns a page (`complete: false`) until you walk it with `offset`. Universe is deduped to one row per CIK, so for a usable backtest universe set this near the index size (SP500 ~505, Russell 3000 ~3050) and page with `offset`."
    • changedInput schema / properties / offset / description
      Previous value: -"Rows to skip when paging through a long list; defaults to 0, e.g. 250."New value: +"Zero-based row offset for paging a large universe. At most 250 rows are inlined per call; when more match, the response carries a `truncation` envelope — pass its `next_offset` here (keeping the same `limit`) to fetch the next page. Defaults to 0."
    • changedInput schema / properties / sector / description
      Previous value: -"Sector name to match, case-insensitive partial match, e.g. Technology."New value: +"Sector filter (case-insensitive substring) over the SIC-derived, GICS-aligned label (not licensed GICS — see tool description). E.g. 'Technology', 'Energy'."
    • addedOutput schema / properties / _meta / properties / cost_usd
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Per-call cost transparency. Omitted for subscription-only tools that have no PAYG-equivalent price.",
      +  "properties": {
      +    "amount_usd": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "basis": {
      +      "description": "payg_charge = real agent-pay charge. payg_rate_card = indicative price, not billed.",
      +      "enum": [
      +        "payg_charge",
      +        "payg_rate_card"
      +      ],
      +      "type": "string"
      +    },
      +    "billed": {
      +      "description": "true = this amount was actually charged via PAYG for this call. false = indicative PAYG-equivalent value; your plan already covers this call for free.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "amount_usd",
      +    "billed",
      +    "basis"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / _meta / properties / data_plan
      Added value: +{
      +  "description": "Access plan: sample | sp500 | pro | full",
      +  "type": "string"
      +}
    • changedOutput schema / properties / _meta / properties / fundamentals_as_of / description
      Previous value: -"Use THIS — not `last_updated` — when telling a user how current the cross-sectional fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to. It is a floor for a single filer, not a ceiling: a filer with a live partition receives its filing, facts and ratios intraday (minutes after EDGAR dissemination), so an entity-scoped read may carry a filing newer than this; cross-sectional ranks (factor scores, earnings signals) refresh with the weekly bulk export."New value: +"ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt in bulk. Use THIS — not `last_updated` — when telling a user how current the cross-sectional fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to. It is a floor for a single filer, not a ceiling: a filer with a live partition receives its filing, facts and ratios intraday (minutes after EDGAR dissemination), so an entity-scoped read may carry a filing newer than this; cross-sectional ranks (factor scores, earnings signals) refresh with the weekly bulk export."
    • addedOutput schema / properties / _meta / properties / last_updated
      Added value: +{
      +  "description": "ISO timestamp when the snapshot was exported",
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / latency_ms
      Added value: +{
      +  "description": "Wall-clock milliseconds this tool call took, measured server-side around the handler.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / _meta / properties / limit_warnings
      Added value: +{
      +  "description": "Soft-warning array for partial fulfillment. Each entry carries a stable subcode + remediation.options[]. AI agents pattern-match on subcode.",
      +  "items": {
      +    "additionalProperties": true,
      +    "properties": {
      +      "code": {
      +        "const": "LIMIT_EXCEEDED",
      +        "type": "string"
      +      },
      +      "current_plan": {
      +        "type": "string"
      +      },
      +      "extensions": {
      +        "additionalProperties": {},
      +        "type": "object"
      +      },
      +      "limit_type": {
      +        "type": "string"
      +      },
      +      "limit_value": {},
      +      "remediation": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "contact_sales": {
      +            "type": "string"
      +          },
      +          "default_action": {
      +            "type": "string"
      +          },
      +          "options": {
      +            "items": {
      +              "additionalProperties": {},
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "pricing_page": {
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "options",
      +          "default_action",
      +          "pricing_page",
      +          "contact_sales"
      +        ],
      +        "type": "object"
      +      },
      +      "requested_value": {},
      +      "returned_value": {},
      +      "subcode": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "code",
      +      "subcode",
      +      "limit_type",
      +      "current_plan",
      +      "remediation"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / _meta / properties / payg_override
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Set when this single response was paid for via the agent-pay PAYG flow — the rate-limit / depth-limit checks were bypassed for this call only.",
      +  "properties": {
      +    "amount_cents": {
      +      "type": "number"
      +    },
      +    "entity_scope_hash": {
      +      "type": "string"
      +    },
      +    "meter": {
      +      "type": "string"
      +    },
      +    "quote_id": {
      +      "type": "string"
      +    },
      +    "retry_token_hash": {
      +      "type": "string"
      +    },
      +    "ticker_count": {
      +      "type": "number"
      +    },
      +    "tool": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "quote_id",
      +    "tool",
      +    "meter",
      +    "amount_cents",
      +    "ticker_count",
      +    "entity_scope_hash",
      +    "retry_token_hash"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / _meta / properties / rate_limit
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Caller's remaining budget",
      +  "properties": {
      +    "limit": {
      +      "type": "integer"
      +    },
      +    "remaining": {
      +      "type": "integer"
      +    },
      +    "reset_at": {
      +      "description": "ISO 8601 timestamp when the window resets",
      +      "type": "string"
      +    },
      +    "window": {
      +      "enum": [
      +        "minute",
      +        "hour"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "limit",
      +    "remaining",
      +    "reset_at",
      +    "window"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / _meta / properties / request_id
      Added value: +{
      +  "description": "Per-request correlation id (8-char)",
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / schema_version
      Added value: +{
      +  "description": "Parquet schema version from manifest.json",
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / snapshot
      Added value: +{
      +  "description": "Snapshot directory name (e.g. snapshot_20260420)",
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / truncation / properties / current_plan
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / truncation / properties / upgrade_required_for
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / truncation / properties / upgrade_url
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / properties / _meta / required
      Previous value: -[
      -  "source",
      -  "pit_safe"
      -]New value: +[
      +  "data_plan",
      +  "schema_version",
      +  "snapshot",
      +  "last_updated",
      +  "source",
      +  "pit_safe"
      +]
  7. Changed23 schema fields changed
    • changedInput schema / properties / as_of_basis / description
      Previous value: -"Which date column drives historical construction. 'effective' (default) = effective_date/removal_date (first trading day; passive replication). 'announcement' = announcement_date/removal_announcement_date (S&P's public-announcement day; for inclusion-arb backtests) — rows with NULL announcement_date (mostly pre-2015) are skipped."New value: +"Which dates decide membership: effective (default, when a change took effect) or announcement (when it was announced), e.g. announcement."
    • changedInput schema / properties / as_of_date / description
      Previous value: -"Historical date (YYYY-MM-DD) for survivorship-free construction. Index queries use index_membership join/leave dates (entrants after the date excluded, later-removed members kept); sector queries use security valid_from/valid_to. Omit for the current universe."New value: +"Date the membership applies to, YYYY-MM-DD; omit for the current universe, e.g. 2022-12-30."
    • changedInput schema / properties / include_share_classes / description
      Previous value: -"false (default) collapses to one row per CIK (index-provider convention — BRK counts once, not BRK-A + BRK-B). true returns every share-class row (GOOG and GOOGL separately) — for security-level analysis only."New value: +"true returns one row per share class instead of one per company; defaults to false, e.g. true."
    • changedInput schema / properties / index / description
      Previous value: -"Index filter. 'sp500' (~500 large caps, curated history back to 1996), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry fund-derived history back to 2000-09-30 at medium confidence, with observation spacing that widens before 2007. Omit for no index filter (sector-only or full universe queries)."New value: +"Index to list: sp500, russell1000, russell2000 or russell3000; omit for no index filter, e.g. sp500."
    • changedInput schema / properties / is_active / description
      Previous value: -"Filter to active (currently trading) companies only. Omit to include all. WARNING: setting this to true on a HISTORICAL query reintroduces survivorship bias — companies that were active on as_of_date but later went bankrupt or got acquired will be filtered out.  Leave unset for true PIT backtests."New value: +"true keeps only companies still trading today, which drops members that later delisted; omit to keep all, e.g. true."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum companies to return (1–3500). Defaults to 100 — which is SMALLER THAN EVERY INDEX, so the default call returns a slice, reports `limit_truncated: true` and withholds `survivorship_free`. `universe_size` always states the full matched count whatever you set here. Raising it is NOT sufficient on its own: at most 250 rows are inlined per call, so a large limit still returns a page (`complete: false`) until you walk it with `offset`. Universe is deduped to one row per CIK, so for a usable backtest universe set this near the index size (SP500 ~505, Russell 3000 ~3050) and page with `offset`."New value: +"Maximum number of members to return, 1 to 3500; defaults to 100, e.g. 505."
    • changedInput schema / properties / offset / description
      Previous value: -"Zero-based row offset for paging a large universe. At most 250 rows are inlined per call; when more match, the response carries a `truncation` envelope — pass its `next_offset` here (keeping the same `limit`) to fetch the next page. Defaults to 0."New value: +"Rows to skip when paging through a long list; defaults to 0, e.g. 250."
    • changedInput schema / properties / sector / description
      Previous value: -"Sector filter (case-insensitive substring) over the SIC-derived, GICS-aligned label (not licensed GICS — see tool description). E.g. 'Technology', 'Energy'."New value: +"Sector name to match, case-insensitive partial match, e.g. Technology."
    • removedOutput schema / properties / _meta / properties / cost_usd
      Removed value: -{
      -  "additionalProperties": false,
      -  "description": "Per-call cost transparency. Omitted for subscription-only tools that have no PAYG-equivalent price.",
      -  "properties": {
      -    "amount_usd": {
      -      "minimum": 0,
      -      "type": "number"
      -    },
      -    "basis": {
      -      "description": "payg_charge = real agent-pay charge. payg_rate_card = indicative price, not billed.",
      -      "enum": [
      -        "payg_charge",
      -        "payg_rate_card"
      -      ],
      -      "type": "string"
      -    },
      -    "billed": {
      -      "description": "true = this amount was actually charged via PAYG for this call. false = indicative PAYG-equivalent value; your plan already covers this call for free.",
      -      "type": "boolean"
      -    }
      -  },
      -  "required": [
      -    "amount_usd",
      -    "billed",
      -    "basis"
      -  ],
      -  "type": "object"
      -}
    • removedOutput schema / properties / _meta / properties / data_plan
      Removed value: -{
      -  "description": "Access plan: sample | sp500 | pro | full",
      -  "type": "string"
      -}
    • changedOutput schema / properties / _meta / properties / fundamentals_as_of / description
      Previous value: -"ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt in bulk. Use THIS — not `last_updated` — when telling a user how current the cross-sectional fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to. It is a floor for a single filer, not a ceiling: a filer with a live partition receives its filing, facts and ratios intraday (minutes after EDGAR dissemination), so an entity-scoped read may carry a filing newer than this; cross-sectional ranks (factor scores, earnings signals) refresh with the weekly bulk export."New value: +"Use THIS — not `last_updated` — when telling a user how current the cross-sectional fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to. It is a floor for a single filer, not a ceiling: a filer with a live partition receives its filing, facts and ratios intraday (minutes after EDGAR dissemination), so an entity-scoped read may carry a filing newer than this; cross-sectional ranks (factor scores, earnings signals) refresh with the weekly bulk export."
    • removedOutput schema / properties / _meta / properties / last_updated
      Removed value: -{
      -  "description": "ISO timestamp when the snapshot was exported",
      -  "type": "string"
      -}
    • removedOutput schema / properties / _meta / properties / latency_ms
      Removed value: -{
      -  "description": "Wall-clock milliseconds this tool call took, measured server-side around the handler.",
      -  "minimum": 0,
      -  "type": "integer"
      -}
    • removedOutput schema / properties / _meta / properties / limit_warnings
      Removed value: -{
      -  "description": "Soft-warning array for partial fulfillment. Each entry carries a stable subcode + remediation.options[]. AI agents pattern-match on subcode.",
      -  "items": {
      -    "additionalProperties": true,
      -    "properties": {
      -      "code": {
      -        "const": "LIMIT_EXCEEDED",
      -        "type": "string"
      -      },
      -      "current_plan": {
      -        "type": "string"
      -      },
      -      "extensions": {
      -        "additionalProperties": {},
      -        "type": "object"
      -      },
      -      "limit_type": {
      -        "type": "string"
      -      },
      -      "limit_value": {},
      -      "remediation": {
      -        "additionalProperties": true,
      -        "properties": {
      -          "contact_sales": {
      -            "type": "string"
      -          },
      -          "default_action": {
      -            "type": "string"
      -          },
      -          "options": {
      -            "items": {
      -              "additionalProperties": {},
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "pricing_page": {
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "options",
      -          "default_action",
      -          "pricing_page",
      -          "contact_sales"
      -        ],
      -        "type": "object"
      -      },
      -      "requested_value": {},
      -      "returned_value": {},
      -      "subcode": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "code",
      -      "subcode",
      -      "limit_type",
      -      "current_plan",
      -      "remediation"
      -    ],
      -    "type": "object"
      -  },
      -  "type": "array"
      -}
    • removedOutput schema / properties / _meta / properties / payg_override
      Removed value: -{
      -  "additionalProperties": false,
      -  "description": "Set when this single response was paid for via the agent-pay PAYG flow — the rate-limit / depth-limit checks were bypassed for this call only.",
      -  "properties": {
      -    "amount_cents": {
      -      "type": "number"
      -    },
      -    "entity_scope_hash": {
      -      "type": "string"
      -    },
      -    "meter": {
      -      "type": "string"
      -    },
      -    "quote_id": {
      -      "type": "string"
      -    },
      -    "retry_token_hash": {
      -      "type": "string"
      -    },
      -    "ticker_count": {
      -      "type": "number"
      -    },
      -    "tool": {
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "quote_id",
      -    "tool",
      -    "meter",
      -    "amount_cents",
      -    "ticker_count",
      -    "entity_scope_hash",
      -    "retry_token_hash"
      -  ],
      -  "type": "object"
      -}
    • removedOutput schema / properties / _meta / properties / rate_limit
      Removed value: -{
      -  "additionalProperties": false,
      -  "description": "Caller's remaining budget",
      -  "properties": {
      -    "limit": {
      -      "type": "integer"
      -    },
      -    "remaining": {
      -      "type": "integer"
      -    },
      -    "reset_at": {
      -      "description": "ISO 8601 timestamp when the window resets",
      -      "type": "string"
      -    },
      -    "window": {
      -      "enum": [
      -        "minute",
      -        "hour"
      -      ],
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "limit",
      -    "remaining",
      -    "reset_at",
      -    "window"
      -  ],
      -  "type": "object"
      -}
    • removedOutput schema / properties / _meta / properties / request_id
      Removed value: -{
      -  "description": "Per-request correlation id (8-char)",
      -  "type": "string"
      -}
    • removedOutput schema / properties / _meta / properties / schema_version
      Removed value: -{
      -  "description": "Parquet schema version from manifest.json",
      -  "type": "string"
      -}
    • removedOutput schema / properties / _meta / properties / snapshot
      Removed value: -{
      -  "description": "Snapshot directory name (e.g. snapshot_20260420)",
      -  "type": "string"
      -}
    • removedOutput schema / properties / _meta / properties / truncation / properties / current_plan
      Removed value: -{
      -  "type": "string"
      -}
    • removedOutput schema / properties / _meta / properties / truncation / properties / upgrade_required_for
      Removed value: -{
      -  "type": "string"
      -}
    • removedOutput schema / properties / _meta / properties / truncation / properties / upgrade_url
      Removed value: -{
      -  "type": "string"
      -}
    • changedOutput schema / properties / _meta / required
      Previous value: -[
      -  "data_plan",
      -  "schema_version",
      -  "snapshot",
      -  "last_updated",
      -  "source",
      -  "pit_safe"
      -]New value: +[
      +  "source",
      +  "pit_safe"
      +]
  8. Changed1 schema field changed
    • changedOutput schema / properties / _meta / properties / fundamentals_as_of / description
      Previous value: -"ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt. Use THIS — not `last_updated` — when telling a user how current the fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to."New value: +"ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt in bulk. Use THIS — not `last_updated` — when telling a user how current the cross-sectional fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to. It is a floor for a single filer, not a ceiling: a filer with a live partition receives its filing, facts and ratios intraday (minutes after EDGAR dissemination), so an entity-scoped read may carry a filing newer than this; cross-sectional ranks (factor scores, earnings signals) refresh with the weekly bulk export."
  9. Changed1 schema field changed
    • changedInput schema / properties / index / description
      Previous value: -"Index filter. 'sp500' (~500 large caps, curated history back to 1996), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry ETF-derived monthly history back to 2007 at medium confidence. Omit for no index filter (sector-only or full universe queries)."New value: +"Index filter. 'sp500' (~500 large caps, curated history back to 1996), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry fund-derived history back to 2000-09-30 at medium confidence, with observation spacing that widens before 2007. Omit for no index filter (sector-only or full universe queries)."
  10. Changed3 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum companies to return (1–3500). Defaults to 100 — which is SMALLER THAN EVERY INDEX, so the default call returns a slice, reports `limit_truncated: true` and withholds `survivorship_free`. `universe_size` always states the full matched count whatever you set here. Universe is deduped to one row per CIK, so for a usable backtest universe set this near the index size (SP500 ~505, Russell 3000 ~3050) and page the response with `offset`."New value: +"Maximum companies to return (1–3500). Defaults to 100 — which is SMALLER THAN EVERY INDEX, so the default call returns a slice, reports `limit_truncated: true` and withholds `survivorship_free`. `universe_size` always states the full matched count whatever you set here. Raising it is NOT sufficient on its own: at most 250 rows are inlined per call, so a large limit still returns a page (`complete: false`) until you walk it with `offset`. Universe is deduped to one row per CIK, so for a usable backtest universe set this near the index size (SP500 ~505, Russell 3000 ~3050) and page with `offset`."
    • addedOutput schema / properties / complete
      Added value: +{
      +  "type": "boolean"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "_meta",
      -  "as_of_date",
      -  "as_of_basis",
      -  "index",
      -  "sector",
      -  "universe_size",
      -  "returned_rows",
      -  "limit_truncated",
      -  "survivorship_free",
      -  "coverage_gap",
      -  "coverage",
      -  "confidence_summary",
      -  "note",
      -  "companies"
      -]New value: +[
      +  "_meta",
      +  "as_of_date",
      +  "as_of_basis",
      +  "index",
      +  "sector",
      +  "universe_size",
      +  "returned_rows",
      +  "complete",
      +  "limit_truncated",
      +  "survivorship_free",
      +  "coverage_gap",
      +  "coverage",
      +  "confidence_summary",
      +  "note",
      +  "companies"
      +]
  11. Changed4 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum companies to return (1–3500). Defaults to 100. Universe is deduped to one row per CIK, so set near the index size (SP500 ~505, Russell 3000 ~3050)."New value: +"Maximum companies to return (1–3500). Defaults to 100 — which is SMALLER THAN EVERY INDEX, so the default call returns a slice, reports `limit_truncated: true` and withholds `survivorship_free`. `universe_size` always states the full matched count whatever you set here. Universe is deduped to one row per CIK, so for a usable backtest universe set this near the index size (SP500 ~505, Russell 3000 ~3050) and page the response with `offset`."
    • addedOutput schema / properties / limit_truncated
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / returned_rows
      Added value: +{
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "_meta",
      -  "as_of_date",
      -  "as_of_basis",
      -  "index",
      -  "sector",
      -  "universe_size",
      -  "survivorship_free",
      -  "coverage_gap",
      -  "coverage",
      -  "confidence_summary",
      -  "note",
      -  "companies"
      -]New value: +[
      +  "_meta",
      +  "as_of_date",
      +  "as_of_basis",
      +  "index",
      +  "sector",
      +  "universe_size",
      +  "returned_rows",
      +  "limit_truncated",
      +  "survivorship_free",
      +  "coverage_gap",
      +  "coverage",
      +  "confidence_summary",
      +  "note",
      +  "companies"
      +]
  12. Changed1 schema field changed
    • changedInput schema / properties / index / description
      Previous value: -"Index filter. 'sp500' (~500 large caps), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market). Omit for no index filter (sector-only or full universe queries)."New value: +"Index filter. 'sp500' (~500 large caps, curated history back to 1996), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market) — the three Russell indices carry ETF-derived monthly history back to 2007 at medium confidence. Omit for no index filter (sector-only or full universe queries)."
  13. Changed2 schema fields changed
    • addedOutput schema / properties / _meta / properties / fundamentals_as_of
      Added value: +{
      +  "description": "ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt. Use THIS — not `last_updated` — when telling a user how current the fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / price_as_of
      Added value: +{
      +  "description": "ISO timestamp when the price surfaces were last refreshed.",
      +  "type": "string"
      +}
  14. Changed2 schema fields changed
    • addedOutput schema / properties / _meta / properties / cost_usd
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Per-call cost transparency. Omitted for subscription-only tools that have no PAYG-equivalent price.",
      +  "properties": {
      +    "amount_usd": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "basis": {
      +      "description": "payg_charge = real agent-pay charge. payg_rate_card = indicative price, not billed.",
      +      "enum": [
      +        "payg_charge",
      +        "payg_rate_card"
      +      ],
      +      "type": "string"
      +    },
      +    "billed": {
      +      "description": "true = this amount was actually charged via PAYG for this call. false = indicative PAYG-equivalent value; your plan already covers this call for free.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "amount_usd",
      +    "billed",
      +    "basis"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / _meta / properties / latency_ms
      Added value: +{
      +  "description": "Wall-clock milliseconds this tool call took, measured server-side around the handler.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
  15. Changed7 schema fields changed
    • changedInput schema / properties / as_of_basis / description
      Previous value: -"Which date column to filter on for historical universe construction. 'effective' (default) — match against effective_date / removal_date (first trading day as a member; passive index replication). 'announcement' — match against announcement_date / removal_announcement_date (the day S&P publicly announced the change; use for inclusion-arb backtests). 'announcement' rows with NULL announcement_date are silently skipped — pre-2015 changes generally lack press-release coverage."New value: +"Which date column drives historical construction. 'effective' (default) = effective_date/removal_date (first trading day; passive replication). 'announcement' = announcement_date/removal_announcement_date (S&P's public-announcement day; for inclusion-arb backtests) — rows with NULL announcement_date (mostly pre-2015) are skipped."
    • changedInput schema / properties / as_of_date / description
      Previous value: -"Historical date (YYYY-MM-DD) for survivorship-free universe construction. For an index: uses index_membership join/leave dates — companies that entered after this date are excluded; companies later removed are kept. For sector: uses security valid_from/valid_to. Omit for the current universe."New value: +"Historical date (YYYY-MM-DD) for survivorship-free construction. Index queries use index_membership join/leave dates (entrants after the date excluded, later-removed members kept); sector queries use security valid_from/valid_to. Omit for the current universe."
    • changedInput schema / properties / include_share_classes / description
      Previous value: -"When false (default), the universe is collapsed to one row per CIK — matches how index providers count constituents (BRK is one S&P 500 member, not two for BRK-A + BRK-B).  When true, every share-class row is returned (GOOG and GOOGL emit separate rows, etc.).  Use only for security-level (not company-level) analysis."New value: +"false (default) collapses to one row per CIK (index-provider convention — BRK counts once, not BRK-A + BRK-B). true returns every share-class row (GOOG and GOOGL separately) — for security-level analysis only."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum number of companies to return (1–3500).  Defaults to 100. Sized to fit Russell 3000 (~3000 members) plus headroom for delisted/historical members.  Universe is deduped to one row per CIK by default, so set near the index size (SP500 ~505, Russell 1000 ~1010, Russell 3000 ~3050) — no need for share-class headroom."New value: +"Maximum companies to return (1–3500). Defaults to 100. Universe is deduped to one row per CIK, so set near the index size (SP500 ~505, Russell 3000 ~3050)."
    • addedInput schema / properties / offset
      Added value: +{
      +  "default": 0,
      +  "description": "Zero-based row offset for paging a large universe. At most 250 rows are inlined per call; when more match, the response carries a `truncation` envelope — pass its `next_offset` here (keeping the same `limit`) to fetch the next page. Defaults to 0.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedInput schema / properties / sector / description
      Previous value: -"Sector filter (case-insensitive substring match) over the SIC-derived, GICS-aligned sector label.  E.g. 'Technology', 'Health Care', 'Energy'. Not licensed GICS — see tool description for caveat."New value: +"Sector filter (case-insensitive substring) over the SIC-derived, GICS-aligned label (not licensed GICS — see tool description). E.g. 'Technology', 'Energy'."
    • addedOutput schema / properties / truncation
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Present only when the inline-row cap withheld rows. Page with `next_offset` (keep the same `limit`) or pull the full set via get_compute_ready_stream.",
      +  "properties": {
      +    "hint": {
      +      "type": "string"
      +    },
      +    "next_offset": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "returned": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "total_available": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "truncated": {
      +      "const": true,
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "truncated",
      +    "returned",
      +    "total_available",
      +    "next_offset",
      +    "hint"
      +  ],
      +  "type": "object"
      +}
  16. Changed2 schema fields changed
    • addedOutput schema / properties / coverage
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "assessed": {
      +          "type": "boolean"
      +        },
      +        "completeness_pct": {
      +          "type": "number"
      +        },
      +        "expected_size": {
      +          "type": "integer"
      +        },
      +        "returned": {
      +          "type": "integer"
      +        },
      +        "undercount": {
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "expected_size",
      +        "returned",
      +        "completeness_pct",
      +        "assessed",
      +        "undercount"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "_meta",
      -  "as_of_date",
      -  "as_of_basis",
      -  "index",
      -  "sector",
      -  "universe_size",
      -  "survivorship_free",
      -  "coverage_gap",
      -  "confidence_summary",
      -  "note",
      -  "companies"
      -]New value: +[
      +  "_meta",
      +  "as_of_date",
      +  "as_of_basis",
      +  "index",
      +  "sector",
      +  "universe_size",
      +  "survivorship_free",
      +  "coverage_gap",
      +  "coverage",
      +  "confidence_summary",
      +  "note",
      +  "companies"
      +]
  17. Changed1 schema field changed
    • addedOutput schema / properties / _meta / properties / pit_safe / description
      Added value: +"true iff a zero-look-ahead point-in-time cut was applied to every returned figure"
  18. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "_meta": {
      +      "additionalProperties": false,
      +      "description": "Provenance envelope — data lineage for every MCP response",
      +      "properties": {
      +        "as_of_date": {
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "data_plan": {
      +          "description": "Access plan: sample | sp500 | pro | full",
      +          "type": "string"
      +        },
      +        "data_quality": {
      +          "additionalProperties": false,
      +          "description": "Server-side invariants run on this response",
      +          "properties": {
      +            "notes": {
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            },
      +            "validation_failed": {
      +              "items": {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "detail": {
      +                    "type": "string"
      +                  },
      +                  "rule": {
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "rule",
      +                  "detail"
      +                ],
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "validation_passed": {
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            }
      +          },
      +          "required": [
      +            "validation_passed",
      +            "validation_failed",
      +            "notes"
      +          ],
      +          "type": "object"
      +        },
      +        "last_updated": {
      +          "description": "ISO timestamp when the snapshot was exported",
      +          "type": "string"
      +        },
      +        "limit_warnings": {
      +          "description": "Soft-warning array for partial fulfillment. Each entry carries a stable subcode + remediation.options[]. AI agents pattern-match on subcode.",
      +          "items": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "code": {
      +                "const": "LIMIT_EXCEEDED",
      +                "type": "string"
      +              },
      +              "current_plan": {
      +                "type": "string"
      +              },
      +              "extensions": {
      +                "additionalProperties": {},
      +                "type": "object"
      +              },
      +              "limit_type": {
      +                "type": "string"
      +              },
      +              "limit_value": {},
      +              "remediation": {
      +                "additionalProperties": true,
      +                "properties": {
      +                  "contact_sales": {
      +                    "type": "string"
      +                  },
      +                  "default_action": {
      +                    "type": "string"
      +                  },
      +                  "options": {
      +                    "items": {
      +                      "additionalProperties": {},
      +                      "type": "object"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "pricing_page": {
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "options",
      +                  "default_action",
      +                  "pricing_page",
      +                  "contact_sales"
      +                ],
      +                "type": "object"
      +              },
      +              "requested_value": {},
      +              "returned_value": {},
      +              "subcode": {
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "code",
      +              "subcode",
      +              "limit_type",
      +              "current_plan",
      +              "remediation"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "payg_override": {
      +          "additionalProperties": false,
      +          "description": "Set when this single response was paid for via the agent-pay PAYG flow — the rate-limit / depth-limit checks were bypassed for this call only.",
      +          "properties": {
      +            "amount_cents": {
      +              "type": "number"
      +            },
      +            "entity_scope_hash": {
      +              "type": "string"
      +            },
      +            "meter": {
      +              "type": "string"
      +            },
      +            "quote_id": {
      +              "type": "string"
      +            },
      +            "retry_token_hash": {
      +              "type": "string"
      +            },
      +            "ticker_count": {
      +              "type": "number"
      +            },
      +            "tool": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "quote_id",
      +            "tool",
      +            "meter",
      +            "amount_cents",
      +            "ticker_count",
      +            "entity_scope_hash",
      +            "retry_token_hash"
      +          ],
      +          "type": "object"
      +        },
      +        "pit_safe": {
      +          "type": "boolean"
      +        },
      +        "rate_limit": {
      +          "additionalProperties": false,
      +          "description": "Caller's remaining budget",
      +          "properties": {
      +            "limit": {
      +              "type": "integer"
      +            },
      +            "remaining": {
      +              "type": "integer"
      +            },
      +            "reset_at": {
      +              "description": "ISO 8601 timestamp when the window resets",
      +              "type": "string"
      +            },
      +            "window": {
      +              "enum": [
      +                "minute",
      +                "hour"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "limit",
      +            "remaining",
      +            "reset_at",
      +            "window"
      +          ],
      +          "type": "object"
      +        },
      +        "request_id": {
      +          "description": "Per-request correlation id (8-char)",
      +          "type": "string"
      +        },
      +        "result_count": {
      +          "type": "integer"
      +        },
      +        "schema_version": {
      +          "description": "Parquet schema version from manifest.json",
      +          "type": "string"
      +        },
      +        "snapshot": {
      +          "description": "Snapshot directory name (e.g. snapshot_20260420)",
      +          "type": "string"
      +        },
      +        "source": {
      +          "const": "SEC EDGAR",
      +          "type": "string"
      +        },
      +        "ticker": {
      +          "type": "string"
      +        },
      +        "truncation": {
      +          "additionalProperties": false,
      +          "description": "Set when fewer rows were returned than requested — explains why and points to a remedy",
      +          "properties": {
      +            "current_plan": {
      +              "type": "string"
      +            },
      +            "plan_limit": {
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "reason": {
      +              "enum": [
      +                "PLAN_LIMIT",
      +                "DATA_NOT_AVAILABLE",
      +                "FISCAL_YEAR_BOUNDARY_FILTER",
      +                "OTHER"
      +              ],
      +              "type": "string"
      +            },
      +            "requested": {
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "returned": {
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "upgrade_required_for": {
      +              "type": "string"
      +            },
      +            "upgrade_url": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "requested",
      +            "returned",
      +            "reason"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "data_plan",
      +        "schema_version",
      +        "snapshot",
      +        "last_updated",
      +        "source",
      +        "pit_safe"
      +      ],
      +      "type": "object"
      +    },
      +    "as_of_basis": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "as_of_date": {
      +      "type": "string"
      +    },
      +    "companies": {
      +      "items": {
      +        "additionalProperties": true,
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "confidence_summary": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": {
      +            "type": "number"
      +          },
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "coverage_gap": {
      +      "type": "boolean"
      +    },
      +    "index": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "note": {
      +      "type": "string"
      +    },
      +    "sector": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "survivorship_free": {
      +      "type": "boolean"
      +    },
      +    "universe_size": {
      +      "minimum": 0,
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "_meta",
      +    "as_of_date",
      +    "as_of_basis",
      +    "index",
      +    "sector",
      +    "universe_size",
      +    "survivorship_free",
      +    "coverage_gap",
      +    "confidence_summary",
      +    "note",
      +    "companies"
      +  ],
      +  "type": "object"
      +}
  19. Changed2 schema fields changed
    • addedInput schema / properties / include_share_classes
      Added value: +{
      +  "default": false,
      +  "description": "When false (default), the universe is collapsed to one row per CIK — matches how index providers count constituents (BRK is one S&P 500 member, not two for BRK-A + BRK-B).  When true, every share-class row is returned (GOOG and GOOGL emit separate rows, etc.).  Use only for security-level (not company-level) analysis.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum number of companies to return (1–3500).  Defaults to 100. Sized to fit Russell 3000 (~3000 members) plus headroom for delisted/historical members. For SP500 set ~510, for Russell 1000 set ~1100."New value: +"Maximum number of companies to return (1–3500).  Defaults to 100. Sized to fit Russell 3000 (~3000 members) plus headroom for delisted/historical members.  Universe is deduped to one row per CIK by default, so set near the index size (SP500 ~505, Russell 1000 ~1010, Russell 3000 ~3050) — no need for share-class headroom."
  20. Changed7 schema fields changed
    • changedInput schema / properties / as_of_date / description
      Previous value: -"Historical date (YYYY-MM-DD) for survivorship-free universe construction. For S&P 500: uses index join/leave dates — companies that entered after this date are excluded. For sector: uses security valid_from/valid_to. Omit for the current universe."New value: +"Historical date (YYYY-MM-DD) for survivorship-free universe construction. For an index: uses index_membership join/leave dates — companies that entered after this date are excluded; companies later removed are kept. For sector: uses security valid_from/valid_to. Omit for the current universe."
    • changedInput schema / properties / index / description
      Previous value: -"Index filter. 'sp500' returns S&P 500 constituents. Omit for no index filter."New value: +"Index filter. 'sp500' (~500 large caps), 'russell1000' (~1000 large/mid), 'russell2000' (~2000 small caps), 'russell3000' (~3000 broad market). Omit for no index filter (sector-only or full universe queries)."
    • changedInput schema / properties / index / enum
      Previous value: -[
      -  "sp500"
      -]New value: +[
      +  "sp500",
      +  "russell1000",
      +  "russell2000",
      +  "russell3000"
      +]
    • changedInput schema / properties / is_active / description
      Previous value: -"Filter to active (currently trading) companies only. Omit to include all."New value: +"Filter to active (currently trading) companies only. Omit to include all. WARNING: setting this to true on a HISTORICAL query reintroduces survivorship bias — companies that were active on as_of_date but later went bankrupt or got acquired will be filtered out.  Leave unset for true PIT backtests."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum number of companies to return (1–510). Defaults to 100."New value: +"Maximum number of companies to return (1–3500).  Defaults to 100. Sized to fit Russell 3000 (~3000 members) plus headroom for delisted/historical members. For SP500 set ~510, for Russell 1000 set ~1100."
    • changedInput schema / properties / limit / maximum
      Previous value: -510New value: +3500
    • changedInput schema / properties / sector / description
      Previous value: -"Sector filter (case-insensitive substring match). E.g. 'Technology', 'Health Care', 'Energy'."New value: +"Sector filter (case-insensitive substring match) over the SIC-derived, GICS-aligned sector label.  E.g. 'Technology', 'Health Care', 'Energy'. Not licensed GICS — see tool description for caveat."
  21. Changed2 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum number of companies to return (1–500). Defaults to 100."New value: +"Maximum number of companies to return (1–510). Defaults to 100."
    • changedInput schema / properties / limit / maximum
      Previous value: -500New value: +510
  22. Changed1 schema field changed
    • addedInput schema / properties / as_of_basis
      Added value: +{
      +  "default": "effective",
      +  "description": "Which date column to filter on for historical universe construction. 'effective' (default) — match against effective_date / removal_date (first trading day as a member; passive index replication). 'announcement' — match against announcement_date / removal_announcement_date (the day S&P publicly announced the change; use for inclusion-arb backtests). 'announcement' rows with NULL announcement_date are silently skipped — pre-2015 changes generally lack press-release coverage.",
      +  "enum": [
      +    "effective",
      +    "announcement"
      +  ],
      +  "type": "string"
      +}
  23. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/idempotent annotations: per-index provenance and reconstruction method, observation-spacing imprecision, the explicit 2016-12-30→2017-07-31 gap with its distortion of the 2017 reconstitution, empty-result-because-no-coverage vs. empty-index, and the `pit_safe`/`confidence` branch conditions. That is exactly the behavior an agent needs to avoid drawing false conclusions from a returned page.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded and well-sectioned with bullets and warnings, but long, and several passages duplicate the schema verbatim in substance (pagination/`limit`/`offset` mechanics, the `is_active` survivorship warning, the sector GICS caveat, the per-row confidence description). Those repeats consume space without adding decision-relevant information beyond the structured fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 params and an output schema, the description still supplies everything an agent needs to call it correctly and interpret it: coverage windows per index, confidence semantics, pagination loop termination via `universe_size`, and the sentinel meanings of `enriched: false` and null `ticker`. Nothing material is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine semantics: ticker vs. CIK preference for historical checks with the present/absent interpretation, the "a page is not a universe" reading of limit/offset against `universe_size`, and the SIC-derived caveat on `sector`. Minor gaps remain (e.g., `include_share_classes` and `is_active` behavior are left entirely to the schema's own text).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource (return a survivorship-free point-in-time index universe) and anchors it with two concrete example questions. It explicitly names the sibling `search_companies` and the boundary between them, so an agent can route without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ("a specific historical date or whether a company was an index member in the past"), when-not ("`search_companies` only returns current membership and cannot answer historical questions"), and the downstream alternative ("first step of a quantitative backtest before `get_compute_ready_stream`"). It also describes the single-company mode vs. list mode within the same tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.