Horizontal

WorksAI and agents

tlly

Hosted dashboards and scheduled data jobs for AI agents, with thresholds, alerts and share links.

Addresshttps://tlly.dev/mcp
Claude Codeclaude mcp add --transport http tlly https://tlly.dev/mcp
For Cursor and other clients
{
  "mcpServers": {
    "tlly": {
      "type": "http",
      "url": "https://tlly.dev/mcp"
    }
  }
}

Watch out

Has tools that change things: 15 of them

The server itself marks these tools as deleting or overwriting data (destructiveHint): have the agent ask you before it calls them.

Test
Works: Handshake succeeded
Tools
30 tools
Handshake
1.5 s
Transport
streamable-http · 2025-06-18
Tested
6 November 2026
Registry name
dev.tlly/tlly v1.0.0
Listed
30 October 2026
Updated
30 October 2026
Website
tlly.dev
Source
github.com/FifthsegmentEng/tlly-mcp
The last 1 tests
WhenResultTime
2026-11-06 12:23 UTCHandshake succeeded1.5 s

The 30 tools it listed

"Read only" and "Changes data" are the server's own marks. Underlined parameters are required.

  1. add_annotationsChanges data

    Add chart annotations

    Attach short dated notes to a series (e.g. 'Policy rate raised to 4.5%'); shown as markers on charts. Single-line plain text, max 280 chars; one note per date (re-adding replaces it); each counts as one data point.

    annotations series

  2. create_dashboard

    Create dashboard

    Create a hosted dashboard; returns its public URL. Dashboard spec: {"title": str, "description"?: str, "range"?: "1m"|"3m"|"6m"|"ytd"|"1y"|"2y"|"5y"|"10y"|"max", "theme"?: "auto"|"light"|"dark" (default mode; auto follows the viewer's system and viewers can switch), "layout"?: "auto"|"overview"|"detail" (only the default for panels without "display": overview makes them tiles, detail makes them charts, auto makes them tiles above 8 panels), "visibility"?: "public"|"private" (default public: anyone with the link; private: only members of this account signed in to tlly.dev, so embeds and shared links stop working for others), "panels": [{"title"?: str, "series": "name" | ["a","b"], "type"?: "line"|"area"|"bar"|"stat"|"gauge"|"bargauge"|"pie"|"heatmap"|"table", "unit"?: str, "note"?: str, "stale_after_days"?: num, "thresholds"?: {"red_above"?, "yellow_above"?, "yellow_below"?, "red_below"?}, "range"?: (as above, overrides the dashboard's), "section"?: str (starts a new titled section at t

    spec

  3. create_jobChanges data

    Create scheduled job

    Schedule a fetch job. It runs once immediately and the result is returned. Job spec: {"series": name, "cron": "m h dom mon dow" (UTC, at most every 5 min), "request": {"url", "method"?: "GET"|"POST", "headers"?: {}, "body"?: obj|str, "pages"?: {"param": "page", "start"?: 0, "max"?: 1-10} (json with items: bump a query parameter until an empty items array) | {"cursor": "paging.next.after", "into": "after", "max"?: 1-10} (copy that JSON path from each response into the JSON body; stop when it is missing. A cursor that remains after max pages is an error, so a sum is never a partial total. HubSpot CRM search uses this. A json aggregate with no request.pages fails when the body still has another page, paging.next.after, has_more true, links.next, pageInfo.hasNextPage or another next cursor, instead of saving a partial total. Set pages. A response with no next marker is complete.)}, "extract": {"format": "json", "items"?: "path.to.array", "date"?: "field", "

    name spec

  4. define_derivedChanges data

    Define derived series

    Create or replace a derived series, computed from other series every time it is read (always fresh, stores no points, counts toward the series limit). definition: {"op":"add"|"subtract"|"multiply"|"divide","a":series,"b":series} (matched by date) | {"op":"pct_change"|"diff"|"moving_average"|"rolling_min"|"rolling_max"|"shift","a":series,"n"?:1-1000} (shift: the value n points earlier) | {"op":"scale","a":series,"factor":number} | {"op":"resample","a":series,"to":"M"|"Q","how"?:"last"|"mean"|"sum"|"ffill"} (to month/quarter ends; ffill also fills gaps up to today) | {"op":"mean"|"sum","inputs":[2-20 series]} (dates all inputs have) | {"op":"status","a":series,"red"?:[rule],"yellow"?:[rule]} → text labels red/yellow/green (red if any red rule holds, else yellow if any yellow rule, else green); rule: {"series"?:name (default a; read as of each date of a),"above"|"below":number,"for"?:1-24 (holds for the last k points)} or {"all":[2-10 rules]}; at most 10 rules | {"op":"composite","inputs"

    definition series

  5. delete_annotationsChanges data

    Delete chart annotations

    Delete annotations of a series on the given dates, or all of them if dates is omitted.

    dates series

  6. delete_dashboardChanges data

    Delete dashboard

    Delete a dashboard (series data is kept).

    dashboard_id

  7. delete_jobChanges data

    Delete job

    Delete a job (its series data is kept).

    job_id

  8. delete_seriesChanges data

    Delete series data

    Delete all points of a series, or remove a derived series' definition.

    series

  9. get_integration_skillRead only

    Read integration playbook

    Read one integration playbook by id: what to track, the minimum credential and scopes, the exact tlly job, and gotchas. google-sheets and json-api also return a template field (Make a copy, public CSV, downloads). Make a copy https://docs.google.com/spreadsheets/d/1Ty5X3LkY2unxTNGbkq36qDzuuYxQMsuywaTNyzL_pac/copy. Public CSV https://docs.google.com/spreadsheets/d/1Ty5X3LkY2unxTNGbkq36qDzuuYxQMsuywaTNyzL_pac/export?format=csv&gid=1746689811. Downloads /templates/google-sheets.csv and /templates/google-sheets.xlsx. Public: no API key required. Call this before inventing an API URL or scope.

    id

  10. get_seriesRead only

    Read series points

    Read the latest points of a series.

    limit series

  11. get_statusRead only

    Workspace health check

    Health check: failing jobs, stale or empty panels, dashboards, storage usage. Call this to verify everything works.

  12. get_usageRead only

    Storage usage

    Storage usage against quotas (data points = values + annotations, series, dashboards, jobs) and the largest series. Check before large writes.

  13. import_onceChanges data

    Import data once

    Fetch a job spec once and save the result, without scheduling it or using a job slot ("cron" is optional and ignored). Use for one-off dashboards whose data doesn't need to update; points count toward the data quota. Job spec: {"series": name, "cron": "m h dom mon dow" (UTC, at most every 5 min), "request": {"url", "method"?: "GET"|"POST", "headers"?: {}, "body"?: obj|str, "pages"?: {"param": "page", "start"?: 0, "max"?: 1-10} (json with items: bump a query parameter until an empty items array) | {"cursor": "paging.next.after", "into": "after", "max"?: 1-10} (copy that JSON path from each response into the JSON body; stop when it is missing. A cursor that remains after max pages is an error, so a sum is never a partial total. HubSpot CRM search uses this. A json aggregate with no request.pages fails when the body still has another page, paging.next.after, has_more true, links.next, pageInfo.hasNextPage or another next cursor, instead of saving a partial

    spec

  14. list_annotationsRead only

    List chart annotations

    Read the latest annotations of a series.

    limit series

  15. list_dashboard_versionsRead only

    List dashboard versions

    List a dashboard's saved versions (newest first) with which one is live and a members-only preview URL for each.

    dashboard_id

  16. list_dashboardsRead only

    List dashboards

    List dashboards with their URLs.

  17. list_integration_skillsRead only

    List integration playbooks

    List integration setup playbooks (Stripe, Shopify, Sheets, and the other sources tlly can read). A spreadsheet starts from the KPI template. Make a copy https://docs.google.com/spreadsheets/d/1Ty5X3LkY2unxTNGbkq36qDzuuYxQMsuywaTNyzL_pac/copy. Public CSV https://docs.google.com/spreadsheets/d/1Ty5X3LkY2unxTNGbkq36qDzuuYxQMsuywaTNyzL_pac/export?format=csv&gid=1746689811. Downloads /templates/google-sheets.csv and /templates/google-sheets.xlsx. Public: no API key required.

  18. list_jobsRead only

    List jobs

    List scheduled fetch jobs with their last run status and any error message.

  19. list_secretsRead only

    List secret names

    List the names of the workspace's stored secrets (API keys for private sources) and the host each may be sent to. Use one in a job's url, headers or body as {{secret:NAME}}.

  20. list_seriesRead only

    List series

    List all series with their type (number or text), point counts and date ranges; text series also list their values.

  21. publish_dashboard_version

    Publish dashboard version

    Make a saved version of a dashboard the live one (also to roll back). The dashboard keeps its URL and visibility.

    dashboard_id version

  22. push_pointsChanges data

    Write series points

    Write dated values to a series (upsert by date). Use when you compute data yourself. Values are numbers, or short text labels for a text series (e.g. a rating or stance; see Data policy). A series' first write fixes its type.

    points series

  23. rotate_dashboard_urlChanges data

    Rotate dashboard URL

    Give a dashboard a new public URL and disable the old one at once (e.g. if a link leaked). Spec and data are unchanged.

    dashboard_id

  24. run_job_nowChanges data

    Run job now

    Run a scheduled fetch job immediately, store any new points, and return the run result.

    job_id

  25. set_alert_webhookChanges data

    Set alert webhook URL

    Set or clear the workspace webhook URL for job-failure and dashboard status alerts (pass an empty url to clear). When events fire, tlly POSTs JSON to that URL (Slack and Discord incoming webhooks get a short text payload instead). Events include job_failed, status_changed (keep panel "id" fields in specs so alerts stay attached), and threshold_crossed. Email alerts work without a webhook. Caps: 12 emails and 60 webhooks per account per hour; the same panel is not alerted twice within an hour.

    url

  26. set_panel_alertChanges data

    Configure panel alerts

    Set when one dashboard panel sends alert email and/or a webhook (colour change, threshold cross, or off). trigger: change (default), red, notgreen, above, below, or off; above/below need limit. notify: both, email, or webhook. panel is the 0-based index in the live spec. Saving can send immediately if a limit was just crossed (unless this panel alerted within the last hour). Later sends happen after scheduled fetches. Default change+both removes a custom rule. Does not change colour lines or save a dashboard version.

    dashboard_id limit notify panel trigger

  27. set_stale_alertChanges data

    Configure stale-data alerts

    Configure when tlly sends stale-data alert email and webhooks because a series stopped updating. after: auto (from the job schedule and point spacing, at least two days), off, hours, or a window like 48h or 7d. Use dashboard_id for every series on a dashboard, series for one series, or both for one series on one dashboard. One email and one webhook when it goes quiet; another when a newer point arrives. Counts toward the hourly caps.

    after dashboard_id series

  28. test_jobRead only

    Preview a fetch job

    Dry-run a job spec: fetch, extract and transform, return a preview. Saves nothing. Job spec: {"series": name, "cron": "m h dom mon dow" (UTC, at most every 5 min), "request": {"url", "method"?: "GET"|"POST", "headers"?: {}, "body"?: obj|str, "pages"?: {"param": "page", "start"?: 0, "max"?: 1-10} (json with items: bump a query parameter until an empty items array) | {"cursor": "paging.next.after", "into": "after", "max"?: 1-10} (copy that JSON path from each response into the JSON body; stop when it is missing. A cursor that remains after max pages is an error, so a sum is never a partial total. HubSpot CRM search uses this. A json aggregate with no request.pages fails when the body still has another page, paging.next.after, has_more true, links.next, pageInfo.hasNextPage or another next cursor, instead of saving a partial total. Set pages. A response with no next marker is complete.)}, "extract": {"format": "json", "items"?: "path.to.array", "date"?: "f

    spec

  29. update_dashboard

    Update dashboard

    Replace a dashboard's spec (URL stays the same). Every update is saved as a numbered version. With "draft": true it is saved without going live: viewers keep seeing the live version, members can preview the draft at the returned preview_url, and publish_dashboard_version makes it live. Use drafts for larger changes and publish when the user confirms. Dashboard spec: {"title": str, "description"?: str, "range"?: "1m"|"3m"|"6m"|"ytd"|"1y"|"2y"|"5y"|"10y"|"max", "theme"?: "auto"|"light"|"dark" (default mode; auto follows the viewer's system and viewers can switch), "layout"?: "auto"|"overview"|"detail" (only the default for panels without "display": overview makes them tiles, detail makes them charts, auto makes them tiles above 8 panels), "visibility"?: "public"|"private" (default public: anyone with the link; private: only members of this account signed in to tlly.dev, so embeds and shared links stop working for others), "panels": [{"title"?: str, "series": "name" | ["a","b"], "type"?:

    dashboard_id draft note replace_thresholds spec

  30. update_jobChanges data

    Update scheduled job

    Replace a job's spec, or pause it with enabled=false. Job spec: {"series": name, "cron": "m h dom mon dow" (UTC, at most every 5 min), "request": {"url", "method"?: "GET"|"POST", "headers"?: {}, "body"?: obj|str, "pages"?: {"param": "page", "start"?: 0, "max"?: 1-10} (json with items: bump a query parameter until an empty items array) | {"cursor": "paging.next.after", "into": "after", "max"?: 1-10} (copy that JSON path from each response into the JSON body; stop when it is missing. A cursor that remains after max pages is an error, so a sum is never a partial total. HubSpot CRM search uses this. A json aggregate with no request.pages fails when the body still has another page, paging.next.after, has_more true, links.next, pageInfo.hasNextPage or another next cursor, instead of saving a partial total. Set pages. A response with no next marker is complete.)}, "extract": {"format": "json", "items"?: "path.to.array", "date"?: "field", "value": "field", "val

    enabled job_id spec

Is this yours?

Claim it to hear the moment it breaks, correct this page and add your own ways to use it.

A test is the handshake and the tool list: no tool was called. Names and descriptions are as listed by whoever registered the server; we haven't checked them.

Back to Tested MCP Servers