Skip to main content
Glama

get_latest_report

Read-only

Get the latest Flexreport research report(s) for one or more tickers. USE THIS BY DEFAULT.

===> THIS IS THE DEFAULT, CORRECT TOOL whenever a user asks for "the report",
"research", "the latest research", "analysis", "a writeup", or "the PDF" for a
ticker (e.g. "get me the latest research on SNOW"). It is the FAST path, and it
only FETCHES: every material event writes the symbol's report as it happens, so
this returns the latest document in seconds, with metadata saying how current it
is. Nothing is built here. ALWAYS call this before `generate_report_for_stock`,
which writes a new note (a few minutes).

If the user's intent is an OPEN-ENDED or exploratory QUESTION rather than a request
for this existing report, do NOT use this tool — default to `explore_data_catalogue`
(fast, interactive), and reach for `generate_research_report` only when the user
EXPLICITLY asks for a full deep-dive writeup. A BESPOKE report ("the SNOW report,
but built around product revenue and RPO") is not a new note either: explore the
items the user named, ideate with them on the result sets, and lay the agreed
results out in their template (`get_user_template`) with your own document tooling.

Accepts one OR many symbols. Returns
{"result":    [{"symbol": "AAPL", "url": "<presigned pdf url>",
                "generated_at": "<iso utc>", "age_hours": 5.2,
                "latest_event_at": "<iso>", "stale": true,
                "template": "default"}, ...],
 "missing":   ["XYZ", ...],
 "stale_symbols": ["AAPL", ...],
 "rendering": {}}
Every symbol lands in exactly ONE of `result` / `missing`; `stale_symbols` lists the
`result` symbols flagged `stale: true`; `rendering` is always empty (kept for older
clients). `template` is "user" when the PDF is the caller's own copy in their saved
template, "default" for the platform layout. Split a list longer than 100 symbols
across calls.

THE PDF IS BEHIND `url`, not in this response: a presigned link valid ~6h from this
call.
  - To GIVE the user the report: hand them the link to open or download.
  - To READ it yourself: download the link (an HTTP / web fetch, or
    `curl -o <SYMBOL>.pdf "<url>"`) and open the PDF; a client that renders PDF
    pages also sees the charts. Quote the report from what you read, not from the
    metadata here.
  - The link serves the symbol's report file as it is when fetched. After ~6h, or
    to pick up a newer report, call this tool again for a fresh link; never edit
    or build a URL.
  - A client that cannot fetch a URL but can run code: download_pdf_from_url(url)
    returns the same PDF as base64 to decode.

READ EACH SYMBOL'S FLAG BEFORE YOU HAND ANYTHING OVER:
  stale: false   -> the PDF reflects the symbol's latest event. Serve it.
  stale: true    -> an event landed after this PDF (`latest_event_at` says when).
                    If that was only minutes ago, the event's own report is probably
                    still being written: say so, and fetch again in a few minutes
                    (or wait for its `report_plan` frame). Otherwise hand over the
                    PDF with that caveat and offer generate_report_for_stock(ticker),
                    which writes a new note in a few minutes. Start it when the user
                    wants it; never fan it out across a list of names unasked.
  stale: null    -> no report inputs are known for the symbol, so freshness cannot
                    be judged. Serve the PDF and quote `generated_at` / `age_hours`.
  in `missing`   -> no report yet. generate_report_for_stock(ticker) writes the first
                    one (a few minutes; later calls here return it) — say so before
                    starting it — or `onboard_symbol` if the ticker is not covered.
To see which symbols have a CURRENT report — by the event that produced it, across
the universe, before anything is pulled — use `list_available_reports`.

Rate-limited to 500/hour. Requires auth (your MCP client attaches the OAuth bearer
automatically).

Input Schema

NameRequiredDescriptionDefault
symbolsYesOne or many tickers, e.g. ["SNOW", "AAPL"]; uppercased and de-duplicated server-side, at most 100 after dedupe (413 above that).

Output Schema

NameRequiredDescriptionDefault
resultNoSymbols served from the cached PDF.
missingNoSymbols with no report written yet.
renderingNoAlways empty: reports are written at event time and nothing renders on fetch. Kept for older clients.
stale_symbolsNoThe `result` symbols flagged stale: true.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$defs": {
      +    "CachedReport": {
      +      "additionalProperties": true,
      +      "properties": {
      +        "age_hours": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "Hours since generated_at.",
      +          "title": "Age Hours"
      +        },
      +        "generated_at": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "When the cached PDF was built (ISO UTC).",
      +          "title": "Generated At"
      +        },
      +        "latest_event_at": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "Timestamp of the symbol's latest report inputs (the event).",
      +          "title": "Latest Event At"
      +        },
      +        "stale": {
      +          "anyOf": [
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "True: the PDF predates the latest event. False: it reflects it. Null: freshness unknown.",
      +          "title": "Stale"
      +        },
      +        "symbol": {
      +          "title": "Symbol",
      +          "type": "string"
      +        },
      +        "template": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "\"user\": the caller's own copy in their saved template. \"default\": the platform layout.",
      +          "title": "Template"
      +        },
      +        "url": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "Presigned link to the PDF, valid ~6h from the call. Download it to read the report; hand it to the user to open. Call get_latest_report again for a fresh link; never edit one.",
      +          "title": "Url"
      +        }
      +      },
      +      "required": [
      +        "symbol"
      +      ],
      +      "title": "CachedReport",
      +      "type": "object"
      +    },
      +    "ReportTask": {
      +      "additionalProperties": true,
      +      "properties": {
      +        "status": {
      +          "description": "Task state at dispatch, normally \"PENDING\".",
      +          "title": "Status",
      +          "type": "string"
      +        },
      +        "symbol": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "default": null,
      +          "description": "Ticker the report task renders.",
      +          "title": "Symbol"
      +        },
      +        "task_id": {
      +          "description": "Celery task id; poll it with get_task_status until SUCCESS.",
      +          "title": "Task Id",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "task_id",
      +        "status"
      +      ],
      +      "title": "ReportTask",
      +      "type": "object"
      +    }
      +  },
      +  "additionalProperties": true,
      +  "properties": {
      +    "missing": {
      +      "description": "Symbols with no report written yet.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "title": "Missing",
      +      "type": "array"
      +    },
      +    "rendering": {
      +      "additionalProperties": {
      +        "$ref": "#/$defs/ReportTask"
      +      },
      +      "description": "Always empty: reports are written at event time and nothing renders on fetch. Kept for older clients.",
      +      "title": "Rendering",
      +      "type": "object"
      +    },
      +    "result": {
      +      "description": "Symbols served from the cached PDF.",
      +      "items": {
      +        "$ref": "#/$defs/CachedReport"
      +      },
      +      "title": "Result",
      +      "type": "array"
      +    },
      +    "stale_symbols": {
      +      "description": "The `result` symbols flagged stale: true.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "title": "Stale Symbols",
      +      "type": "array"
      +    }
      +  },
      +  "title": "CachedReportsResult",
      +  "type": "object"
      +}
  2. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only supply readOnlyHint=true; the description adds substantial context beyond that: it FETCHES and never builds, returns in seconds, rate limit of 500/hour, OAuth bearer required, and the URL is a presigned link valid ~6h after which a fresh call is required. It also warns never to edit or construct a URL, which prevents a realistic failure mode.

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

