io.github.tickerbot/mcp-server
REMOTE · API.TICKERBOT.IO · 2 COMPONENTS · SCANNED OCT 5
The stock market, in SQL — scan, replay, or subscribe across ~12k US tickers and top 100 cryptos.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security89
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token. View diagnostics → Pass
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- HSTS check failed: the Strict-Transport-Security header is absent. See how to fix → View diagnostics → Fail
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
- The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents. View diagnostics → Partial
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability62
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 12250 tokens (~382/item across 32 items; 32 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management70
- Stability check failed: schema churn in the 30 days we've observed: 9 tool removals, 3 breaking changes, 0 auth/transport breaks, 6 additions. See how to fix → Fail
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (91% of tools); any adoption earns full credit.Pass
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 0 of 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "tickerbot_delete_custom_signal" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
- An AI judge read all 32 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities60
- Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28. See how to fix → Fail
How do I install the io.github.tickerbot/mcp-server server?
io.github.tickerbot/mcp-server is a hosted endpoint at https://api.tickerbot.io/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · api.tickerbot.io
claude mcp add --transport http tickerbot-mcp-server 'https://api.tickerbot.io/mcp'
{
"mcpServers": {
"tickerbot-mcp-server": {
"url": "https://api.tickerbot.io/mcp"
}
}
} {
"servers": {
"tickerbot-mcp-server": {
"type": "http",
"url": "https://api.tickerbot.io/mcp"
}
}
} [mcp_servers.tickerbot-mcp-server] url = "https://api.tickerbot.io/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"tickerbot-mcp-server": {
"type": "remote",
"url": "https://api.tickerbot.io/mcp",
"enabled": true
}
}
} openclaw mcp add tickerbot-mcp-server --url 'https://api.tickerbot.io/mcp' --transport streamable-http
mcp_servers:
tickerbot-mcp-server:
url: "https://api.tickerbot.io/mcp" {
"McpServers": {
"tickerbot-mcp-server": {
"Transport": "http",
"Url": "https://api.tickerbot.io/mcp"
}
}
} assistant mcp add tickerbot-mcp-server -t streamable-http -u 'https://api.tickerbot.io/mcp'
{
"mcpServers": {
"tickerbot-mcp-server": {
"type": "http",
"url": "https://api.tickerbot.io/mcp"
}
}
} The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 3 Oct 26 0
- “tickerbot_get_signal” reworded the description of “interval” cosmetic
- “tickerbot_get_ticker” reworded the description of “asof” cosmetic
- “tickerbot_get_ticker” reworded the description of “interval” cosmetic
- “tickerbot_list_events” reworded the description of “interval” cosmetic
- “tickerbot_list_events” reworded the description of “join” cosmetic
- “tickerbot_scan” reworded the description of “asof” cosmetic
- “tickerbot_scan” reworded the description of “interval” cosmetic
- “tickerbot_scan” reworded the description of “universe” cosmetic
- “tickerbot_get_series” reworded the description of “asof” cosmetic
- “tickerbot_get_signal” reworded the description of “asof” cosmetic
- “tickerbot_get_bars” reworded the description of “asof” cosmetic
- “tickerbot_get_series” reworded the description of “interval” cosmetic
12 cosmetic changes on this day. Switch on “Show cosmetic changes” to see them.
- 2 Oct 26 0
- “tickerbot_scan” reworded the description of “universe” cosmetic
1 cosmetic change on this day. Switch on “Show cosmetic changes” to see it.
- 30 Sept 26 −1
- “tickerbot_scan” reworded the description of “universe” cosmetic
- “tickerbot_list_events” reworded the description of “kind” cosmetic
2 cosmetic changes on this day. Switch on “Show cosmetic changes” to see them.
- 29 Sept 26 0
- Tool “tickerbot_get_ticker_coverage” rewrote its description, which is the text the model reads security
- 28 Sept 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 27 Sept 26 0
- “tickerbot_create_custom_signal” reworded the description of “expr” cosmetic
- “tickerbot_update_custom_signal” reworded the description of “expr” cosmetic
2 cosmetic changes on this day. Switch on “Show cosmetic changes” to see them.
- 25 Sept 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 24 Sept 26 0
- Tool “tickerbot_get_signal” rewrote its description, which is the text the model reads security
- “tickerbot_get_signal” reworded the description of “signal” cosmetic
- “tickerbot_get_signal” reworded the description of “condition” cosmetic
- “tickerbot_subscribe_signal” reworded the description of “condition” cosmetic
- “tickerbot_scan” reworded the description of “universe” cosmetic
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 8 Oct 2026 · Probed https://api.tickerbot.io/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=api.tickerbot.io | CN=YE2,O=Let's Encrypt,C=US | 12 Sept 2026 | 11 Dec 2026 | ECDSA 256 | ECDSA-SHA384 | 6a9b724237f1a73a10a834d941a40fa0d66 |
| SANs: api.tickerbot.io | ||||||
| CN=YE2,O=Let's Encrypt,C=US (CA) | CN=Root YE,O=ISRG,C=US | 3 Sept 2025 | 2 Sept 2028 | ECDSA 384 | ECDSA-SHA384 | 4df3b15dd6c0784c507cd37b58e6f115 |
| CN=Root YE,O=ISRG,C=US (CA) | CN=ISRG Root X2,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | ECDSA-SHA384 | 872165fc34b6e5fba8add5b3705fb53a |
| CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) | CN=ISRG Root X1,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | ECDSA 384 | SHA256-RSA | 6c8f1dc727c7117f7baf853ac980f9cd |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of api.tickerbot.io. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| io. | present | 57355 | 8 | Verified |
| tickerbot.io. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication Enforced and verified
The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.
| Result | Enforced and verified |
|---|---|
| Enforced | On connection |
| HTTP status | 401 |
WWW-Authenticate challenge Bearer realm="mcp", resource_metadata="https://api.tickerbot.io/.well-known/oauth-protected-resource"
Bearer realm="mcp", resource_metadata="https://api.tickerbot.io/.well-known/oauth-protected-resource" | Header | Value |
|---|---|
| www-authenticate | Bearer realm="mcp", resource_metadata="https://api.tickerbot.io/.well-known/oauth-protected-resource" |
Protected resource metadata
| Document | https://api.tickerbot.io/.well-known/oauth-protected-resource |
|---|---|
| Retrieved | Yes |
| Resource | https://api.tickerbot.io/mcp |
| Authorisation server | https://api.tickerbot.io |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://api.tickerbot.io/mcp | Auth required | 401 | |
| http (plaintext) | http://api.tickerbot.io/mcp | HTTPS enforced | 301 | https://api.tickerbot.io/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
tickerbot_create_custom_signal ~436
A named boolean predicate you can reference anywhere a built-in signal goes.
| Name | Type | Req | Description |
|---|---|---|---|
| description | string | – | Free-form notes. Max 500 chars. Absent or empty comes back as `""` rather than null. |
| expr | string | yes | Boolean SQL predicate. May reference built-in signals and other custom signals you own. Must evaluate to true/false. Max 4000 chars. Stricter grammar than scan `q`: comparisons, `AND`/`OR`/`NOT`, `IN… |
| name | string | yes | Slug — `^[a-z][a-z0-9_]{0,63}$`. Must not collide with any built-in signal name, and 15 names are reserved outright: `columns`, plus the `/v2/series` OHLCV aliases `open`/`high`/`low`/`close`/`volume… |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | Only when `expr` named a column under its pre-2026-09-07 spelling: `deprecated_columns` lists each one (`requested`, `use`, `note`). The stored `expr` carries the current name. |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| signal | object | yes | The stored signal: `name`, `kind` (`custom`), `description`, `expr` (your predicate as stored), `created_at`, `updated_at`. |
No examples provided.
tickerbot_create_universe ~230
Create a named ticker list owned by your account.
| Name | Type | Req | Description |
|---|---|---|---|
| description | string | – | Free-form notes, up to 500 characters. Stored as `""` when omitted. |
| id | string | – | Optional slug — becomes the universe's permanent handle everywhere (`?universe=`, subscribe `universe`, CRUD path). Pattern `^[a-z][a-z0-9_]{0,62}$` — starts with a lowercase letter, then lowercase l… |
| name | string | yes | Human-readable label, up to 80 characters. Display-only — never used to reference the universe. |
| tickers | array | yes | Ticker symbols, up to 10,000. Validated against the active universe. `[]` is accepted — a shell universe you can fill later via PATCH. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| created_at | number | yes | Creation timestamp. |
| description | string | yes | Free-form notes; `""` when unset. |
| effective_at | number | – | System universes only; absent on yours. |
| id | string | yes | The slug — the universe's handle in `?universe=`. |
| name | string | yes | Display label. |
| next_rebalance_at | number | – | System universes only; absent on yours. |
| rebalance_method | string | – | System universes only; absent on yours. |
| size | number | yes | Member count. |
| system | boolean | yes | `false` — this is your universe. |
| tickers | array | yes | Members, after this call. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_create_webhook ~481
Canonical create: a webhook is a trigger plus a delivery. Trigger shapes: scan {type:"scan", q, universe?}; ticker {type:"ticker", ticker, condition}; signal {type:"signal", signal, ticker?, universe?, condition?}; event {type:"event", kinds, tickers?, universe?, event_q?}. The subscribe tools are flat sugar over exactly this. Webhooks need a paid plan (Free has no webhook slots).
| Name | Type | Req | Description |
|---|---|---|---|
| cadence | string | – | Evaluation cadence — a user preference — never gated. Event triggers deliver on ingest — only `realtime` is accepted on them (400 otherwise). |
| channel | string | – | Delivery channel. See Delivery channels. |
| columns | string | – | Extra columns echoed in fired payloads' match rows (`fields` accepted as an alias). Not accepted on `event` triggers (400) — event deliveries carry the event payload, not state rows. |
| device_id | string | – | Registered device id (channel `mobile_push`, see /v2/devices). |
| dir | string | – | Sort direction for `order`. Not accepted on `event` triggers (400). |
| discord_url | string | – | Discord webhook URL (channel `discord`). |
| name | string | – | Display name, max 80 characters. Defaults to an auto-generated one from the trigger. |
| order | string | – | Signal the fired payload's match lists are sorted by before the 100-row cap is applied — so a truncated list is the deterministic top 100, not an arbitrary sample. Same contract as `POST /v2/scan`. N… |
| target_url | string | – | HTTPS delivery URL (the `webhook` channel), max 1024 characters. Omit for in-app delivery, or use `channel` + `discord_url`/`device_id` for other channels. |
| trigger | object | yes | What fires the webhook. A discriminated object — `trigger.type` picks the shape, and the fields below belong inside it. Each shape is also available as a flat-params shortcut: `POST /v2/scan/subscrib… |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | Returned on create only, and only when the rule or `columns` named a column under its pre-2026-09-07 spelling: `deprecated_columns` lists each one (`requested`, `use`, `note`). The stored rule carrie… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| cadence | string | yes | How often the trigger is evaluated — `realtime`, `hourly`, or `nyse_open`. |
| channel | string | yes | Where deliveries go: `webhook`, `discord`, `in_app`, or `mobile_push`. |
| channel_config | object | yes | Returned on create only: the channel-specific delivery settings as stored (e.g. the Discord URL, the device id). |
| created_at | number | yes | Creation timestamp. |
| delivery | string | yes | Legacy alias of `channel`, kept aligned for older readers. |
| dir | string | yes | Sort direction for that list; `null` means the default (`desc`). |
| event_kinds | array | – | Event-trigger webhooks only: the kinds subscribed (`split`, `dividend`, `insider`, `analyst`, `earnings`). |
| event_q | string | – | Event-trigger webhooks only: the payload filter, or `null`. |
| event_tickers | array | – | Event-trigger webhooks only: the symbols the trigger is scoped to, or `null` for the universe / whole market. |
| fields | string | yes | Extra signals carried on each fired match row; `null` means the standard set. |
| id | string | yes | The webhook id — `wh_…`, the handle for every other call on this record. |
| last_error | string | – | The last evaluation error; `null` on a healthy hook. The answer to "why is my webhook not firing?". |
| last_eval_error_at | number | – | When the last evaluation error happened; `null` on a healthy hook. |
| last_evaluated_at | number | yes | When it was last evaluated; `null` until the first run. |
| last_fired | number | yes | When a delivery last went out; `null` if it never has. |
| last_match_set | array | yes | Tickers matching at the last evaluation — the set the next run is diffed against, which is what makes firing edge-triggered. |
| last_predicate_value | string | yes | The trigger's value at the last evaluation; `null` until it has run. |
| name | string | yes | Your label for the subscription. |
| next_eval_at | number | yes | When the evaluator will next consider this subscription. |
| order | string | yes | Sort signal for the payload row list; `null` means the evaluator default (`market_cap`). |
| q | string | yes | The stored predicate. Custom signals appear expanded: the SQL is frozen at creation. |
| rule_id | string | yes | Legacy link to a v1 alert rule; `null` on everything created through v2. |
| signing_secret | string | yes | Returned on create only — shown once, never again. HMAC key for verifying the `X-Tickerbot-Signature` header on deliveries. |
| source | string | yes | Which API version created the record; `v2` for anything you create today. |
| status | string | yes | `active` or `disabled`. Auto-disable follows repeated delivery failure. |
| subscription_origin | object | yes | Which door created it — `type` (`ticker`/`signal`/`scan`/`event`), its `ref`, and the `condition` in display form. |
| target_url | string | yes | Your HTTPS endpoint; `null` on every channel except `webhook`. |
| test_url | string | – | Returned on create only: the `POST /v2/webhooks/{id}/test` URL for this record. |
| trigger_kind | string | – | Event-trigger webhooks only: `event`. |
| universe_id | string | yes | Universe the trigger is scoped to, or `null` for the whole market. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_delete_custom_signal ~83
Delete one of your custom signals. Refused by default if another of your signals references it.
| Name | Type | Req | Description |
|---|---|---|---|
| force | boolean | – | When `true`, skip the reference check and delete. References will break on next recompile. |
| signal | string | yes | Custom signal slug (the signal name). A built-in name answers 404 — built-ins are read-only. |
No output schema declared.
No examples provided.
tickerbot_delete_universe ~93
Permanently delete one of your universes. Webhooks that reference the deleted universe fail on their next eval — clean those up first.
| Name | Type | Req | Description |
|---|---|---|---|
| force | boolean | – | A universe still referenced by live webhooks refuses to delete with `409 universe_referenced`. Pass `force=true` to delete anyway — those webhooks will match nothing until re-pointed or deleted. |
| id | string | yes | Universe slug. |
No output schema declared.
No examples provided.
tickerbot_delete_webhook ~33
Delete a webhook subscription, and its delivery history with it.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Webhook id. |
No output schema declared.
No examples provided.
tickerbot_enable_webhook ~48
Re-enable a disabled webhook and start it clean. Clears match-state, so the next eval treats every currently-matching ticker as new.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Webhook id. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| cadence | string | yes | How often the trigger is evaluated — `realtime`, `hourly`, or `nyse_open`. |
| channel | string | yes | Where deliveries go: `webhook`, `discord`, `in_app`, or `mobile_push`. |
| created_at | number | yes | Creation timestamp. |
| delivery | string | yes | Legacy alias of `channel`, kept aligned for older readers. |
| dir | string | yes | Sort direction for that list; `null` means the default (`desc`). |
| event_kinds | array | – | Event-trigger webhooks only: the kinds subscribed (`split`, `dividend`, `insider`, `analyst`, `earnings`). |
| event_q | string | – | Event-trigger webhooks only: the payload filter, or `null`. |
| event_tickers | array | – | Event-trigger webhooks only: the symbols the trigger is scoped to, or `null` for the universe / whole market. |
| fields | string | yes | Extra signals carried on each fired match row; `null` means the standard set. |
| id | string | yes | The webhook id — `wh_…`, the handle for every other call on this record. |
| last_error | string | – | The last evaluation error; `null` on a healthy hook. The answer to "why is my webhook not firing?". |
| last_eval_error_at | number | – | When the last evaluation error happened; `null` on a healthy hook. |
| last_evaluated_at | number | yes | When it was last evaluated; `null` until the first run. |
| last_fired | number | yes | When a delivery last went out; `null` if it never has. |
| last_match_set | array | yes | Tickers matching at the last evaluation — the set the next run is diffed against, which is what makes firing edge-triggered. |
| last_predicate_value | string | yes | The trigger's value at the last evaluation; `null` until it has run. |
| name | string | yes | Your label for the subscription. |
| next_eval_at | number | yes | When the evaluator will next consider this subscription. |
| order | string | yes | Sort signal for the payload row list; `null` means the evaluator default (`market_cap`). |
| q | string | yes | The stored predicate. Custom signals appear expanded: the SQL is frozen at creation. |
| rule_id | string | yes | Legacy link to a v1 alert rule; `null` on everything created through v2. |
| source | string | yes | Which API version created the record; `v2` for anything you create today. |
| status | string | yes | `active` or `disabled`. Auto-disable follows repeated delivery failure. |
| subscription_origin | object | yes | Which door created it — `type` (`ticker`/`signal`/`scan`/`event`), its `ref`, and the `condition` in display form. |
| target_url | string | yes | Your HTTPS endpoint; `null` on every channel except `webhook`. |
| trigger_kind | string | – | Event-trigger webhooks only: `event`. |
| universe_id | string | yes | Universe the trigger is scoped to, or `null` for the whole market. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_get_bars ~778
OHLCV bars from 1-second through monthly. The prices underneath the table.
| Name | Type | Req | Description |
|---|---|---|---|
| adjusted | boolean | – | Default `true`: prices are split-adjusted — restated after each later split, as the tape is, so a series is continuous across a split. `false` returns the price as it printed that day (a name that la… |
| asof | string | – | Point-in-time: the most recent bar whose period had closed at or before that moment. A bare `YYYY-MM-DD` means that day's close. A full timestamp means the last FINISHED bar — at 10:00 ET on a Wednes… |
| before | string | – | Return the N bars ending strictly before this date/timestamp — back-paging. Mutually exclusive with `cursor` (they are the same control — a 400 when both are sent). |
| cursor | string | – | Continuation token from a prior response's `next_cursor`; sugar for `before` (sending both is a 400; a blank `cursor=` counts as absent), and the way to page inside a `from`/`to` window. |
| from | string | – | Window start (inclusive): `YYYY-MM-DD`, ISO timestamp, or epoch-ms. Combines with `to` for an explicit window; page within it using `cursor`. Mutually exclusive with `asof` and `before` (400). |
| interval | string | yes | Bar interval. `2h`/`4h` roll up hourly bars; `1w`/`1mo` roll up daily bars into calendar weeks (Monday start) and months — the bar's `t` is the bucket start (UTC), and with `asof` the last bucket is… |
| limit | integer | – | Most-recent N bars. Max 1000 — an over-cap value is clamped, not an error. |
| session | string | – | Sub-hour intervals only. `all` (default) includes pre- and post-market bars. `regular` keeps bars whose start is in 09:30–16:00 ET (DST-aware). Why you might want it: the vendor buckets trades by SIP… |
| ticker | string | yes | Ticker symbol, or a comma-separated list (up to 50) for a bulk response keyed by symbol. |
| to | string | – | Window end (inclusive): a bare `YYYY-MM-DD` means through the end of that day, same as series. Mutually exclusive with `asof` and `before` (400). |
| Name | Type | Req | Description |
|---|---|---|---|
| adjusted | boolean | yes | Whether the bars are split-adjusted — `true` unless you passed `adjusted=false`. |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| bars | array | yes | OHLCV bars, chronological, in the compact array shape. Bulk requests key this by symbol instead. |
| count | number | yes | Bars returned in single-symbol mode; the number of SYMBOLS in bulk mode. |
| coverage | string | yes | `covered` when bars were found, `no_data` when nothing exists for the symbol in the window (before its first session, a market holiday, a thin name with no prints). A page that could not be completed… |
| interval | string | yes | The bar size served. |
| next_cursor | string | – | Opaque token for the next page; `null` on the last page. Absent on bulk (comma-list) requests, which are unpaged. Absent on bulk requests — page bulk symbol-by-symbol. |
| note | string | – | Present only when there is something to disclose about how the page was served: the first request for a symbol at a sub-hour interval loads and stores its bars, so that one call is slower than later… |
| notes | object | – | Bulk (comma-list) requests only: the per-symbol disclosures, keyed by symbol, in place of `note`. |
| session | string | yes | The session filter applied: `all` (default) or `regular` (09:30–16:00 ET, sub-hour intervals only). |
| ticker | string | – | The symbol you asked for. |
No examples provided.
tickerbot_get_etf_holdings ~214
Returns an ETF's constituents and their weights, heaviest first. When the ticker is not an ETF, `is_etf` is false and `holdings` is empty; `is_etf: true` with zero holdings means a real ETF whose holdings are not ingested yet. The reverse lookup ("which ETFs hold NVDA") is a scan filter on `etf_holders`, not this tool.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Max holdings returned. Max 5000. When the cap cuts the list, the response sets `truncated: true` and `total` (the ETF's full holding count) — raise `limit` to at least `total` to get the full set, po… |
| ticker | string | yes | ETF symbol. Case-insensitive. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Holdings in this page. |
| holdings | array | yes | Constituents, heaviest first, each with its weight. |
| is_etf | boolean | yes | Whether the symbol is an ETF, from the instrument type on its ticker record. |
| ticker | string | yes | The ETF you asked for. |
| total | number | – | Total constituents held, before `limit`. |
| truncated | boolean | – | `true` when `limit` cut the list short. |
No examples provided.
tickerbot_get_etf_sectors ~70
Returns an ETF's sector weights, heaviest first. Always complete, since sector breakdowns are small. When the ticker is not an ETF, `is_etf` is false and `sectors` is empty.
| Name | Type | Req | Description |
|---|---|---|---|
| ticker | string | yes | ETF symbol. Case-insensitive. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Sectors returned. |
| is_etf | boolean | yes | Whether the symbol is an ETF, from the instrument type on its ticker record. |
| sectors | array | yes | Sector weights, heaviest first, in the vendor's ETF-profile vocabulary. |
| ticker | string | yes | The ETF you asked for. |
No examples provided.
tickerbot_get_series ~1,185
Any signals for any tickers on one shared time grid — up to 50 tickers by 25 columns per call. One flat row per ticker per interval step, cursor-paged backward. `transitions_only: true` with boolean signals returns only the rows where a boolean flipped.
| Name | Type | Req | Description |
|---|---|---|---|
| asof | string | – | Point-in-time read: ONE row per ticker — the state at that instant — rather than a range. `YYYY-MM-DD` or a full ISO timestamp, the same meaning `asof` carries on `/v2/tickers`, `/v2/scan` and `/v2/s… |
| columns | string | – | Up to 25 columns (POST accepts an array): OHLCV names, signals, and your custom signals, freely mixed. Omitted → the ticker-history default set (price, change_1d_pct, relative_volume, market_cap), in… |
| cursor | string | – | Opaque cursor from the previous response — every ticker pages backward in lockstep on the shared grid, no per-ticker gaps or duplicates. |
| from | string | – | Earliest timestamp (inclusive), `YYYY-MM-DD` or ISO. Intraday requests default to a recent window (`1m`: 7 days, `1h`: 60 days) — the cursor keeps walking further back window-by-window, or pass `from… |
| interval | string | – | Grid granularity. `1w` resamples the daily tier weekly (Monday-keyed); `1q` is the fiscal-quarter grid. This is the grid, not a state tier: there is no `auto` here and nothing blends — under `asof` y… |
| limit | integer | – | Grid steps per page (shared across tickers). Max 1000 — an over-cap `limit` is clamped to 1000 (house convention, `limit=10000` means "max"). Separately, tickers × limit may not exceed 25,000 rows pe… |
| ticker | string | – | Single-symbol form — `/v2/series?ticker=AAPL` is ticker history in its canonical spelling. Exactly one of `ticker` or `tickers` is required. |
| tickers | string | – | Comma-separated symbols, up to 50 (POST accepts a JSON array). Exactly one of `tickers` or `ticker` is required; when both are passed, `ticker` wins — so sending both silently narrows the request to… |
| to | string | – | Latest timestamp (inclusive), `YYYY-MM-DD` or ISO. |
| transitions_only | boolean | – | Only rows where a boolean signal changed state. Accepted spellings: `true`/`1`/`yes` and `false`/`0`/`no` (case-insensitive) — anything else is a 400, never silently off. Requires at least one boolea… |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | yes | Per-column `sources` (`bars`, `state`, or `custom` for your own signals; `earnings`/`statements` at 1q) and per-ticker `coverage`, plus `non_trading_days_dropped` / `transitions_only` / `from_default… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| columns | array | yes | Columns in the response, echoed. |
| count | number | yes | Rows per ticker in this page. |
| interval | string | yes | The grid granularity served. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| series | object | yes | Keyed by ticker: an array of flat rows, chronological, each keyed `t` plus the columns you asked for. |
| tickers | array | yes | Symbols in the response, echoed. |
No examples provided.
tickerbot_get_signal ~825
The state of a signal is the set of tickers matching it right now, or with `asof`, as of any moment. One name, the whole market, one call. Booleans need no `condition`; every other type needs one, typed like the signal: ">70" (numeric), "<YYYY-MM-DDTHH:MM:SSZ" (timestamp), ">=YYYY-MM-DD" (date), "=ETF" (string). Sorted by signal value desc for non-booleans.
| Name | Type | Req | Description |
|---|---|---|---|
| asof | string | – | Optional. Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as… |
| condition | string | – | Required for every non-boolean signal; the shape follows the signal's `type` in the catalog. Single bound, `<op><value>`. numeric: `>70`, `<=200`, `!=0` (operators `>`, `>=`, `=`, `!=`, `<`, `<=`). t… |
| cursor | string | – | Opaque cursor from the previous response. |
| include_active_since | boolean | – | Built-in booleans only: adds `active_since` and `days_live` per row — the first day of the current true streak, from daily state (the day after the last false day; if the boolean has never been false… |
| interval | string | – | Grain the past state is read at: `1m`, `1h`, `1d`, or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed da… |
| limit | integer | – | Page size. Max 200. |
| signal | string | yes | A signal name. Booleans (e.g. `golden_cross`, `above_sma_50`) are detected automatically; every other type (numeric `rsi_14`, timestamp `price_asof`, date `earnings_date`, string `asset_class`) requi… |
| sort_by | string | – | Row order: `default` (alphabetic for booleans, highest-value-first for numerics) or `market_cap` (desc NULLS LAST; adds `market_cap` to each row). Live only — with `asof` it is a 400 (the snapshot's… |
| universe | string | – | Optional. Scope to a system or caller-owned universe slug. |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | With `asof`: how the read was resolved — interval served and requested, blending, sources, frozen fields (see the as-of read below). On any read, `deprecated_columns` when you named the signal under… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| condition | string | yes | The bound you passed, echoed; `null` for boolean and custom signals. |
| count | number | yes | Rows in this page. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| results | array | yes | Matching tickers with the signal value. |
| signal | string | yes | The signal you asked for. |
| universe | string | yes | The universe you scoped to, echoed; `null` when unscoped. |
No examples provided.
tickerbot_get_ticker ~458
The full ticker row, every signal on the schema page, for one symbol or a comma list of up to 50. Right now, or with `asof`, as of any past date. Pass a comma list of up to 50 symbols for a batch (`data` keyed by symbol plus `not_found`). Crypto is the X-prefixed pair (X:BTCUSD) — bare BTC/ETH are US-listed ETFs.
| Name | Type | Req | Description |
|---|---|---|---|
| asof | string | – | Optional. Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as… |
| interval | string | – | Grain the past state is read at: `1m`, `1h`, `1d`, or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed da… |
| ticker | string | yes | One symbol, or a comma-separated list of up to 50 for a batch response keyed by symbol. Case-insensitive. Equities are bare symbols (`AAPL`); every other class carries a prefix — rates (`R:SOFR`), cr… |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | With `asof` only: how the read was resolved — the interval served and requested, whether rows blend intervals, sources and frozen fields. See the as-of read below. |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | – | List form only — how many of `requested` were found. |
| data | object | yes | The full ticker row — every signal on the schema page. On the list form, an object keyed by symbol, one full row each. |
| not_found | string | – | List form only — the requested symbols we do not track, in request order. An empty array when every symbol was found. |
| requested | string | – | List form only — the canonical symbols asked for, de-duplicated, in request order. |
| ticker | string | – | The symbol you asked for, normalised. Single form only. |
No examples provided.
tickerbot_get_ticker_coverage ~141
For one ticker, what we hold and how far back — so an empty result is never ambiguous. Ask this before treating a gap in bars or series as an outage. An absent `minute` span is not a gap — sub-hour bars load on the first request for a symbol.
| Name | Type | Req | Description |
|---|---|---|---|
| ticker | string | yes | Case-insensitive. Equities are bare symbols (`AAPL`); every other class carries a prefix — rates (`R:SOFR`), crypto (`X:BTCUSD`), fx (`X:EURUSD`). Bare `BTC`/`ETH` are US-listed ETFs, not spot crypto… |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| measured_fields | array | yes | Per-field measured depth where the backfill engine has probed — `field`, the grain it was measured at (`daily`, `hourly`, `minute`), `first_date`, `last_date`, `pct_complete`. Capped at 1500 rows. |
| minute_tier | object | yes | Deprecated (see the changelog): an internal precompute roster that has no bearing on what bars you can read — sub-hour bars are available for every active symbol. Do not branch on it. |
| name | string | yes | Company or instrument name. |
| spans | object | yes | Per resolution — `oldest`, `newest`, `rows`. |
| ticker | string | yes | The symbol you asked for. |
No examples provided.
tickerbot_get_universe ~53
Returns the universe doc. Use `top_10`/`top_100` to fetch a system universe; any other slug must be one your account owns.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Universe slug. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| created_at | number | yes | Creation timestamp. |
| description | string | yes | Free-form notes; `""` when unset. |
| effective_at | number | – | System universes only: when this membership took effect. |
| id | string | yes | The slug — the universe's handle in `?universe=`. |
| name | string | yes | Display label. |
| next_rebalance_at | number | – | System universes only: when membership is next recomputed. |
| rebalance_method | string | – | System universes only: how membership is chosen. |
| size | number | yes | Member count. |
| system | boolean | yes | `true` for a built-in universe, `false` for one you created. |
| tickers | array | yes | Members. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_get_webhook ~47
The current state of one webhook subscription.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Webhook id returned by a subscribe endpoint (`POST /v2/tickers/{T}/subscribe`, etc.). |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| cadence | string | yes | How often the trigger is evaluated — `realtime`, `hourly`, or `nyse_open`. |
| channel | string | yes | Where deliveries go: `webhook`, `discord`, `in_app`, or `mobile_push`. |
| created_at | number | yes | Creation timestamp. |
| delivery | string | yes | Legacy alias of `channel`, kept aligned for older readers. |
| dir | string | yes | Sort direction for that list; `null` means the default (`desc`). |
| event_kinds | array | – | Event-trigger webhooks only: the kinds subscribed (`split`, `dividend`, `insider`, `analyst`, `earnings`). |
| event_q | string | – | Event-trigger webhooks only: the payload filter, or `null`. |
| event_tickers | array | – | Event-trigger webhooks only: the symbols the trigger is scoped to, or `null` for the universe / whole market. |
| fields | string | yes | Extra signals carried on each fired match row; `null` means the standard set. |
| id | string | yes | The webhook id — `wh_…`, the handle for every other call on this record. |
| last_error | string | – | The last evaluation error; `null` on a healthy hook. The answer to "why is my webhook not firing?". |
| last_eval_error_at | number | – | When the last evaluation error happened; `null` on a healthy hook. |
| last_evaluated_at | number | yes | When it was last evaluated; `null` until the first run. |
| last_fired | number | yes | When a delivery last went out; `null` if it never has. |
| last_match_set | array | yes | Tickers matching at the last evaluation — the set the next run is diffed against, which is what makes firing edge-triggered. |
| last_predicate_value | string | yes | The trigger's value at the last evaluation; `null` until it has run. |
| name | string | yes | Your label for the subscription. |
| next_eval_at | number | yes | When the evaluator will next consider this subscription. |
| order | string | yes | Sort signal for the payload row list; `null` means the evaluator default (`market_cap`). |
| q | string | yes | The stored predicate. Custom signals appear expanded: the SQL is frozen at creation. |
| rule_id | string | yes | Legacy link to a v1 alert rule; `null` on everything created through v2. |
| source | string | yes | Which API version created the record; `v2` for anything you create today. |
| status | string | yes | `active` or `disabled`. Auto-disable follows repeated delivery failure. |
| subscription_origin | object | yes | Which door created it — `type` (`ticker`/`signal`/`scan`/`event`), its `ref`, and the `condition` in display form. |
| target_url | string | yes | Your HTTPS endpoint; `null` on every channel except `webhook`. |
| trigger_kind | string | – | Event-trigger webhooks only: `event`. |
| universe_id | string | yes | Universe the trigger is scoped to, or `null` for the whole market. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_list_events ~1,215
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.
| Name | Type | Req | Description |
|---|---|---|---|
| action | string | – | Analyst-only structured filter — requires `kind=analyst` alone. Same `action` vocabulary as Analyst actions. |
| cursor | string | – | Opaque cursor from the previous response — carries the original filters (and `q` when short), so pass it alone. Not valid with `group_by`. |
| dir | string | – | Aggregate-mode sort direction. |
| firm | string | – | Analyst-only structured filter — requires `kind=analyst` alone (`400` otherwise). Exact firm-name match on the ratings feed. |
| from | string | – | 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.) |
| group_by | string | – | 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. Na… |
| having | string | – | Post-aggregation filter. Requires `group_by`. |
| interval | string | – | Grain the per-event state is read at, when `join=state`: `1m`, `1h`, `1d`, or `auto` (default). Under `auto`, row reads blend each signal at its freshest grain at or before the event across hourly an… |
| join | string | – | Set to `state` to allow ticker-state signals in `q`/`select`/`group_by`/`having`, evaluated as of each event's timestamp at daily resolution: an event on day D sees the daily state through D-1, never… |
| kind | string | – | Comma list of kinds. Omitted → the five corporate kinds; `signal`, `news` and `estimate_revision` join only when named here. |
| limit | integer | – | Page size (row modes) / max rollup rows (aggregate mode). Max 1000. |
| order | string | – | 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: `g… |
| q | string | – | 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-cl… |
| select | string | – | 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. |
| signal | string | – | 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. |
| ticker | string | – | Single-ticker filter. When both `ticker` and `tickers` are passed, `ticker` wins. |
| tickers | string | – | Comma list of tickers (max 50). Mutually exclusive with `universe`. |
| to | string | – | 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 a… |
| transition | string | – | Signal-only filter — requires `kind=signal` alone. `enter` (false→true) or `exit` (true→false). |
| universe | string | – | Universe slug (`top_10`, `top_100`, or one of yours) to scope the stream. Mutually exclusive with `tickers`. |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | With `join=state` only: `state_interval`, the grain the joined state was read at, and `deprecated_columns` when a state column was named under its pre-2026-09-07 spelling and served under its current… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| next_cursor | string | – | 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. |
| query | object | yes | 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=s… |
| results | array | yes | One row per event (`ticker`, `ts`, `kind`, `payload`), or rollup rows plus `truncated: true` when an aggregate exceeds `limit`. |
| truncated | boolean | – | Aggregate mode only (`group_by`): `true` when the rollup stopped at its row cap. Aggregate responses are unpaged, so `next_cursor` is absent there. |
No examples provided.
tickerbot_list_signals ~119
Every signal you can name in a query — the built-in signals and your own custom signals, in one catalog. Use to discover the signal names and `q` vocabulary before composing a scan; custom signals appear with `kind: custom`.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Opaque cursor from a prior response. |
| kind | string | – | Filter by kind (`expression` accepted as a legacy alias for `custom`). Omit to return both. |
| limit | integer | – | Page size for the custom-signal slice. Max 200. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page — the canonical count, equal to `count_builtin` + `count_custom`. |
| count_builtin | number | yes | Built-in signals in the catalog. |
| count_custom | number | yes | Your custom signals. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| signals | array | yes | The catalog, your custom signals first, then built-ins. Built-ins carry `kind: builtin` plus their taxonomy membership — `category`/`category_label`/`group`/`group_label` (slugs are stable, switch on… |
| taxonomy | object | – | Absent when the page holds no built-ins (`kind=custom`). The signal taxonomy tree, once per response: `groups[]` in derivation-ladder order (record → behavior → indicator → company side), each with `… |
No examples provided.
tickerbot_list_tickers ~452
Every symbol we track, active or delisted, as one identity row each. Use `/v2/tickers/{ticker}` for the full row.
| Name | Type | Req | Description |
|---|---|---|---|
| asset_class | string | – | Filter by asset class — `stocks`, `rates`, `crypto`, `fx`, or a comma-separated list (the live classes today; validated for shape, not against a fixed list, so a well-formed class we don't track simp… |
| asset_type | string | – | Filter by instrument type WITHIN equities — the stored `asset_type` value (`CS`, `ETF`, `ADRC`, `PFD`, `FUND`, `UNIT`, `SP`, `ETS`, `WARRANT`, `RIGHT`, `ETN`, `ETV`), matched case-insensitively. `equ… |
| cursor | string | – | Opaque cursor from the previous response's `next_cursor` field. Continues the walk from after that page. A cursor minted under `search` only resumes the same search. |
| exchange | string | – | Filter by exchange name — the value rows carry in their `exchange` field. MIC codes (`XNAS`, `XNYS`, `BATS`) are also accepted and match `exchange_mic`. A malformed value (non-letters, over 16 chars)… |
| limit | integer | – | Page size. Max 1000. |
| search | string | – | Case-insensitive match on `ticker` or `name`, max 64 characters (longer is a 400). Results are ranked: an exact ticker match first, then symbols that start with the term, then name matches — alphabet… |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | With `asset_class` only: `scope.asset_class` lists the classes the page was filtered to. |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. |
| results | array | yes | One identity row per symbol — the thirteen signals named above, nothing else. `active: false` rows carry `delisted_utc`; they are still addressable on the state route with `asof`. |
No examples provided.
tickerbot_list_universes ~138
Every universe you can reference: your own named ticker lists and the built-in ones. `owner: system` lists the built-in universes (top_10, top_100); `all` lists both. Use a slug as `universe` on scan, signal, and subscribe tools.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Opaque cursor from the previous response. |
| limit | integer | – | Page size (applies to your own). Max 100. |
| owner | string | – | Which universes to list: `me` (your own), `system` (built-ins), or `all` (both). |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| universes | array | yes | The universes in scope. Every row carries `system: true|false`. |
No examples provided.
tickerbot_list_webhook_deliveries ~177
Recent deliveries for one webhook — what was sent, and what came back.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Opaque cursor. |
| from | string | – | Only deliveries created at/after this moment — epoch seconds, epoch milliseconds (13+ digits), or an ISO datetime (`since` is accepted as an alias). Delivery history is retained for 90 days; deleting… |
| id | string | yes | Webhook id. |
| limit | integer | – | Page size. Max 100. |
| status | string | – | Filter by delivery status. |
| to | string | – | Only deliveries created at/before this moment — same value grammar as `from`. A date-only value means through the end of that UTC day. `from` after `to` is a 400. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| deliveries | array | yes | Attempts, newest first: status, attempt, response code, error, and `body_string` — the exact JSON POSTed. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
No examples provided.
tickerbot_list_webhooks ~112
Every webhook subscription on this account, newest first.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Opaque cursor from the previous response. |
| limit | integer | – | Page size. Max 100. |
| status | string | – | Filter by status: `active` or `disabled` — the only two states a webhook has (`disabled` covers both a user pause and the automatic disable after repeated delivery failures; `consecutive_failures`/`l… |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| webhooks | array | yes | Your subscriptions, newest first, each with its `subscription_origin` and health fields. `signing_secret` is stripped — it is shown only on create. |
No examples provided.
tickerbot_scan ~912
Every ticker matching a SQL WHERE clause. Right now, or with `asof`, as of any past date. The `q` grammar is a flat SQL WHERE over signal names: AND/OR/NOT, comparisons, numeric and string literals, custom signals by name. No JOIN or subqueries. With `group_by` the result is rollup rows, not tickers. Example: `gap_up AND market_cap < 2000000000 AND NOT earnings_this_week`.
| Name | Type | Req | Description |
|---|---|---|---|
| asof | string | – | Optional. Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as… |
| asset_class | string | – | One or more asset classes — slug or comma-separated list (`stocks`, `rates`, `crypto`, `fx`). Validated for shape, not against a fixed list, so a well-formed class we don't track simply matches nothi… |
| columns | string | – | Extra signals per row, ADDITIVE — the defaults are always present (ticker, name, asset_class, asset_type, price, change_1d_pct, gap_pct, relative_volume, market_cap). `fields` accepted as an alias. |
| cursor | string | – | Opaque cursor from the previous response's `next_cursor`. Row mode only. |
| dir | string | – | Sort direction. |
| full | boolean | – | Return every signal instead of the default set. Mutually exclusive with `columns` — passing both is a 400. |
| group_by | string | – | AGGREGATE MODE: 1–6 group keys (signals, expressions, or one of your custom signals as a boolean key). Results become rollup rows. Name a key with `AS` to choose its JSON key (`market_cap > 1e11 AS m… |
| having | string | – | Filter the aggregate rows (requires `group_by`). Custom signals are valid here too. |
| interval | string | – | Grain the past state is read at: `1m`, `1h`, `1d`, or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed da… |
| limit | integer | – | Page size. Max 100. Aggregate mode does not paginate — it sets `truncated: true` when groups were cut, so sort with `order` to keep the ones you want. |
| order | string | – | Signal to sort by. In aggregate mode the default is the count alias `tickers` — or, with a custom `select`, the last item's alias — sorted NULLS LAST with the group keys as tiebreak. |
| q | string | yes | SQL WHERE expression. Max 4000 chars; semicolons, comments and write keywords are rejected. Your custom signals are valid here — each expands to its SQL at run time. |
| select | string | – | Aggregate output items (requires `group_by`). Default: the group keys + `COUNT(*) AS tickers`. Supports count/avg/sum/min/max/stddev/string_agg/bool_and/bool_or plus `FILTER (WHERE …)`, and your cust… |
| universe | string | – | Slug of a system universe (`top_10`, `top_100`) or one of your own. Omitted, the scan runs across all ~23,212 tracked tickers. |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | `null_coverage` reports, per signal in the predicate, how many in-scope rows are NULL and therefore never evaluated — absence from `results` means "no value", not "did not match". `scope` additionall… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| next_cursor | string | – | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| query | object | yes | Your query, echoed — `q`, `order`, `dir`, `limit`, and any scope. |
| results | array | yes | One row per match — every signal on the schema page, plus any you named. |
| truncated | boolean | – | Aggregate mode only (`group_by`): `true` when the rollup stopped at its row cap. Aggregate responses are unpaged, so `next_cursor` is absent there. |
No examples provided.
tickerbot_search_news ~715
SQL query over the news archive. Article rows, or rollups when you group them. Filter to a ticker with the `ticker` param, or in `q` via the auto-unnest alias `tk = 'NVDA'`. `search` is full-text over title and summary. Rollups with group_by/having return `truncated: true` instead of paging.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Opaque pagination cursor from a prior response's `next_cursor`. |
| dir | string | – | Sort direction. |
| from | string | – | Earliest `time_published` (inclusive) — strict ISO: `YYYY-MM-DD` or `YYYY-MM-DDTHH:MM[:SS]Z`. (`since` accepted as an alias.) |
| group_by | string | – | AGGREGATE MODE: comma-separated group keys, 1-6 (max 1000 chars). Switches the response to rollup rows. Use `tk` to roll up per ticker without writing the UNNEST. Name a key with `AS` to choose its J… |
| having | string | – | HAVING clause on the aggregate (max 1000 chars). Requires `group_by`. |
| limit | integer | – | Page size. Max 1000. |
| order | string | – | Sort — a bare column name or SELECT alias only (put expressions in `select` and order by their alias). Defaults to `time_published` (article rows) or `volume` (aggregate rows). |
| q | string | – | WHERE clause over the news_article table. Max 4000 chars. Required UNLESS `search` or a scoping param (`ticker`/`tickers`/`universe`/`from`/`to`) is present — the simplest call needs no SQL. Queryabl… |
| search | string | – | Full-text search over `title` + `summary` — websearch grammar: `apple earnings` (all words), `"price target"` (phrase), `chips OR semiconductors`, `-crypto` (negation). Max 200 chars. ANDs with `q` a… |
| select | string | – | Columns/expressions to return (max 2000 chars). Defaults to article columns (no `group_by`) or `<group_by cols>, COUNT(*) AS volume` (with `group_by`). |
| ticker | string | – | Articles mentioning this symbol (ANDed with `q`). |
| tickers | string | – | Comma list, up to 50 — articles mentioning ANY of them. Not combinable with `ticker` or `universe`. |
| to | string | – | Articles strictly before this instant — same strict ISO subset, matching `/v2/events`. (`until` accepted as an alias.) |
| universe | string | – | Universe slug — articles mentioning any member. Not combinable with `ticker`/`tickers`. |
| Name | Type | Req | Description |
|---|---|---|---|
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| count | number | yes | Rows in this page. |
| next_cursor | string | yes | Opaque token for the next page; `null` on the last page. Pass it back as `cursor`. |
| query | object | yes | Your filters, echoed. |
| results | array | yes | Article rows, or rollup rows when you passed `group_by`. Aggregate responses add `truncated: true` when `limit` cut the group list. |
| truncated | boolean | – | Aggregate mode only (`group_by`): `true` when the rollup stopped at its row cap. |
No examples provided.
tickerbot_subscribe_events ~467
Push new events: we POST your endpoint when events of the kinds you chose land in the archives. Webhooks need a paid plan (Free has no webhook slots). `q` filters the ticker STATE; `event_q` filters the EVENT payload in the /v2/events grammar. Latency is the ingest cadence (analyst ≤1h, corporate kinds daily), not sub-minute.
| Name | Type | Req | Description |
|---|---|---|---|
| channel | string | – | Delivery channel. `slack` is reserved and returns `501`. |
| device_id | string | – | Device to notify, from `POST /v2/devices/register`. Required when `channel` is `mobile_push`; unknown ids are a 404 `device_not_found`. |
| discord_url | string | – | Discord incoming-webhook URL. Required when `channel` is `discord`. Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliver… |
| event_q | string | – | Optional event-CONTENT filter in the `/v2/events` grammar — only `ticker`, `ts`, `kind`, `payload` may appear. Composes with `q`. |
| kinds | string | yes | Event kinds to fire on — array or comma list. |
| name | string | – | Display name. Defaults to `events: <kinds> · <scope>`. |
| q | string | – | Optional row-STATE filter evaluated against the event's ticker at fire time. Same grammar as scan `q`; custom signals are expanded and frozen at creation. |
| target_url | string | – | HTTPS delivery URL; or use `channel` + `discord_url`/`device_id`. Omit for in-app. |
| ticker | string | – | Single-symbol shorthand for `tickers`. |
| tickers | string | – | Scope to specific tickers (max 50). Mutually exclusive with `universe` — and with the singular alias `ticker` (sending both is a 400). Omit both for all tickers. |
| universe | string | – | Scope to a universe slug (`top_10`, `top_100`, or one of yours). `universe_id` accepted as an alias. |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | Returned on create only, and only when the rule or `columns` named a column under its pre-2026-09-07 spelling: `deprecated_columns` lists each one (`requested`, `use`, `note`). The stored rule carrie… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| cadence | string | yes | How often the trigger is evaluated — `realtime`, `hourly`, or `nyse_open`. |
| channel | string | yes | Where deliveries go: `webhook`, `discord`, `in_app`, or `mobile_push`. |
| channel_config | object | yes | Returned on create only: the channel-specific delivery settings as stored (e.g. the Discord URL, the device id). |
| created_at | number | yes | Creation timestamp. |
| delivery | string | yes | Legacy alias of `channel`, kept aligned for older readers. |
| dir | string | yes | Sort direction for that list; `null` means the default (`desc`). |
| event_kinds | array | – | Event-trigger webhooks only: the kinds subscribed (`split`, `dividend`, `insider`, `analyst`, `earnings`). |
| event_q | string | – | Event-trigger webhooks only: the payload filter, or `null`. |
| event_tickers | array | – | Event-trigger webhooks only: the symbols the trigger is scoped to, or `null` for the universe / whole market. |
| fields | string | yes | Extra signals carried on each fired match row; `null` means the standard set. |
| id | string | yes | The webhook id — `wh_…`, the handle for every other call on this record. |
| last_error | string | – | The last evaluation error; `null` on a healthy hook. The answer to "why is my webhook not firing?". |
| last_eval_error_at | number | – | When the last evaluation error happened; `null` on a healthy hook. |
| last_evaluated_at | number | yes | When it was last evaluated; `null` until the first run. |
| last_fired | number | yes | When a delivery last went out; `null` if it never has. |
| last_match_set | array | yes | Tickers matching at the last evaluation — the set the next run is diffed against, which is what makes firing edge-triggered. |
| last_predicate_value | string | yes | The trigger's value at the last evaluation; `null` until it has run. |
| name | string | yes | Your label for the subscription. |
| next_eval_at | number | yes | When the evaluator will next consider this subscription. |
| order | string | yes | Sort signal for the payload row list; `null` means the evaluator default (`market_cap`). |
| q | string | yes | The stored predicate. Custom signals appear expanded: the SQL is frozen at creation. |
| rule_id | string | yes | Legacy link to a v1 alert rule; `null` on everything created through v2. |
| signing_secret | string | yes | Returned on create only — shown once, never again. HMAC key for verifying the `X-Tickerbot-Signature` header on deliveries. |
| source | string | yes | Which API version created the record; `v2` for anything you create today. |
| status | string | yes | `active` or `disabled`. Auto-disable follows repeated delivery failure. |
| subscription_origin | object | yes | Which door created it — `type` (`ticker`/`signal`/`scan`/`event`), its `ref`, and the `condition` in display form. |
| target_url | string | yes | Your HTTPS endpoint; `null` on every channel except `webhook`. |
| test_url | string | – | Returned on create only: the `POST /v2/webhooks/{id}/test` URL for this record. |
| trigger_kind | string | – | Event-trigger webhooks only: `event`. |
| universe_id | string | yes | Universe the trigger is scoped to, or `null` for the whole market. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_subscribe_scan ~597
Push a whole query: we POST your endpoint every time the match set changes. Webhooks need a paid plan (Free has no webhook slots). Use for "alert me when this happens" requests.
| Name | Type | Req | Description |
|---|---|---|---|
| cadence | string | – | `realtime` (the default) is evaluated on every data refresh (~1×/min); `hourly` and `nyse_open` throttle to a batch schedule. `1m` is a deprecated alias for `realtime`. |
| channel | string | – | Delivery channel. `webhook` (POST to `target_url`), `discord` (embed to `discord_url`), `in_app` (dashboard only), or `mobile_push` (requires a `device_id` from `POST /v2/devices/register`). Inferred… |
| columns | string | – | Extra signals per fired payload match row, beyond the standard set (`ticker`, `name`, `asset_type`, `price`, `change_1d_pct`, `market_cap`). Each must be a real signal; unknown ones are rejected at c… |
| device_id | string | – | Device to notify, from `POST /v2/devices/register`. Required when `channel` is `mobile_push`; unknown ids are a 404 `device_not_found`. |
| dir | string | – | Sort direction for `order`. |
| discord_url | string | – | Discord incoming-webhook URL. Required when `channel` is `discord`. Stored as a posting credential: the create response echoes it back under `channel_config`, but every later read (list, get, deliver… |
| name | string | – | Human-readable label (up to 80 chars). Defaults to `scan: <q>`. |
| order | string | – | Signal the payload's match lists are sorted by before the 100-row cap applies, so a truncated list is the deterministic top 100 rather than an arbitrary sample. Must be a real signal (validated at cr… |
| q | string | yes | WHERE-clause expression using signal names — the same grammar and the same 4000-char cap as `POST /v2/scan`, so anything scannable is subscribable. Custom signals are expanded and frozen in at creati… |
| target_url | string | – | https:// URL to POST when the match set changes. Omit for in-app delivery. |
| universe | string | – | System or user-owned universe to scope the scan. `universe_id` accepted as an alias. Unknown universes are a 404 `universe_not_found`. |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | Returned on create only, and only when the rule or `columns` named a column under its pre-2026-09-07 spelling: `deprecated_columns` lists each one (`requested`, `use`, `note`). The stored rule carrie… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| cadence | string | yes | How often the trigger is evaluated — `realtime`, `hourly`, or `nyse_open`. |
| channel | string | yes | Where deliveries go: `webhook`, `discord`, `in_app`, or `mobile_push`. |
| channel_config | object | yes | Returned on create only: the channel-specific delivery settings as stored (e.g. the Discord URL, the device id). |
| created_at | number | yes | Creation timestamp. |
| delivery | string | yes | Legacy alias of `channel`, kept aligned for older readers. |
| dir | string | yes | Sort direction for that list; `null` means the default (`desc`). |
| event_kinds | array | – | Event-trigger webhooks only: the kinds subscribed (`split`, `dividend`, `insider`, `analyst`, `earnings`). |
| event_q | string | – | Event-trigger webhooks only: the payload filter, or `null`. |
| event_tickers | array | – | Event-trigger webhooks only: the symbols the trigger is scoped to, or `null` for the universe / whole market. |
| fields | string | yes | Extra signals carried on each fired match row; `null` means the standard set. |
| id | string | yes | The webhook id — `wh_…`, the handle for every other call on this record. |
| last_error | string | – | The last evaluation error; `null` on a healthy hook. The answer to "why is my webhook not firing?". |
| last_eval_error_at | number | – | When the last evaluation error happened; `null` on a healthy hook. |
| last_evaluated_at | number | yes | When it was last evaluated; `null` until the first run. |
| last_fired | number | yes | When a delivery last went out; `null` if it never has. |
| last_match_set | array | yes | Tickers matching at the last evaluation — the set the next run is diffed against, which is what makes firing edge-triggered. |
| last_predicate_value | string | yes | The trigger's value at the last evaluation; `null` until it has run. |
| name | string | yes | Your label for the subscription. |
| next_eval_at | number | yes | When the evaluator will next consider this subscription. |
| order | string | yes | Sort signal for the payload row list; `null` means the evaluator default (`market_cap`). |
| q | string | yes | The stored predicate. Custom signals appear expanded: the SQL is frozen at creation. |
| rule_id | string | yes | Legacy link to a v1 alert rule; `null` on everything created through v2. |
| signing_secret | string | yes | Returned on create only — shown once, never again. HMAC key for verifying the `X-Tickerbot-Signature` header on deliveries. |
| source | string | yes | Which API version created the record; `v2` for anything you create today. |
| status | string | yes | `active` or `disabled`. Auto-disable follows repeated delivery failure. |
| subscription_origin | object | yes | Which door created it — `type` (`ticker`/`signal`/`scan`/`event`), its `ref`, and the `condition` in display form. |
| target_url | string | yes | Your HTTPS endpoint; `null` on every channel except `webhook`. |
| test_url | string | – | Returned on create only: the `POST /v2/webhooks/{id}/test` URL for this record. |
| trigger_kind | string | – | Event-trigger webhooks only: `event`. |
| universe_id | string | yes | Universe the trigger is scoped to, or `null` for the whole market. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
tickerbot_subscribe_signal ~760
Push one signal: we POST your endpoint whenever any ticker starts matching it. Webhooks need a paid plan (Free has no webhook slots). Omit `ticker` to watch the whole universe.
| Name | Type | Req | Description |
|---|---|---|---|
| cadence | string | – | `realtime` (the default) is evaluated on every data refresh (~1×/min); `hourly` and `nyse_open` throttle to a batch schedule. `1m` is a deprecated alias for `realtime`. |
| channel | string | – | Delivery channel. `webhook` (POST to `target_url`), `discord` (post an embed to `discord_url`), `in_app` (dashboard only), or `mobile_push` (notify a phone signed in to the Tickerbot mobile app; requ… |
| columns | string | – | Comma-separated extra signals to include in each fired payload match row, beyond the standard set (`ticker`, `name`, `asset_type`, `price`, `change_1d_pct`, `market_cap`). Each must be a real signal;… |
| condition | string | – | Required for every non-boolean signal; the shape follows the signal's `type`. Numeric: `">70"`, `"<30"`, `">=100"`. Timestamp: `"<YYYY-MM-DDTHH:MM:SSZ"` (or a bare date). Date: `">=YYYY-MM-DD"`. Stri… |
| device_id | string | – | Device to notify, from `POST /v2/devices/register`. Required when `channel` is `mobile_push`; unknown ids are a 404 `device_not_found`. |
| dir | string | – | Sort direction for `order`. |
| discord_url | string | – | Discord incoming-webhook URL (`https://discord.com/api/webhooks/…`). Required when `channel` is `discord`. Stored as a posting credential: the create response echoes it back under `channel_config`, b… |
| name | string | – | Human-readable label (up to 80 chars). Defaults to the predicate — `at_52w_high` for a boolean, `rsi_14 > 70` for a numeric, prefixed with `<TICKER>: ` when `ticker` scopes it. |
| order | string | – | Signal the fired payload's match lists are sorted by before the 100-row cap is applied, so a truncated list is the deterministic top 100 rather than an arbitrary sample. Must be a real signal (valida… |
| signal | string | yes | Signal name from the schema (case-insensitive). |
| target_url | string | – | https:// URL to POST when fired. Omit for in-app delivery. |
| ticker | string | – | Restrict to a single ticker. Default: any ticker. |
| universe | string | – | Restrict to a system or user-owned universe (e.g. `top_100`). `universe_id` accepted as an alias. Unknown universes are a 404 `universe_not_found`. |
| Name | Type | Req | Description |
|---|---|---|---|
| _meta | object | – | Returned on create only, and only when the rule or `columns` named a column under its pre-2026-09-07 spelling: `deprecated_columns` lists each one (`requested`, `use`, `note`). The stored rule carrie… |
| as_of | string | yes | Server time this response was assembled (ISO 8601). |
| cadence | string | yes | How often the trigger is evaluated — `realtime`, `hourly`, or `nyse_open`. |
| channel | string | yes | Where deliveries go: `webhook`, `discord`, `in_app`, or `mobile_push`. |
| channel_config | object | yes | Returned on create only: the channel-specific delivery settings as stored (e.g. the Discord URL, the device id). |
| created_at | number | yes | Creation timestamp. |
| delivery | string | yes | Legacy alias of `channel`, kept aligned for older readers. |
| dir | string | yes | Sort direction for that list; `null` means the default (`desc`). |
| event_kinds | array | – | Event-trigger webhooks only: the kinds subscribed (`split`, `dividend`, `insider`, `analyst`, `earnings`). |
| event_q | string | – | Event-trigger webhooks only: the payload filter, or `null`. |
| event_tickers | array | – | Event-trigger webhooks only: the symbols the trigger is scoped to, or `null` for the universe / whole market. |
| fields | string | yes | Extra signals carried on each fired match row; `null` means the standard set. |
| id | string | yes | The webhook id — `wh_…`, the handle for every other call on this record. |
| last_error | string | – | The last evaluation error; `null` on a healthy hook. The answer to "why is my webhook not firing?". |
| last_eval_error_at | number | – | When the last evaluation error happened; `null` on a healthy hook. |
| last_evaluated_at | number | yes | When it was last evaluated; `null` until the first run. |
| last_fired | number | yes | When a delivery last went out; `null` if it never has. |
| last_match_set | array | yes | Tickers matching at the last evaluation — the set the next run is diffed against, which is what makes firing edge-triggered. |
| last_predicate_value | string | yes | The trigger's value at the last evaluation; `null` until it has run. |
| name | string | yes | Your label for the subscription. |
| next_eval_at | number | yes | When the evaluator will next consider this subscription. |
| order | string | yes | Sort signal for the payload row list; `null` means the evaluator default (`market_cap`). |
| q | string | yes | The stored predicate. Custom signals appear expanded: the SQL is frozen at creation. |
| rule_id | string | yes | Legacy link to a v1 alert rule; `null` on everything created through v2. |
| signing_secret | string | yes | Returned on create only — shown once, never again. HMAC key for verifying the `X-Tickerbot-Signature` header on deliveries. |
| source | string | yes | Which API version created the record; `v2` for anything you create today. |
| status | string | yes | `active` or `disabled`. Auto-disable follows repeated delivery failure. |
| subscription_origin | object | yes | Which door created it — `type` (`ticker`/`signal`/`scan`/`event`), its `ref`, and the `condition` in display form. |
| target_url | string | yes | Your HTTPS endpoint; `null` on every channel except `webhook`. |
| test_url | string | – | Returned on create only: the `POST /v2/webhooks/{id}/test` URL for this record. |
| trigger_kind | string | – | Event-trigger webhooks only: `event`. |
| universe_id | string | yes | Universe the trigger is scoped to, or `null` for the whole market. |
| updated_at | number | yes | Last modification timestamp. |
No examples provided.
What is the io.github.tickerbot/mcp-server server?
io.github.tickerbot/mcp-server is listed in the public MCP registry as io.github.tickerbot/mcp-server. The stock market, in SQL, scan, replay, or subscribe across ~12k US tickers and top 100 cryptos. This page covers its hosted endpoint (https://api.tickerbot.io/mcp).
Is the io.github.tickerbot/mcp-server server safe to use?
io.github.tickerbot/mcp-server scores 81 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the io.github.tickerbot/mcp-server server expose?
io.github.tickerbot/mcp-server exposes 32 tools: tickerbot_list_tickers, tickerbot_get_ticker, tickerbot_subscribe_ticker, tickerbot_get_ticker_coverage, tickerbot_list_signals, and 27 more. Their descriptions and schemas cost roughly 12,250 tokens of context every time the server is loaded.
Does the io.github.tickerbot/mcp-server server require authentication?
Yes. io.github.tickerbot/mcp-server asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.
Is the io.github.tickerbot/mcp-server server still maintained?
io.github.tickerbot/mcp-server is still listed as active in the MCP registry. We last reached this channel on 5 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.