# Every Number About a Stock: The Complete Field Reference

*Published 2026-09-04 | tags: Reference*

> A verified field-by-field reference of what an AI agent can get about a stock from Stocklake: which MCP tool returns it, which tier, and the cost.

Canonical: https://www.stocklake.dev/blog/every-number-about-a-stock

This is a reference page, not an essay. If you are an agent deciding which tool to call, or a developer deciding whether a tier covers your use case, everything below was read off production responses on 4 September 2026 - not off a spec, and not off docs that might have drifted. Every field name listed here appeared in a real response.

## How to read this

Stocklake exposes **20 MCP tools**. Eleven work on the free tier; nine require Pro. The split is not "free gets a worse version of everything" - it is closer to *market data is open, synthesis is paid*. Prices, fundamentals, OHLCV history, the nine standard technical indicators, screening and market movers are all on the free tier at full fidelity. What Pro adds is the derived layer: composite scores, AI-written research, the scored insider and institutional read (free gets the filing facts), macro and sector assessments, the multi-year financial statements underneath the forensic scores (free gets the latest fiscal year), and the second set of nine technical indicators.

Free tier

44 fields

Pro tier

54 fields

get_stock's top-level field count by tier - the extra 10 are all derived, not raw market data

Two mechanics are worth knowing before the tables. First, **`tools/list` returns all 20 tools regardless of tier** - gating happens when you call, not when you enumerate. An agent that discovers the toolset on a free key will see nine tools it cannot yet use. Second, a Pro-gated call from a free key does not fail silently: it returns a structured `pro_required` object carrying a small real `preview` of the data, plus `your_tier`, `message`, `upgrade` and a `tell_your_user` string written for an agent to relay verbatim. That is a deliberate design choice - a paywall an agent can explain is more useful than one it can only report as an error.

Terms used throughout

Tier

guest (no key, 25 calls/day), free (key, 200/day), pro (key or OAuth, 5,000/day). Guest and free reach the same eleven tools; only the quota differs.

ai_score / ai_score_band

A 0-100 composite on a single stock, plus its bucket label (Moderate, Strong, …). Pro, on `get_stock`, `get_stocks`, `get_screener`, `get_market_movers`, `get_watchlist`, `get_earnings_intelligence`.

signal_score / signal_score_band

A different 0-100 score, attached to a flagged idea or a news article rather than to a company. Appears on `get_signals`, `get_news_feed`, `get_stock_news`, `get_insider_activity`.

rating

A 0-10 technical composite with a per-indicator breakdown. `direction` is `POSITIVE` / `NEUTRAL` / `NEGATIVE` - not bullish/bearish wording.

## The tool index

Free-tier tools

11 / 20

Pro-only tools

9 / 20

Every tool, its tier, the question it answers, and its hard ceiling. Parameters marked `*` are required; the rest show their default.

