Vistazo as an MCP server

Build and manage dashboards from your own agent.

Contents

  1. What can your agent do in Vistazo?
  2. Which tools does the server have?
  3. How does your agent read a dashboard?
  4. How does your agent build a widget?
  5. What does a first build look like?
  6. How does your agent reach your sources?
  7. What does a tool call cost?

What can your agent do in Vistazo?

Your agent can build and run Vistazo dashboards through a set of tools served over MCP, an open standard for connecting AI agents to software. Add the server to Claude, Claude Code, Cursor, Codex, Gemini CLI, VS Code or any client that supports remote MCP servers. Connect your own agent has the setup for each one.

https://mcp.vistazo.ai/mcp

Claude Code, Codex and Cursor, which load tools only when they need them, take https://mcp.vistazo.ai/mcp/full. Gemini CLI and VS Code, which load every tool up front, take https://mcp.vistazo.ai/mcp/slim. Connect your own agent lists what each address carries.

Your agent does the thinking, on its own model and its own plan. The tools carry out what it asks. They create a dashboard, wire a widget to a source, set a schedule, or return what a dashboard currently shows.

The server also carries the tools of the sources connected in your workspaces, and its read_docs tool returns any page of these docs. A plain-text index of every page is at /llms.txt.

Which tools does the server have?

About 55 tools, documented in groups.

Group What it covers
Identity and workspaces Who your agent acts as, and the workspaces it can reach
Dashboards Create, find, describe, copy, theme and archive dashboards
Versions Save and roll back dashboards, skills, notebooks and visualizations
Widgets Add widgets, wire them to data, and set their style and layout
Parameters The filters and date ranges a dashboard's widgets read
Refresh and freshness Fetch new data, check how current it is, and try values without publishing
Metric alerts Your own thresholds, changes and anomaly alerts on a widget
Sharing and access Public links and embeds
Data connections The data sources a workspace reads from
Datasets Tables from the files you upload
Skills Procedures written in your workspace, loaded before the work they cover
Workspace knowledge The metrics and dimensions your dashboards declare, and the notes members sign on them
Notebooks Markdown with Python cells
Visualization library Chart code for charts the built-in widgets cannot draw
Product docs Any page of these docs
Workspace administration Members, invitations, usage and the audit log
Governance Assets that need an owner decision

Your client loads only the tools you can use. The administration and governance tools appear only if you are an admin of at least one workspace, and a call against a workspace you do not administer is refused.

Every tool carries the hints MCP defines for when a client should ask you first. Read-only tools are marked read-only. Each write is marked destructive or not, and your client uses those marks to decide which calls to confirm with you.

How does your agent read a dashboard?

get_dashboard returns a dashboard's widgets, its parameters and a written summary of what it shows. The summary includes a plain-language reading of each widget, which often answers a question without fetching anything. get_widget with include: ["data"] returns a widget's last published rows, also without a fetch. refresh fetches new data now and publishes it to everyone who views the dashboard.

list_dashboards with a query searches names, tags and descriptions and ranks the matches. Without one it lists every dashboard you can open, with its widget count, owner and last update.

How does your agent build a widget?

A widget is a pipeline and a payload. The pipeline is one or more stages, each a call to a source tool, followed by one transform, a short script that reshapes their results into rows for the chart. The payload is the chart's configuration.

update_widget changes a widget in sections. Its pipeline replaces the whole pipeline, and pipelineArguments changes only a stage's arguments. Unless your agent also sends the finished rows, pipeline runs the transform first and refuses one that fails. A broken transform never reaches the dashboard that way.

Your agent writes the transform. A refresh your agent starts re-runs the saved transform and never writes a new one. When a source changes shape and the transform no longer fits, that refresh reports stale_transform, and your agent sends a corrected transform. A scheduled refresh repairs the transform itself, unless an admin has turned off Repair broken charts with AI under Settings → Assistant.

What does a first build look like?

