Skip to main content
Glama

tickerbot_list_events

One timeline across every ticker: earnings, dividends, splits, insider filings, analyst actions, plus opt-in signal firings and news. Requires at least one bound: a ticker scope (ticker/tickers/universe), a time window (from/to), or firm/action — q alone is not a bound. firm/action match case-insensitively; a q payload match is case-sensitive. join: state attaches the ticker state as of each event.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qNoSQL WHERE over the projection — `ticker`, `ts`, `kind`, `payload` (plus ticker-state signals when `join=state`). When exactly ONE `kind` is named, that kind's payload fields are additionally first-class typed columns (`amount > 1`, `firm = 'Goldman Sachs'` — see each kind page for its list); multi-kind requests use `payload->>'…'`. Max 4000 chars. ANDs with the filter params.
toNoWindow end — same strict ISO subset. A bare `YYYY-MM-DD` means through the end of that day, matching bars/series/spans; a timestamp is exclusive (events strictly before it). (`until` accepted as an alias.)
dirNoAggregate-mode sort direction.desc
firmNoAnalyst-only structured filter — requires `kind=analyst` alone (`400` otherwise). Exact firm-name match on the ratings feed.
fromNoEvents at/after this instant — strict ISO: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM[:SS]Z`. A bare `YYYY-MM-DD` means from the start of that day. (`since` accepted as an alias.)
joinNoSet to `state` to allow ticker-state signals in `q`/`select`/`group_by`/`having`, evaluated as of each event's timestamp (daily resolution).
kindNoComma list of kinds. Omitted → the five corporate kinds; `signal` and `news` join only when named here.
limitNoPage size (row modes) / max rollup rows (aggregate mode). Max 1000.
orderNoAggregate-mode sort — a bare column name or an output name only (put expressions in `select` and sort by their alias). A group key's name works too, whether you aliased it or it was named for you: `group_by=payload->>'firm' AS firm&order=firm`. Default: `events`. (Row mode is always newest-first.)
actionNoAnalyst-only structured filter — requires `kind=analyst` alone. Same `action` vocabulary as Analyst actions.
cursorNoOpaque cursor from the previous response — carries the original filters (and `q` when short), so pass it alone. Not valid with `group_by`.
havingNoPost-aggregation filter. Requires `group_by`.
selectNoAggregate-mode output columns (requires `group_by`). Default: group keys + `COUNT(*) AS events`. Same naming rule as `group_by` — alias with `AS`, or take the name derived for you.
signalNoSignal-only filter — requires `kind=signal` alone (`400` otherwise). One built-in boolean signal; REQUIRED with `q` or `join=state` on that kind. See Signal firings.
tickerNoSingle-ticker filter. When both `ticker` and `tickers` are passed, `ticker` wins.
tickersNoComma list of tickers (max 50). Mutually exclusive with `universe`.
group_byNoComma list of rollup keys — switches the response to aggregate rows. Columns (`kind`, `ticker`), payload fields (`firm`, or the explicit `payload->>'firm'`), and expressions over them all roll up. Name a key with `AS` to choose its JSON key: `payload->>'firm' AS firm`. Un-named keys are named for you — a payload read takes its key (`payload->>'firm'` → `firm`), a function keeps the function's name (`lower(ticker)` → `lower`), and anything else falls back to `group_1`, `group_2`.
intervalNoGrain the per-event state is reconstructed at, when `join=state`: `1m`, `1h`, `1d`, or `auto` (default). `auto` resolves to `1d` — the event set's tickers are not known before the query runs, and `1d` is the only tier covering the whole universe, so it is the only grain guaranteed to satisfy every event. An explicit `1m`/`1h` trades coverage for precision: events on tickers absent from that tier join to `null`. A referenced column the grain does not store is a `400`. Reported back as `_meta.state_interval`.auto
universeNoUniverse slug (`top_10`, `top_100`, or one of yours) to scope the stream. Mutually exclusive with `tickers`.
transitionNoSignal-only filter — requires `kind=signal` alone. `enter` (false→true) or `exit` (true→false).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
as_ofYesServer time this response was assembled (ISO 8601).
countYesRows in this page.
queryYesYour filters, echoed exactly as you sent them — `q`, `select`, `group_by` and `having` come back in your spelling, not the SQL they compile to — including `join` and its grain when you passed `join=state`.
resultsYesOne row per event (`ticker`, `ts`, `kind`, `payload`), or rollup rows plus `truncated: true` when an aggregate exceeds `limit`.
truncatedNoAggregate mode only (`group_by`): `true` when the rollup stopped at its row cap. Aggregate responses are unpaged, so `next_cursor` is absent there.
next_cursorNoOpaque token for the next page; `null` on the last page. Carries `q_truncated: true` alongside it when an oversized `q` could not ride the token — resend `q` on later pages.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "as_of": {
      +      "description": "Server time this response was assembled (ISO 8601).",
      +      "type": "string"
      +    },
      +    "count": {
      +      "description": "Rows in this page.",
      +      "type": "number"
      +    },
      +    "next_cursor": {
      +      "description": "Opaque token for the next page; `null` on the last page. Carries `q_truncated: true` alongside it when an oversized `q` could not ride the token — resend `q` on later pages.",
      +      "type": "string"
      +    },
      +    "query": {
      +      "description": "Your filters, echoed exactly as you sent them — `q`, `select`, `group_by` and `having` come back in your spelling, not the SQL they compile to — including `join` and its grain when you passed `join=state`.",
      +      "type": "object"
      +    },
      +    "results": {
      +      "description": "One row per event (`ticker`, `ts`, `kind`, `payload`), or rollup rows plus `truncated: true` when an aggregate exceeds `limit`.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "truncated": {
      +      "description": "Aggregate mode only (`group_by`): `true` when the rollup stopped at its row cap. Aggregate responses are unpaged, so `next_cursor` is absent there.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "as_of",
      +    "query",
      +    "count",
      +    "results"
      +  ],
      +  "type": "object"
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / kind / enum
      Previous value: -[
      -  "earnings",
      -  "dividend",
      -  "split",
      -  "insider",
      -  "analyst",
      -  "news",
      -  "signal"
      -]New value: +[
      +  "dividend",
      +  "split",
      +  "insider",
      +  "analyst",
      +  "earnings",
      +  "signal",
      +  "news"
      +]
  3. Changed25 schema fields changed
    • changedInput schema / properties / action / description
      Previous value: -"kind=analyst only. Exact rating-action filter."New value: +"Analyst-only structured filter — requires `kind=analyst` alone. Same `action` vocabulary as Analyst actions."
    • changedInput schema / properties / cursor / description
      Previous value: -"Opaque cursor from a prior response — carries the original filters, pass it alone (long q values must be resent alongside it)."New value: +"Opaque cursor from the previous response — carries the original filters (and `q` when short), so pass it alone. Not valid with `group_by`."
    • addedInput schema / properties / dir / default
      Added value: +"desc"
    • changedInput schema / properties / firm / description
      Previous value: -"kind=analyst only. Case-insensitive analyst-firm filter (e.g. \"Goldman Sachs\" matches \"goldman sachs\") — prefer this over a q payload match, which is case-sensitive."New value: +"Analyst-only structured filter — requires `kind=analyst` alone (`400` otherwise). Exact firm-name match on the ratings feed."
    • changedInput schema / properties / from / description
      Previous value: -"Events at or after this ISO date/datetime (inclusive; a bare YYYY-MM-DD means from the start of that day). `since` accepted as alias."New value: +"Events at/after this instant — strict ISO: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM[:SS]Z`. A bare `YYYY-MM-DD` means from the start of that day. (`since` accepted as an alias.)"
    • changedInput schema / properties / group_by / description
      Previous value: -"Comma list of rollup keys — switches to aggregate rows, e.g. payload->>'firm' AS firm, or kind. `AS` names the JSON key; an un-named payload read is keyed by its payload key (payload->>'firm' -> firm)."New value: +"Comma list of rollup keys — switches the response to aggregate rows. Columns (`kind`, `ticker`), payload fields (`firm`, or the explicit `payload->>'firm'`), and expressions over them all roll up. Name a key with `AS` to choose its JSON key: `payload->>'firm' AS firm`. Un-named keys are named for you — a payload read takes its key (`payload->>'firm'` → `firm`), a function keeps the function's name (`lower(ticker)` → `lower`), and anything else falls back to `group_1`, `group_2`."
    • changedInput schema / properties / having / description
      Previous value: -"Post-aggregation filter (requires group_by), e.g. COUNT(*) > 5."New value: +"Post-aggregation filter. Requires `group_by`."
    • addedInput schema / properties / interval / default
      Added value: +"auto"
    • changedInput schema / properties / interval / description
      Previous value: -"Grain for join=state replay (finest covering tier by default)."New value: +"Grain the per-event state is reconstructed at, when `join=state`: `1m`, `1h`, `1d`, or `auto` (default). `auto` resolves to `1d` — the event set's tickers are not known before the query runs, and `1d` is the only tier covering the whole universe, so it is the only grain guaranteed to satisfy every event. An explicit `1m`/`1h` trades coverage for precision: events on tickers absent from that tier join to `null`. A referenced column the grain does not store is a `400`. Reported back as `_meta.state_interval`."
    • changedInput schema / properties / interval / enum
      Previous value: -[
      -  "1m",
      -  "1h",
      -  "1d"
      -]New value: +[
      +  "1m",
      +  "1h",
      +  "1d",
      +  "auto"
      +]
    • changedInput schema / properties / join / description
      Previous value: -"join=state attaches each event's ticker STATE as of that event's moment (the replay join) under a `state` key — \"downgrades where rsi_14 was already under 40\" composes with q. Free on every plan."New value: +"Set to `state` to allow ticker-state signals in `q`/`select`/`group_by`/`having`, evaluated as of each event's timestamp (daily resolution)."
    • changedInput schema / properties / kind / description
      Previous value: -"Comma list of kinds to include. Default is the four corporate kinds: dividend, split, insider, analyst. Two more are opt-in and join only when named: `signal` (boolean firings) and `news`."New value: +"Comma list of kinds. Omitted → the five corporate kinds; `signal` and `news` join only when named here."
    • addedInput schema / properties / kind / enum
      Added value: +[
      +  "earnings",
      +  "dividend",
      +  "split",
      +  "insider",
      +  "analyst",
      +  "news",
      +  "signal"
      +]
    • addedInput schema / properties / limit / default
      Added value: +50
    • changedInput schema / properties / limit / description
      Previous value: -"Page size. Max 1000."New value: +"Page size (row modes) / max rollup rows (aggregate mode). Max 1000."
    • removedInput schema / properties / merge_gap_seconds
      Removed value: -{
      -  "description": "kind=signal only, with `signal` AND `tickers` set (filter mode — no q/join/group_by). Interval-union before unpivoting: runs of the boolean separated by ≤ N seconds collapse into one, so a boolean with thousands of per-tick fragments yields one enter and one exit per real run (3600 for hourly booleans, 86400 for daily). Default 0 = raw fragments. A cursor pins this; resend it unchanged when paging.",
      -  "type": "integer"
      -}
    • changedInput schema / properties / order / description
      Previous value: -"Aggregate-mode sort column/alias. Default: events."New value: +"Aggregate-mode sort — a bare column name or an output name only (put expressions in `select` and sort by their alias). A group key's name works too, whether you aliased it or it was named for you: `group_by=payload->>'firm' AS firm&order=firm`. Default: `events`. (Row mode is always newest-first.)"
    • changedInput schema / properties / q / description
      Previous value: -"SQL WHERE over (ticker, ts, kind, payload jsonb) — ONLY those four identifiers. Payload fields via jsonb operators: payload->>'firm' = 'Goldman Sachs', (payload->>'shares')::numeric > 1e6. On kind=signal this requires `signal` (the firing log is ~175M rows); kind=signal takes no group_by."New value: +"SQL WHERE over the projection — `ticker`, `ts`, `kind`, `payload` (plus ticker-state signals when `join=state`). When exactly ONE `kind` is named, that kind's payload fields are additionally first-class typed columns (`amount > 1`, `firm = 'Goldman Sachs'` — see each kind page for its list); multi-kind requests use `payload->>'…'`. Max 4000 chars. ANDs with the filter params."
    • changedInput schema / properties / select / description
      Previous value: -"Aggregate-mode output columns (requires group_by). Default: group keys + COUNT(*) AS events."New value: +"Aggregate-mode output columns (requires `group_by`). Default: group keys + `COUNT(*) AS events`. Same naming rule as `group_by` — alias with `AS`, or take the name derived for you."
    • changedInput schema / properties / signal / description
      Previous value: -"kind=signal only. One built-in boolean signal (e.g. golden_cross). REQUIRED to use `q` or `join` on kind=signal — naming the signal is what keeps the query on an index; optional otherwise."New value: +"Signal-only filter — requires `kind=signal` alone (`400` otherwise). One built-in boolean signal; REQUIRED with `q` or `join=state` on that kind. See Signal firings."
    • changedInput schema / properties / ticker / description
      Previous value: -"Single-ticker filter, e.g. AAPL."New value: +"Single-ticker filter. When both `ticker` and `tickers` are passed, `ticker` wins."
    • changedInput schema / properties / tickers / description
      Previous value: -"Comma-separated tickers, max 50. Mutually exclusive with `universe`."New value: +"Comma list of tickers (max 50). Mutually exclusive with `universe`."
    • changedInput schema / properties / to / description
      Previous value: -"Window end: a bare YYYY-MM-DD means through the END of that day (matching bars/series/spans); a timestamp is exclusive — events strictly before it. `until` accepted as alias."New value: +"Window end — same strict ISO subset. A bare `YYYY-MM-DD` means through the end of that day, matching bars/series/spans; a timestamp is exclusive (events strictly before it). (`until` accepted as an alias.)"
    • changedInput schema / properties / transition / description
      Previous value: -"kind=signal only. `enter` (false->true) or `exit` (true->false). Always optional — an ordinary filter."New value: +"Signal-only filter — requires `kind=signal` alone. `enter` (false→true) or `exit` (true→false)."
    • changedInput schema / properties / universe / description
      Previous value: -"Universe slug (top_10, top_100, or a saved one) to scope the stream. Mutually exclusive with `tickers`."New value: +"Universe slug (`top_10`, `top_100`, or one of yours) to scope the stream. Mutually exclusive with `tickers`."
  4. Changed2 schema fields changed
    • changedInput schema / properties / kind / description
      Previous value: -"Comma list of kinds to include. Default is the four corporate kinds: dividend, split, insider, analyst. Two more are opt-in and join only when named: `signal` (boolean-flag firings) and `news`."New value: +"Comma list of kinds to include. Default is the four corporate kinds: dividend, split, insider, analyst. Two more are opt-in and join only when named: `signal` (boolean firings) and `news`."
    • changedInput schema / properties / merge_gap_seconds / description
      Previous value: -"kind=signal only, with `signal` AND `tickers` set (filter mode — no q/join/group_by). Interval-union before unpivoting: runs of the flag separated by ≤ N seconds collapse into one, so a flag with thousands of per-tick fragments yields one enter and one exit per real run (3600 for hourly flags, 86400 for daily). Default 0 = raw fragments. A cursor pins this; resend it unchanged when paging."New value: +"kind=signal only, with `signal` AND `tickers` set (filter mode — no q/join/group_by). Interval-union before unpivoting: runs of the boolean separated by ≤ N seconds collapse into one, so a boolean with thousands of per-tick fragments yields one enter and one exit per real run (3600 for hourly booleans, 86400 for daily). Default 0 = raw fragments. A cursor pins this; resend it unchanged when paging."
  5. Changed2 schema fields changed
    • addedInput schema / properties / merge_gap_seconds
      Added value: +{
      +  "description": "kind=signal only, with `signal` AND `tickers` set (filter mode — no q/join/group_by). Interval-union before unpivoting: runs of the flag separated by ≤ N seconds collapse into one, so a flag with thousands of per-tick fragments yields one enter and one exit per real run (3600 for hourly flags, 86400 for daily). Default 0 = raw fragments. A cursor pins this; resend it unchanged when paging.",
      +  "type": "integer"
      +}
    • changedInput schema / properties / signal / description
      Previous value: -"kind=signal only. One built-in boolean flag (e.g. golden_cross). REQUIRED to use `q` or `join` on kind=signal — naming the signal is what keeps the query on an index; optional otherwise."New value: +"kind=signal only. One built-in boolean signal (e.g. golden_cross). REQUIRED to use `q` or `join` on kind=signal — naming the signal is what keeps the query on an index; optional otherwise."
  6. Changed1 schema field changed
    • changedInput schema / properties / group_by / description
      Previous value: -"Comma list of rollup keys — switches to aggregate rows, e.g. payload->>'firm' AS firm, or kind."New value: +"Comma list of rollup keys — switches to aggregate rows, e.g. payload->>'firm' AS firm, or kind. `AS` names the JSON key; an un-named payload read is keyed by its payload key (payload->>'firm' -> firm)."
  7. Changed4 schema fields changed
    • addedInput schema / properties / action
      Added value: +{
      +  "description": "kind=analyst only. Exact rating-action filter.",
      +  "enum": [
      +    "upgrades",
      +    "downgrades",
      +    "initiates_coverage_on",
      +    "maintains",
      +    "reiterates",
      +    "assumes",
      +    "reinstates",
      +    "suspends",
      +    "terminates_coverage_on"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / firm
      Added value: +{
      +  "description": "kind=analyst only. Case-insensitive analyst-firm filter (e.g. \"Goldman Sachs\" matches \"goldman sachs\") — prefer this over a q payload match, which is case-sensitive.",
      +  "type": "string"
      +}
    • changedInput schema / properties / from / description
      Previous value: -"Events at or after this ISO date/datetime (inclusive). `since` accepted as alias."New value: +"Events at or after this ISO date/datetime (inclusive; a bare YYYY-MM-DD means from the start of that day). `since` accepted as alias."
    • changedInput schema / properties / to / description
      Previous value: -"Events strictly before this ISO date/datetime (exclusive). `until` accepted as alias."New value: +"Window end: a bare YYYY-MM-DD means through the END of that day (matching bars/series/spans); a timestamp is exclusive — events strictly before it. `until` accepted as alias."
  8. Changed6 schema fields changed
    • addedInput schema / properties / from
      Added value: +{
      +  "description": "Events at or after this ISO date/datetime (inclusive). `since` accepted as alias.",
      +  "type": "string"
      +}
    • addedInput schema / properties / interval
      Added value: +{
      +  "description": "Grain for join=state replay (finest covering tier by default).",
      +  "enum": [
      +    "1m",
      +    "1h",
      +    "1d"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / join
      Added value: +{
      +  "description": "join=state attaches each event's ticker STATE as of that event's moment (the replay join) under a `state` key — \"downgrades where rsi_14 was already under 40\" composes with q. Free on every plan.",
      +  "enum": [
      +    "state"
      +  ],
      +  "type": "string"
      +}
    • removedInput schema / properties / since
      Removed value: -{
      -  "description": "Events at or after this ISO date/datetime.",
      -  "type": "string"
      -}
    • addedInput schema / properties / to
      Added value: +{
      +  "description": "Events strictly before this ISO date/datetime (exclusive). `until` accepted as alias.",
      +  "type": "string"
      +}
    • removedInput schema / properties / until
      Removed value: -{
      -  "description": "Events strictly before this ISO date/datetime.",
      -  "type": "string"
      -}
  9. Changed4 schema fields changed
    • changedInput schema / properties / kind / description
      Previous value: -"Comma list of kinds to include (default all): dividend, split, insider, analyst."New value: +"Comma list of kinds to include. Default is the four corporate kinds: dividend, split, insider, analyst. Two more are opt-in and join only when named: `signal` (boolean-flag firings) and `news`."
    • changedInput schema / properties / q / description
      Previous value: -"SQL WHERE over (ticker, ts, kind, payload jsonb) — ONLY those four identifiers. Payload fields via jsonb operators: payload->>'firm' = 'Goldman Sachs', (payload->>'shares')::numeric > 1e6."New value: +"SQL WHERE over (ticker, ts, kind, payload jsonb) — ONLY those four identifiers. Payload fields via jsonb operators: payload->>'firm' = 'Goldman Sachs', (payload->>'shares')::numeric > 1e6. On kind=signal this requires `signal` (the firing log is ~175M rows); kind=signal takes no group_by."
    • addedInput schema / properties / signal
      Added value: +{
      +  "description": "kind=signal only. One built-in boolean flag (e.g. golden_cross). REQUIRED to use `q` or `join` on kind=signal — naming the signal is what keeps the query on an index; optional otherwise.",
      +  "type": "string"
      +}
    • addedInput schema / properties / transition
      Added value: +{
      +  "description": "kind=signal only. `enter` (false->true) or `exit` (true->false). Always optional — an ordinary filter.",
      +  "enum": [
      +    "enter",
      +    "exit"
      +  ],
      +  "type": "string"
      +}
  10. Added

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It discloses several important behaviors: case-sensitivity rules ('`firm`/`action` match case-insensitively; a `q` payload match is case-sensitive'), the `join: state` behavior ('attaches the ticker state as of each event'), and the interval resolution behavior ('`auto` resolves to `1d`... events on tickers absent from that tier join to `null`'). It also discloses error conditions (400 for firm without kind=analyst, 400 for signal without kind=signal). This is substantial behavioral context beyond what the schema provides.

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?

The description is compact for a tool with 20 parameters. It front-loads the core purpose in the first sentence, then states the critical bound requirement, then adds the case-sensitivity and join behavior. Every sentence adds value. It could be slightly more structured (e.g., separating the bound requirement into its own paragraph), but it's efficient and well-ordered.

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

Completeness4/5

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

Given the tool's complexity (20 parameters, 6 enums, aggregate vs row modes, join=state, signal-only filters), the description covers the most critical cross-cutting behaviors: the bound requirement, case-sensitivity, join semantics, and interval resolution. The output schema exists, so return values are covered. The description doesn't explicitly mention pagination or cursor behavior, but the schema documents the cursor parameter. It's complete enough for an agent to call this tool correctly in most cases.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all 20 parameters thoroughly. The description adds some cross-cutting semantic context: the bound requirement (ticker scope, time window, or firm/action), the case-sensitivity distinction, and the join=state behavior. However, most parameter-level semantics are already in the schema, so the description's incremental value is moderate. Baseline 3 is appropriate.

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?

The description opens with a clear, specific statement: 'One timeline across every ticker: earnings, dividends, splits, insider filings, analyst actions, plus opt-in signal firings and news.' This names the resource (events), the verb (list), and the scope (across every ticker), and enumerates the event kinds. It distinguishes itself from siblings like get_bars, get_series, and search_news by focusing on the unified event timeline.

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?

The description explicitly states the requirement: 'Requires at least one bound: a ticker scope (ticker/tickers/universe), a time window (from/to), or firm/action — `q` alone is not a bound.' It also explains when to use alternatives implicitly by describing what this tool covers (events) versus siblings like get_bars (price bars) and search_news (news search). The bound requirement is a clear usage rule that prevents invalid calls.

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.