A statistical analyst in your AI chat: bring data and a question, get a citable, re-runnable report.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Your MCP Analytics API key, from https://account.mcpanalytics.ai
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Platform documentation and info: how it works (Answer, Analytics, Custom Analytics), usage.
Topic: platform, manual, connectors, or a docs section
Platform documentation and info: how it works (Answer, Analytics, Custom Analytics), usage.
| Argument | Type | Description |
|---|---|---|
| topic* | string | Topic: platform, manual, connectors, or a docs section |
{
"type": "object",
"required": [
"topic"
],
"properties": {
"topic": {
"type": "string",
"description": "Topic: platform, manual, connectors, or a docs section"
}
}
}Direct link to the right account page for anything not doable in chat: billing, browser upload, report management. Hand the user the link and guide them.
| Argument | Type | Description |
|---|---|---|
| section | string | Where to send the user |
{
"type": "object",
"required": [],
"properties": {
"section": {
"enum": [
"home",
"billing",
"upgrade",
"create",
"upload",
"reports"
],
"type": "string",
"description": "Where to send the user"
}
}
}Apply the user's layout wishes to the estimate's page through the layout agent; a new named arrangement, nothing overwritten, no number changes.
| Argument | Type | Description |
|---|---|---|
| estimate_id* | string | |
| instructions* | string | What to change, in the user's words |
{
"type": "object",
"required": [
"estimate_id",
"instructions"
],
"properties": {
"estimate_id": {
"type": "string"
},
"instructions": {
"type": "string",
"description": "What to change, in the user's words"
}
}
}AI help desk: which analysis fits your question, interpreting results, fixing errors. Multi-turn.
| Argument | Type | Description |
|---|---|---|
| message* | string | Your question or request |
{
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Your question or request"
}
}
}Ask a question across all your delivered analyses: a synthesized answer with citations back to specific reports.
| Argument | Type | Description |
|---|---|---|
| question* | string | Plain-language question to answer from your report library |
{
"type": "object",
"required": [
"question"
],
"properties": {
"question": {
"type": "string",
"description": "Plain-language question to answer from your report library"
}
}
}Check a commissioned build in-chat: stage progress, queue position, rejection reason if the data didn't match the objective, honest ETA, report link when delivered.
| Argument | Type | Description |
|---|---|---|
| pipeline_id | integer | pipeline_id from a build (modify_analysis) |
| track_token | string | Token from the tracking URL |
{
"type": "object",
"required": [],
"properties": {
"pipeline_id": {
"type": "integer",
"description": "pipeline_id from a build (modify_analysis)"
},
"track_token": {
"type": "string",
"description": "Token from the tracking URL"
}
}
}Before naming a library tool: does it fit THIS dataset for THIS question? Column mapping, missing required inputs, method-fit verdict, the places it delivers. Read-only.
| Argument | Type | Description |
|---|---|---|
| objective | string | |
| tool_name* | string | |
| dataset_ref* | string |
{
"type": "object",
"required": [
"tool_name",
"dataset_ref"
],
"properties": {
"objective": {
"type": "string"
},
"tool_name": {
"type": "string"
},
"dataset_ref": {
"type": "string"
}
}
}List and search your uploaded datasets, with fuzzy matching on name, description, and tags. Returns each dataset's uuid:// reference for use in path_resolver and path_tool_run.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Max results |
| search | string | Search by name, description, or tags |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"description": "Max results"
},
"search": {
"type": "string",
"description": "Search by name, description, or tags"
}
}
}Get your data in. Pass `data` as an array of row objects to create the dataset immediately and get a dataset_ref ready for path_resolver; omit it to get an upload link for a file only the user can reach. Add replace_ref (uuid://ID:KEY) with data to REFRESH an existing dataset in place; schedules and tools holding that reference read the new data on their next run.
| Argument | Type | Description |
|---|---|---|
| data | array | Rows as an array of flat objects, creates the dataset in one call |
| expires_in | integer | Token expiration in seconds |
| replace_ref | string | uuid://ID:KEY of an existing dataset to overwrite in place with `data` (the push/refresh mode) |
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object"
},
"description": "Rows as an array of flat objects, creates the dataset in one call"
},
"expires_in": {
"type": "integer",
"default": 300,
"description": "Token expiration in seconds"
},
"replace_ref": {
"type": "string",
"description": "uuid://ID:KEY of an existing dataset to overwrite in place with `data` (the push/refresh mode)"
}
}
}Browse the analyses you can run: the ones you commissioned plus the platform Standard Library (prebuilt tools; each result tagged source:'own' or 'standard_library'). Plain-language match; no query lists everything, your own first. Nothing fits? Commission it with path_resolver.
| Argument | Type | Description |
|---|---|---|
| query | string | Plain-language search over your library + the Standard Library; omit to list everything |
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Plain-language search over your library + the Standard Library; omit to list everything"
}
}
}Before estimating: how did we answer this objective before, on this data or any data? Prior packages and library runs with their tools, mappings, bespoke module names, method and verdicts. Platform-wide, read-only.
| Argument | Type | Description |
|---|---|---|
| k | integer | |
| objective* | string | |
| dataset_ref | string |
{
"type": "object",
"required": [
"objective"
],
"properties": {
"k": {
"type": "integer",
"default": 10
},
"objective": {
"type": "string"
},
"dataset_ref": {
"type": "string"
}
}
}List and search the objects you own across every question: the curated charts, tables and figures of each delivered package, grouped by objective.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| query | string | |
| include_dropped | boolean |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 50
},
"query": {
"type": "string"
},
"include_dropped": {
"type": "boolean",
"default": false
}
}
}Read an analytics package back: status, every run under it, the report link once delivered.
| Argument | Type | Description |
|---|---|---|
| package_id* | string |
{
"type": "object",
"required": [
"package_id"
],
"properties": {
"package_id": {
"type": "string"
}
}
}A read of the data (a total, an average, a count, the top group), computed on every row, in this response. When the question is not a read it says so and names the next step. Time: as path_resolver quotes.
| Argument | Type | Description |
|---|---|---|
| objective* | string | the question, in the person's words |
| dataset_ref* | string | the dataset: a uuid://, upload:// or dataset id the caller owns |
| resolution_id | integer | The resolution_id from path_resolver's path_input. Pass path_input as given. |
{
"type": "object",
"title": "AnswerInput",
"required": [
"objective",
"dataset_ref"
],
"properties": {
"objective": {
"type": "string",
"title": "Objective",
"maxLength": 4000,
"minLength": 3,
"description": "the question, in the person's words"
},
"dataset_ref": {
"type": "string",
"title": "Dataset Ref",
"maxLength": 512,
"minLength": 1,
"description": "the dataset: a uuid://, upload:// or dataset id the caller owns"
},
"resolution_id": {
"type": "integer",
"description": "The resolution_id from path_resolver's path_input. Pass path_input as given."
}
},
"description": "A read of the data computed on every row, in this response. Free. Abstains (immediate=false) when the question\nis not a read; it never guesses.",
"additionalProperties": false
}Order a custom analysis built for this data from a confirmed estimate, optionally with library tools alongside. Needs the person's yes and an idempotency key; a retry returns the first order. Time: as path_resolver quotes.
| Argument | Type | Description |
|---|---|---|
| tool_names | any | library tools to run alongside the build |
| estimate_id* | string | |
| resolution_id | integer | The resolution_id from path_resolver's path_input. Pass path_input as given. |
| idempotency_key* | string | |
| layout_objective | any |
{
"type": "object",
"title": "BespokeInput",
"required": [
"estimate_id",
"idempotency_key"
],
"properties": {
"tool_names": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"title": "Tool Names",
"default": null,
"description": "library tools to run alongside the build"
},
"estimate_id": {
"type": "string",
"title": "Estimate Id",
"maxLength": 128,
"minLength": 1
},
"resolution_id": {
"type": "integer",
"description": "The resolution_id from path_resolver's path_input. Pass path_input as given."
},
"idempotency_key": {
"type": "string",
"title": "Idempotency Key",
"maxLength": 128,
"minLength": 8
},
"layout_objective": {
"anyOf": [
{
"type": "string",
"maxLength": 2000
},
{
"type": "null"
}
],
"title": "Layout Objective",
"default": null
}
},
"description": "PAID. The order that includes a custom build, from a CONFIRMED estimate only. The idempotency key makes a retry\nor a double click replay the first order instead of placing a second (research: Stripe, IETF idempotency draft).",
"additionalProperties": false
}A rough answer over a sample and the layout of the full report, for the person to confirm before anything is ordered. Time: as path_resolver quotes.
| Argument | Type | Description |
|---|---|---|
| objective* | string | the question, in the person's words |
| tool_names | any | |
| dataset_ref* | string | the dataset: a uuid://, upload:// or dataset id the caller owns |
| completeness | any | |
| resolution_id | integer | The resolution_id from path_resolver's path_input. Pass path_input as given. |
| layout_objective | any |
{
"type": "object",
"title": "EstimateInput",
"required": [
"objective",
"dataset_ref"
],
"properties": {
"objective": {
"type": "string",
"title": "Objective",
"maxLength": 4000,
"minLength": 3,
"description": "the question, in the person's words"
},
"tool_names": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
},
"maxItems": 8
},
{
"type": "null"
}
],
"title": "Tool Names",
"default": null
},
"dataset_ref": {
"type": "string",
"title": "Dataset Ref",
"maxLength": 512,
"minLength": 1,
"description": "the dataset: a uuid://, upload:// or dataset id the caller owns"
},
"completeness": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Completeness",
"default": null
},
"resolution_id": {
"type": "integer",
"description": "The resolution_id from path_resolver's path_input. Pass path_input as given."
},
"layout_objective": {
"anyOf": [
{
"type": "string",
"maxLength": 2000
},
{
"type": "null"
}
],
"title": "Layout Objective",
"default": null
}
},
"description": "Free: a rough answer over a sample and the layout of the full report, for the person to confirm.",
"additionalProperties": false
}Run a delivered analysis again, on its own dataset or a new one: the same tools and mappings, no rebuild. Time: as path_resolver quotes.
| Argument | Type | Description |
|---|---|---|
| package_id* | string | |
| dataset_ref | any | absent = the package's own dataset |
| resolution_id | integer | The resolution_id from path_resolver's path_input. Pass path_input as given. |
{
"type": "object",
"title": "RerunInput",
"required": [
"package_id"
],
"properties": {
"package_id": {
"type": "string",
"title": "Package Id",
"maxLength": 128,
"minLength": 1
},
"dataset_ref": {
"anyOf": [
{
"type": "string",
"maxLength": 512
},
{
"type": "null"
}
],
"title": "Dataset Ref",
"default": null,
"description": "absent = the package's own dataset"
},
"resolution_id": {
"type": "integer",
"description": "The resolution_id from path_resolver's path_input. Pass path_input as given."
}
},
"description": "Run a delivered package again, on its own dataset or a new one. Same tools, same mappings; no rebuild.",
"additionalProperties": false
}Which path a question about data should take (reuse, rerun, answer, tool_run, estimate, bespoke, ask or none), with the reason, every path's score and time, and the ready input for the path it picks. Executes nothing and charges nothing.
| Argument | Type | Description |
|---|---|---|
| door | string | |
| meta | array | open list of {key, value}; the caller's entries are always `stated` |
| objective* | string | the question, in the person's words |
| dataset_ref | any | absent = no data yet (the resolver asks for it) |
{
"type": "object",
"$defs": {
"MetaEntry": {
"type": "object",
"title": "MetaEntry",
"required": [
"key"
],
"properties": {
"key": {
"type": "string",
"title": "Key",
"pattern": "^[a-z0-9_.-]+$",
"maxLength": 64,
"minLength": 1
},
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"title": "Note",
"default": null
},
"used": {
"type": "boolean",
"title": "Used",
"default": true
},
"value": {
"title": "Value",
"default": null
},
"source": {
"enum": [
"stated",
"derived"
],
"type": "string",
"title": "Source",
"default": "stated"
}
},
"description": "One piece of metadata about a question (LAT-3752; operator 2026-10-04: \"the metadata should be a list\"). The list\nis OPEN: any key is accepted. `source` says who said it: `stated` (the caller) or `derived` (the server looked it up).\nA caller can only ever produce `stated` entries; entitlement keys are read only from `derived` (meta.RESERVED).",
"additionalProperties": false
}
},
"title": "Question",
"required": [
"objective"
],
"properties": {
"door": {
"enum": [
"account",
"mcp",
"mailroom",
"widget",
"api",
"internal"
],
"type": "string",
"title": "Door",
"default": "api"
},
"meta": {
"type": "array",
"items": {
"$ref": "#/$defs/MetaEntry"
},
"title": "Meta",
"maxItems": 32,
"description": "open list of {key, value}; the caller's entries are always `stated`"
},
"objective": {
"type": "string",
"title": "Objective",
"maxLength": 4000,
"minLength": 3,
"description": "the question, in the person's words"
},
"dataset_ref": {
"anyOf": [
{
"type": "string",
"maxLength": 512
},
{
"type": "null"
}
],
"title": "Dataset Ref",
"default": null,
"description": "absent = no data yet (the resolver asks for it)"
}
},
"description": "What arrives at path_resolver from any door, after the door's own adapter has normalised it.",
"additionalProperties": false
}Hand back the report already delivered for this question on this data. Time: as path_resolver quotes.
| Argument | Type | Description |
|---|---|---|
| objective* | string | the question, in the person's words |
| dataset_ref* | string | the dataset: a uuid://, upload:// or dataset id the caller owns |
| resolution_id | integer | The resolution_id from path_resolver's path_input. Pass path_input as given. |
{
"type": "object",
"title": "ReuseInput",
"required": [
"objective",
"dataset_ref"
],
"properties": {
"objective": {
"type": "string",
"title": "Objective",
"maxLength": 4000,
"minLength": 3,
"description": "the question, in the person's words"
},
"dataset_ref": {
"type": "string",
"title": "Dataset Ref",
"maxLength": 512,
"minLength": 1,
"description": "the dataset: a uuid://, upload:// or dataset id the caller owns"
},
"resolution_id": {
"type": "integer",
"description": "The resolution_id from path_resolver's path_input. Pass path_input as given."
}
},
"description": "Hand back a report already delivered on this data for this question. Re-checked at execution, never trusted\nfrom the suggestion: a report deleted or no longer the caller's is refused, not served.",
"additionalProperties": false
}Run one or more tested library tools on this dataset, with charts and a written report. No custom build. Time: as path_resolver quotes.
| Argument | Type | Description |
|---|---|---|
| objective* | string | the question, in the person's words |
| tool_names* | array | |
| dataset_ref* | string | the dataset: a uuid://, upload:// or dataset id the caller owns |
| estimate_id | any | |
| resolution_id | integer | The resolution_id from path_resolver's path_input. Pass path_input as given. |
| column_mapping | any | dataset column for each input the tool needs; absent = suggested from the data |
| idempotency_key | any | send one per run; a retry with the same key replays the first call instead of running it again |
| module_parameters | any |
{
"type": "object",
"title": "ToolRunInput",
"required": [
"objective",
"dataset_ref",
"tool_names"
],
"properties": {
"objective": {
"type": "string",
"title": "Objective",
"maxLength": 4000,
"minLength": 3,
"description": "the question, in the person's words"
},
"tool_names": {
"type": "array",
"items": {
"type": "string"
},
"title": "Tool Names",
"maxItems": 8,
"minItems": 1
},
"dataset_ref": {
"type": "string",
"title": "Dataset Ref",
"maxLength": 512,
"minLength": 1,
"description": "the dataset: a uuid://, upload:// or dataset id the caller owns"
},
"estimate_id": {
"anyOf": [
{
"type": "string",
"maxLength": 128
},
{
"type": "null"
}
],
"title": "Estimate Id",
"default": null
},
"resolution_id": {
"type": "integer",
"description": "The resolution_id from path_resolver's path_input. Pass path_input as given."
},
"column_mapping": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Column Mapping",
"default": null,
"description": "dataset column for each input the tool needs; absent = suggested from the data"
},
"idempotency_key": {
"anyOf": [
{
"type": "string",
"maxLength": 128,
"minLength": 8
},
{
"type": "null"
}
],
"title": "Idempotency Key",
"default": null,
"description": "send one per run; a retry with the same key replays the first call instead of running it again"
},
"module_parameters": {
"anyOf": [
{
"type": "object"
},
{
"type": "null"
}
],
"title": "Module Parameters",
"default": null
}
},
"description": "One or more tested library tools on this dataset. One tool runs directly; several run as a library-only package\n(no custom build: that is path_bespoke).",
"additionalProperties": false
}Browse a delivered report's individual cards (charts, tables, insights) inline in chat.
| Argument | Type | Description |
|---|---|---|
| processing_id* | string | The report's processing id, returned by path_tool_run or build_status |
{
"type": "object",
"required": [
"processing_id"
],
"properties": {
"processing_id": {
"type": "string",
"description": "The report's processing id, returned by path_tool_run or build_status"
}
}
}Your report library: every analysis delivered, with status and links. Pass semantic_query to search report content in plain language.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Max results |
| semantic_query | string | Natural-language search over your reports' content |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 10,
"description": "Max results"
},
"semantic_query": {
"type": "string",
"description": "Natural-language search over your reports' content"
}
}
}Get a shareable browser link for a report, viewable without authentication.
| Argument | Type | Description |
|---|---|---|
| processing_id* | string | Processing ID from path_tool_run / reports_list |
{
"type": "object",
"required": [
"processing_id"
],
"properties": {
"processing_id": {
"type": "string",
"description": "Processing ID from path_tool_run / reports_list"
}
}
}The estimate as you review it WITH the user: the question as understood, the estimated answer (sample, marked), every place and its question, the page link, a review checklist. Before path_bespoke.
| Argument | Type | Description |
|---|---|---|
| estimate_id* | string |
{
"type": "object",
"required": [
"estimate_id"
],
"properties": {
"estimate_id": {
"type": "string"
}
}
}Standing re-runs of analyses you own: action='create' (weekly/monthly against a re-runnable data reference, connector:// or an https:// link; report emailed after each run), 'list', or 'cancel'.
| Argument | Type | Description |
|---|---|---|
| action* | string | What to do |
| cadence | string | |
| tool_name | string | create: the analysis to schedule |
| dataset_ref | string | create: re-runnable reference (connector:// or https://) |
| schedule_id | integer | cancel: from action='list' |
| column_mapping | object |
{
"type": "object",
"required": [
"action"
],
"properties": {
"action": {
"enum": [
"create",
"list",
"cancel"
],
"type": "string",
"description": "What to do"
},
"cadence": {
"enum": [
"weekly",
"monthly"
],
"type": "string"
},
"tool_name": {
"type": "string",
"description": "create: the analysis to schedule"
},
"dataset_ref": {
"type": "string",
"description": "create: re-runnable reference (connector:// or https://)"
},
"schedule_id": {
"type": "integer",
"description": "cancel: from action='list'"
},
"column_mapping": {
"type": "object"
}
}
}Get an analysis's parameter schema. ALWAYS call before path_tool_run.
| Argument | Type | Description |
|---|---|---|
| tool_name* | string | Name of the analysis |
{
"type": "object",
"required": [
"tool_name"
],
"properties": {
"tool_name": {
"type": "string",
"description": "Name of the analysis"
}
}
}Query your org's data warehouse free: browse the catalog (tables with column roles + computed metrics), semantically find data, plain-language ask, or named templates. Requires warehouse enablement (business plans).
| Argument | Type | Description |
|---|---|---|
| query | string | |
| action* | string | |
| params | object | |
| question | string |
{
"type": "object",
"required": [
"action"
],
"properties": {
"query": {
"type": "string"
},
"action": {
"enum": [
"ask",
"query",
"queries",
"catalog",
"find"
],
"type": "string"
},
"params": {
"type": "object"
},
"question": {
"type": "string"
}
}
}