Tools
MCP tools available on the FullVision server
The FullVision MCP mirrors the API: reports, people, audiences and custom reports, plus insights and data-health tools. 38 tools in total. There is no raw SQL and no schema exploration — you ask for a report, not a query. See Setup to connect.
Use this page when you want to know what your AI agent can actually reach, or when it calls the wrong tool and you want to name the right one for it.
Reports
These answer "where does the money come from?" — by page, channel, search keyword, paid campaign, email campaign or form.
One tool per report. Each has a group form (omit the addressing key → ranked
list) and a single form (pass the key → one entity's deep-dive). fields
trims the response blocks; it never widens one.
| Tool | Description |
|---|---|
page-report | Full per-page report — traffic, engagement, first-touch and assisted attribution, revenue, and product events. page_url_scope pins the marketing or product host. |
channel-report | Traffic plus attributed new/returning customers and cash per channel bucket. Omit channel for all 9 buckets ranked; pass one for its sources, top landing pages and outcomes. |
keyword-report | Attributed revenue plus Search Console metrics (clicks, impressions, CTR, position) with striking-distance and content-gap flags per query. Synced GSC data, not live. |
seo-opportunities | Revenue upside of ranking #1, #2 or #3 for pages that earn organic revenue, sized from a blended click-through curve. |
ad-report | Spend-ranked paid-campaign leaderboard with full- and fair-window metrics, campaign LTV/CAC/ROAS (Google-only), and product events. level = campaign / ad_group / ad / keyword. |
form-report | Starts → submits and completion rate, reach plus causal revenue, and (single form) the captured-submissions list. Submissions contain what people typed into your forms — treat them as personal data. |
bot-traffic | Which crawlers (ChatGPT, Claude, Perplexity, Google…) and automated browsers read your site: per-crawler server requests and JavaScript page views, most-crawled pages, a daily trend, and automated-browser page views. server_requests and tracker_pageviews measure different requests — never add them. Group-only. |
youtube | Your YouTube channel from the YouTube APIs: daily channel totals (views, watch minutes, subscribers, thumbnail impressions and CTR, subscriber count), per-video totals, one video's daily trend (needs video_id) and views by traffic source. Lags 2–3 days; plays of videos embedded on the site are web-videos. Group-only. |
Amounts are integer cents in each row's currency. Never sum across currencies.
People
These answer "who?" rather than "how much?". People and journeys return personal data — names, email addresses, event timelines — so an agent should quote them, not dump them.
| Tool | Description |
|---|---|
visitors | Audience profile: device / browser / country splits, active-hours heatmap, new-vs-returning, engagement top-line. Group-only. |
people | Find people by identifier (q: email / cus_… / person id) or by criteria (first-touch channel, plan, paid…). Returns person rows plus a lifetime-revenue summary — never timelines; follow journey_id to journeys. Rows are PII. |
journeys | The event-by-event timeline for one person (journey_id or q) or a cohort — the only surface that returns timelines. Two date axes: from/to is the event window, created_from/created_to is cohort membership. Rows are PII. |
Audiences
Build a segment as a criteria tree, check it, then activate it. The loop is build → preview → revise → commit, then attach a destination.
preview_audience answers a rejected tree with HTTP 200 and
{ "valid": false, "errors": [...] }, not a 4xx. Read the body, not the
status code.
attach_audience_destination starts real delivery. The scheduler uploads
the audience's members to the live ad account on its next tick — there is no
preview and no dry run.
| Tool | Description |
|---|---|
list_audiences | Every audience in the workspace: id, name, member count, refresh cadence, last refresh time and error. Archived audiences excluded. |
create_audience | Create an audience from a criteria_json tree. Names are unique per workspace (409 duplicate_name). Nothing is delivered until a destination is attached. |
get_audience | One audience in full, including its criteria tree, snapshot ids and emailable count. |
update_audience | Patch name, description, refresh cadence or the criteria tree. Replacing the tree invalidates the current snapshot — attached destinations then see a full delta. |
delete_audience | Archive an audience (soft delete). It stops refreshing and its destinations stop receiving members. No un-archive on this surface. |
preview_audience | Validate a tree and estimate its size without creating anything. is_estimate: true with hit_limit: true means the count query timed out — the tree is valid, the number is unknown. |
attach_audience_destination | Attach Google Ads Customer Match, Meta Custom Audience, LinkedIn DMP segment, or a webhook. Ad-platform targets require consent_attested: true and a ready platform connection (409 connection_not_ready). |
list_audience_destinations | The destinations attached to an audience, with per-platform sync state (match_status, list_size, last_synced_at). |
The criteria grammar is documented at
Criteria DSL; the create_audience and
preview_audience tool descriptions carry the same grammar inline, so
your agent has it without reading the docs.
Custom reports
Publish live charts on a FullVision-hosted custom report your team (or a client)
can open, the way you would publish an artifact. A custom report has an id, a
title and a URL on app.fullvision.io, and can be pinned as a tab in the app
sidebar for everyone in the workspace. Add, edit, remove or reorder its blocks,
move a block to another custom report, or create a separate custom report for a
separate audience. An agency working across clients uses each client's own key,
so every custom report lives in that client's workspace. The same custom reports
are available over the REST API.
A block is a { chart, size } card. Its chart is a live request (source: "report"): a report tool
call pinned with its params, re-run on every view rather than a copy of the
numbers. Data charts (source: "data") are refused on custom reports. Cards
with the chart fields at the top level are still accepted until 2026-12-31. Pass
a rolling range (last_30_days, 90d, last_year...) for a custom report
that stays current, or fixed from/to for a period that should not move. Each
block takes a viz. Any viz works on any report: the viz picks which part of the
answer it draws.
- Over time, from the report's
series(needparams.granularityand ametric):line,area, andbarwith a granularity. Up to four more metrics incolumnsadd one line or bar each (for example spend and revenue on one chart).combodrawsmetricas bars andcolumns[0]as a line on its own axis.stacked_barandstacked_areaalso needparams.series_byand draw one layer per segment. - From the ranked
rows(need ametric):barwithout a granularity,bar_table(labelled horizontal bars),pieanddonut(the largest slices, the rest folded into Other), andscatter(also needsmetric_xfor the x axis).tableshows up to sixcolumnsof the ranked rows. - From the totals (need
params.totals: true):big_number(onemetric),big_number_sparkline(also needsparams.granularity), andfunnel(two to six totalcolumns, one per step, in funnel order). heatmapshades a grid. With ametric,columnsnames the row and column dimensions, e.g.visitorswithblock: "active_hours",metric: "page_views",columns: ["day_of_week", "hour"]. Without one, the first column labels each row and the rest are its cells, e.g.block: "retention",columns: ["cohort_period", "m0", "m1", "m2"].
The row vizes (bar without a granularity, bar_table, pie, donut,
scatter, table, heatmap) can draw another list from the answer with
block: visitors has devices, browsers, countries, active_hours and
retention; channel-report has sources; ad-report has landing_pages.
Block rows are summed per label and sorted by the metric.
An invalid combination is rejected with a message naming the field to add.
A key can only request a report it is allowed to read, and a custom report holds
at most 24 blocks. people and journeys cannot be requested, because they return
individual people.
Viewer filters
A custom report, and any single chart on it, can carry filters: controls
that anyone viewing it uses to change the dates or narrow the data without
editing the saved custom report. Add them when the user says which filters a
custom report should offer.
| Key | Applies to | Default | Viewer choices |
|---|---|---|---|
date_range | every chart | { "range": "<preset>" } or { "from", "to" } | the rolling presets; signed-in members also a custom window |
page_url_scope | page-report, channel-report, keyword-report, form-report, visitors | marketing, product or all | those three |
platform | ad-report | one platform | All, google, facebook, linkedin, reddit, twitter |
account_id | ad-report | one option value | All plus the declared options |
campaign_type | ad-report | a list of Google campaign types | SEARCH, PERFORMANCE_MAX, DEMAND_GEN, DISPLAY, VIDEO, SHOPPING, SMART |
exclude_campaign | ad-report | a list of option values | the declared options |
account_id and exclude_campaign need options ({ value, label }, 1 to
50): read the account ids and campaign ids from ad_report first. A custom
report holds at most 6 filters and a chart at most 3. Omit default to keep each chart's
saved value until the viewer picks one.
{
"title": "Paid acquisition",
"filters": [
{ "key": "date_range", "default": { "range": "last_30_days" } },
{ "key": "platform" },
{ "key": "exclude_campaign", "options": [{ "value": "21063556273", "label": "Brand" }] }
],
"blocks": [
{
"size": "wide",
"chart": { "source": "report", "report": "ad-report", "title": "Spend", "viz": "line", "metric": "spend", "params": { "range": "last_30_days", "granularity": "daily" } },
"filters": [{ "key": "campaign_type" }]
}
]
}For each chart, its own filter wins over the custom report's filter, which wins
over the chart's saved params. A custom-report filter must apply to at least one
chart on it, and a chart filter to its own chart; otherwise the write is
refused, and removing the last chart a custom-report filter applies to is
refused until the same call removes the filter. A chart a custom-report filter
does not apply to says so ("Not filtered by Platform"). On update_custom_report, filters replaces the custom report's list
whole ([] removes them); on a card edit, filters replaces that card's list.
| Tool | Description |
|---|---|
list_custom_reports | The workspace's custom reports: id, title, URL, block count, sidebar pin and rank. Pinned custom reports first, in sidebar order. |
get_custom_report | One custom report with its filters and every block as a { id, size, chart, filters? } card. |
create_custom_report | Create a custom report from a title and a list of { chart, size } cards; pinned: true adds it to the sidebar. Returns its id and url. |
update_custom_report | Retitle, pin or unpin (or set the sidebar rank), add { chart, size } cards, edit cards by id ({ block_id, chart?, size? }, a new chart replaces the old one whole) or remove them, and reorder, in one call. Widgets built in the web app can be removed but not edited. |
move_custom_report_block | Move one block to another custom report, keeping its id, title and request. |
delete_custom_report | Delete a custom report; its URL and sidebar tab stop working. |
Insights
Fixes FullVision found for this workspace (landing-page conversion fixes, SEO, ads, retention), each with the issue, the fix, the page URL and an estimated monthly earning. An agent can apply a fix in your codebase or CMS and record it. An applied fix with a metric becomes an experiment, so the agent can also read whether it worked.
| Tool | Description |
|---|---|
list_insights | The workspace's insights with a given status (proposed by default, applied or dismissed), up to limit (default 50, max 200). Needs insights:read. |
get_insight | One insight by id, with its status, note and applied date. Needs insights:read. |
set_insight_status | Mark an insight applied, dismissed or back to proposed, with an optional note (what changed, or why it was dismissed). Needs insights:read and insights:write; read:* does not grant the write. |
list_experiments | The workspace's experiments: each applied insight or ads change with a metric, measured before and after against a control. Filter by status, kind, source (insight, ads_proposal or api) or insight_id, up to limit (default 50, max 200). Each carries its name, prediction, verdict, evidence grade and latest measurement; money is in cents. Needs insights:read. |
get_experiment | One experiment by id, with its latest measurement and the daily target and control counts. Needs insights:read. |
get_experiment_track_record | How well predictions held up, grouped by kind, fix type and metric: completion rate, hit rate weighted by evidence grade (stopped, unapplied and deleted experiments count as misses), median measured ÷ predicted improvement and inconclusive share. Needs insights:read. |
create_experiment | Measure a change you or the customer made on one catalog metric, before and after against a control. Give metric_key with a matching scope ({page_url} for landing_* metrics, {platform, account_id, campaign_ids} for ad_* metrics) and a name, or give insight_id to fill them from the insight, which is then marked applied. changed_at defaults to now and must lie within the last 30 days. Fails with experiment_conflict when a live experiment already measures the same metric and scope, when 50 live experiments were created through the API, or when the insight's current application is already measured. Needs insights:write. |
update_experiment | Change an experiment's name or description (any status), its maximum duration cap_days (only while running, at least the current cap and at most twice the metric's catalog cap) or its change date changed_at (only while starting or running, within 7 days of the current change date). cap_days and changed_at queue a recompute; every field is checked before any is written. Needs insights:write. |
stop_experiment | Stop a running experiment early. The next hourly pass writes a final snapshot with the verdict stopped_early; the stop is final and counts as a miss in the track record. Needs insights:write. |
refresh_experiment | Queue a recompute of a running experiment at the next hourly pass (minute 43 UTC). Calling again before that pass queues nothing more. Needs insights:write. |
delete_experiment | Cancel a starting or running experiment (cancel_reason deleted). The experiment and its measurements stay readable, and a deleted experiment with a prediction counts as a miss. A closed or stopped result is final. In Vizio, asks the user to confirm in the FullVision chat. Needs insights:write. |
Data health
| Tool | Description |
|---|---|
check_data_health | Call BEFORE trusting any number. Runs the three coverage checks (identity reconciliation, checkout-cookie coverage, server-event-cookie coverage) against fixed thresholds and returns a verdict: green = trust the numbers; amber = they are biased low by roughly the coverage gap; red = abort revenue-based decisions; no_data = nothing to measure yet (a new workspace before its first paying customer, checkout or tracked event), not a failure. |
login-funnel | Login pageview → identify or signup in 30 minutes, same visitor_id. OAuth-safe: do not quote bounce on a login URL. from_path is required (path prefixes, each starting with /). Unlinked API signups with no visitor_id never convert. |
Setup
Five tools let a coding agent install FullVision in your project. They appear only on a connection you approved in the browser as a workspace owner, never for a pasted API key. See Install FullVision with your coding agent.
Setup steps, in order: account, stripe_connect, tracker:marketing,
tracker:app, events, checkout, channels. Each has a status: pending,
waiting_on_user, live, skipped or blocked. A pending step that belongs
to another project carries the reason other_repository.
| Tool | Description |
|---|---|
setup_next_step | The next pending step this project can do, with instructions for the project's stack, the values to fill in (tracker key, cookie domain, proxy prefix, connect links), and the setup_verify call to make afterwards. Takes the detected stack: framework, language, has_backend, checkout (stripe_checkout, payment_links, elements, none or unknown), surfaces (marketing and/or app: what this project contains) and optionally no_code (a surface built in webflow, framer, wix, squarespace, wordpress or other). Returns wrap_up when nothing is pending here, with other_repository_steps listing what remains in the other project. |
setup_status | Every step's status and reason, the link to open when Stripe or a channel still needs connecting, and next_step. |
setup_verify | Checks one step now and returns its status. Pass code_in_place: true for tracker:marketing, tracker:app, events or checkout once the code edit is done (for a site builder, once the snippet is pasted). It never waits; call again after retry_seconds. |
setup_create_event_key | Creates a secret key that can only send events and returns it once, for .env as FULLVISION_SECRET_KEY. At most three active setup keys per workspace; beyond that it returns blocked with a link to Settings → API keys. |
setup_skip | Marks stripe_connect, checkout or channels as not needed, with a short reason, after you confirm. The tracker steps and events cannot be skipped. |