This walkthrough builds a dashboard over the hosted Countries source. It has a population chart, a headline figure, a country filter and a weekly refresh. Each step names the tool and the arguments that matter.

  1. get_me lists your workspaces. Take the workspaceId of one marked reachable.

  2. create_dashboard with workspaceId and name returns the new dashboard's id.

  3. set_parameter adds the filter. Pass key: "country", label: "Country", type: "select", options as value and label pairs such as {"value": "BRA", "label": "Brazil"}, and a default value of "BRA". Define a parameter before any pipeline that reads it, because a pipeline renders an undefined parameter as empty. Options you list by hand are not checked against the source, so confirm the codes first.

  4. add_widget twice. The chart takes type: "echartsConfig". The headline figure takes type: "vistazoConfig" with kind: "kpi". Each call returns a widget id.

  5. update_widget for each widget, with the same pipeline. A hosted source's mcpId is its lowercase name, here countries, and list_mcp_connections lists every id in the workspace. toolName is the tool's own name, get_data. argumentTemplate holds the tool's arguments as a JSON string, where {{ params.country }} stands for the filter's value.

    {"database_id": "WB_WDI", "indicator_id": "WB_WDI_SP_POP_TOTL", "country_code": "{{ params.country }}", "start_year": 2000}
    

    transformFunctionBody is the body of a JavaScript function. With one stage it receives the source's result as rawResponse. With several it receives inputs, keyed by each stage's alias. It returns an array of flat rows whose values are strings, numbers, booleans or null.

    return rawResponse.rows
      .map(r => ({ year: Number(r.time_period), population: r.obs_value }))
      .sort((a, b) => a.year - b.year)
    

    fields lists each row key with a label and a type, dimension or measure. The server fetches the source, runs the transform and refuses the write if it throws or returns no rows. The rows it produced are published, so the widget shows data at once.

  6. update_widget with a style sets each payload, the configuration that draws the widget. The chart's goes in echartsConfig. In an ECharts chart each series' name is the row field it reads, so this draws population by year.

    {"xAxis": {"type": "category"}, "yAxis": {"type": "value"}, "series": [{"type": "line", "name": "population"}]}
    

    The headline figure takes {"kind": "kpi", "valueColumn": "population"} as its vistazoConfig, which shows the last row. get_chart_recipe returns complete configurations for other forms. A payload can also ride on add_widget, and style can ride in the same call as step 5's pipeline.

  7. update_dashboard with dashboardId and cadence: { enabled: true, interval, unit }. Match the interval to how often the source publishes. Countries data is annual, so interval: 1 with unit: "weeks" keeps it current, where a daily schedule fetches the same figures 365 times a year. The shortest interval is 15 minutes, and each person can schedule 25 dashboards in a workspace. Limits lists both.

  8. refresh with dashboardId. The rows are already published after step 5. The first refresh also records the shape of each source's response, which a scheduled run uses to notice when a source changes.

  9. get_widget with include: ["data"] for each widget. A reply with ok: true and rowCount: 0 means the fetch matched nothing.

  10. render with kind: "widget" and the chart's id draws the chart on the server and reports what went wrong, such as clipped labels. KPI, table and markdown widgets are not rendered this way.

How does your agent reach your sources?

The same server reaches the tools of every source connected in the workspaces you grant your agent, plus the five public sources Vistazo hosts. Your agent finds one with search_tools and runs it with call_tool, or call_write_tool for one that changes something. It adds no other server and holds no credentials. Your connected sources covers which workspace a call runs in and which tools may run.

What does a tool call cost?

Calling a tool is free. So are the refreshes and data fetches your agent sets off, the hosted sources and your own datasets included. upload_file is free because Vistazo reads a file's tables without a model, and the file counts toward your storage. Your agent's own model calls never count toward anything in Vistazo.

A few things count toward an allowance exactly as they would from the app:

  • run_notebook counts as compute, for each second the cells run.
  • A scheduled refresh that repairs a transform counts as inference.
  • A dashboard's written summary is rewritten in the background after edits, and that counts as inference.

Usage explains the allowances. Rate limits apply to every request your agent sends, and they are listed in Limits.