MCP App Store
by KeenEthics

Overview

Ask questions about your business and get answers straight from your own data - no spreadsheets, no waiting on a report. WitCloud connects Claude to all your marketing, sales, and ecommerce data in one place, so you can explore customers, campaigns, and revenue just by chatting. Claude understands the context of your business, so the answers actually make sense for you.

Tools

add_context_log_entry

ChatGPT
Append a new entry to the Context Log spreadsheet for the chosen business context. Only works for contexts with type="context_log". Use when the user asks to record a business event. Requires business_context_id — there is NO automatic selection. If the user has not picked one yet, ask them which context to log against (options come from load_project.businessContexts, filter by type="context_log").

cancel_workflow_execution

ChatGPT
Stops a running execution of a workflow. Acts on any workflow, system ones included. A cancelled execution cannot be resumed — run_workflow starts a new one. The schedule is not affected (pause_workflow stops it).

check_onboarding_step

ChatGPT
Read-only pre-check before complete_onboarding_step, for the two steps that have one: - connect-google-cloud-project: the GCP project ids the WitCloud service account can currently see. Call it after the user says they granted IAM access, to confirm the grant took effect. Use the returned list — never ask the user to type their project id; one result, confirm it and proceed, several, ask them to pick. - choose-a-location-to-store-your-data: the available BigQuery regions. Any other step returns an error — go straight to complete_onboarding_step.

complete_onboarding_step