| Tool | Tier | Answers | Parameters | Ceiling |
|---|---|---|---|---|
| `get_stock` | Free | Everything about one company right now | `symbol*` | 1 symbol |
| `get_stocks` | Free | The same, for many symbols in one call | `symbols*` | 25 symbols |
| `get_stock_history` | Free | Daily OHLCV bars | `symbol*`, `days=90` | 365 days |
| `get_stock_news` | Free | Recent articles for one symbol | `symbol*`, `limit=10`, `days=30` | 50 / 90d (Pro) 5 / 30d (Free) |
| `get_screener` | Free | Which stocks match these filters | 18 filters, `preset`, `sort_by`, `limit=20` | 25 results |
| `get_market_movers` | Free | Today's gainers, losers, most active | `category=all`, `limit=10`, `min_market_cap_b` | 20 per category |
| `get_market_pulse` | Free | VIX, Fear & Greed, breadth, indices | - none - | - |
| `get_earnings_calendar` | Free | Who reports in the next N days | `days=7` | - |
| `get_stock_research` | Pro | One-call deep dive: stock + AI summary + news + sentiment + signals | `symbol*` | 1 symbol |
| `get_insider_activity` | Free | Insider filing facts; the scored read, institutional holders and the full year on Pro | `symbol*` | 1 symbol |
| `get_indicator_history` | Pro | How the indicators moved over time | `symbol*`, `days=90`, `full=False` | 730 days |
| `get_analyst_trend` | Pro | How analyst ratings and price targets moved over time | `symbol*`, `days=90` | 365 days |
| `get_stock_financials` | Free | Balance sheet, income statement, cash flow; latest fiscal year free, every year and quarter on Pro | `symbol*`, `period=annual`, `statement=all` | 5 years / ~8 quarters |
| `get_signals` | Pro | What the screeners flagged lately | `limit=25`, `min_signal_score=60`, `direction`, `source` | 50 results |
| `get_news_feed` | Pro | Market-wide scored news, not per symbol | `limit=10`, `days=3`, `min_signal_score=60` | 25 results |
| `get_market_assessment` | Pro | Macro regime and market outlook | `history_count=0` | - |
| `get_sector_intelligence` | Pro | One sector, or all 11 ranked | `sector`, `sort_by_strength=False`, `history_count=0` | 11 sectors |
| `get_earnings_intelligence` | Pro | Upcoming earnings with AI verdict and risks | `days_ahead=14`, `sector`, `min_ai_score`, `limit=25` | 25 results |
| `get_economic_calendar` | Free | Macro releases, past and upcoming; 7 days ahead free, 14 on Pro | `days=3`, `lookback_days=2`, `limit=20`, `major_only`, `key_events_only` | - |
| `get_watchlist` | Pro | The caller's own starred symbols | - none - | 500 saved |

Two easy-to-miss signature details. `get_earnings_calendar` takes **only** `days` - passing `limit` returns a validation error, not a truncated list. And `get_signals` still accepts `min_conviction` and `min_flag_score` for backwards compatibility, but **they no longer filter anything**: the real gate is `min_signal_score`, and the `filters` object echoed back in the response confirms which ones actually applied.

## Price, identity and fundamentals

All free, all on `get_stock` and `get_stocks`. Forty-four top-level fields, identical for a US mega cap and a European or Japanese listing - there is no reduced schema for international symbols.

| Group | Fields |
|---|---|
| Identity | `symbol` `name` `sector` `industry` `country` `currency` `exchange` `description` `website` `employees` `officers` |
| Price | `price` `prev_close` `change_pct` `volume` `avg_volume` `week52_high` `week52_low` `updated_at` |
| Valuation | `market_cap` `enterprise_value` `pe_trailing` `pe_forward` `price_to_book` `beta` |
| Profitability | `revenue_ttm` `revenue_growth` `earnings_growth` `gross_profit_ttm` `profit_margins` `operating_margins` `return_on_equity` |
| Balance sheet | `debt_to_equity` `free_cashflow` |
| Dividend | `dividend_rate` `dividend_yield` `ex_dividend_date` |
| Analysts | `analyst_rating` `analyst_rating_score` `analyst_target` `analyst_count` |
| Earnings | `earnings_date` `earnings_is_estimate` |

`earnings_is_estimate` is the one to read carefully: when true, `earnings_date` is a projection, not a confirmed date. And `currency` reports the currency of the quote you are being given, which for a US-listed depositary receipt of a European company is USD, not the home-market currency - check `country` and `exchange` together if that distinction matters to you.

## Technical indicators

Eighteen indicators sit under `indicators` on `get_stock`. Nine are free; nine more unlock on Pro. Each is a nested object, not a bare number - `macd` carries its line, signal and histogram; `bollinger_bands` carries upper, middle, lower and width.

| Tier | Keys under `indicators` |
|---|---|
| Free | `rsi` `macd` `bollinger_bands` `sma20` `sma50` `sma200` `ema20` `ema200` `atr_20` |
| Pro | `williams_r` `ultimate_osc` `vix_fix` `williams_ad` `td_sequential` `elliott_wave` `adx` `ichimoku` `squeeze` |

