mcp server
mcp-server
The stock market, in SQL — scan, replay, or subscribe across ~12k US tickers and top 100 cryptos.
Description as published by the maintainer. Source
- version 0.1.3
- active
active — Registry entry last updated 2026-06-11.
What this server can do
35 functions, named and described by the server itself. Parameter names are shown because they say more about what a function does than its name usually does.
tickerbot_create_custom_signal(expr, name, description)- Save a SQL WHERE expression as a named custom signal the caller can reference by name in future scans. Required: name, expr.
tickerbot_create_universe(id, name, tickers, description)- Create a new universe (named set of tickers) for scoping future scans. Required: name, tickers.
tickerbot_create_webhook(name, cadence, channel, columns, trigger, device_id, target_url, discord_url)- The canonical webhook create — POST /v2/webhooks with an explicit `trigger` object: { type: "scan" | "ticker" | "signal" | "event", … } plus delivery fields. The subscribe tools above are flat sugar over exactly this; use this form when composing the trigger programmatically or when a sugar door doesn't fit. 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?}. Required: trigger.
tickerbot_delete_custom_signal(name, force)- Delete one of the caller's custom signals. Cascade-safe by default: refused with 409 if another custom signal references it (the error lists the referencing signals). Pass `force: true` to delete anyway — existing references will break on next recompile. Available on every plan. Required: name.
tickerbot_delete_universe(id)- Delete one of the caller's universes. System universes (`top_10`/`top_100`) cannot be deleted. Webhooks that reference the deleted universe will fail on their next eval, so clean those up first. Required: id.
tickerbot_delete_webhook(id)- Delete a webhook subscription by id. Use after listing webhooks when the user wants to remove an alert. Required: id.
tickerbot_enable_webhook(id)- Re-enable a disabled webhook — flips it back to `active` and clears its match-state so the next eval treats every currently-matching ticker as new. Use after fixing whatever caused auto-disable. No-op on an already-active webhook. Required: id.
tickerbot_get_series(to, from, limit, cursor, ticker, columns, tickers, interval, transitions_only)- THE series primitive: cross-ticker, multi-column time series on one aligned grid. Pick up to 25 columns (price, OHLCV, indicators like rsi_14, boolean flags, custom signals) and up to 50 tickers; get one flat row per ticker per interval step ({ticker, t, price, rsi_14, …}), cursor-paged backward. `transitions_only=true` with boolean columns returns only the rows where a flag CHANGED — "every golden_cross flip this year" in one call. All-time on every plan. Replaces looping asof snapshots per date, and replaces the sunset per-ticker history routes.
tickerbot_get_signals_match(asof, limit, cursor, signal, sort_by, universe, condition, include_active_since)- Find tickers that match a single signal right now (or at a past moment with `asof`). Booleans need no condition. Numerics need a `condition` like ">70" or "<=200". Sorted by signal value desc for numerics. Required: signal.
tickerbot_get_ticker(asof, ticker)- Get the full current row for one ticker — every column on the schema (price, change, indicators like rsi_14, every boolean flag like above_sma_50, fundamentals like pe_ratio). Pass `asof` (YYYY-MM-DD or ISO timestamp like 2026-07-20T15:30:00Z) for the row as it stood at that past moment — date-only gives the close of that day. Required: ticker.
tickerbot_get_ticker_bars(to, asof, from, limit, before, cursor, ticker, interval)- Get OHLCV (open/high/low/close/volume) bars for one or more symbols at a given interval, oldest-first. Pass a comma-separated `ticker` list (up to 50) for a bulk response keyed by symbol. Use `asof` for a single point-in-time bar, or `before`+`limit` to back-page. `1d`/`1h` cover the full universe with full history; sub-hour intervals back-fill on demand. Required: ticker, interval.
tickerbot_get_ticker_coverage(ticker)- Data-coverage report for one ticker — which intervals and columns exist, from when, at what depth. The honesty endpoint: ask this before assuming a gap in bars/series is a data outage vs. genuinely-never-covered (e.g. sub-hour bars outside the active universe, fundamentals on non-equities). Required: ticker.
tickerbot_get_ticker_history(asof, ticker)- Time-travel SNAPSHOT: the full wide row for one ticker as it stood at a past date (one row, not a series — for a multi-column time SERIES use tickerbot_get_series). Returns indicators, boolean flags, and the most-recent fundamentals known on that date. Unlimited depth on every plan. Required: ticker, asof.
tickerbot_get_ticker_holdings(limit, ticker)- Get an ETF's constituent holdings 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 aren't ingested yet. (The reverse lookup "which ETFs hold NVDA" is a scan filter on the `etf_holders` column, not this tool.) Required: ticker.
tickerbot_get_ticker_sectors(ticker)- Get an ETF's sector allocation (sector weights, heaviest first). When the ticker is not an ETF, `is_etf` is false and `sectors` is empty; `is_etf: true` with zero sectors means a real ETF whose sector data isn't ingested yet. Required: ticker.
tickerbot_get_universe(id)- Get one universe by slug, including its ticker list. Required: id.
tickerbot_get_webhook(id)- Fetch one webhook subscription by id (current state, match-set, schedule). Account-scoped: any key on the account can read any of the account's webhooks. Required: id.
tickerbot_list_events(q, to, dir, firm, from, join, kind, limit, order, action, cursor, having, select, signal, ticker, tickers, group_by, interval, universe, transition)- THE events primitive — one timeline over every event log, cross-ticker: dividends, splits, insider transactions, and analyst actions ("all splits this month", "every analyst action in my universe this week", "AAPL's full corporate history" via `ticker`), plus two opt-in kinds that join only when named: `signal` (boolean-flag firings) and `news`. Rows are { ticker, ts, kind, payload }, newest first. Analyst payloads (history to 2012) carry firm/analyst/action/rating/price_target; filter them with `firm=`/`action=` (structured, case-insensitive — a `q` payload match is case-SENSITIVE) — actions: upgrades, downgrades, initiates_coverage_on, maintains, reiterates, assumes, reinstates, suspends, terminates_coverage_on. Use `q` for other payload conditions: it speaks the SQL grammar over exactly (ticker, ts, kind, payload jsonb); `group_by`/`select`/`having` roll the stream up (aggregates return `truncated: true` instead of paginating); `join=state` attaches the ticker's state as of each event. 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.
tickerbot_list_signal_events(to, from, limit, cursor, signal, ticker, merge_gap_seconds)- Occurrence SPANS of a boolean signal for one ticker, newest-first. For STATE flags (above_sma_50, in_uptrend) each row is a true-WINDOW: started_at when it flipped true, ended_at when it flipped back (null while still true), with prices at both ends. For EVENT flags (golden_cross, gap_up) each row is a point firing (started_at = ended_at). "Golden crosses in June" is from=2026-06-01&to=2026-06-30. Built-in booleans only — numerics and custom signals have no precomputed spans (use tickerbot_get_series). Required: signal, ticker.
tickerbot_list_signals_catalog(kind, limit, cursor)- List the unified signal catalog: every built-in column on the schema (`kind: builtin`) plus the caller's custom signals (`kind: expression`). Built-in rows carry the audited spec metadata — description, category, update cadence, ticker coverage (`ticker_scope`), history depth (`history`/`history_since`), queryable resolutions, and asset classes. Use to discover what `q=` clauses and signal names are available before composing a scan.
tickerbot_list_system_universes- List the built-in system universes (`top_10`, `top_100` — the most-actively-traded tickers by 30-day trailing dollar volume, rebalanced monthly). Available to every account regardless of plan. Use these slugs as `universe` in scans/signals or `universe_id` when subscribing.
tickerbot_list_tickers(limit, cursor, search, sector, tickers, exchange, universe, asset_type, asset_class, min_market_cap)- List active tickers from the Tickerbot universe (~14,500 US equities, plus the US Treasury curve and Fed policy rates under `R:`, and major FX pairs, spot metals and crypto under `X:`). Use `tickers` for bulk lookup of named symbols (returns full rows); otherwise walks the universe alphabetically with `cursor` pagination. Supports filters: search, asset_type, exchange, sector, min_market_cap.
tickerbot_list_universes(limit, owner, cursor)- List universes — your saved ones and/or the built-in system universes (top_10, top_100). Filter with `owner` (like the signals catalog's `kind`): `me` (default, your own), `system` (built-ins), or `all` (both). Each row carries `system: true|false`.
tickerbot_list_webhook_deliveries(id, to, from, limit, cursor, status)- List recent deliveries (pings and fires) for a webhook, newest-first — for diagnosing failures. Returns metadata only (status, attempt, response code, error); the POST body is not stored. Required: id.
tickerbot_list_webhooks(limit, cursor, status)- List the caller's webhook subscriptions (rules created via the subscribe tools), newest-first. Use `status` to filter to active or disabled rules.
tickerbot_patch_webhook(id, name, cadence, enabled, target_url)- Edit a webhook in place: `name`, `cadence`, `target_url`, `enabled` (pausing/resuming without losing match-state). The trigger (q) and channel are immutable by design — delete and re-create to change what fires or where it delivers. Unknown fields are a 400, never silently ignored. Required: id.
tickerbot_scan(q, dir, asof, full, limit, order, cursor, fields, having, select, group_by, universe)- Run a SQL WHERE clause against the live ticker universe (or against a past moment with `asof` — unlimited depth on every plan). Returns matching tickers sorted by chosen column, OR — with `group_by` — aggregate rollups instead of rows (breadth stats: "count of tickers above their 200dma by sector", "median RSI by sector on 2026-03-03"). The `q` grammar is a flat WHERE: column names from the schema, AND/OR/NOT, comparison operators, numeric/string literals. No JOIN or subqueries. Example: `gap_up AND market_cap < 2000000000 AND NOT earnings_this_week`. Required: q.
tickerbot_search_news(q, dir, limit, order, cursor, having, search, select, group_by)- Search the news archive (back to 2015) with a SQL WHERE clause. Available on every plan. Columns on news_article include `time_published`, `title`, `summary`, `source`, `source_domain`, `category`, `authors`, `topics`, `tickers` (array), `overall_sentiment_score`, `overall_sentiment_label`, `url`. To filter to one ticker use `'NVDA' = ANY(tickers)` or the auto-unnest alias `tk = 'NVDA'`. Example: `q=tk='NVDA' AND time_published >= NOW() - INTERVAL '1 day'`. Supports group_by + having for aggregation (e.g. count of articles per day). Required: q.
tickerbot_subscribe_events(q, name, kinds, channel, event_q, tickers, universe, device_id, target_url, discord_url)- Create an event-trigger webhook: fires when NEW events land — dividends, splits, insider filings, analyst actions ("every split in my universe", "Goldman downgrades on large caps"). TWO composable filters: `q` filters the event's TICKER STATE (market_cap > 1e10); `event_q` filters the EVENT CONTENT in the /v2/events grammar (payload->>'firm' = 'Goldman Sachs'). Paid plans (webhook slots). Deliveries carry event: "events.fired" with an events array. Latency = ingest cadence: analyst ≤1h, corporate kinds daily — NOT sub-minute like state webhooks. Required: kinds.
tickerbot_subscribe_scan(q, name, cadence, channel, universe, device_id, target_url, discord_url)- Register a webhook that fires when matches for a scan query change. Pass `target_url` for an https POST, or `channel:"discord"` + `discord_url` to post an embed to Discord; omit for in-app delivery in the dashboard. `cadence` is real-time (1m) by default; throttle to hourly or nyse_open. Use to satisfy "alert me when this happens" prompts. Required: q.
tickerbot_subscribe_signal(name, signal, ticker, cadence, channel, universe, condition, device_id, target_url, discord_url)- Register a webhook that fires when a signal turns true (booleans) or its value crosses a condition (numerics). Optional `ticker` restricts to one symbol; omit to watch the whole universe. Pass `target_url` for an https POST, or `channel:"discord"` + `discord_url` to post to Discord; omit for in-app. Required: signal.
tickerbot_subscribe_ticker(name, ticker, cadence, channel, condition, device_id, target_url, discord_url)- Register a webhook that fires when one ticker matches a condition. `condition` is a SQL WHERE-clause fragment scoped to that ticker (e.g. "rsi_14 > 70 AND relative_volume > 2"). Pass `target_url` for an https POST, or `channel:"discord"` + `discord_url` to post to Discord; omit for in-app. Required: ticker, condition.
tickerbot_test_webhook(id)- Send a real-shape `webhook.fired` POST to the webhook's target_url synchronously, right now. The body is byte-identical to a real fire (same signing); the test marker rides in an `X-Tickerbot-Test: true` header. Returns the inline outcome (`delivered`, `http_status`, `elapsed_ms`, `error`). One-shot — a failed test never retries and never auto-disables the webhook. Fails with 400 if the webhook has no target_url (in-app deliveries have nothing to fire over the wire). Required: id.
tickerbot_update_custom_signal(expr, name, new_name, description)- Edit one of the caller's custom signals — supply `expr`, `description`, `new_name`, or any combination. Providing `expr` recompiles it against the live column whitelist. Renaming is refused (409) while other custom signals reference the current name. Built-in signals are read-only; only custom signals the caller owns can be patched. Available on every plan. Required: name.
tickerbot_update_universe(id, add, name, remove, tickers, description)- Update one of the caller's universes. Pass `name`/`description` to relabel, `tickers` to replace the whole list, or `add`/`remove` to adjust subsets without replacing. System universes (`top_10`/`top_100`) cannot be edited. Required: id.
Last successful function declaration observed on . Source: https://api.tickerbot.io/mcp. We list what the server declared; we do not call any of these functions.
Endpoint status observed on . Source: https://api.tickerbot.io/mcp.
Signals
These are separate measurements of different things. They are deliberately not combined into one score, because a popularity number that mixes website traffic with saves and stars cannot be checked or acted on.
| Signal | Value | What it measures | Window | Observed | Source |
|---|---|---|---|---|---|
| Latest published version | 0.1.3 | Latest version string the maintainer published to the registry. | as of fetch | Model Context Protocol | |
| Registry record last updated | 2026-06-11 | When the registry record was last updated by its maintainer. | point in time | Model Context Protocol | |
| First listed in the MCP Registry | 2026-06-11 | Date this server was first published to the official MCP Registry. Not a usage or quality measure. | point in time | Model Context Protocol | |
| mcp tools declared | 35 tools | Number of functions the server itself declared when asked to list them. This is what the server offers an agent, not a measure of how well any of them work. | as of probe | api.tickerbot.io | |
| mcp endpoint status | ok | The server listed 35 functions when asked. | as of probe | api.tickerbot.io |
Where to get it
This record as data
Every field on this page, with its source and observation date, is in the catalog JSON. Fetch the whole kind at once instead of parsing this HTML.
GET /api/v1/entries/mcp_server.json