MCP App Store
by KeenEthics

Overview

Cube is the agentic analytics platform, built on a semantic layer. This connector brings it to where you already work. The semantic layer is what makes the AI useful. Your data team defines metrics, dimensions and joins once, and Claude answers against those definitions rather than raw tables — "revenue" means what your team decided it means, not what a column name implies. Claude can search the model, run read-only SQL through the Cube SQL API, and page through large results. It can also build and publish dashboards, edit existing reports, and — for users with data-model permissions — read and edit the semantic model's source files on a dev branch that never touches production. Access follows your existing Cube permissions: users only see the deployments, views and model files their role grants them, and row-level security applies to every query. Requires a Cube account on a Premium or Enterprise plan, with the Viewer role or higher.

Tools

buildPreAggregation

ChatGPT
Queue an on-demand build of one pre-aggregation and return once it is accepted. The build runs asynchronously — poll getPreAggregationStatus afterwards to see whether the partitions were built or to read the failure. Note this runs real queries against the data warehouse and, for external pre-aggregations, writes through the export bucket, so it consumes warehouse resources. Pre-aggregation verification workflow (confirm the rollups/caches a data model defines actually build): getPreAggregationStatus (list pre-aggs, their partitions and last build errors) → buildPreAggregation (trigger a build for one) → getPreAggregationStatus again (confirm it succeeded, or read the exact failure). Omit branchName to use the branch this session is on (the deployed production model unless the endpoint named one); pass the dev branchName from startDataModelEdit to verify pre-aggs added on a branch before deploying, or null to force the deployed model. Use getDeploymentEnv when a build fails on missing configuration such as an export bucket.

chat

ChatGPT
Ask a question about your data through the Cube semantic layer. The agent queries the existing semantic model, runs SQL against your governed metrics and dimensions, and searches existing reports to ground its answers. This tool is read-only — it does not modify the data model, files, workbooks, or reports. If the user asks for a chart, graph, table, visualization, or dashboard-style output, answer in text because the visualize tool is not available for this client. Pass branchName to run the turn against a dev branch's un-deployed data model AND its agent configuration (skills, rules, spaces), which is how a branch is exercised before it is deployed; the branch used comes back as branchName (null = deployed model). A conversation stays on the branch it started on, so omit branchName when resuming with a chatId and start a new chat to ask the same question of another branch. The response's cubeChatUrl field is the only valid link to this conversation in Cube — no other URL opens it. It is null when the conversation has no linkable Cube page.

commitDataModelChanges

ChatGPT
Commit the dev branch’s edits onto the branch it was created from. This is what makes your work exist outside the development session: until you call it, everything writeDataModelFile saved lives only in the dev worker’s working copy — it is not on any branch the user can select, nobody reviewing sees it, and telling the user the change is ready would be wrong. Call it once the model compiles; the dev branch stays usable afterwards so you can keep editing. Usually the parent is an ordinary branch and this does NOT touch production — but a dev branch created from the deployment’s default branch publishes live, and that call is refused until the user has confirmed it. Afterwards, name the branch it reports (targetBranchName) to the user and offer switchUserBranch so they can look at it. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

commitToNewBranch

ChatGPT
Commit the dev branch’s edits to a NEW branch instead of the one it was created from, optionally opening a pull request. Use it when the work should be reviewed on a branch of its own; use commitDataModelChanges when it should land on the branch the session forked from. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

createFolder

ChatGPT
Create a workspace folder, at the root or inside parentId. It starts empty: file an exploration into it with folderId on createReport / updateReport, or move existing items in with moveWorkspaceItem.

createReport

ChatGPT
Save a query + its visualization as a Report, and return its numeric reportId and a url. The report always carries a chartCategory: "table" (default), "vega" (pass vegaSpec for a Vega-Lite graph), "kpi" (pass kpiChartSpec for a KPI metric tile), "html" (pass htmlChartSpec), "map" (pass mapChartSpec), or "sankey" (pass sankeyChartSpec for a flow diagram) — a KPI tile is a CHART widget backed by a kpi-category report. WHERE IT LANDS is decided by workbookId, and the two placements are visible in different places. WITH a workbookId: the report becomes a tab of that workbook and can be referenced by a CHART widget on that workbook's dashboard — create it here first, then pass the returned reportId to updateDashboard; it will NOT appear in the workspace report list or the Google Sheets / Excel add-on. WITHOUT a workbookId: a standalone exploration at the workspace root (or under folderId), which IS what the workspace browser and the Sheets/Excel add-on list, and which no dashboard widget can reference. Never invent a reportId and never use a raw query id — that produces empty "deleted" widgets. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

createWorkbook

ChatGPT
Create a new empty workbook — the container that holds reports and a dashboard. Returns its numeric workbookId (which every other dashboard tool needs) and a url you can share with the user to open the new dashboard. Do NOT create a workbook if you were given one to build into. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

create_dashboard

ChatGPT
Create a Cube dashboard with tabs, widgets, layouts, and data sources. IMPORTANT: The IDs for filters, row_header_dimension_ids, and column_header_dimension_ids must be retrieved first using the get_chart_of_accounts tool. Do not guess these IDs. Args: name: The name of the dashboard. Must be unique within the company. ctx: The context of the request. This is used to get the user company from the request context. description: Optional description of the dashboard. filters: Optional global dashboard filters where each key is a top-level dimension name and each value is a member dimension ID from that hierarchy. tabs: Optional list of tab definitions. Each tab can include a name and widgets. Widget definitions include name, type, visual_type, filters, row_header_dimension_ids, column_header_dimension_ids, layout_x, layout_y, width, height, and settings. Returns: A message with the created dashboard ID or a validation error explaining what needs to be fixed.