A Pro-only `signals` block sits alongside them, flattening the same readings into labelled verdicts - `rsi.signal` as `"neutral"`, `td_sequential.phase` as `"countdown_done"`, `vix_fix.percentile`, `williams_ad.divergence`, and an `overall` roll-up. An indicator with insufficient history returns `null` rather than being omitted, so a key you expect is always present.

### Indicators over time

`get_indicator_history` (Pro) returns daily snapshots, up to 730 days. Its default response is deliberately slim - seven fields per snapshot - because a 700-row response with fifteen fields each is a lot of context for an agent to carry. Pass `full=true` to restore the rest.

| Response | Per-snapshot fields |
|---|---|
| Default | `recorded_at` `price` `rsi` `macd_histogram` `bb_pct` `sma20` `sma200` |
| `full=true` | … plus `williams_r` `ultimate_osc` `vix_fix_value` `williams_ad_trend` `td_signal` `td_phase` `analyst_rating` `analyst_target` |

Note that `analyst_rating` and `analyst_target` are in the history payload - which makes this the way to see how analyst posture on a name has shifted, not just where it stands today. If fewer than three snapshots exist for a symbol the response comes back with an empty `snapshots` array and an explanatory `note`, rather than an error.

### Financial statements

`get_stock_financials` (latest fiscal year free, every year and quarter on Pro) is a separate tool from everything above, not a bigger field on `get_stock` - it returns the raw balance sheet, income statement and cash flow line items themselves, not a score derived from them. Where `forensic_scores` tells you a company's Altman Z-Score is 2.1, this tool is where you'd go to see the actual working-capital and total-assets figures that number was built from. `period` chooses `annual` (up to 5 fiscal years, the default), `quarterly` (roughly the last 7-8 quarters), or `both`; `statement` narrows to one of the three statements or returns all of them. Around 50-60 curated line items per statement, each shaped `{line_item: {period_end: value}}` - every available period for a line item comes back in one call, not just the latest one, so you can compute your own year-over-year deltas rather than requesting each year separately. Kept as its own tool deliberately: folding the full annual-plus-quarterly payload into `get_stock_research` would have roughly tripled that tool's response size for a use case most callers of it don't need.

### Price history

`get_stock_history` (free, up to 365 days) returns bars with `date`, `open`, `high`, `low`, `close`, `volume` - and a `source` field naming which feed that individual bar came from. Per-bar provenance is unusual to expose, and it exists because bars from different feeds can disagree on volume for the same session.

## Scores and synthesis

These are the Pro-only blocks on `get_stock` - six documented below, plus `signals` (a flattened view of the same technical readings, covered under indicators above). Together the seven span all ten Pro-only top-level fields (`ai_score` alone accounts for four: `ai_score`, `ai_score_band`, `ai_verdict`, `ai_headline`), and they answer genuinely different questions - it is worth not treating them as interchangeable "the AI's opinion".

