MCP Server
Zeotap exposes its capabilities through a Model Context Protocol (MCP) server, enabling external AI tools to interact with your CDP programmatically.
Overview
The MCP server runs alongside the control plane and provides a standardized interface for AI agents to discover and use Zeotap tools. This allows integration with Claude Desktop, Cursor, and any other MCP-compatible client.
Lists, paging and large results
Every list_* tool answers one page in the same shape, with the counts first so a client can tell a short page from a short collection:
{
"total": 212,
"returned": 50,
"offset": 0,
"limit": 50,
"has_more": true,
"next_offset": 50,
"truncated": { "reason": "limit" },
"fields": "summary",
"detail": "Partial: 50 of 212 models shown. …",
"items": [ { "id": "…", "name": "…", "column_count": 40 } ]
}- Items are summaries by default — enough to pick one (id, name, status, the ids it points at, a few counts), with empty fields left out. Fetch one in full with the matching
get_*tool, or passfields: "full"(every field) or a list of field names. - Find, don’t scan. Lists take
limit,offsetand the filters their schema lists, such asparent_model_idorstatus, and most takesearch(case-insensitive; every word must appear; an exact id or name ranks first). Run histories page newest first by offset only; asearchsent to a list that does not take one is refused rather than ignored. A few small catalogues (blueprints, realtime destination types, asset providers) return whole items by default. - A partial page says so.
has_moreis true whenever more matched;next_offsetis where the next page starts (repeat the call with the same arguments and thatoffset);truncated.reasonislimit(more items exist) orsize(the page was ended early to stay within the response budget). A list whose source reads only the newest runs says so withwindow_exhaustedand states no total. - Large single objects (
get_*) takefieldsto return only some sections.get_modelpages its columns in place withcolumn_search,column_limitandcolumn_offset; a paged call reports how many there are incolumns_page. An object too large for the budget comes back with_truncatednaming what was cut: its largest lists are shortened from the end, each with a<field>_pagewhosenext_offsetyou pass back asoffsets: {"<field>": n}for the rest, and any other large value is replaced by an[omitted: …]marker you can read alone withfields. query_warehousereportsrow_count,has_more_rowsand, when rows or cells were left out,truncatedwith the reason.
A result is sized to about 8,000 tokens unless the client asks otherwise. The platform’s own agent sends the room left in its conversation as _response_budget_tokens, a reserved argument the server removes before the call is evaluated or audited.
Available Tools
The MCP server registers 107 tools, of which the 100 documented here are generally available — the rest seed demo data and are granted only to demo accounts. They span every CDP surface — schema inspection, audience and computed-attribute authoring, audience canvases, identity resolution, per-profile and per-record reads, realtime events, orchestrations, stores, event streams, and direct warehouse access. Tools are grouped below by domain.
Schema
| Tool | Description |
|---|---|
list_models | List the data models in the workspace — name, entity type, source table, keys, status and column count. Columns and column configuration come from get_model. |
get_model | Get detailed information about a specific model — columns, types, primary key, entity type, SQL, and column_config (sensitivity, PII types, aliases). |
list_relationships | List all entity relationships (joins) connecting parent, related, and event models in the workspace. |
list_traits | List all computed attributes (aggregated values) defined on parent or related models in the workspace. |
Audiences
| Tool | Description |
|---|---|
list_audiences | List the audiences in the workspace, with name, parent model, estimated size, status, folder and tags. The filter tree comes from get_audience. |
get_audience | Get an audience’s full filter tree, parent model, estimated size, and sync status. |
estimate_audience_size | Estimate the row count matching a filter tree against a parent model without creating an audience. |
validate_filter_node | Validate a FilterNode JSON structure for correctness without executing it. |
compile_filter | Compile a FilterNode tree into SQL and return the estimated size; useful before saving an audience. |
create_audience | Create a new audience from a FilterNode tree. The filter is validated and compiled before saving. |
update_audience | Update an existing audience’s name, description, filter tree, or status. Only provided fields change. |
Audience Canvases
| Tool | Description |
|---|---|
list_audience_canvases | List all audience canvases in the workspace, with parent model, audience count, and when each was last published. |
get_audience_canvas | Get a canvas’s draft nodes and edges, its published version, and its parent model. |
validate_canvas_changeset | Validate proposed nodes and edges before saving or publishing — cycles, unwired tiles, missing audience names. |
create_audience_canvas | Create a new, empty canvas on a parent model, optionally routed through an identity graph. |
update_canvas_draft | Replace a canvas’s draft nodes and edges. Autosaved and visible in the editor; nothing is published yet. |
publish_audience_canvas | Publish the current draft, compiling every Create Audience tile and materialising the audiences it owns. |
Computed Attributes
| Tool | Description |
|---|---|
create_trait | Create a new computed attribute on a parent entity model; it is computed on read wherever it is referenced. |
update_trait | Update a computed attribute’s name, description, configuration, result type, or status. Only provided fields change; setting the status publishes or unpublishes it. |
trigger_trait_evaluation | Trigger an optional manual refresh of computed attributes for a parent model and return a run ID for tracking. Not required — computed attributes are computed on read. |
Models & Schema (Write)
| Tool | Description |
|---|---|
create_model | Create a model from a warehouse table or custom SQL. Columns auto-infer; entity_type and primary_key_column are required. |
update_model | Update an existing model’s name, description, columns, SQL, entity type, or status. |
update_column_config | Set per-column sensitivity levels, PII types, display aliases, and enabled state. Fields an entry omits keep their stored values. |
update_column_descriptions | Describe what a model’s columns mean (partial update). Never replaces a description a user, the warehouse or a blueprint wrote unless overwrite is set. See Column Descriptions. |
create_relationship | Create a relationship (join) between two models, enabling event and relation conditions in audience filters. |
Sources & Warehouses
| Tool | Description |
|---|---|
list_sources | List the configured data sources (input warehouses) in the workspace, with type and status (fields: ["config"] for connection config). |
introspect_source | List all database schemas available in a source connection. |
list_tables | List all tables in a specific schema of a source connection. |
list_columns | List all columns in a specific table, including name, data type, and nullability. |
get_warehouse_context | Get the full data model context — models, columns, relationships, computed attributes, event schema, and system tables. Use before writing warehouse SQL. |
query_warehouse | Execute a read-only SQL query against a data warehouse, with the SQL editor’s rules: the person needs Models write access, and a person an access policy restricts cannot use it. One SELECT statement only, capped at 500 rows. Results are masked. Every call is recorded in the AI audit log. |
write_warehouse | Execute a write SQL statement (INSERT, UPDATE, CREATE TABLE). DELETE, DROP, ALTER, TRUNCATE are blocked. |
Destinations & Syncs
| Tool | Description |
|---|---|
list_destinations | List the configured destinations (output targets), with type and status (fields: ["config"] for connection config). |
create_destination | Create a new destination (Snowflake, BigQuery, Databricks, webhook, etc.) for syncing audience or model data. |
list_syncs | List the Reverse ETL syncs in the workspace — model, destination, mode, schedule, and status (fields: ["field_mapping"] for mappings). |
list_audience_syncs | List the audience syncs — audience, destination, mode, schedule and status (fields: ["field_mapping", "config"] for mappings and Audience Boost config). |
create_audience_sync | Create a new audience sync linking an audience to a destination, with field mapping, sync mode, and schedule. Optionally enables Audience Boost. |
trigger_sync | Trigger a Reverse ETL sync to execute immediately. Returns the sync run ID. |
trigger_audience_sync | Trigger an audience sync to execute immediately. If Audience Boost is enabled, runs dual pipelines and reports per-identifier metrics. |
pause_sync / resume_sync | Pause a Reverse ETL sync, or resume it and reset its failure count. Changes only the status; the mapping, config and schedule are not touched or re-checked. |
pause_audience_sync / resume_audience_sync | The same for an audience sync. Works even when the saved field mapping would fail a newer rule. Resume works whether a person or repeated failures paused it. |
list_sync_runs | List recent runs for a model sync or an audience sync (newest first) — status, timing, row counts, batch counts, and errors. |
get_sync_run | Get the status and metrics of a single sync run. Use it to poll a run started by trigger_sync or trigger_audience_sync. |
Loaders
| Tool | Description |
|---|---|
list_loaders | List all loaders (inbound ELT connectors) — type, source, target schema, streams, schedule, status, and last-run summary. |
list_loader_runs | List recent load runs for a loader (newest first) — status, timing, rows loaded, per-stream counts, and errors. |
get_loader_run | Get the status and metrics of a single load run. |
Stores
Store tools are only available on workspaces where Stores is enabled.
| Tool | Description |
|---|---|
list_stores | List all stores in the workspace, with primary index and status. |
get_store | Get a single store by ID. |
list_store_feeds | List the feeds attached to a store — model, deletion behaviour, schedule, and last refresh (large field mappings are summarised; fields: "full" returns them). |
list_store_feed_runs | List a feed’s recent refresh runs, with rows added, updated and deleted, status, and any error. |
create_store | Create a store. The primary index is the row key and cannot be changed afterwards. |
archive_store | Archive a store. Its feeds stop running. |
create_store_feed | Attach a feed that mirrors one parent-entity model into the store. |
update_store_feed | Rename, reschedule, or remap a feed, or change its deletion behaviour. |
delete_store_feed | Delete a feed. Data already written to the store is not removed. |
trigger_store_feed | Refresh a feed immediately. Returns the run ID. |
resume_store_feed | Resume a feed that auto-paused after repeated failed refreshes. |
Identity Resolution
| Tool | Description |
|---|---|
list_identity_graphs | List all ID graphs in the workspace. |
get_identity_graph | Get the full configuration of an ID graph — metadata plus models, identifiers, merge rules, limits, and probabilistic rules. |
create_identity_graph | Create a new ID graph with full configuration in one call. |
update_identity_graph | Update an ID graph’s metadata. Only provided fields change. |
configure_identity_graph_rules | Configure models, identifiers, merge rules, limit rules, and probabilistic rules for an ID graph (partial update). |
delete_identity_graph | Delete an ID graph permanently — definition, models, identifiers, rules, run history, and golden-record configs. |
list_identity_graph_runs | List recent resolution runs for an ID graph (newest first) with status, timing, and metrics. |
get_identity_graph_run | Get details for a specific ID graph resolution run. |
trigger_identity_graph_run | Trigger or cancel an ID graph resolution run. |
explore_identity_graph | Look up a resolved profile by an identifier value — returns the unified profile (ss_id) and all source rows. |
configure_golden_record | Create or update the golden-record configuration (survivorship rules) for an ID graph. |
get_golden_record | Read a unified profile’s golden record by ss_id or by identifier, with the attribute definitions and source ranking behind each value. |
Profiles and Records
Resolved-profile tools read through an identity graph; the two record tools answer the same per-customer question in a workspace that has models and relationships but no graph.
| Tool | Description |
|---|---|
get_profile_members | Return the source rows of one model that belong to a resolved profile (ss_id), with their column values — the records behind a cluster. |
get_profile_related | Follow one registered relationship out from a profile and return the related model’s rows — a customer’s orders, tickets, subscriptions. |
get_profile_lineage | Explain why a profile’s records merged: the identity edges inside the cluster, which rows were linked, on which identifier, at what confidence. |
get_golden_record_lineage | Explain, attribute by attribute, where a profile’s golden-record values came from — the candidate values each ranked source holds. |
get_model_record | Read one row of a model by its primary key, with its visible column values — the per-customer view without an identity graph. |
get_model_record_related | Follow one registered relationship out from a single model record and return the related rows, without an identity graph. |
Realtime Events
| Tool | Description |
|---|---|
list_realtime_events | List all realtime events in the workspace — stream-sourced related events declared on a parent model. |
list_model_realtime_events | List the realtime events declared on one parent model, to see what a realtime audience condition can already reach. |
get_realtime_event | Get one realtime event, including its event source, event type, parent relationship, and its filterable property catalog. |
create_realtime_event | Declare a realtime event on a parent model, bound to the existing event-ingest spine. |
update_realtime_event | Update a realtime event’s editable fields. Only provided fields change. |
delete_realtime_event | Delete a realtime event. Refused, naming the audiences, while any audience filter still references it. |
Orchestrations
| Tool | Description |
|---|---|
list_journeys | List all orchestrations in the workspace. Each orchestration is a DAG of tiles defining a multi-step engagement flow. |
get_journey | Get full details of an orchestration — tiles, edges, entry/exit criteria, schedule, status, and last run info. |
create_journey | Create a new orchestration (starts in draft status). |
update_journey | Update an orchestration’s name, description, tiles, edges, or schedule. Only provided fields change. |
delete_journey | Delete an orchestration permanently. Warehouse tables created during activation are not auto-deleted. |
validate_journey | Validate the DAG structure — cycles, dangling edges, missing tiles, schedule correctness. |
activate_journey | Activate an orchestration (draft/paused -> active), provisioning warehouse tables and scheduling. |
pause_journey | Pause an active orchestration. Existing member state is preserved. |
resume_journey | Resume a paused orchestration. Evaluation continues from where it left off. |
trigger_journey | Manually trigger an evaluation run for an active orchestration. |
list_journey_runs | List recent evaluation runs for an orchestration with status, timing, and per-tile metrics. |
get_journey_run | Get details for a specific orchestration run, including evaluation metrics. |
cancel_journey_run | Cancel a pending or running orchestration evaluation. |
Event Streams
| Tool | Description |
|---|---|
list_event_keys | List all event source write keys in the workspace, with name, value, status, topic, and last-used timestamp. |
get_event_volume | Get hourly event volume metrics for the workspace over the last 7 days, grouped by event type and name. |
list_event_contracts | List all event contracts — schemas, enforcement modes, and undeclared-field handling. |
list_event_contract_violations | List event contract violations — type, field path, expected vs received values, sample event ID, count. |
list_event_forwarding_rules | List event forwarding rules — destination, event filter, transformation, field mapping, consent, rate limit. |
list_event_transformations | List event transformations — JavaScript functions that modify event payloads before forwarding. |
get_event_warehouse_config | Get the event warehouse configuration — source ID, schema, staging bucket, and enabled status. |
Anomalies
Access to what anomaly monitoring and your alert rules found in the workspace. An MCP client cannot open or resolve an anomaly, but it can dismiss one whose change was intended, and acknowledge or mute an alert incident. These three tools need the write:alerting scope, are checked against your workspace’s guardrail policies, and are recorded in the audit log.
| Tool | Description |
|---|---|
list_anomalies | List anomalies found by the background monitor, newest first — metric, resource, observed vs usual, severity, open or resolved, and the root-cause analysis once written. Filter by state, resource type or resource. |
get_anomaly | Get one anomaly with the evidence its analysis was written from: the resource’s status and dependencies, recent runs and most frequent errors, other anomalies open at the same time, and — for an event-volume drop — which events fell. Audit-log entries (who changed what) are never returned to an MCP client. |
dismiss_anomaly | Dismiss an open anomaly that will never recover because the change was intended, recording why. |
ack_incident | Acknowledge one of the workspace’s alert incidents: record that somebody is on it. It does not stop notifications. |
mute_incident | Mute one of the workspace’s alert incidents until a time or indefinitely, recording why. |
Utility
| Tool | Description |
|---|---|
check_approval_status | Check the status of a pending guardrail approval. Use this when a previous tool call returned pending_approval. |
get_workspace_memory | Retrieve durable facts learned about this workspace — naming conventions, quirks of the data model, pitfalls hit before, team preferences. |
Authentication
The MCP server authenticates requests using API keys.
- In the Zeotap UI, open API Keys under Governance in the left sidebar and select the AI API Keys tab.
- Click Create API Key, give it a name, and select the scopes your MCP client needs (see Scopes below). A key needs at least one scope.
- Copy the generated key — it starts with
sk_and is shown only once. Store it securely; if you lose it, revoke and regenerate. - Configure your MCP client to send the key as a bearer token in the
Authorizationheader.
The workspace your tool calls run against is derived from the API key itself — there is no separate workspace header.
Scopes
Each MCP tool requires a specific scope on the API key. Grant the minimum set your client needs:
| Capability | Required scope |
|---|---|
| Read models, relationships, and warehouse context | read:schema |
| Read computed attributes | read:trait |
| Create or modify computed attributes | write:trait |
| Read audiences and canvases, estimate sizes, validate filters | read:audience |
| Create or modify audiences, canvases, and audience syncs | write:audience |
| Read syncs and destinations, sync run history, and anomalies | read:sync |
| Trigger sync runs | trigger:sync |
| Read connected warehouses and loaders, introspect tables and columns, and read loader run history | read:source |
| Create or modify models and relationships | write:model |
| Configure destinations | write:destination |
| Read identity graphs, resolved profiles, and profile lineage | read:identity |
| Modify identity graphs and golden-record rules | write:identity |
| Read orchestrations | read:journey |
| Modify orchestrations | write:journey |
| Trigger orchestration runs | trigger:journey |
| Read event streams | read:event |
| Read realtime events | read:realtime_event |
| Create or modify realtime events | write:realtime_event |
| Run read-only warehouse queries | query:warehouse |
| Run warehouse write statements | write:warehouse |
| Read stores and feeds | read:store |
| Create or modify stores and feeds | write:store |
| Trigger or resume feed refreshes | trigger:store |
A tool call returns an authorization error if the matching scope is missing. A scope says what a key may ask for; the person who created the key still needs the role to do it. Writing to the warehouse needs Sources write access, changing a model’s column settings needs Models write access, and changing Stores and their feeds needs Stores write access (or Stores trigger access to run a feed). Reads follow the same rule: reading Stores needs Stores read access, the event tools need the matching Events read access (event keys, contracts, forwarding rules, transformations), the real-time event tools need Realtime events read access, the anomaly tools need Alerting read access, get_warehouse_context needs Models read access, query_warehouse needs Models write access (as the SQL editor does), and get_workspace_memory needs Agent read access. check_approval_status reads the agent’s own held calls, and anyone else’s only with access to the approvals queue. A key whose creator lacks the permission is refused with an error naming it, even when the key holds the scope.
You can only grant a scope your own role supports in the workspace: each scope needs at least one of the permissions behind its tools (for example write:warehouse needs Sources write access), and asking for one you do not have is refused with the permission it needs. The scopes stay in step with the person afterwards. On every request a key can use only the scopes its creator’s current role supports, so when someone’s role in a workspace narrows, their keys keep working with what the new role allows, and get their original scopes back if the role is restored. When they lose access to the workspace, every key they created there is revoked except serving keys, which belong to the workspace. The agent’s own session works the same way: it carries only the scopes the user’s role supports, so a Member’s agent can read but cannot change anything, and a conversation open when the user’s role narrows carries on with what the new role allows.
check_approval_status, get_workspace_memory, get_model_record and get_model_record_related are all covered by read:schema.
These scopes govern MCP tool calls only. None of them authorises an HTTP read: the Profile API takes its own svk_ serving key and the Membership API a public pk_ membership key, and an sk_ key is refused on both.
Two scopes are worth granting deliberately rather than as part of a broad selection: query:warehouse lets a client read any table the warehouse connection can reach, and write:warehouse lets it write to that warehouse directly. Unlike the other scopes, neither is bounded to a resource Zeotap manages. A person an access policy restricts cannot use query_warehouse at all, as in the SQL editor; otherwise a warehouse scope is only as narrow as the warehouse credentials behind it. Grant them to clients you would trust with those credentials, and use guardrails to constrain what the agent does with them.
query_warehouse lets the agent do what its user can do in the SQL editor, and follows the same rules. The person needs Models write access, as the editor does, so a member who can only view models cannot use it through the agent either. A person an access policy restricts cannot use it, in the editor or through the agent, because a free-form query returns the rows the policy hides. The agent then answers with the tools that apply those restrictions: record lookups, audience estimates and column profiles.
Results are masked before they reach the agent. A column that any model in the workspace marks redacted comes back as ***REDACTED***, and one marked sync-only or blocked is left out. So is any column whose name looks like personal data (an email, a phone number, a name), whether or not a model has marked it. The masking is by column name, so it does not survive a renamed or computed column; for a guarantee that does, give the warehouse connection a masked, read-only credential for interactive use. The warehouse then enforces the masking for the SQL editor and the agent alike.
The tool accepts exactly one SELECT statement. Every call, whether run, refused or failed, leaves an entry in the AI audit log with a fingerprint of the query, the columns returned and the row count, never the query text or the rows.
Integration with Claude Desktop
The Zeotap MCP server speaks JSON-RPC over HTTP, which Claude Desktop cannot connect to directly — it expects a stdio transport. Bridge the two with the mcp-remote proxy (no install needed; npx fetches it on demand).
Add the following block to your Claude Desktop claude_desktop_config.json:
{
"mcpServers": {
"zeotap": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.zeotap.com/mcp",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer YOUR_API_KEY"
}
}
}
}Replace YOUR_API_KEY with the key copied at creation time, then fully quit and restart Claude Desktop. The ${AUTH_HEADER} indirection keeps the Bearer prefix intact — passing the full header value directly inside args triggers a Claude Desktop bug that splits the string on whitespace.
The same mcp-remote config works for any MCP-compatible client that supports stdio servers (Cursor, Cline, etc.). Clients that already implement the MCP Streamable HTTP transport can connect to https://mcp.zeotap.com/mcp directly, sending the API key as Authorization: Bearer YOUR_API_KEY.
Available Resources
The MCP server also exposes resources that provide structured context to AI agents:
| Resource | Description |
|---|---|
zeotap://schema/models | All data models with columns, primary keys, entity types, and sensitive-column metadata for PII-safe querying. |
zeotap://schema/relationships | Entity relationship graph — how parent, related, and event models connect via foreign keys. |
zeotap://schema/traits | All computed attribute definitions in the workspace, with types and parent models. |
zeotap://schema/filter-node-spec | The JSON Schema defining the FilterNode structure used for audience filter trees. |