create_dimension

ChatGPT
Create a new dimension under an existing parent dimension. IMPORTANT: parent_id must be retrieved first using the get_chart_of_accounts tool. Do not guess IDs. When the parent is under the Scenario top-level dimension, the new dimension is created with AI write protection so it can receive published data via publish_data. Otherwise write protection defaults to none. Args: parent_id: The ID of the parent dimension from the Chart of Accounts. name: The name of the dimension to create. rollup_type: Time rollup type. Valid values: SUM, AVERAGE, BALANCE, BEGINNING_BALANCE, or an empty string when rollup does not apply (e.g. non-Account/Scenario hierarchies). Scenario children typically use SUM. ctx: The context of the request. This is used to get the user company from the request context. Returns: The created dimension as JSON with id, name, parent_id, rollup_type, and write_protection, or a validation error message.

create_formula

ChatGPT
Create a new formula dimension under an existing parent. CONFIRM WITH THE USER BEFORE CALLING. Formula calculation runs in the background after create and can be expensive depending on formula complexity. Calculated values are not available immediately. Before calling, show the user the proposed name, parent, and exact formula text and wait for confirmation. IMPORTANT: parent_id and all dimension names referenced in the formula must come from get_chart_of_accounts in this session. Do not guess IDs or names. Formula syntax (quoted dimension names preferred). Call get_formula_syntax before writing non-trivial expressions (IF composition, functions, SKIP, intersections, TABLE_LOOKUP). - Dimension refs: "Revenue" or <id> - Operators: + - * / ^, unary +/-, parentheses - Comparisons: = != > >= < <=; AND / OR (case-insensitive) - Conditionals: IF(condition, true_expr, false_expr) - Constraints: referenced dimensions must share the new dimension's TLD; no Time, tags, self, or parent; at least one dimension reference required The formula applies to all scenarios. Write protection is none (formula members are not writable). Args: parent_id: Parent dimension ID from get_chart_of_accounts. name: Name of the new formula dimension. formula: Formula expression using names from the chart of accounts. rollup_type: Time rollup type. Valid values: SUM, AVERAGE, BALANCE, BEGINNING_BALANCE, or "". Use BALANCE when the formula includes RUNNING_TOTAL. ctx: The context of the request. This is used to get the user company from the request context. rollup_logic: ROLLUP_THEN_APPLY_FORMULA (default) or APPLY_FORMULA_THEN_ROLLUP. Returns: JSON with the created dimension id, name, parent_id, rollup_type, type, formula, rollup_logic, and a message that background calculation is in progress; or a validation/permission error to fix and retry.

create_planning_table

ChatGPT
Create a planning table with a typed column schema and empty datasets for the given scenarios. IMPORTANT: Call get_planning_table_schema_options first for valid column types, required attributes, format enums, and top-level dimension IDs (tld_id for dimension columns). Call get_chart_of_accounts for Scenario member IDs to pass in scenario_ids. Creates one header-only dataset per scenario so write_planning_table_data can populate data next. Only AI-write-protected scenarios (write_protection = 'AI') can subsequently receive data via write_planning_table_data, even though any writable scenario may be used at create time. Column types: text, number, date, enum, dimension, calculation. Omit column id (auto-assigned). Calculated columns require required=false and a formula; output_type is inferred on save. sharing_scheme may be MANAGERS (default) or ALL — SPECIFIC is not supported via MCP. Args: name: Unique planning table name within the company. schema: List of column definitions. Each column needs name, type, required, plus type-specific attributes from get_planning_table_schema_options. scenario_ids: Writable Scenario dimension member IDs from get_chart_of_accounts. At least one required. Empty header-only datasets are created for each. ctx: The context of the request. This is used to get the user company from the request context. sharing_scheme: MANAGERS (default) or ALL. Returns: JSON with the created table id, name, columns, sharing_scheme, and scenario_ids, or a rejection message describing schema/permission failures to fix before retrying.

create_tag

ChatGPT
Create a new tag with the given name and member dimensions. IMPORTANT: Member IDs must be retrieved first using the get_chart_of_accounts tool. All member dimensions must belong to the same top-level dimension. Args: name: The name of the tag to create. member_ids: List of dimension IDs to include as tag members. ctx: The context of the request. This is used to get the user company from the request context. Returns: The created tag as JSON with id, name, and member names, or a validation error message.

create_task

ChatGPT
Create a new draft task on a workflow. Call list_workflows first to get workflow_id. The task is created as DRAFT with no assignee. Use due_date as an ISO date string (YYYY-MM-DD); omit or pass empty string for no due date. Args: workflow_id: The workflow (process) ID from list_workflows. name: Task name (must be unique within the workflow). ctx: The context of the request. This is used to get the user company from the request context. description: Optional task description. due_date: Optional ISO date string (YYYY-MM-DD). Must not be in the past. Returns: The created task as JSON, or a validation/permission error message.

create_workflow

ChatGPT
Create a new workflow (process). The workflow is created with NOT_STARTED status and the current user as owner. Args: name: Unique workflow name within the company. ctx: The context of the request. This is used to get the user company from the request context. description: Optional workflow description. Returns: The created workflow as JSON, or a validation/permission error message.

deleteDataModelFile

ChatGPT
Delete a Cube semantic model source file on your dev branch. Requires the dev branchName from startDataModelEdit. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

deleteFolder