Conciseness4/5

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

Front-loaded with the decisive 'USE THIS BY DEFAULT' line, then triggers, then exclusions, then response semantics. It is long, but nearly every block maps to a real decision (stale flag handling, PDF access, list splitting). Minor redundancy: the inline JSON response shape overlaps with the existing output schema.

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?

Covers the full lifecycle an agent must handle: symbol partitioning into `result`/`missing`, stale-true/false/null handling with a recommended next action, 6h link expiry, download-and-read vs hand-the-link distinction, and the >100-symbol split rule. Nothing needed to call this correctly is missing.

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% and the single `symbols` parameter is already documented (uppercased, de-duplicated, max 100), so the baseline is 3. The description adds operational meaning with 'Split a list longer than 100 symbols across calls', which tells the agent how to recover from the documented 413 rather than just what the limit is.

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 specific verb and resource ('Get the latest Flexreport research report(s) for one or more tickers') and immediately differentiates itself from siblings: it is the default fetch path, not `generate_report_for_stock`, `generate_research_report`, `explore_data_catalogue`, or `list_available_reports`. An agent can route correctly without opening any 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 triggers ('the report', 'research', 'the latest research', 'analysis', 'a writeup', 'the PDF'), explicit when-NOT (open-ended/exploratory questions go to `explore_data_catalogue`; bespoke writeups go to template tooling), and ordering guidance ('ALWAYS call this before `generate_report_for_stock`'). This is as close to a routing decision table as a description gets.

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.

Resources