- Brand
- OWOX
- Category
- Data & Analytics
- Primary Subcategory
- Self-Serve BI & Conversational Analytics
Integration details
Description
OWOX Data Marts connects ChatGPT/Codex to your company's governed analytics layer. Data Analysts define trusted data marts — metrics, dimensions, and join logic — on top of your own warehouse (BigQuery, Snowflake, Databricks, Redshift, Athena). From ChatGPT/Codex you can discover the right data mart with natural-language search, inspect its fields, query governed data and get answers with server-side totals — computed from analyst-defined metrics and joins, never guessed from raw tables — and manage recurring report run schedules. Your data stays in your warehouse; OWOX connects to it but never retains it.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Self-Serve BI & Conversational Analytics
- Secondary Subcategories
- None listed
- Brand
- OWOX
- Access
- Account required
- First tracked
- 2026-07-02
- Tool count
- 21
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for OWOX Data Marts
Get updates when OWOX Data Marts’s Discoverability Score or category rank changes.
Competing in ChatGPT Self-Serve BI & Conversational Analytics
View Category21 tools agents can invoke
Adds a report-delivery destination. Behavior depends on destination_type: for google_sheets, returns a link to a simple in-app "Connect Google Sheets" page — the user must be signed in to OWOX (prompted if not) and a member of this project (asked to request access if not); on the page they click to start Google OAuth, and the destination is created automatically as soon as they approve access — no extra save step; the person who completed it can use it in their own reports right away, but it starts unshared for everyone else on the project — another project member cannot use it until a human shares it — this call does NOT return a destination_id, because the destination does not exist yet, and its name is not known in advance either (the user sets it directly in the form, this tool never pre-fills it); after the user confirms they completed it, call list_destinations and filter to google_sheets entries whose connectedGoogleAccount matches who the user expected — never pick by createdAt/recency, another destination may be created concurrently by someone else; if more than one entry still matches, ask the user which one they mean instead of guessing; for email, slack, and teams, creates the destination directly and requires the emails parameter; for google_chat, MCP supports channel-email delivery only and also requires emails — direct webhook delivery is configured in the OWOX UI/API, and its secret URL must not be sent through MCP/chat; no OAuth is involved and destination_id is returned immediately; for looker_studio (pull-based connector), creates the destination directly and returns destination_id immediately — no OAuth, no emails needed; the connector credentials (including the Destination Secret Key/Token) are never sent through MCP/chat — the user must open the destination in the OWOX Data Marts UI to copy them.
add_destination
Create an OWOX report that exports a data mart to an existing destination (create one with add_destination if the project has none — check list_destinations first). Use when the user wants a refreshable export or delivery to Google Sheets, email, Slack, Microsoft Teams, Google Chat, or Looker Studio. Create one report per user request, then change it with update_report when the user asks to add a filter, sort, aggregation, or rename it — do not create another report for the same data: the tool refuses a report whose fields duplicate one you already created on this data mart and destination (error_code similar_report_exists). For push destinations, the new report runs immediately by default: this starts one billed Report Run and delivers data, then initial_run returns the run_id to poll with get_report_run_status. Set run_immediately=false only when the user explicitly wants to create configuration without delivering data, such as before adding a schedule. Every destination type accepts the same optional output controls as query_data_mart — filters, slices, aggregations, date_buckets, sort — applied on each run: when the user asks to export numbers they saw in a query, copy those parameters verbatim from that query so the report matches what they saw. Google Sheets: a new Google Sheet is created automatically (an external Google Drive side effect) with its file and sheet named after `name`, and linked to the report; pass spreadsheet_id to add the report as a sheet of an existing spreadsheet instead, so several related exports share one document. Looker Studio is pull-based, never runs through this tool, and accepts no name; omit run_immediately or set it false. Email, Slack, Microsoft Teams, Google Chat: requires message; the default initial run sends it to the configured recipients or channels.
add_report
Creates a new recurring run schedule for a report. Translate the user's natural-language schedule ("every Monday at 9am", "daily at midnight") into a standard 5-field cron expression before calling (e.g. "0 9 * * 1"). This creates an additional schedule and does not replace, delete, or update existing schedules for the same report. To change an existing schedule, first call list_report_run_schedules and then call update_report_run_schedule with the specific trigger_id. time_zone must be a valid IANA timezone (e.g. "Europe/Kyiv"); if the user does not specify one, default to UTC and confirm with them. is_active defaults to true.
create_report_run_schedule
Delete a report by id. The report stops running and disappears from the project; the underlying data mart, destination, and any already-exported documents are not affected. This cannot be undone.
delete_report
Removes the single report run schedule identified by trigger_id (get it from list_report_run_schedules). Only that schedule is removed — the Report and any other schedules it may have are left intact. The response echoes the removed trigger_id and report_id with schedule: null to confirm that specific schedule is gone; check list_report_run_schedules if you need to know whether other schedules remain.
delete_report_run_schedule
Find relevant non-draft data marts in the current OWOX project from a natural-language prompt, limited to data marts visible to the current MCP user. This is the default discovery step for a concrete analytical question when the data mart has not already been confirmed. Use it when the user asks to find, discover, or search published data marts by title, description, business meaning, schema fields, or metrics. This tool returns only data marts, not data storages or destinations, and it intentionally excludes draft data marts. Use get_project_context → list_contexts to discover business goals, then pass context_ids to restrict discovery to any selected context; omission preserves project-wide discovery within your existing access. Responses include all attached context IDs and names.
get_relevant_data_marts_by_prompt
Find existing reports in the current OWOX project from a natural-language prompt, limited to reports whose data mart and destination are visible to the current MCP user. Matches the report name first, then the data mart and destination names. Use it when the user refers to a report by name or subject and its id is not yet known — to open, rerun, change, or schedule it; each result carries the report id, its data mart and destination, and a direct link. Use get_data_mart_reports instead when the data mart is already known and you need every report with its full definition.
get_relevant_reports_by_prompt
Get available details for a specific published OWOX Data Mart by data_mart_id, including its URL, attached context IDs and names, native output fields, and (only on explicit request) joined_fields contributed by blended/joined data marts. Use detail_level=native by default: it avoids exposing irrelevant joined fields and keeps the response fast. Request detail_level=with_joined_fields only when the question truly needs a joined Data Mart. Use displayName for user-facing wording and copy name verbatim into query_data_mart. Each controllable field carries its type "category", and every field carries the effective "allowedAggregations" query_data_mart may apply to it; "operators_by_category" maps each category to the filter/slice operators its fields accept — build queries from these instead of guessing. An empty allowedAggregations on a field whose "calculated" level is "metric" means the value is ALREADY computed, not that the field is unusable: select it by name in query_data_mart instead of recomputing it from other fields, and read the "usage" note carried on that field — it may also warn that a join distorts the number. Array fields are the exception: when mode is REPEATED or type or sliceType is ARRAY, the field omits category and has empty allowedAggregations. It may appear in fields, but never in filters, slices, sort, aggregations, or date_buckets. Follow get_project_context → list_contexts → context-filtered Data Mart discovery. This tool is optional in that flow: get_relevant_data_marts_by_prompt finds relevant Data Marts, and this tool adds field-level metadata for a selected Data Mart. It does not return data owners, data freshness, sample values, or actual data rows.
get_data_mart_details_by_id
List the reports tied to a data mart in the active OWOX project, including each report destination, what it exports (fields, filters, slices, aggregations, date_buckets, sort, limit — in add_report/update_report vocabulary), the spreadsheet it writes to (Google Sheets), run schedules (a report can have any number of schedule triggers), and last run status. Call it before add_report to find a report that already exports what the user asks for — especially one with created_by_current_user=true — and change that one with update_report instead of creating a duplicate; reuse its spreadsheet_id when a related export should land in the same Google Sheets document.
get_data_mart_reports
Returns the current OWOX project selected for this MCP connection, including its complete admin-maintained project description, id, title, roles, status, and creation date. Call this tool before the first project-specific operation in a conversation and when the user asks which project is current, active, selected, or connected. If the user asks how to change or switch projects, explain that project selection happens during OWOX authorization: disconnect and reconnect this MCP server, then sign in again and choose the desired project.
get_project_context
Use when you need the columns a saved report's rows will carry, in the order they are projected — the names to put above the values the report delivers. Includes the columns a report synthesises (aggregated `revenue | SUM`, Unique Count, calculated fields), which appear in no data mart schema. Answers from the stored schema and the report config, so it reads no report data — the columns are as of the Data Mart's last schema actualization, so one added warehouse-side and not yet actualized is missing until a run or a data read picks it up. This tool reads stored metadata only: it does not query report rows or refresh SQL views in the warehouse.
get_report_output_schema
Get the current status of a report run, identified by report_id and run_id. The run_id may come from run_report or from add_report when initial_run.status is "queued". Report runs routinely take several minutes, so keep polling while should_poll is true and stop when should_poll is false; terminal statuses are "success", "failed", "cancelled", "interrupted", and "restricted". If you can wait between tool calls, poll about every 15 seconds; otherwise call again immediately. The message field tells you what to do next, including when to warn that a run is taking longer than usual and when to treat it as stuck and stop polling. stop_reason is set only when status is still "running" but should_poll is false, such as queued_too_long or running_too_long. queued_at is when the run was created; started_at is null until execution starts, including the brief worker-claimed state before the start time is recorded. raw_status exposes the backend status, and error is populated only for failed runs.
get_report_run_status
List data marts available to the current OWOX project member. Defaults to published data marts; use status=draft only to browse draft metadata, because other MCP data-mart tools accept published data marts only. Use only when the user explicitly asks to list or browse data marts; for a concrete analytical question use get_relevant_data_marts_by_prompt instead, and for open-ended orientation use summarize_data_catalog. Use get_project_context → list_contexts to discover business goals, then pass context_ids to restrict discovery to any selected context; omission preserves project-wide discovery within your existing access. Responses include all attached context IDs and names.
list_data_marts
List destinations in the active OWOX project to target when creating a report. Also the only way to learn the destination_id and connected Google account for a google_sheets destination just created via add_destination, since that call does not return an id synchronously — see its description. When matching that destination, never pick by createdAt/recency — someone else may create a destination at the same time, so the newest entry is not reliably the right one. Filter by connectedGoogleAccount matching who the user expected instead; if exactly one entry matches, use it, and if more than one still matches, ask the user which one they mean rather than guessing. Destinations created via add_destination start unshared: the creator can use them in their own reports right away, but other project members cannot until a human shares them (Configure destination → Sharing) — this tool does not report sharing status, so if the report is for someone other than the destination's creator, confirm with the user that it has been shared rather than assuming it.
list_destinations
List business contexts in the connected OWOX project, including IDs, names and complete descriptions (null when missing). Discovery flow: get_project_context → list_contexts → list_data_marts or get_relevant_data_marts_by_prompt with context_ids → get_data_mart_details_by_id. Read descriptions for business goals and Markdown links to specific Data Marts. Listing a context or following a reference never grants access to its resources; all Data Mart tools enforce existing access controls.
list_contexts
Lists every scheduled REPORT_RUN trigger (report run schedule) in the current OWOX project that the current MCP user can see, in a single response. Each item includes trigger_id — pass it to update_report_run_schedule to modify that specific schedule or delete_report_run_schedule to remove it — plus the report and data mart it belongs to. To add another schedule for a report, call create_report_run_schedule; creating never replaces existing schedules.
list_report_run_schedules
Query an OWOX data mart and return its data rows in a compact, header-once table, plus server-side totals computed over all matching rows (ignoring the row limit). Each call costs credits, records a run, and may replace an OWOX-managed technical view when the Data Mart has a SQL definition. Call get_data_mart_details_by_id first to get the data mart's exact field names and joinable/blended fields, then copy field names verbatim into fields — unless you already have that schema in context. Field names must be exact; never guess or invent them. When building the query: - Request only the fields relevant to the user's question — never request all fields. - Use limit to control how many rows come back (1–1000, default 20). There is no offset/pagination: the tool returns a bounded subset. - aggregations: SUM, COUNT, COUNT_DISTINCT, AVG, MIN, MAX, and percentiles P25/P50/P75/P95 — which of them a given field allows depends on the field's type and the data mart's per-field settings (see the matrix below). Group-by is implied by the non-aggregated fields you select. - Prefer a metric the data mart already defines: when get_data_mart_details_by_id shows a field whose "calculated" level is "metric", that field IS the quantity, computed at the grain your query asks for — list it in "fields" and read the value. Do not rebuild it by aggregating its inputs and dividing them yourself; on such a field an empty allowedAggregations means "already computed", never "unusable". - For “how many” questions, use COUNT or COUNT_DISTINCT (when the business meaning is unique entities) instead of returning raw rows and counting them yourself. Keep only dimensions the user asked to break the count by. - date_buckets: bucket a date/timestamp field by DAY/WEEK/MONTH/QUARTER/YEAR (e.g. "revenue by month"). Only date-category fields can be bucketed; time_zone applies only to types with a time-of-day component (TIMESTAMP/DATETIME — not pure DATE), and never to a Calculated Field, whose bucket must be requested without one. Which operators and aggregations fit which field type (using each field's "type" from get_data_mart_details_by_id): - number (INTEGER, FLOAT, NUMERIC, …): operators eq, neq, in, not_in, gt, gte, lt, lte, between, is_blank, is_not_blank; aggregations SUM, AVG, MIN, MAX by default; P25, P50, P75, P95 only where enabled on the field - string (STRING, VARCHAR, TEXT, …): operators eq, neq, contains, not_contains, starts_with, ends_with, in, not_in, is_blank, is_not_blank; aggregations COUNT, COUNT_DISTINCT by default; MIN, MAX only where enabled on the field - date (DATE, DATETIME, TIMESTAMP, …): operators eq, neq, in, not_in, gt, gte, lt, lte, between, is_blank, is_not_blank, before, after, in_last_n_days, in_next_n_days, this_week, last_week, this_month, this_quarter, last_quarter, this_year; aggregations MIN, MAX by default; COUNT, COUNT_DISTINCT only where enabled on the field - time (TIME): operators eq, neq, in, not_in, gt, gte, lt, lte, between, is_blank, is_not_blank, before, after; aggregations MIN, MAX by default; COUNT, COUNT_DISTINCT only where enabled on the field - boolean (BOOLEAN): operators eq, neq, is_blank, is_not_blank (eq/neq take a boolean true or false, not a string); aggregations COUNT, COUNT_DISTINCT - other (JSON, STRUCT, GEOGRAPHY, …): operators is_blank, is_not_blank; aggregations COUNT - Arrays are column-only: when a field's mode is REPEATED or its type or sliceType is ARRAY (including parameterized ARRAY types), it may appear in fields, but never in filters, slices, sort, aggregations, or date_buckets. This overrides all category rules above, including COUNT, ANY_VALUE and blank checks. A data mart can narrow a field's aggregations further ("only where enabled on the field") — get_data_mart_details_by_id returns each field's effective allowedAggregations; trust that over this table. Note COUNT/COUNT_DISTINCT are NOT available on number fields — to count rows per group, apply COUNT to a non-number field you already select that is always filled (an id field works well; COUNT skips NULLs, so a nullable field undercounts). To count UNIQUE records of a JOINED data mart (e.g. "how many distinct orders per customer"), do not aggregate its id column — instead select that source's own Unique Count field like any other field; get_data_mart_details_by_id (with_joined_fields) lists it among that source's joined fields whenever one is available. Copy its "name" (e.g. "orders__unique_count"), never its human-readable "displayName". It can be selected in "fields" and ordered by in "sort" (using that same exact name), but it cannot be used in filters, slices, aggregations, or date_buckets. - sort: order the result rows by { field, direction } with direction "asc" or "desc"; rules apply in order (the first is the primary key). Each sorted field must also be listed in fields. - fields must list every column the query uses, INCLUDING any field named in aggregations, date_buckets, or sort — a field you aggregate, bucket, or sort but omit from fields is rejected. Example — "revenue by month": fields ["ts", "revenue"], aggregations [{field: "revenue", function: "SUM"}], date_buckets [{field: "ts", unit: "MONTH"}]. (Filters are the exception: a filter may reference a field that is not in fields.) Choosing between slices and filters (both are row-level predicates applied to raw values BEFORE any aggregation, so neither can threshold a total you asked for via "aggregations" — the one exception is a Calculated Field whose level is "metric", whose formula is already aggregated and whose filter therefore compares the aggregated value): - slices (pre-join): narrow a JOINED data mart before it is blended in — criteria on a joined data mart's own fields only. Slices do NOT apply to the main data mart. More efficient — they reduce the joined volume before the join. A slice runs on the field's ORIGINAL value, so when get_data_mart_details lists a "sliceType" for the field, use operators valid for that pre-join type (not the field's blended-result "type"). - filters (post-join): row-level criteria on the blended result — use for anything on the MAIN data mart's fields or on a joined field. A filter on a field you also aggregate restricts which raw rows feed the aggregate (e.g. filter revenue > 0 → SUM over positive rows), NOT the group total. - Rule: pre-narrowing a joined data mart's rows → slices; any other raw-row criterion → filters. - Filtering by a total you asked for via "aggregations" (e.g. "groups whose SUM(revenue) > 100") is NOT supported — return all groups with their totals and let the caller compare. If the data mart already defines that quantity as a Calculated Field with level "metric", filter on THAT field instead and the threshold is applied to the aggregated value; list it in "fields" when you do. - Example — "orders in the last 3 months" where orders is a joined data mart: the date range narrows the joined orders before the join → slices. Using the results: - Use metrics and totals from the response directly — never recompute a value already present (totals are computed server-side over all matching rows, so they stay correct even when rows are truncated). - The totals block is separate from the rows. - Totals keys are technical output column names. Match a totals key to column_metadata[].name, not to a business-friendly columns label. - data_last_updated answers "how current is what I am looking at?". Read it carefully before repeating it: - data_last_updated_at is when the SOURCE TABLES last changed in the data warehouse. It is NOT a statement about which time period the data covers: a table rewritten today may have only backfilled figures for 2021. Say "the source tables were last updated on X", never "the data is fresh as of X". - null means unknown, not old and not fresh. Say the warehouse does not report it, and do not infer staleness from it. - coverage "partial" means some sources could not be read, so the real time can only be MORE recent than the one reported — present it as "at least as recent as X" and mention that the picture is incomplete. "unavailable" means nothing could be determined. - Mention it unprompted when the user's question depends on recency (today's numbers, "latest", trends up to now) or when they are about to act on the result. - Present every timestamp from this block (including per-table sources) in a business-friendly form — e.g. "August 4, 2026 at 09:46 UTC" — converted to the user's time zone when the conversation establishes one, otherwise in UTC with the zone named. Never show a raw ISO-8601 value like 2026-08-04T09:46:33Z. If truncated is true, not all matching rows were returned: narrow the query (fewer fields, tighter slices/filters) or raise limit (up to 1000). Always use the source metadata in the response: name the Data Mart the answer came from, distinguish numbers calculated by OWOX from arithmetic you perform yourself, and clearly warn the user when rows were truncated.
query_data_mart
Start an existing report by report_id and deliver fresh data to its push destination. Use this for a later rerun or when add_report returned initial_run.status="failed_to_queue". Do not call it when add_report already returned a queued run_id. Returns immediately with report_id and run_id; it does not wait for final status. Poll get_report_run_status with those ids until should_poll is false, waiting up to 15 seconds between checks when possible. Each call starts a new billed Report Run; concurrent runs are rejected as "Report is already running or pending".
run_report
Returns a high-level summary input for the current OWOX project published Data Mart catalog so the LLM can orient the user. Use when the user asks open-ended questions like "what data is available here?", "what can I analyze?", or "where should I start?". The tool returns counts and top published Data Marts ranked by configured relationship connectivity, with shortened descriptions and basic usage metadata. It does not query actual data rows, compute data freshness, or generate a natural-language summary.
summarize_data_catalog
Update an existing report: rename it, replace which data mart fields it exports, replace its output controls — filters/slices, aggregations, date_buckets, sort, limit — using the same vocabulary as query_data_mart ([] removes a control, null removes the limit), and/or — for reports with an email, slack, teams, or google_chat destination — change the message subject or body. Use it whenever the user asks to change a report that already exists — including one you created earlier in this conversation ("add a filter", "sort by revenue", "rename it") — instead of creating another report with add_report. Provide at least one change; anything not provided stays unchanged. Returns the report as it is after the update, and by default re-runs a Google Sheets report when the export changed (run.status="queued" — poll get_report_run_status), so the sheet shows the new definition; email, Slack, Teams, and Google Chat reports are re-sent only with run_immediately=true.
update_report
Updates one existing report run schedule identified by trigger_id (get it from list_report_run_schedules). This changes cron_expression, and optionally time_zone and is_active; it does not change the report target and does not create another schedule. Changing or disabling a schedule can skip report deliveries, and missed runs are not replayed when the schedule is restored. To add another schedule for the same report, call create_report_run_schedule instead. time_zone must be a valid IANA timezone (e.g. "Europe/Kyiv"); if omitted, the schedule keeps its current timezone. If is_active is omitted, the schedule keeps its current active state.
update_report_run_schedule
OWOX Data Marts ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve OWOX Data Marts's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are OWOX Data Marts alternatives on ChatGPT?
As of 2026-11-02, OWOX Data Marts competes with ADECI, Adzviser Google Analytics, Adzviser Shopify, AI for Database, AI2SQL, Alteryx Insights, AnalyticsLog, Anomaly AI and 81 more in ChatGPT Self-Serve BI & Conversational Analytics, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.