ChatGPT
Delete a workspace folder. What was inside it — explorations, workbooks, dashboards — is NOT deleted: it moves to the workspace root. A folder that still holds sub-folders cannot be deleted; move or delete those first.

deleteReport

ChatGPT
Permanently delete a report by its numeric id. Works for both standalone and workbook-bound reports. WARNING: if a dashboard CHART widget still references this reportId, its tile will render empty ("deleted") until you remove or re-point the widget with updateDashboard — delete the widget first, or instead of deleting, edit the report in place with updateReport. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

discardDataModelChanges

ChatGPT
Throw away the dev branch’s pending edits, resetting it to its parent (or to a specific commit hash). Use it to start over when the model will not compile and the way back is unclear. The edits are not recoverable, so only call it when the user asked to discard, or when the changes are yours from this same session and you are deliberately restarting. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

duplicate_scenario

ChatGPT
Duplicate an existing Scenario into a new AI-managed Scenario. IMPORTANT: source_scenario_id must be retrieved first using the get_chart_of_accounts tool. Do not guess IDs. The duplication copies leaf-level cube values from the source Scenario in the background. The new Scenario ID is not available immediately; tell the user it is running in the background and they will receive an email when it completes. After it finishes, the new Scenario has AI write protection so publish_data can write to it. Args: source_scenario_id: The dimension ID of the existing Scenario to copy data from. new_name: The name for the new duplicated scenario. ctx: The context of the request. This is used to get the user company from the request context. Returns: A message that duplication is running in the background, or a validation/permission error to fix and retry.

getBranchDiff

ChatGPT
Show what a branch changed to the data model: the complete changed-file list with per-file insertion/deletion counts, plus the unified diff. Works for ANY branch (feature branches included) and compares against the deploy branch by default, so this is the tool for "what did this branch change?". Prefer it over reading files one by one: when a branch edits existing cubes (adding a pre_aggregations block, say) the file LIST is identical on both branches, so listDataModelFiles reveals nothing. On a large change the patch may be trimmed or omitted — diffComplete: false plus message says so explicitly, while files, insertions and deletions still describe the FULL change, so never infer the size of a change from the length of the returned patch. ONE exception, and check it first: if comparable is false (with reason: "no-common-history" and usedMergeBase: false) the two branches share no ancestor, so nothing was compared — the empty files and zero counts mean UNKNOWN, not "no changes", and no narrower request will return anything. Diff against a branch the target was created from instead. Use getDataModelChanges instead only when you specifically want your own dev branch versus its immediate parent. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

getBranchState

ChatGPT
Report which branch this session works on, which branch the USER is looking at in the Cube console, which branch is the deployment’s production branch, and whether the branch has edits that are not committed yet. Call it before editing (so work does not land somewhere the user will never look) and after committing (to see whether the user still has to be switched over). The two names differ far more often than they look like they should: a session connected to a dev branch edits a private working copy the user’s branch switcher never shows. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

getDataModelChanges

ChatGPT
Show the diff of your dev branch against its parent — the pending data-model changes. Use this to review edits before committing. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

getDataModelHistory

ChatGPT
The git commit log of the data model, newest first: SHA, author name and email, commit date and subject. Answers "who changed this file?" and "what changed recently?". Pass filePath to limit it to one file, branchName to read a branch other than production. hasMore: true means older commits exist past limit. Only committed work appears; uncommitted dev-branch edits do not. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

getDeploymentEnv

ChatGPT
List the deployment’s environment variables, with every secret-looking value redacted to [ENCRYPTED]. Use it to confirm configuration is present and shaped as expected — for example an export bucket (CUBEJS_DB_EXPORT_BUCKET, CUBEJS_DB_EXPORT_BUCKET_TYPE) when an external pre-aggregation build fails on missing config. Read-only: this tool cannot change env vars. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

getPreAggregationStatus

ChatGPT
List the data model’s pre-aggregations with their definitions and, for each, how many partitions exist, how many have actually been built, when the newest build landed, and the exact error if a build failed. This is how you verify pre-aggregations work: a query alone cannot prove a rollup was used, and external pre-aggregations fail in configuration-specific ways (a missing export bucket, denied bucket permissions) that only a build surfaces. Pre-aggregation verification workflow (confirm the rollups/caches a data model defines actually build): getPreAggregationStatus (list pre-aggs, their partitions and last build errors) → buildPreAggregation (trigger a build for one) → getPreAggregationStatus again (confirm it succeeded, or read the exact failure). Omit branchName to use the branch this session is on (the deployed production model unless the endpoint named one); pass the dev branchName from startDataModelEdit to verify pre-aggs added on a branch before deploying, or null to force the deployed model. Use getDeploymentEnv when a build fails on missing configuration such as an export bucket.

get_change_history

ChatGPT
Return recent audit trail changes for the selected company. Answers questions like "what has changed in my cube recently?" Events include spreadsheet publishes, AI publishes, data imports, reverts, and source-system dimension re-syncs. Each row includes who made the change, when it occurred, and OlapCubeChange.metadata (document/sheet/range, import date range, etc.). Rows that share the same batch_id belong to one user action (e.g. a batched dimension remap) and should be summarized together. Args: ctx: Request context used to resolve the selected user company. start_date: Optional ISO-8601 start of the window. Defaults to 30 days ago. end_date: Optional ISO-8601 end of the window. Defaults to now. limit: Max events to return (default 25, max 100). user_ids: Optional list of user IDs to restrict results to. event_type: Optional event type name. Valid values: CubeChangeEvent, ConnectionSyncEvent. Returns: JSON with start_date, end_date, returned, truncated, and changes. Each change has change_id, occurred_at, changed_by, event_type, change_type, message, status, num_changes, batch_id, metadata, link, and reverted_by_change_id.

