Vistazo as an MCP server
Build and manage dashboards from your own agent.
Contents
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.
-
get_melists your workspaces. Take theworkspaceIdof one marked reachable. -
create_dashboardwithworkspaceIdandnamereturns the new dashboard's id. -
set_parameteradds the filter. Passkey: "country",label: "Country",type: "select",optionsas value and label pairs such as{"value": "BRA", "label": "Brazil"}, and a defaultvalueof"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. -
add_widgettwice. The chart takestype: "echartsConfig". The headline figure takestype: "vistazoConfig"withkind: "kpi". Each call returns a widget id. -
update_widgetfor each widget, with the samepipeline. A hosted source'smcpIdis its lowercase name, herecountries, andlist_mcp_connectionslists every id in the workspace.toolNameis the tool's own name,get_data.argumentTemplateholds 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}transformFunctionBodyis the body of a JavaScript function. With one stage it receives the source's result asrawResponse. With several it receivesinputs, 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)fieldslists each row key with a label and a type,dimensionormeasure. 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. -
update_widgetwith astylesets each payload, the configuration that draws the widget. The chart's goes inechartsConfig. In an ECharts chart each series'nameis the row field it reads, so this drawspopulationby year.{"xAxis": {"type": "category"}, "yAxis": {"type": "value"}, "series": [{"type": "line", "name": "population"}]}The headline figure takes
{"kind": "kpi", "valueColumn": "population"}as itsvistazoConfig, which shows the last row.get_chart_recipereturns complete configurations for other forms. A payload can also ride onadd_widget, andstylecan ride in the same call as step 5'spipeline. -
update_dashboardwithdashboardIdandcadence: { enabled: true, interval, unit }. Match the interval to how often the source publishes. Countries data is annual, sointerval: 1withunit: "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. -
refreshwithdashboardId. 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. -
get_widgetwithinclude: ["data"]for each widget. A reply withok: trueandrowCount: 0means the fetch matched nothing. -
renderwithkind: "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_notebookcounts 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.