ChatGPT
Perform or acknowledge one onboarding step — the same code path as the app's "Next" button. Returns {success: true}, or {success: false, code, message}: relay message and look up code in that step's onboarding/stages/* document. Re-run get_onboarding_status afterwards. "choose-a-location-to-store-your-data" is WRITE-ONCE — get the user's explicit confirmation of the exact region before calling. The last four steps perform nothing: they only verify the audit already shows the step ok and record it, so do the real work with the dedicated tools first.

create_business_context

ChatGPT
Create a business context, in any of its three forms: inline content, a Google Doc (content_doc_url), or a context_log Google Sheet (context_log_spreadsheet_url with type="context_log"). Both Google forms must be shared with the project service account first — Viewer for a Doc, Editor for a Sheet. This tool verifies that before saving and refuses if it cannot read the file; the address to share with is load_project.project.serviceAccountEmail. The user creates the file themselves — we cannot, it would land in the wrong Drive. Never invent the content: save what the user wrote or approved. onboarding/stages/business-context documents what a good business context covers.

create_channel_grouping

ChatGPT
Create a custom channel grouping (category "other") with its channels. The seeded "Marketing Channels" and "Market" groupings already exist and cannot be created — change their channels with update_channel_grouping. Saving changes configuration only: new All-in-One data follows the new rules, while existing rows keep their old values until reprocess_channel_grouping runs. onboarding/stages/channel-grouping documents the available fields, operators and matching rules.

create_data_source

ChatGPT
Registers BigQuery tables as a custom data source of the project. Each table is checked first; one the service account cannot read, or that does not exist, fails the call with the reason. The source then shows in list_data_sources as custom:<slug>, with its documentation as a project document. A query job's result table (get_integration → outputTable) can be registered like any other table, once the job has run and the table exists.

create_kpi_metric

ChatGPT
Create a custom KPI. Either one aggregated base metric (kind="base", operandA only) or a two-operand formula (kind="formula", operandA op operandB), each operand optionally filtered to some rows. Reach for one only when neither a base metric nor a predefined metric (get_kpi_metrics) already measures it. To check what a formula returns before saving, run the same columns through run_query on All-in-One.

create_kpi_tree

ChatGPT
Create a KPI tree. A tree is nodes, each measuring one metric, and edges from a parent node to the child nodes that drive it (revenue → sessions × conversion rate × AOV). Node ids are your own short keys, unique in the tree; each node has at most one parent. Positions are optional — the app lays out nodes that have none. A ready-made template is usually the better start: pass template_id (get_kpi_tree_catalog section="templates", one with available: true) instead of the graph, optionally tree.name. A template may also switch on alerts for some of its nodes — they mail the signed-in user — so list them first (catalog with template_id) and leave out the ones the user does not want with exclude_alert_keys; exclude_node_keys leaves out nodes.

create_query_job

ChatGPT
Creates a query job — BigQuery SQL the project runs as a workflow step, optionally saving its results to a table. The SQL is dry-run first; an invalid query is not saved. The response reports the bytes one run (one date) would process. A new query job runs only once it is a step in a workflow (create_workflow / update_workflow), and its table appears after the first run — only then can it be registered as a data source (create_data_source). With validate_only, only the dry run happens.

delete_kpi_tree_item

ChatGPT
Delete one custom metric, tree, goal or alert. Irreversible — name the item and get the user's confirmation first. To stop an alert or goal mailing without losing it, set enabled=false with update_kpi_alert / update_kpi_goal instead. A metric still used by alerts, trees or goals is not deleted: the response lists them.

delete_workflow

ChatGPT
Deletes a user workflow and its schedule. It cannot be undone, and a running execution is not stopped (cancel it first with cancel_workflow_execution). Refused for system workflows, and for a workflow another workflow still refers to.

describe_columns

ChatGPT
Return business descriptions for specific columns of a table. Use this AFTER get_table_schema when you need to understand what columns mean (picking the right metric, interpreting an enum, deciding which fields to JOIN on). Always pass only the columns you actually need — full schema descriptions can be very large.

get_business_context

ChatGPT
Return a business context. Behaviour depends on the context type: • type="text" — returns the company/product description (name, description, content). • type="context_log" — returns the Context Log, a timeline of business events (rebrands, launches, campaigns, structural changes). Optional date/category filters apply. Requires business_context_id — there is NO automatic selection. If the user has not picked one yet, fetch the options from load_project.businessContexts (which includes the type field) and ask them. If they decline, do not call this tool.

get_channel_grouping

ChatGPT
The full configuration of ONE channel grouping by id: name, index, category and every channel with its condition rules. Raw config, no data analysis — and the exact shape to edit and pass back to upsert_channel_grouping. The ids are in load_project.channelGroupings.

get_custom_audience

ChatGPT
One Custom Audience: its name, source and segments — exactly what update_custom_audience takes — plus, per segment, how its Facebook / TikTok lists synced (sync), the BigQuery tables Google Ads and Klaviyo read it from with whether they exist yet (destinations, with the platform guide for connecting them), and run, the workflow that rebuilds it daily with its latest execution.

get_custom_audience_setup

ChatGPT
What a Custom Audience of this project can be built from. Without source: the sources — solutions that offer audiences, a Customer Analysis first among them — and the existing audiences. With source: its presets (ready-made segments and column mapping; a Customer Analysis offers grouped and granular segment sets) and its columns, what a condition's metric takes. The source must have run once for its columns to exist. Through the assistant an audience goes to Google Ads and Klaviyo, which read it from BigQuery; Facebook and TikTok need an ad account authorised in the app. Read custom-audience/setup first.

get_customer_analysis

ChatGPT
One Customer Analysis: its settings — exactly the arguments update_customer_analysis takes — whether its tables exist yet, and run, the workflow that runs it hourly with its latest execution (run_workflow runs it now; get_workflow tells why a run failed). The ids are in load_project's customer-analysis data source or get_customer_analysis_setup.analyses.

get_customer_analysis_setup

ChatGPT
What a Customer Analysis of this project can be set up with: the form's defaults; the options the project's All-in-One orders offer (shops, order statuses, integrations, GA4 sources — the values order filters and the attribution take); the segmentMetrics and segmentOperators custom segments and labels are built from; the project's business contexts; and its existing analyses. optionsError says why the options could not be read — usually All-in-One with e-commerce orders is not running yet, which the analysis needs too. For extra fields: extraFieldTargets (the customer table columns they fill, by kind) and extraFieldTables (the project's tables a source can read); pass extra_field_table for its extraFieldColumns. Read customer-analysis/setup before setting one up with the user.

get_integration

ChatGPT
One integration in full: kind, subtype, output table (with its fully qualified name for run_query) and the workflows that run it. For a query job also its SQL, variables and options — the shape update_integration takes back.

get_integration_status

ChatGPT
Connector run history, live from the job event stream — answers "is connector X working?", "why did it fail?", "has it run recently?". Raw runs, no verdict: you judge them. Two things you will get wrong otherwise: - attemptCount > 1 with status: "SUCCESS" = failed, then passed on retry. NOT a broken connector, and its errors are transient. Only "FAILED" never succeeded. - The window is when jobs RAN, not which dates they collected (runDate can be far older — backfills). So no runs means "nothing ran in the last N days", never "this never ran". Says nothing about whether data reached All-in-One — jobs can succeed and deliver nothing. For that use get_onboarding_status. onboarding/audits/integrations documents how to read the runs and the per-connector quirks behind each error.

get_kpi_alerts

ChatGPT
The project's KPI alerts. Without id: each one in short, with its id. With id: the full definition of that one — the exact shape to edit and pass back to update_kpi_alert. What the daily run computed for them is in kpi_alert_<seed> (see get_kpi_tree_settings), not here.

get_kpi_goals

ChatGPT
The project's KPI goals. Without id: each one in short, with its id. With id: the full definition of that one — the exact shape to edit and pass back to update_kpi_goal. What the daily run computed for them is in kpi_goal_<seed> (see get_kpi_tree_settings), not here.

get_kpi_metrics

ChatGPT
Every measure a tree, goal or alert can point at, each with its source: "base" — an All-in-One column (label, unit, category, allowedAggregations); "predefined" — a ready-made formula (ROAS, ERS, CPA…); "custom" — a KPI this project defined (create_kpi_metric). ref is the exact value to put in a definition's metric (for a base metric, with its default aggregation). source and category (ga4, ads, ecommerce, marketplace…) narrow the list. With id: the full definition of one custom metric — the shape update_kpi_metric takes back — and usedBy, the trees, goals and alerts that reference it. What the daily run computed is in kpi_tree_<seed> / kpi_goal_<seed> / kpi_alert_<seed> (see get_kpi_tree_settings), not here.

get_kpi_tree_catalog

ChatGPT
What KPI Tree definitions are built from, by section: - building_blocks (default): filterableDimensions, breakdowns (index → grouping), comparisonPresets and the project's custom comparisonRanges, units, aggregations. The measures themselves are in get_kpi_metrics. - templates: ready-made trees, each saying whether this project's data can compute it (available, missing). Pass template_id for one template's nodes and alerts. - predefined_alerts: ready-made alerts the project's data supports, with alertId / enabled when already switched on. - dimension_values: the values present in the data for one dimension_column (a filterableDimensions column) or one breakdown_index — what a filter's values take. Templates, predefined alerts and dimension values query BigQuery.

get_kpi_tree_settings

ChatGPT
The project's KPI Tree settings: whether the daily run is on, scheduleHour with the timezone it is read in, nextRunAt and lastRunAt. settings is null when KPI Tree was never set up. What KPI Tree computed is not returned here: the daily run writes it to the project's kpi-tree data source — kpi_tree_<seed> (each node per tree), kpi_alert_<seed> (each alert, triggered or not), kpi_goal_<seed> (each goal: value, attainment, behind by) and kpi_metrics_<seed> (custom metric definitions), one partition per run date. Find them with list_tables(dataSourceId='kpi-tree') and read them with run_query, after kpi-tree/introduction. Something created or changed now appears there after the next run (nextRunAt).

get_kpi_trees

ChatGPT
The project's KPI trees. Without id: each one in short, with its id. With id: the full definition of that one — the exact shape to edit and pass back to update_kpi_tree. What the daily run computed for them is in kpi_tree_<seed> (see get_kpi_tree_settings), not here.

get_onboarding_status

ChatGPT
Live setup status for a project: an ok/warning/missing/error verdict per foundation step (GCP, data location, currency, integrations, All-in-One, channel grouping, business context), the ordered checklist, and nextStep — the first step not yet acknowledged. Cheap and idempotent, so it can be re-run after every change. Each item carries two different things: auditStatus (the live fact) and status (whether the step was explicitly acknowledged). It also returns a products block, which is out of scope for now. onboarding/introduction documents how the steps fit together and which document covers each one.

get_table_schema

ChatGPT
Return the BigQuery schema (fields, types, modes) for a specific tableId. Use the full tableId returned by list_tables (with suffix). Field descriptions are NOT included here to keep responses lean — call describe_columns for the columns you actually want to understand.

get_workflow

ChatGPT
One workflow in full: its steps as definition v2 (the shape create_workflow and update_workflow take), schedule, time zone, origin and state, plus its latest executions. With execution_id, also that execution's report: per resource and date, whether the job ran, failed or is still running, with errors.

list_activity

ChatGPT
The project's change history, newest first: who changed which resource (actor: an email, or "system"), when, from where (source: "api" — the app, "mcp" — an assistant, "system" — WitCloud itself), and every changed field with its value before and after. Filter by resource_id for one workflow's or integration's history. Use it to see what changed — say, before a workflow started failing — and to restore an earlier version: a query job's previous SQL is the before of its query change, its variables of variables — pass them to update_integration; a workflow's previous steps are under definition (or schema for older ones) — pass them to update_workflow. Every value is there but secrets (passwords, tokens, keys, credentials inside URLs) and the titles of documentation folders, which come as "[redacted]", and values too long to keep, as "[truncated]". view says what the caller gets: "full" for editors and above; "app" for viewers — what the app's history shows, where most configuration fields are "[redacted]". Entries recorded before the log kept every value may show "[redacted]" too. Neither can be restored from here.

list_data_sources

ChatGPT
Refresh the list of active data sources for the current project. Same shape as load_project.dataSources. Call this only if you need an updated registry mid-session (e.g. after a solution was just executed and produced new tables).

list_documents

ChatGPT
Generic listing of project documentation. Returns summaries (no content) so it is cheap on tokens. Filter by slug prefix or free-text search. Slugs are path-like, e.g. 'aio/tables/aio_main', 'solutions/customer-analysis/introduction'.

list_integrations

ChatGPT
The project's integrations — connectors (Google Ads, Shopify, GA4…) and query jobs — each with its kind, subtype, the table it writes, and the workflows that run it: its own system workflows and the user workflows that have it as a step. An integration in no workflow never runs. Run history is in get_integration_status.

list_projects

ChatGPT
Call this tool first. Returns all projects the user has access to. Present the list to the user and ask which project (or projects) they want to work on. Then call load_project with the chosen project_id.

list_tables

ChatGPT
List BigQuery tables in the project dataset with classification (which dataSource each table belongs to). Tables that cannot be classified (no AIO suffix and no matching solution instance ID) are hidden. Use this BEFORE run_query to discover the full tableId (which always includes a suffix) and partitioning info.

list_workflows

ChatGPT
The project's workflows: id, name, origin ("user" — built by people, or "system" — created by WitCloud for one integration), editable (whether you may change it), state (Active / Paused), schedule and time zone, the number of steps and the resource ids they run. System workflows also name their owner and systemType (historical backfill, ongoing collection, alignment re-collection).

load_project

ChatGPT
Load a project after the user has picked one. Returns project identifiers, available data sources, and business contexts. REQUIRED: immediately after calling this tool, call read_document with slug "introduction" — that document contains all instructions on how to guide the user through the session. For cross-project analysis, call this tool once per project — results accumulate in context.

pause_workflow

ChatGPT
Stops a workflow's schedule from firing. Acts on any workflow, system ones included. A running execution goes on (cancel_workflow_execution stops it); resume_workflow restores the schedule.

read_document

ChatGPT
Read the full markdown content of a document by its slug. Slugs are path-like, e.g. 'aio/tables/aio_main'. Use list_documents to discover slugs first.

reprocess_channel_grouping

ChatGPT
Recompute the channel_grouping columns on historical All-in-One data after a grouping change. New data does not need this — only history. ALWAYS call with mode="estimate" first: it is a free dry-run returning totalBytesProcessed and estimatedCostUsd. Show those to the user and get explicit confirmation before calling mode="execute", which costs real money. Scope it like the app panel: full=true for all history, or an explicit start_date/end_date range.

resume_workflow

ChatGPT
Restores the schedule of a paused workflow: it fires again at its next scheduled time. Acts on any workflow, system ones included. It starts nothing now (run_workflow does) and does not resume a cancelled execution.

run_query

ChatGPT
Execute a SELECT query against the project BigQuery dataset. PREREQUISITES: call list_tables and (when needed) get_table_schema / read_document for any table you query. RULES: - Use fully qualified names: googleCloudProjectId.datasetId.tableId (the full suffixed tableId from list_tables) - ALWAYS include a partition filter for any partitioned table to keep scans cheap. Use the partitioning field returned by list_tables: • partitioning.field === "_PARTITIONTIME" → ingestion-time partitioning; filter on _PARTITIONTIME or _PARTITIONDATE • any other field (e.g. "event_date") → column- or range-partitioning; filter on that exact column name • partitioning is null → no partition filter needed - Only SELECT queries are allowed; DML keywords are rejected by the backend - Cross-source JOIN (AIO × solution table) is supported because everything lives in one dataset

update_business_context

ChatGPT
Change a business context: only the fields passed change. Its type stays — a text context takes content or content_doc_url (one replaces the other), a context_log its context_log_spreadsheet_url. Both Google forms must be shared with the project service account first — Viewer for a Doc, Editor for a Sheet. This tool verifies that before saving and refuses if it cannot read the file; the address to share with is load_project.project.serviceAccountEmail. The user creates the file themselves — we cannot, it would land in the wrong Drive. Never invent the content: save what the user wrote or approved. onboarding/stages/business-context documents what a good business context covers.

update_channel_grouping

ChatGPT
Change a channel grouping: only the fields passed in grouping change. channels, when given, replaces them all — pass the complete list from get_channel_grouping with your change applied. The seeded "Marketing Channels" and "Market" groupings cannot be renamed; only their channels change. Saving changes configuration only: new All-in-One data follows the new rules, while existing rows keep their old values until reprocess_channel_grouping runs. onboarding/stages/channel-grouping documents the available fields, operators and matching rules.

update_custom_audience

ChatGPT
Change a Custom Audience: its name, its segments, or both. segments, when given, replaces them all — pass the complete list from get_custom_audience with your change applied, each kept segment with its id (that keeps its lists on the platforms; a segment without an id is new and makes new lists). Facebook and TikTok already on a kept segment stay; leaving out a segment that sends to them stops updating its list there, which needs confirm_dropped_platform_lists: true once the user agreed. The source is changed in the app. validate_only saves nothing and counts the rows each segment takes.

update_customer_analysis

ChatGPT
Change a Customer Analysis: only the fields passed change; a list given (order_filters, attribution, custom_segments, custom_labels, extra_fields) replaces the stored one — pass the complete list from get_customer_analysis with your change applied. The next hourly run rebuilds its tables with the new settings. validate_only checks the change without saving it, and when it changes custom_segments or custom_labels, counts the customers each one takes on the last run; when it changes extra_fields, how many customers each source matches (each count queries BigQuery).

update_integration

ChatGPT
Renames any integration — its system workflows are renamed with it — and, for a query job, changes its SQL, variables or options (options are merged: pass only what changes). Changed SQL is dry-run first and not saved if invalid. Changing prefix makes the job write a new table; the old one stays. With validate_only nothing is saved: the SQL — as changed, or as stored when nothing changes — is dry-run and the bytes one run would process for run_date come back (free; one run = one date — a workflow running it over a date range runs it once per date, which create_workflow / update_workflow with validate_only add up). To restore an earlier SQL, take it from list_activity.

update_kpi_metric

ChatGPT
Change a custom KPI: only the fields passed in metric change. Either one aggregated base metric (kind="base", operandA only) or a two-operand formula (kind="formula", operandA op operandB), each operand optionally filtered to some rows. Changing a metric changes every tree node, goal and alert that references it (get_kpi_metrics with its id lists them in usedBy).

update_kpi_tree

ChatGPT
Change a KPI tree: its name, its graph, or both. A tree is nodes, each measuring one metric, and edges from a parent node to the child nodes that drive it (revenue → sessions × conversion rate × AOV). Node ids are your own short keys, unique in the tree; each node has at most one parent. Positions are optional — the app lays out nodes that have none. The graph goes whole — nodes and edges together replace the stored ones, so pass the complete graph from get_kpi_trees with your change applied; to rename only, pass just tree.name.

update_workflow

ChatGPT
Changes a user workflow: its name, time zone, schedule (null removes it) or steps. steps, when given, replaces all of them — pass the complete list from get_workflow with your change applied. Fields left out stay as they are. System workflows are refused (they follow their integration) unless editable says otherwise — Witbee's application admins may edit them. A schedule change of an active workflow takes effect immediately. With validate_only nothing is saved: the definition comes back checked and in canonical form (or every problem with its path), with estimate — what its query jobs would process in BigQuery. Each query job is dry-run (free) for one sample date — its latest date before today, or yesterday — and multiplied by the dates one execution passes it (perRun), then by how often the schedule fires in the next 30 days (per30Days). Bytes processed, not billed; connectors, solutions and All-in-One are not estimated. The changes are applied to the stored workflow first, so validate_only alone estimates it as it is.

upsert_business_context

ChatGPT
Create (omit business_context_id) or update (include it) a business context, in any of its three forms: inline content, a Google Doc (content_doc_url), or a context_log Google Sheet (context_log_spreadsheet_url with type="context_log"). Both Google forms must be shared with the project service account first — Viewer for a Doc, Editor for a Sheet. This tool verifies that before saving and refuses if it cannot read the file; the address to share with is load_project.project.serviceAccountEmail. The user creates the file themselves — we cannot, it would land in the wrong Drive. Never invent the content: save what the user wrote or approved. onboarding/stages/business-context documents what a good business context covers.

upsert_channel_grouping

ChatGPT
Create (omit grouping.id) or update (include it) a whole channel grouping in one call. New ones are always custom (category "other"); the seeded "Marketing Channels" and "Market" cannot be created, renamed or deleted — pass their existing id to edit their channels. Saving changes configuration only: new All-in-One data follows the new rules, while existing rows keep their old values until reprocess_channel_grouping runs. onboarding/stages/channel-grouping documents the available fields, operators and matching rules.

upsert_project_document

ChatGPT
Save a document to the client's own project documentation — create it, or replace the one with the same slug. For knowledge worth keeping across sessions: how the client defines a metric, which filter a report always needs, what a column really holds in their data — or an analysis the user wants to repeat, saved as a playbook: its steps and SQL, and a description saying which question it answers, since the description is all list_documents shows of it. - scope: "personal" saves it among the user's own documents, read by their assistant alone: how they work, their role and responsibilities, the format of a report they ask for, an analysis of theirs — whatever the user asks you to remember about themselves. Definitions the whole company shares belong in the project documentation (the default scope). - Only after the user has read and confirmed the exact content: with the default scope this writes to their documentation, visible to everyone on the project. - To change a document, read it first and send the whole new content — this replaces it. - Slugs live under project/ (the prefix is added when missing), e.g. 'metrics/revenue'. project/sources/ is reserved: custom data sources are documented from the app. - To file it in a folder, pass folder and keep slug to the document's own name. Name each level either as the folder is titled (the project introduction's headings) or as it appears in slugs — 'Analizy/Sprzedaż' and 'analizy/sprzedaz' reach the same folder. Levels that do not exist are created, so reuse an existing folder where one fits, and start a new one only when the user agreed to it. - project/introduction is the client's overview of the project; an index of the other project documents is appended to it automatically, so do not list them in it. - WitCloud's own documents cannot be changed.

add_context_log_entry

Claude

check_onboarding_step

Claude

complete_onboarding_step

Claude

describe_columns

Claude

get_business_context

Claude

get_channel_grouping

Claude

get_integration_status

Claude

get_onboarding_status

Claude

get_table_schema

Claude

list_data_sources

Claude

list_documents

Claude

list_projects

Claude

list_tables

Claude

load_project

Claude

read_document

Claude

reprocess_channel_grouping

Claude

run_query

Claude

upsert_business_context

Claude

upsert_channel_grouping

Claude

Capabilities

Writes

Similar Apps