get_chart_of_accounts

ChatGPT
Get the Chart of Accounts for this company

get_dashboard

ChatGPT
Get a Cube dashboard by ID, including tabs, widgets, layout, and range dimensions

get_dimension_children

ChatGPT
Browse direct children of a dimension when chart-of-accounts children were truncated. Use after get_chart_of_accounts returns a node with _children_truncated. Dimension IDs must come from get_chart_of_accounts in this session. Paginate with offset/limit; optionally filter with name_contains for wide lists (hundreds of children). Args: dimension_id: Parent dimension ID from get_chart_of_accounts. ctx: The context of the request. This is used to get the user company from the request context. offset: Zero-based index into the filtered child list (default 0). limit: Max children to return per page (default 100). name_contains: Optional case-insensitive substring filter on child names. Returns: JSON envelope with parent_id, parent_name, total, offset, limit, has_more, and children.

get_drilldown_data

ChatGPT
Use this for TRANSACTION-LEVEL auditing. This is the lowest level of detail available. Use this when a user asks for "source data," "specific transactions," or "the details behind this number." A header will be present for each dimension the company has, the value of the data point, as well as any additional metadata that is stored about that data point. IMPORTANT: The IDs for 'filter_dimension_ids' MUST be retrieved first using the 'get_chart_of_accounts' tool. Do not guess these IDs. All dimensions must be represented in this dictionary. Prefer using 'get_financial_slice_of_data' for aggregated reporting. Only use this tool when transaction-level detail is specifically requested. Args: filter_dimension_ids: A dictionary where each key is a dimension name and each value is the ID of a single child from that dimension in the Chart of Accounts. All dimensions must be represented in this dictionary. operation: A pandas DataFrame operation to run on the drilldown data. Common operations: - 'head': Returns first N rows (e.g., {'n': 10}). Use to preview the data structure. - 'sort_values': Find outliers (e.g., {'by': 'Value', 'ascending': False}). - 'query': Filter further (e.g., {'expr': 'Value > 10000'}). - 'sum': Aggregate a column (e.g., {'numeric_only': True}). operation_parameters: The parameters to pass to the pandas operation. See pandas DataFrame documentation for operation-specific parameters. ctx: The context of the request. This is used to get the user company from the request context. Returns: The result of the pandas operation as a string. If the resulting DataFrame exceeds 500 rows, it will be automatically truncated with a warning. If you see a truncation warning, refine your 'operation_parameters' to be more specific (e.g., use more filters or aggregation operations like 'sum()', 'mean()', etc.).

get_financial_slice_of_data

ChatGPT
Use this function to get a slice of financial data for this company. This function acts like a pivot table in a spreadsheet and will show a slice of financial data. The row and column headers will be on the top and left side of the grid. The filters will be applied to the data in the grid. Think of this as building a Summary Table. It aggregates data into a grid based on the dimensions you provide. IMPORTANT: The IDs for 'filters', 'row_header_dimension_ids', and 'column_header_dimension_ids' MUST be retrieved first using the 'get_chart_of_accounts' tool. Do not guess these IDs. Args: filters: A dictionary where each key is a dimension name and each value is the ID of a single child from that dimension in the Chart of Accounts. If a dimension is included in the filters, it should not be included in the row or column headers. These are global constraints on the data. row_header_dimension_ids: A list of IDs of children from a single dimension. This dimension IDs must be from the company's Chart of Accounts. This cannot be empty. column_header_dimension_ids: A list of IDs of children from a single dimension. This dimension IDs must be from the company's Chart of Accounts. This cannot be empty. ctx: The context of the request. This is used to get the user company from the request context. Returns: A slice of financial data comprised of a grid of values with their corresponding row and column header dimension names added in the first row and column.

get_formula_syntax

ChatGPT
Get full Cube formula syntax: IF, functions, SKIP, intersections, TABLE_LOOKUP, and constraints

get_planning_table_data

ChatGPT
Get the 2D data grid for a planning table in a specific scenario. Planning tables store typed columnar data (text, number, dimension, calculated columns) used for strategic planning such as headcount. Call list_planning_tables first to discover available table IDs. Scenario IDs must come from get_chart_of_accounts (Scenario dimension). Returns JSON with planning_table_name, scenario_id, headers (column names), and rows (2D array of cell values). Rows the user cannot access due to dimension permissions are excluded. Args: planning_table_id: The ID of the planning table from list_planning_tables. scenario_id: The Scenario dimension member ID from get_chart_of_accounts. ctx: The context of the request. This is used to get the user company from the request context. Returns: JSON string with headers and filtered data rows for the planning table dataset.

get_planning_table_schema_options

ChatGPT
Get valid planning table column types, attributes, formats, and the company top-level dimensions for dimension columns. Call before create_planning_table.

get_widget_settings_schema

ChatGPT
Get available widget settings fields and valid values for dashboard widgets

initiate_import

