Skip to main content
Glama

stream_events

Read-only

Listen for realtime events as they publish — a bounded read of the backend's ad-hoc SSE stream (GET /events), filter passed inline, nothing saved server-side.

DEFAULT DELIVERY — BUILD A DASHBOARD: when the user asks to stream / watch / keep
listening for live events, build a live dashboard (in Claude, an Artifact) whose
page calls this tool in its own loop, carrying `cursor` from read to read, and
renders each event as it lands. One prompt then keeps the stream open with no agent
turn per read. If the page cannot reach this server, run the loop yourself and write
each event into the dashboard's shared store. Stream into chat only when the user
asks for that, or the client cannot render a dashboard.

Returns {"events": [...], "cursor": "<last id seen>", "closed": null | reason,
"elapsed_seconds": n}. Each item in `events` is the same object `list_realtime_events` returns for that
type ({event_type, symbol, payload, published_at, id}) — summary, thesis impact,
significant changes, citations — the moment it publishes, no polling of the 12h
cache. There is NO PDF link on an event: the event's report lands a few minutes
later, announced on the `report_plan` topic, and get_latest_report([symbol]) then
returns it (stale or missing with no report on the way -> generate_report_for_stock,
ticker only).

THE LOOP: a call returns after `max_events` matched events or `max_wait_seconds`
(cap 55 s), whichever comes first — call it again to keep listening, and ALWAYS
pass the returned `cursor` back in: this stream keeps no state, so without it
the next call starts at "now" and drops whatever published in between. The
cursor advances on heartbeats too (events the filter dropped), so an empty
`events` list with a moved cursor is normal on a quiet tape. Omit `cursor` on
the first call to start at now. For a subscription that resumes by itself, use
register_event_subscription + stream_event_subscription instead.

`topics` (optional, any mix; case-insensitive):
  - an event type from list_options("event_types") — eps_update, 8k_release,
    transcript_update, ir_publication, biggest_mover, 13f_new, strategy_update, ...
  - a family from the same listing — earnings, news, market_movement,
    institutional_ownership, analyst_activity, strategy, prediction — which
    matches every type in it, including types added later;
  - `report_plan` (stream-only): a frame each time a symbol's new report is
    PUBLISHED — its document is already written ({symbol, event_type, planned_at,
    queued_at, plan_key, report_key}); the next step is get_latest_report([symbol]),
    which returns it (`stale: false`). Subscribe to it to stream research as it is
    written.
`symbols` (optional): tickers; 13f_* filer events carry the filer's CIK in the
symbol slot. No topics and no symbols = everything. Unknown topic -> 422 with the
allowed lists in `detail`.

`closed` set means the server ended the stream — do not reconnect with that id.
Requires auth (your MCP client attaches the OAuth bearer automatically).

Input Schema

NameRequiredDescriptionDefault
cursorNoThe `cursor` returned by the previous read; resume after it. Omit to start at now.
topicsNoEvent types or families from list_options("event_types") (e.g. "eps_update", "earnings"), plus the stream-only "report_plan"; case-insensitive. Omit for every topic.
symbolsNoTickers to listen for (13f_* filer events carry the filer's CIK in the symbol slot). Omit for every symbol.
max_eventsNoReturn after this many matched events (clamped to 1-200).
max_wait_secondsNoReturn after this many seconds even if fewer events arrived (clamped to 1-55).

Output Schema

NameRequiredDescriptionDefault
closedNoSet when the server ended the stream (e.g. "subscription deleted"); do not reconnect.
cursorNoLast stream id seen (advances on heartbeats too). Pass it back on the next call; null only when no frame carried an id and none was passed in.
eventsYesMatched events in publish order; empty on a quiet tape. A frame whose data was not JSON comes through as {"raw": <text>}.
elapsed_secondsYesWall time this read held the stream open.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare readOnlyHint=true, and the description is fully consistent while adding substantially more: bounded read semantics, the 55s cap, statelessness of the stream, cursor advancement on heartbeats, the meaning of `closed`, and the OAuth requirement. It also explains downstream behavior (no PDF on an event; report arrives later via `report_plan` + `get_latest_report`) that no annotation conveys.

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 purpose, then labeled sections (DEFAULT DELIVERY, THE LOOP, topics, symbols, closed) so a reader can skim to what matters. It is long and includes delivery-policy instructions (build an Artifact) that sit somewhat outside pure tool description, but nearly every sentence carries operational information an agent needs to loop correctly.

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?

Although an output schema exists, the description still spells out the return contract (`events`, `cursor`, `closed`, `elapsed_seconds`) and what an event item is, plus the loop protocol needed to keep listening without data loss. Auth, error behavior, and termination semantics are all covered, so nothing an agent needs 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%, so the baseline would be 3; the description earns more by explaining that `topics` accepts families that match future types, that `report_plan` is stream-only with its own payload shape, and that 13f filer events put a CIK in the `symbols` slot. It also documents failure behavior (unknown topic -> 422 with allowed lists) and the heartbeat-driven cursor advance, which the schema cannot express. It stops short of full coverage only because the schema already restates much of the cursor/topic semantics.

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 ('Listen for realtime events as they publish') plus the underlying mechanism ('ad-hoc SSE stream `GET /events`') and the non-persistent scope ('nothing saved server-side'). It explicitly contrasts with `list_realtime_events` (no polling of the 12h cache) and with `register_event_subscription` + `stream_event_subscription`, so an agent can distinguish it from siblings without opening schemas.

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 rules ('when the user asks to stream / watch / keep listening') and a default delivery pattern (build a dashboard, fall back to agent-run loop, stream into chat only when asked or when the client cannot render). It also names the alternative for stateful resumption: 'For a subscription that resumes by itself, use register_event_subscription + stream_event_subscription instead.'

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