| Block | Shape | What it actually is |
|---|---|---|
| `rating` | `score` 0-10, `direction`, `signals{}` | Technical composite. `signals` breaks out `rsi`, `williams_r`, `ultimate_osc`, `macd`, `bb`, `trend` - each with `text`, `value`, `strength`, `verdict`. No AI involved. |
| `ai_score` | int 0-100 | Company-level composite. Paired with `ai_score_band` (bucket label), `ai_verdict`, and `ai_headline` (one sentence). |
| `relative_strength` | `windows{}`, `verdict` | Five windows - `5d` `20d` `60d` `120d` `12m` - each with `stock_return_pct`, `rs_vs_spy`, `rs_vs_qqq`, `rs_vs_sector`, in percentage points. |
| `market_risk` | `beta_spy_1y`, `corr_spy_1y` | Trailing one-year beta and correlation against [SPY](https://www.stocklake.dev/stock/SPY), computed rather than sourced. |
| `forensic_scores` | `altman_z`, `piotroski_f`, `beneish_m`, `computed_at` | Three published accounting formulas. Each carries its own `score`, `note`, and where applicable a band (`strength`, `zone`). |
| `stance_signals` | array | Every independent read on the name, one row each: `source`, `stance`, `conviction`, `horizon`, `edge_quality`, `raw_label`, `as_of`. |

`stance_signals` is the one most worth understanding, because it is the only field that shows you disagreement. A single symbol typically returns five rows - `technical_rating`, `ai_summary` at two horizons, `insider_sentiment`, `analyst_consensus` - and they are not required to agree. A name can carry a `NEUTRAL` swing stance and a `POSITIVE` long-term stance simultaneously, each with its own `as_of` timestamp. For an agent, that is more honest input than a single blended verdict would be.

**If you're choosing between the two stock tools, here's the one thing that actually differs.** On Pro, `get_stock` returns 54 top-level fields for its one symbol; `get_stocks` returns 53 per symbol in the batch - a gap of exactly one field, and it's always the same one: `stance_signals` only ships on the single-symbol call, because assembling it needs a couple of extra per-symbol lookups that don't scale cleanly across a 25-symbol batch. Nothing else is thinner in a batch response - the nine Pro-only indicators and every other score block (`rating`, `ai_score`, `forensic_scores`, `relative_strength`, `market_risk`) come back identically for each symbol either way.

### The one-call research bundle

`get_stock_research` (Pro) is a different shape from everything above: a five-key envelope rather than a flat field list. `stock` holds a 17-field summary; `ai_summary` holds `verdict`, `ai_score`, `ai_score_band`, `summary`, `key_points[]`, `risks[]`, `headline`, `price_at_generation`, `generated_at`, plus `near_term` and `longer_term` objects each carrying their own `stance` and `confidence`; `news` and `signals` hold recent scored items; and `sentiment` holds `signal`, `signal_score`, `signal_score_band`, `insider_trend`, `institutional_pct`. The `price_at_generation` field matters - it tells you what the price was when the text was written, so you can judge whether the narrative has been overtaken by the tape.

get_stock / get_stocks

Flat top-level fields - 44 free, 54 on Pro

symbol

price

rating

ai_score

signals

indicators

market_risk

forensic_scores

relative_strength

stance_signals

get_stock_research

One five-key envelope, each key its own nested object

stock

17-field summary

ai_summary

verdict, key_points[], risks[], near_term, longer_term

news

recent scored articles

signals

recent scored signals

sentiment

insider_trend, institutional_pct

Same data universe, two different contracts - a flat field list on one call, a nested envelope on the other

## News and sentiment

This is where the tier difference is starkest, and it is worth being blunt about it. Free `get_stock_news` returns five articles from the last 30 days, and each article has exactly two fields. Pro returns up to 50 from the last 90 days, with six.

| Tier | Per-article fields | Ceiling |
|---|---|---|
| Free | `title` `published_at` | 5 articles / 30 days |
| Pro | `title` `published_at` `ai_sentiment` `ai_summary` `signal_score` `signal_score_band` | 50 articles / 90 days |

The free response carries a `tier_note` string naming what Pro would add, so an agent can tell a user exactly what it is missing without guessing. Requesting more than the tier ceiling is clamped silently - asking for `limit=80, days=400` on a free key returns 5 and 30, and the response echoes those numbers back, so you can always tell what you actually got.

`get_news_feed` (Pro) is the market-wide counterpart: same six article fields plus `symbol`, filtered by `min_signal_score` rather than by ticker - the tool to call when the question is "what is worth reading right now" rather than "what is being said about [NVDA](https://www.stocklake.dev/stock/NVDA)".

## Insider and institutional

`get_insider_activity` (filing facts free, the scored read on Pro). On Pro the top level carries `signal`, `signal_score`, `signal_score_band`, `insider_signal`, `inst_signal`, `summary`, `insider_buys`, `insider_sells`, `inst_ownership`, `total_holders`, `holder_count_divergence`, `updated_at`. Beneath that:

| Array | Fields per row |
|---|---|
| `transactions[]` | `date` `name` `role` `type` `shares` `price` `value` |
| `top_holders[]` | `name` `shares` `pct_held` `sources` `share_counts_by_source` |

The last two fields on a holder are the interesting ones: `sources` lists which filings agreed on that position, and `share_counts_by_source` shows the individual numbers. Where they disagree, `holder_count_divergence` flags it rather than picking a winner. The free-tier `preview` on this tool still returns real values for `signal`, `insider_signal`, `inst_signal`, `insider_buys` and `insider_sells` - enough to know whether the full call is worth making.

## Market and sector context

`get_market_pulse` is free and needs no arguments: `vix` as a bare number, `fear_greed` with `value` / `description` / `last_update`, `indices` with `spy` / `qqq` / `iwm`, `bonds_commodities` with `tlt` / `gld`, and a `breadth` object giving `universe_size`, `oversold_count`, `overbought_count`, `neutral_count` and each as a percentage.

`get_market_assessment` (Pro) returns 26 top-level fields. The regime side gives `regime`, `regime_bias`, `regime_bias_note`, `regime_confidence`, `regime_rationale`, `regime_strength`, `regime_stale`, `regime_updated_at`, `macro_score`, `macro_score_trend`, `risk_appetite_score`, `vix_at_assessment`. The outlook side gives `outlook`, `outlook_conviction`, `outlook_rationale`, `outlook_key_risk`, `outlook_stale`, `outlook_updated_at`, `preferred_sectors`, `avoided_sectors`, `key_risks`, `catalyst`, `watch_for`, `equity_view`. Plus an `indicators` object holding `breadth`, `macro_data`, `market_sentiment` and `volatility_term_structure`.

The two `_stale` booleans are load-bearing: they tell you the assessment has aged past its refresh window, which is a very different situation from it being current and merely unchanged. `macro_score_trend` gives `change_7d`, `change_30d` and a `direction` label, so you get the trajectory of the read without a second call.

`get_sector_intelligence` (Pro) returns `sector`, `signal`, `sector_score`, `sector_score_trend`, `strength_score`, `cycle_stage`, `rotation_signal`, `confidence`, `drivers`, `alert`, `updated_at` - plus a substantial `stats` block with `avg_rsi`, `rsi_distribution`, `rsi_percentile`, `avg_perf_1w_pct`, `avg_perf_1m_pct`, `perf_1m_percentile`, `cap_weighted_1m_pct`, `sma200_breadth_pct`, `top5_concentration_pct`, `overbought_pct`, `oversold_pct`, `median_market_cap_B`, `top_movers`, `bottom_movers`, `stocks`, `stocks_cleaned`, `outliers_excluded`. Omit `sector` to get all eleven; add `sort_by_strength=true` to get them ranked.

## Calendars

| Tool | Tier | Per-row fields |
|---|---|---|
| `get_earnings_calendar` | Free | `symbol` `name` `sector` `earnings_date` `is_estimate` `eps_forward` `eps_trailing` `price` `rsi` `market_cap` |
| `get_earnings_intelligence` | Pro | … the same ten, plus `ai_verdict` `ai_score` `ai_score_band` `ai_risks` `analyst_rating` `analyst_target` |
| `get_economic_calendar` | Free | `date` `time` `country` `event` `actual` `consensus` `previous` `key_event` |

The earnings pair is the cleanest illustration of the whole tier model: the free tool tells you *who reports and when*, the Pro tool adds *what to watch for*. The economic calendar splits its response into `released_recent`, `today` and `upcoming`, so a released event carries a real `actual` alongside its `consensus` and `previous`, and an upcoming one does not.

## What a call costs

Quotas are per calendar day, resetting at midnight UTC: **guest 25, free 200, Pro 5,000**. Guest needs no key at all - drop the `Authorization` header entirely and you are rate-limited by IP.

10

100

1,000

5,000

Guest

25

Free

200

Pro

5,000

Log scale, capped at Pro's own 5,000/day ceiling - a linear bar would make Guest and Free nearly invisible next to Pro's real 200x and 25x advantage

The part that surprises people: five tools bill **one call per ticker actually returned**, not one per request. A `get_stocks` call for 25 symbols costs 25 against your quota, not 1.

| Tool | Default | Hard cap | Over-cap behaviour |
|---|---|---|---|
| `get_stocks` | - | 25 | Returns a `batch_too_large` error - it does not silently truncate |
| `get_screener` | 20 | 25 | Clamped silently |
| `get_signals` | 25 | 50 | Clamped silently |
| `get_market_movers` | 10 | 20 per category | Clamped silently |
| `get_earnings_intelligence` | 25 | 25 | Clamped silently |

Two consequences worth planning around. `get_signals` defaults to 25 but will go to 50 if you ask - the default is deliberately lower than the ceiling to keep a typical response light, so you have to opt into the wider feed. And a Pro-gated batch tool called from a free key costs **1**, not the batch size: the request is rejected at the gate before it reaches the query, so exploring what you cannot access yet is cheap.

## Coverage, and where it thins out

Around 3,500 symbols across US, European and Asian listings. The schema does not change by region - [SAP](https://www.stocklake.dev/stock/SAP), [Toyota](https://www.stocklake.dev/stock/TM) and [BP](https://www.stocklake.dev/stock/BP) each return the same 54 Pro fields as NVIDIA, with populated `country`, `sector`, `relative_strength`, `ai_score` and `stance_signals`. What varies is *within* a field rather than across the field list.

`forensic_scores` is the honest example. Checked across four symbols, one returned all three formulas, one returned two, and two returned one apiece - the rest coming back as `{"score": null, "note": "..."}` with a plain-English explanation, most often that the company is a bank or insurer whose balance sheet does not carry the line items those formulas require. That is a real limit of the formulas, not a gap in the data, and the tool says so in the response rather than silently omitting the key. The same pattern holds elsewhere: `elliott_wave` is frequently `null` because a clean wave count often is not present, and `get_indicator_history` returns an empty array with a `note` when a symbol has fewer than three snapshots.

**The general rule for parsing any of this:** a `null` here means "we checked and there is no defensible value", not "we failed". Nulls arrive with an explanation wherever one exists. Code that treats a missing value as an error will be wrong more often than code that treats it as information.

## The honest caveat

This page was read off real responses on one specific day, and the surface it describes moves. Fields get added; defaults get tuned; a cap that reads 25 today was 50 four months ago. Everything here is accurate as of 4 September 2026 and was verified field by field against production, but if you are building something that depends on an exact field being present, call `tools/list` and read one real response rather than trusting any prose - including this. Nothing on this page is a recommendation about any security; it is a description of what an MCP tool returns.

## Frequently asked questions

Which tool should I call: get_stock, get_stocks, or get_stock_research?

`get_stock` for one symbol when you want every field, including `stance_signals`. `get_stocks` for several symbols at once - it costs one call per symbol either way, so batching is about round trips, not billing. `get_stock_research` when you specifically want the written AI narrative (`summary`, `key_points`, `risks`) plus recent news and signals bundled into one response - it has a different shape from the other two, not just more fields.

Do free and guest tiers see a different set of tools?

No - `tools/list` returns all 19 regardless of tier, and gating happens on the call, not on discovery. A free key calling a Pro-only tool gets a structured `pro_required` response with a real (truncated) data preview, not a bare error.

Why does a field come back null instead of just being missing from the response?

By design. An explicit `null` is something your code can check for; a key that silently isn't there depends on you already knowing to look for its absence. Wherever a null has a reason - a bank that can't carry a forensic score, a symbol too new for `get_indicator_history` - the response explains it in a `note` alongside the null.

Does the international coverage (SAP, Toyota, BP) use a smaller schema?

No. Every symbol on Pro returns the same 54 top-level fields regardless of exchange or country - what differs between a US mega cap and a European or Asian listing is which individual fields happen to be populated, never the shape of the response itself.

Will this field list still be accurate next month?

Treat it as a snapshot, not a contract. Fields get added, defaults get retuned, and a ceiling that reads 25 today has been a different number before. Call `tools/list` and read one real response if your code depends on an exact field being present.