ChatGPT
Start a data import for a connection's data table. Prefer reusing parameters from list_connections recent_imports: start_time_dimension_id, end_time_dimension_id, scenario_dimension_id, and other_dimensions (flat leaf IDs for defaults such as Department). Dimension IDs may also come from get_chart_of_accounts. When other_dimension_ids is omitted, the tool reuses defaults from the most recent successful import for that connection. If there is no prior successful import, you must pass other_dimension_ids explicitly. If a prior initiate_import failed with "Sync source dimensions before importing", confirm with the user first, then retry with sync_dimensions_first=True. If the response has status DIMENSION_SYNC_BACKGROUNDED, tell the user to wait for the background sync to finish, then call initiate_import again without sync_dimensions_first. Args: data_table_id: The data_table_id from list_connections for the connection to import. scenario_id: Scenario dimension member ID to import into. start_time_dimension_id: Start of the Time range to import. end_time_dimension_id: End of the Time range to import. ctx: The context of the request. This is used to get the user company from the request context. other_dimension_ids: Optional list of default leaf dimension IDs for non-mapped TLDs (e.g. Department). Exclude Scenario and Time; Scenario is passed separately. sync_dimensions_first: When True, sync source dimensions before starting the import. Use only after confirming with the user when a prior attempt required a sync. Returns: The started import object as JSON (id, status, time/scenario dimensions, etc.), or a DIMENSION_SYNC_BACKGROUNDED status when the sync was started in the background.

listDataModelFiles

ChatGPT
List the Cube semantic model SOURCE files (the raw .yml / .js / .py schema files that define cubes and views) on a branch. Use this to discover which files to read/edit — it complements searchDataModel, which returns the compiled meta rather than the editable source. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

listDataSources

ChatGPT
List the data sources configured on this deployment (name and database type) — the warehouses/databases Cube can query, as distinct from the Cube semantic model built on top of them. Use this before runSourceQuery to find a valid dataSource name.

listDeployments

ChatGPT
Returns all Cube deployments and their agents that you can access. Use this to discover valid deploymentId values before passing them to any other tool: every tool takes an optional deploymentId and defaults to the deployment this session connected to, so pass one explicitly whenever the user asks about a different deployment. Passing an id not listed here is rejected. Every deployment supports the Auto agent (pass agentId: null to chat) — the default agent used when no specific agent is selected — in addition to any configured agents listed.

listWorkspaceItems

ChatGPT
List the workspace: folders, workbooks (each can hold a dashboard) and standalone reports (saved explorations), each with its type, id, name and the folderId it sits in (null = root). Every id another tool needs comes from here — never guess one: a FOLDER id is folderId on createReport / updateReport / moveWorkspaceItem, a WORKBOOK id is workbookId on readWorkbook / updateDashboard, a REPORT id is reportId on readReport / updateReport. Pass search to find an item by name in any folder; otherwise one folder level is listed. Pages hold up to 100 items — pass nextCursor back as cursor for the next one.

list_companies

ChatGPT
List all companies the user has access to

list_connections

ChatGPT
List the company's data connections, each with its most recent imports and scheduled-import configuration

list_dashboards

ChatGPT
List Cube dashboards the user has access to

list_planning_tables

ChatGPT
List planning tables the user has access to

list_tags

ChatGPT
List all tags and their members for this company

list_tasks

ChatGPT
List tasks for a workflow the user has access to. Call list_workflows first to discover workflow IDs. workflow_id is required. Args: workflow_id: The workflow (process) ID from list_workflows. ctx: The context of the request. This is used to get the user company from the request context. status: Optional task status filter. Valid values: DRAFT, TODO, DONE. Returns: JSON list of tasks with id, name, description, status, due_date, assignee_id, and process_id.

list_workflows

ChatGPT
List workflows (processes) the user has access to, with optional status filter

loadQueryResults

ChatGPT
Fetch additional rows of a SQL query that a prior chat tool call already executed. The original query is re-run against the Cube semantic layer (the same SQL, no LIMIT/OFFSET injected) so it can be served from Cube's cache, and 100 rows starting at offset are returned. Use this ONLY when the user explicitly asks for more rows of a previous query. Identify the query via the id (uuid) of one of the SQL queries the prior chat response reported: take it from that response's cubeSqlApiQueries[*].id, which lists every query that turn ran. (toolCalls[*].calls[*].id carries the same uuid, but only for queries the answer cited explicitly, so it is often empty — prefer the former.) Page size is fixed at 100 — paginate by incrementing offset in steps of 100 (calls with different offsets may be issued in parallel) until the response reports hasMore: false. Do NOT call this tool to retry a failed query — re-issue the chat request instead.

mergeToDefaultBranch

ChatGPT
Merge a branch into the deployment’s default (production) branch, making its changes live for everyone. This is a publish step with real consequences, so call it ONLY when the user has explicitly asked to publish or merge to production — never on your own initiative after committing. Commit first with commitDataModelChanges: this merges committed branches, not the development session. Prefer letting the user test the branch first (switchUserBranch). Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

moveWorkspaceItem

ChatGPT
Move a folder, workbook or standalone report into another folder, or to the workspace root with folderId: null. Take the item and the destination from listWorkspaceItems. A folder moves with everything inside it. To file an exploration as you save it, pass folderId on createReport instead.

publishDashboard

ChatGPT
Publish the workbook’s current dashboard draft to make it live. Idempotent — publishing an unchanged draft is a no-op (reported via warning). Returns the live dashboard url (share this with the user) and its dashboardPublicId. Only publish after updateDashboard returned success and you have verified the layout. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

publish_data

ChatGPT
Publish financial data to an AI-managed Scenario in the cube. IMPORTANT: Call get_chart_of_accounts first and enumerate this cube's actual TLDs and leaf members. Only Account, Time, Scenario, and Department are guaranteed; all other TLDs are customer-defined and vary by cube (Entity, Market, Product, Vendor, Region, etc. — or none). All dimension references (row headers, column headers, filter values) must be IDs from that response — never hardcode names or reuse IDs from memory or a previous session/company. PERFORMANCE: Each publish triggers formula recalculations and is a heavy operation. Minimize the number of publish calls by batching as much data as possible into each one. Use multiple row headers and column headers to publish a wide matrix in a single call rather than making many small publishes. For example, publish all accounts x all time periods in one call instead of one call per account or per period. COMPLETENESS AND LEAF-LEVEL RULE: Every TLD the cube has must appear on a row/column axis in data or as a key in filters. Data is stored only at child (leaf) members — parents, formula members, and tag members cannot be written to (they recalculate from inputs). Write leaf driver accounts and let formula rollups (Net Income, EBITDA, Gross Margin, etc.) recompute. Filters pin exactly one leaf per dimension for the whole call. NESTED ROW AXES: Multiple dimensions nest on the row axis (stacked header columns, one per dimension) with Time across the columns. A fully-dimensional dataset publishes as a single range. Do not loop one publish per dimension-combination — batch all intersections and periods into one wide payload. Example with Account and Department on rows, Time on columns, Scenario in filters (IDs illustrative; use real IDs from get_chart_of_accounts; pivot cells in the top-left are empty strings): [["", "", time_id_1, time_id_2], [acct_id_1, dept_id_1, 100, 200], [acct_id_1, dept_id_2, 300, 400], [acct_id_2, dept_id_1, 150, 250]] DISTRIBUTE HIGH-LEVEL CHANGES: Changes are usually described at a high level ("grow platform revenue 8%", "hold S&M flat"), but the cube stores at leaf intersections. Don't collapse a high-level change onto an arbitrary or single leaf — look at how the baseline scenario the change builds on is broken down across dimensions and distribute in a way that respects that shape. Read real joint intersections via get_financial_slice_of_data where possible rather than reconstructing from marginals or assuming; reason per line, since different lines break down differently. This is default behavior, not a hard rule: explicit user guidance on how a change should land overrides it. Be transparent that any dimensional detail so introduced is inferred from the baseline, not user-specified. The Scenario dimension must be included in filters and must target an AI-managed scenario (write_protection = 'AI'). Args: data: 2D array. Column headers (Time IDs) occupy the first row after empty pivot cells. Nested row-axis dimensions occupy leading columns of each data row (one cell per TLD), then numeric values. Include as many rows and columns as possible to minimize total publish calls. filters: TLD name -> member dimension ID. Must include Scenario and all other TLDs not represented in row/column headers. Each value must be a writable leaf member ID. message: Changelog description for the publish. ctx: MCP context. Returns: A summary of values updated and an audit trail link, validation errors, or a background-processing message if the publish is still running after monitoring completes (publishes always run via a background worker with up to ~3 minutes of status polling before returning).

readDataModelFile

ChatGPT
Read the raw source of one Cube semantic model file (the editable YAML/JS defining a cube or view). Read this before writeDataModelFile so you edit on top of the current content rather than overwriting it. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

readReport

ChatGPT
Read one saved report by its numeric id: its title, sqlQuery, chart category + spec (in meta), placement (workbookId — null for a standalone exploration — and folderId), publicId, and a shareable url. Use it to inspect a report before updateReport, or to see what a dashboard CHART widget (config.reportId) points at. Reads a single report by id — works for both standalone and workbook-bound reports, unlike a report list which the server filters to workbook-less rows. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

readWorkbook

ChatGPT
Read a workbook: its name and its current dashboard dashboardDraft and dashboardPublished configs. ALWAYS call this before updateDashboard so you can pass the current draft as oldDashboardConfig (concurrency guard) and edit on top of it rather than overwriting. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

renameFolder

ChatGPT
Rename a workspace folder. Take its id from listWorkspaceItems.

runQuery

ChatGPT
Run a Cube SQL query against the Cube SQL API (PostgreSQL dialect — see https://docs.cube.dev/reference/core-data-apis/sql-api) and return the result rows. Returns schema (columns), a page of data rows (limit rows, 100 by default), and hasMore/totalRows for pagination via offset. Read-only — it does not modify the model, workbooks, or reports. Use searchDataModel first to find the exact cubes/views and members to query — never guess member names, and call it with the same branchName so it reports the same model this query will run against. Pass branchName to run against a dev branch's un-deployed model instead of the deployed one; the branch the query actually ran on comes back as branchName (null = deployed model). CubeSQL Query Rules Always follow data_model_rules when generating CubeSQL queries: <data_model_rules> - When querying measures, always use MEASURE() function, e.g. MEASURE(revenue), do not nest MEASURE() in other functions. SUM(MEASURE(revenue)) IS INVALID and NOT ALLOWED, use MEASURE(revenue) instead. - A condition that narrows the WHOLE result ("only completed orders", "just the US") is a WHERE clause on the query, and every measure stays MEASURE(): SELECT DATE_TRUNC('month', created_at), MEASURE(revenue) FROM orders_view WHERE status = 'completed' GROUP BY 1. Keeping the member intact is what keeps its title and its number format; a hand-written aggregate has neither. - Use a filtered measure ONLY when a filtered and an unfiltered measure must sit side by side in one row (completed revenue next to total revenue). Then write AGG(CASE WHEN condition THEN view_measure END) where AGG matches the measure's aggregation type: COUNT, SUM, AVG, MIN, MAX, COUNT DISTINCT, APPROX_DISTINCT. Use the bare view measure reference inside CASE, not MEASURE(). Example: SUM(CASE WHEN status = 'completed' THEN revenue END) AS completed_revenue. Never use filtered measures with number-type measures. - A view can expose several time dimensions (an order's created_at and its line item's created_at, say). They bucket the same measure differently, so pick one, say which you used when you report the result, and keep it across every follow-up on that result unless the user asks for another — a follow-up is an edit of the statement you already ran, never a fresh derivation from the model. - When two of your own results disagree, diff the two SQL statements before explaining anything: the difference is almost always in them (a different time dimension, a different filter, a different view), not in the data model. Do not describe join or grain behaviour you have not read in the model. - Do not quote identifiers - When using DATE_TRUNC, you can't use different time grains in SELECT statement and window functions. Convention to call it <date_dimension_name>_<date_trunc_part>, e.g. date_dimension_month. - Avoid using ROUND function - Never use joins between cubes and views. Use selects from views that contain all necessary members instead. You can use joins between CTEs though. - You can't GROUP BY with aliases. You need to use indexes: ``sql SELECT DATE_TRUNC('month', date_dimension) AS date_dimension_month, category_dimension, MEASURE(metric_column) FROM semantic_view WHERE semantic_view.category_dimension = 'value' GROUP BY 1,2 ORDER BY 1,2 LIMIT 5000 ` - Avoid using aliases, except for time dimensions and custom dimensions and measures: `sql SELECT DATE_TRUNC('month', orders_view.date) AS date_month, MEASURE(orders_view.count), MEASURE(orders_view.revenue), MEASURE(orders_view.revenue) / NULLIF(MEASURE(orders_view.count), 0) AS avg_order_value FROM orders_view GROUP BY 1 ORDER BY 1 LIMIT 5000 `` - Your semantic model is Cube. Cube allows to model complex metrics and dimensions. - Views in Cube are user facing. Cube SQL is Postgres SQL. - NEVER query raw cubes directly. You should only query views. If a user asks to query a cube that has no corresponding view, suggest building a view for it first and ask for confirmation before proceeding. Measures must be queried with MEASURE() function, e.g. MEASURE(revenue)…

runSourceQuery

ChatGPT
Execute a SQL query directly against a configured data source (warehouse/database), in the source's own dialect, and return the result rows — for inspecting raw source data that is not modelled in Cube yet, e.g. while building or verifying a new cube or view. Call listDataSources first to find a valid dataSource name. This does NOT modify Cube's model, workbooks, or reports, but on a deployment where SQL Runner DDL is enabled the underlying credential can run arbitrary statements against the data source itself, including ones that write or drop data — treat this the same as running SQL directly against the warehouse. To query the compiled Cube semantic model instead (which cannot alter source data), use runQuery.

searchDataModel

ChatGPT
Search the Cube semantic model by similarity — views and their measures & dimensions — to discover what is queryable. Returns compact records (name, title, description, type) you can then reference in a runQuery SQL statement. Call this before runQuery to find the exact view and member names, and pass the same branchName to both so the members you find are the ones the query will see: on a dev branch this reports THAT branch’s un-deployed model, including members that do not exist in production yet. The model searched is reported back as branchName (null = deployed model).

select_company

ChatGPT
Selects which company of the ones the user has access to is used for requests. Args: company_id: The ID of the company to select. ctx: The context of the request. This is used to get information about the user's session. Returns: A message indicating the company has been selected.

startDataModelEdit

ChatGPT
Enter development mode and start a dev worker. Returns the branchName you MUST pass to writeDataModelFile / deleteDataModelFile / getDataModelChanges. Editing always happens on this dev branch — the deploy branch is never writable. Call this first, before any edit. To RESUME a specific edit later, pass the same feature-branch name you used before; omitting branchName starts a NEW edit session each call, so reuse the returned branchName for all follow-up tools rather than calling this again. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

switchUserBranch

ChatGPT
Switch the USER over to a branch in the Cube console, so they can see and test what was committed to it — the same action as the branch switcher in the UI. This is what closes the loop after a commit: without it, the user is still looking at whatever branch they had selected and cannot find the work. It changes what they are looking at, so call it only when the user asks to be moved onto a branch, or agrees when you offer — never unprompted. Pass the shared branch a commit landed on, never a dev-… personal branch and never the default (production) branch. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

updateDashboard

ChatGPT
Save the dashboard layout (the full widgets array) to the workbook DRAFT. This does not go live until publishDashboard. Send the COMPLETE widget set every time — this replaces the draft widgets (other top-level draft fields are preserved). CHART widgets must reference a real reportId from a createReport call made WITH this same workbookId; an id from another workbook or from a standalone (workbook-less) report is rejected and nothing is saved. Grid rules: 12 columns (x + w ≤ 12); CHART h≈11 (KPI-style ~w=3, h=3 with { hideTitle:true }), TEXT h is recomputed from its markdown server-side (pick any reasonable h; just size w), FILTER/TIME_GRAIN/FIELD/PARENT h=2 (w=3) on the top control row (y=0), a CONTAINER row/column stack takes a root-grid position sized to hold its children (its children carry LOCAL 1×1 positions by order — see the widget config field), DIVIDER h=1 and SPACER h=2 (both full-width w=12). Pass oldDashboardConfig (from readWorkbook) for a safe concurrent update. Returns a url to the updated dashboard you can share with the user. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

updateReport

ChatGPT
Edit an EXISTING report in place, KEEPING its reportId. Do NOT recreate a report to change it; that orphans the CHART widgets pointing at it. Send only the fields you want to change; omitted fields are left untouched. You can change: title; sqlQuery; the visualization (chartCategory + its matching spec — table/vega/kpi/html/map/sankey); and placement — set workbookId to a workbook id to bind it there, or null to detach it into a standalone exploration, and folderId to file a standalone report. Editing title/SQL/visualization keeps every referencing widget rendering. CHANGING workbookId DOES NOT: a dashboard CHART widget resolves its report from its OWN workbook's report list, so moving a report out of (or between) workbooks empties every tile on the old workbook's dashboard that referenced it — the same "deleted" empty state deleteReport warns about. Before changing workbookId on a report a dashboard uses, call readWorkbook and re-point or remove those widgets with updateDashboard first. Works for both standalone and workbook-bound reports. Returns the reportId and a url. Dashboard-authoring workflow (use together): createWorkbook → createReport (one per chart/visualization) → updateDashboard → publishDashboard; readWorkbook reads the current state. To manage an EXISTING report (standalone or workbook-bound) rather than recreating it: readReport, updateReport (edit its title / SQL / visualization / placement in place, keeping its reportId), deleteReport.

update_dashboard

ChatGPT
Update an existing Cube dashboard by replacing its metadata, tabs, widgets, and layouts. IMPORTANT: Call get_dashboard first if you need to preserve existing tabs or widgets. This tool applies the submitted dashboard definition to the existing dashboard. Args: dashboard_id: The ID of the dashboard to update. name: The updated dashboard name. Must be unique within the company. ctx: The context of the request. This is used to get the user company from the request context. description: Optional updated description. filters: Optional global dashboard filters where each key is a top-level dimension name and each value is a member dimension ID from that hierarchy. tabs: Optional list of tab definitions. Each tab can include a name and widgets. Widget definitions use the same structure as create_dashboard. type must be RANGE (data widget) or TEXT (text block). visual_type must be DATA_TABLE, LINE, BAR, ROW, COMBO, PIE, DONUT, METRIC, TREND, WATERFALL, or TEXT. Do not put a visual_type such as BAR or DATA_TABLE in type. Returns: A message with the updated dashboard ID or a validation error explaining what needs to be fixed.

writeDataModelFile

ChatGPT
Create or overwrite a Cube semantic model source file on your dev branch (whole-file replacement — send the COMPLETE content). After saving, the dev worker recompiles the model and this returns valid plus any validationError. If it does not compile, fix the content and call this again — the file stays saved so you can iterate. Requires the dev branchName from startDataModelEdit. Data-model editing workflow (edit the Cube semantic model / schema YAML on a dev branch, never production): startDataModelEdit (enter dev mode → dev branchName) → readDataModelFile / writeDataModelFile / deleteDataModelFile (pass that branchName) → getDataModelChanges (review the diff) → runQuery with that same branchName (verify the edited model returns the right rows before deploying). Use listDataModelFiles / readDataModelFile to discover the current model source, getBranchDiff to see what ANY branch changed relative to the deploy branch, and getDeploymentEnv to check the deployment’s configuration. Call getBranchState whenever you need to know which branch you and the USER are each on. Before authoring a cube for data that is not modelled yet, use listDataSources to find the data sources configured on the deployment. Use runSourceQuery against one of them to inspect the underlying warehouse tables directly — it bypasses the semantic layer entirely, unlike runQuery. Your edits stay invisible — to the user, to the Cube UI and to anyone reviewing — until commitDataModelChanges commits the dev branch onto its parent; then offer switchUserBranch so the user is looking at that branch, commitToNewBranch to put the work on a branch of its own, discardDataModelChanges to start over, and mergeToDefaultBranch (only when the user asks to publish) to make it live.

write_planning_table_data

ChatGPT
Replace the full dataset for a planning table in a specific scenario. IMPORTANT: Always call get_planning_table_data first, modify the returned rows, and resend the complete set of rows. Omitted rows are deleted from the caller's accessible data. Rows the caller cannot see due to dimension permissions are preserved automatically. This check is scoped to the exact (planning_table_id, scenario_id) pair you're about to write. Checking one scenario does not clear you to write to a different scenario — if the target scenario changes for any reason (including mid-conversation redirection by the user), call get_planning_table_data again for that specific scenario_id before writing, even if empty/no-data was already confirmed elsewhere. The Scenario must have AI write protection (write_protection = 'AI'). Scenario IDs must come from get_chart_of_accounts. Column order and count must match the headers from get_planning_table_data / list_planning_tables. Dimension cells may be member IDs (as returned by get) or member names. Args: planning_table_id: The ID of the planning table from list_planning_tables. scenario_id: The Scenario dimension member ID from get_chart_of_accounts (must be AI-managed). rows: Full 2D array of cell values (no header row). Same shape as get_planning_table_data rows. ctx: The context of the request. This is used to get the user company from the request context. Returns: JSON summary of the write (created/updated, rows written) or a rejection message describing validation/permission failures to fix before retrying.

buildPreAggregation

Claude

chat

Claude

createReport

Claude

createWorkbook

Claude

deleteDataModelFile

Claude

deleteReport

Claude

getBranchDiff

Claude

getDataModelChanges

Claude

getDeploymentEnv

Claude

getPreAggregationStatus

Claude

listDataModelFiles

Claude

listDeployments

Claude

loadQueryResults

Claude

publishDashboard

Claude

readDataModelFile

Claude

readReport

Claude

readWorkbook

Claude

runQuery

Claude

searchDataModel

Claude

startDataModelEdit

Claude

updateDashboard

Claude

updateReport

Claude

writeDataModelFile

Claude

Similar Apps