Skip to main content

Overview

The Narrative MCP server exposes platform operations as tools that AI assistants can discover and call. All tool names use the narrative_ prefix. This page documents every available tool, its parameters, and usage patterns. For setup instructions, see Connecting to the Narrative MCP Server. For background on how the server works, see MCP Server for Agents.

Server URL

Context tools

Context tools manage your authenticated session and company scope.

narrative_context_get

Returns the current session context: authenticated user, role, and active company (if one has been set). Use this to confirm which company is active before running queries or operations. If no company is set, follow up with narrative_context_set_company.

narrative_context_get_companies

Lists the companies the authenticated user belongs to. Returns each company’s id and name. Use this to discover which companies you can switch to.

narrative_context_set_company

Switches the active company for the current session. All subsequent tool calls operate against the selected company until changed.

narrative_context_search_companies

Searches companies by name using case-insensitive substring matching. Available to global administrators only. Returns { id, name } for each matching company.

Dataset tools

Dataset tools let you search, describe, and inspect datasets. Finds datasets by fuzzy keyword match, tags, or data plane. At least one filter must be supplied — calling with no filters returns an error rather than the full corpus. Filters compose with AND. Returns at most 50 ranked matches. If the response indicates more matches exist, narrow the filters and retry. For full metadata on a shortlisted dataset, call narrative_datasets_describe with its id.

narrative_datasets_describe

Describes one or more datasets with configurable detail levels. Accepts multiple dataset ids in a single call and fetches them in parallel. Available include values: In the metadata section, default_compute_pool_id appears only when the dataset has its own default compute pool configured. Jobs against the dataset that don’t name a pool (such as sample requests) run on that pool, taking precedence over the company-level and data-plane-level defaults shown by the data plane tools. See compute pools for the full resolution chain. When mappings is in the include set, the section lists the dataset’s stored mappings plus the derived mappings they imply. A derived row has source: derived, no id (it is computed on the request from a stored mapping and a derivation rule, nothing is stored), and a provenance naming the source mapping, the derivation path, and whether the result is exact, lossy, or imprecise. Fetching without mappings (or from any other tool that reads a dataset) skips derivation and returns only stored rows.

narrative_dataset_get_column_stats

Returns per-column statistics for a single dataset. Available include values:

narrative_dataset_set_column_stats_config

Replaces the column-statistics configuration for a dataset. This is a write that overwrites whatever configuration was previously stored.
Omit a configuration slot entirely to inherit from the parent level. An explicit null is not the same thing, and the API rejects it where a value is required.

Dataset operation tools

These tools trigger asynchronous operations on datasets. All return a job or operation id that you can poll for completion.

narrative_dataset_request_sample

Triggers a workflow that samples a dataset and runs Narrative’s privacy model over those rows in a single run, so the sample redaction is written against the rows it is masking. Returns the workflow’s id and metadata plus a run_id. Poll the run with narrative_workflow_runs_list until it reaches a terminal state, then read the sample (already redacted) with narrative_datasets_describe using include=["sample"]. Pass redacted=false on that call to read the raw unredacted rows behind the mask.

narrative_dataset_refresh_materialized_view

Triggers a refresh of a materialized-view dataset. Returns the refresh job id. Poll completion with narrative_jobs_describe.

narrative_dataset_recalculate_statistics

Enqueues a column-statistics recalculation job for a dataset. The dataset must have a statistics configuration; the request is rejected otherwise. Returns the recalculation id, which is a job id. Poll completion with narrative_jobs_describe.

narrative_dataset_update

Updates the safe, curator-editable metadata of a dataset: display name, description, and tags. Wraps PUT /datasets/:id. Structural fields (name, schema, write mode) are never editable through this tool. At least one of display_name, description, add_tags, or remove_tags must be provided. Omitted fields are left unchanged (partial update). Tags are edited additively: the tool reads the dataset’s current tags, applies add_tags and remove_tags, then writes the resulting set. A small set of platform-managed system tags — _nio_view, _nio_inference, _nio_cached_mapping, and _nio_materialized_view — are immutable and silently ignored if included in add_tags or remove_tags; any other tag (including custom _nio* tags) is caller-controlled. pending datasets accept updates to all safe fields; active datasets accept display name, description, and tags; archived datasets reject any update.
The upstream endpoint currently treats an empty tag list as a no-op, so a remove_tags that would clear the dataset’s last remaining tag is rejected with a clear error rather than silently ignored.
Returns a confirmation with the updated display name, description, and tags.

narrative_dataset_activate

Activates a Narrative dataset. Activation locks in the dataset’s schema and lets Narrative start ingesting data into it. Wraps PUT /datasets/:id/activate. New datasets start inactive with status pending, as does the cache dataset that narrative_mapping_create creates for a cached_mapping. Activation is a one-time step: the API rejects the call with an error if the dataset is already active, does not exist, or is not accessible to the current company. Use narrative_datasets_describe to inspect the dataset before or after activating it. Returns the dataset id and its new status.

Transfer tools

Transfer tools copy the rows of one of your datasets into another dataset, which can be on another data plane, and follow the copy through to completion. A transfer runs as a workflow: its status moves from pending to running, then to completed, failed (with a failure_reason), or cancelled.
Transfers are in beta. The tools’ inputs and outputs may change without notice.

narrative_transfer_create

Requests a transfer from a source dataset of the active company into a target dataset. Wraps POST /v1/transfers. The tool is marked destructive, because an overwrite replaces the target’s rows.
  • window picks the source rows by _nio_last_modified_at: { "type": "transfer_window_last_modified_at", "lower": ..., "upper": ... } copies rows where lower < _nio_last_modified_at <= upper. Both bounds are optional RFC 3339 timestamps with a Z offset, and upper can be no later than the source’s last committed write, which is also its default. An append without a window copies every row again each time.
  • target is either an existing active dataset of the company, { "type": "transfer_target_dataset", "dataset_id": <id>, "mode": ... }, or a new dataset created from the source’s columns, { "type": "transfer_target_new_dataset", "data_plane_id": "<uuid>", "mode": ... }. mode is append (adds the rows) or overwrite (replaces the dataset’s rows with them).
  • compute_pool_id goes inside source and inside target, and names the compute pool (a UUID) that side’s data plane runs the transfer on. It defaults to the dataset’s default pool, else its data plane’s. For a new dataset, it’s also the pool that creates the dataset, and it’s required when the target’s data plane has no default pool. The top-level source_compute_pool_id and target_compute_pool_id parameters were removed; a request that still sends them runs on the default pools.
  • A new dataset also takes optional name, display_name, and retention. name defaults to the source’s name followed by _ and 8 random hex characters, and display_name defaults to the source’s. Without retention the dataset keeps every snapshot and every row. retention is { "type": "copy_source" } to use the source’s policies (refused when the target can’t enforce them), or { "type": "policies", "policies": ... } with the body of the dataset retention policy endpoint. Those policies only run when they include a schedule_config.
  • idempotency_key: send a new UUID for each transfer and reuse it if you call the tool again after a failure or timeout. A request with a key that was already used returns the transfer the first request created instead of starting another. Without a key, the tool generates one per call, which protects only that call’s own retries.
Returns the transfer, including its id, status, and workflow_id. Follow it with narrative_transfers_describe.

narrative_transfers_describe

Describes one or more transfers of the active company by id. Wraps GET /v1/transfers/{transfer_id}. Available include values:

narrative_transfers_list

Lists the active company’s transfers, newest first, with their status, outcome, and request. Wraps GET /v1/transfers. Filters combine, so the list holds only the transfers that match all of them.

Attribute tools

Attribute tools let you explore, inspect, create, and update Rosetta Stone attributes. Searches Rosetta Stone attributes by name, by the hints they carry, or both. Available include values: Some attributes aren’t mapped from a single column but from a dataset as a whole, because their value is built from several columns of a row. The tool tells connected AI assistants to find them with hint_kind: "when_to_map" and hint_level: "dataset", without a search_term, and to map such an attribute when its hint’s condition holds for the dataset.

narrative_attributes_describe

Describes one or more attributes by id. Accepts multiple attribute ids in a single call. Uses the same include values as narrative_attributes_search. derivations is on by default here: the tool fetches each attribute’s derivation graph from GET /attributes/{id}/derivation-graph alongside the attribute itself. Reading derivation edges. Each edge renders on one line: derives <target> via <rule> means the attribute is upstream of the target, and derived from <source> via <rule> means the source is upstream. Each line also flags whether the rule is exact, lossy, or imprecise, plus any fidelity note. When the attribute has no edges, the section renders _none_. Both attribute tools tell connected AI assistants to map a dataset column to the attribute closest to the root of the derivation graph: the one with no derived from line that the column actually contains. A dataset mapped to the source attribute of a derivation rule automatically gets mappings to every derived attribute, whereas a mapping created directly to a descendant covers only that one attribute. Mapping directly to a derived attribute is right only when the dataset holds nothing but the derived form, such as hashed emails with no plain addresses.

narrative_attribute_create

Creates a new attribute owned by the currently selected company. Wraps POST /attributes. The type_definition argument accepts one of these shapes:
  • Scalar types — { "type": "string" | "long" | "double" | "boolean" | "timestamptz" }. string and long accept an optional enum of allowed values. All scalars accept optional validations: Spark SQL boolean expressions over $this that a value must satisfy (e.g. "$this >= 0").
  • Object types — { "type": "object", "properties": { <name>: <type definition>, ... }, "required": [ <name>, ... ] }. Nest additional type definitions inside properties.
  • Array types — { "type": "array", "items": <type definition> }.
Attributes are created private to the owning company (no view/map collaborators). To share one, call narrative_attribute_update with collaborators. The created attribute’s id, name, display name, type, description, tags, owning company, and schema details are returned in the response.
Search the catalog with narrative_attributes_search before creating a new attribute — mapping into an existing attribute keeps the marketplace’s shared vocabulary consistent. A good reason to create a new attribute is to define the type contract for a downstream system (usually reached through a connector) that data is normalized into.
See attribute types for the full type reference.

narrative_attribute_update

Updates an attribute owned by the currently selected company. Wraps PUT /attributes/{id}, which replaces the whole attribute, so the tool reads the stored attribute, applies the fields you pass, and sends the result back. At least one of display_name, description, type_definition, collaborators, or hints must be provided. Omitted fields keep their current values.
  • type_definition replaces the whole type, so send the complete new type, not just the part that changes. The API rejects changes that would break data already mapped to the attribute: removing enum values or object properties, making an optional property required, adding a required property, turning off is_join_key, changing a $ref, or changing the base type.
  • collaborators replaces both the view and the map settings. Each takes { "type": "none" | "inclusion" | "exclusion" | "all", "company_ids": [ ... ] }, where company_ids is required for inclusion and exclusion and not allowed for none and all. Only Narrative may use all or exclusion, and map can’t be broader than view. To share an attribute with one more company, read the current settings with narrative_attributes_describe first and keep the companies already listed.
  • hints replaces all of the attribute’s hints. To add one, read the current hints with narrative_attributes_describe first and send them along with the new one. An empty list removes them all.
An attribute’s name can’t be changed, and its tags can’t be edited after it is created. Only the owning company can update an attribute; Narrative owns the global attributes. Returns the attribute as stored after the update: id, display name, name, description, collaborators, the type definition as JSON, and any hints, with any $ref left as a reference. For a follow-up change to the type, start from this definition rather than from narrative_attributes_describe, which resolves references.

Access rule tools

Access rule tools let you discover and inspect the access rules your company owns or has been granted, create and update the rules your company owns, and manage their query policies. Access rules are the permissions and pricing controls applied to datasets. Searches access rules the active company has access to. At least one filter must be provided; calling with no filters returns an error rather than dumping the full corpus. Filters compose with AND. Matches are ranked by fuzzy score with name-side fields weighted above description and company fields, and truncated with an explicit note when the cap fires; refine the filters if you see the truncation message. Available include values: To reference a rule in NQL, use <owning_company_slug>.<access_rule_name>.

narrative_access_rules_describe

Describes one or more access rules by id. Accepts multiple ids in a single call and fetches them in parallel. Available include values: A query that breaks an access rule’s query policy reads no rows from that rule and reports no error. Check the policy before you write a query.

narrative_access_rule_create

Creates an access rule owned by the currently selected company. Wraps POST /v2/access-rules.
  • nql sets the rule’s schema and data plane, and can’t be changed later. Joins, aggregates, and computed columns aren’t supported, and view datasets can’t be shared this way. Check the query with narrative_nql_validate first. For example: SELECT company_data."123"."email" AS email FROM company_data."123".
  • collaborators takes { "type": "none" | "inclusion" | "exclusion" | "all", "company_ids": [ ... ] } for both view and query. none keeps the rule private to your company, and company_ids is required for inclusion and exclusion and not allowed otherwise. view also accepts anonymous, which shows the rule to visitors who aren’t signed in.
  • query_policy is validated against the rule before anything is stored, so the rule is never queryable without its policy, and an invalid policy creates no rule.
Returns the new rule’s id, metadata, collaborators, price, and query policy.

narrative_access_rule_update

Updates an access rule owned by the currently selected company. Wraps PUT /v2/access-rules/{access_rule_id}. Rules shared with your company can’t be updated. At least one field besides access_rule_id must be provided. Omitted fields keep their current values.
  • collaborators replaces both view and query, so pass the whole object. A company you leave out can no longer see or query the rule.
  • Tags are edited against the rule’s current tags. The _nio_access_rule tag is managed by Narrative and is always kept.
A rule’s name and NQL query can’t be changed after it is created; to share different rows or columns, create a new rule. This tool doesn’t change the query policy — use narrative_access_rule_set_query_policy. Returns the rule as stored after the update, including its current query policy.

narrative_access_rule_get_query_policy

Returns the query policy attached to one access rule. Wraps GET /v2/access-rules/{access_rule_id}/query-policy. Any company that can view the rule can read its policy. The API returns 404 when the rule has no policy or you cannot view the rule.

narrative_access_rule_set_query_policy

Attaches a query policy to an access rule, replacing the current one if there is one. Wraps PUT /v2/access-rules/{access_rule_id}/query-policy and returns the stored policy. Only the owning company can set the policy. The API validates the policy against the access rule. An invalid policy returns 400 listing every problem and leaves the current policy in place. See query policies for the policy structure. The MCP server does not expose a tool to delete a policy.

Mapping tools

Mapping tools let you list and create Rosetta Stone mappings from datasets to attributes in the active company.

narrative_mappings_list

Lists the active mappings the currently selected company has on one dataset, stored and derived together, so you can see which attributes the dataset already covers before you create a mapping. Wraps GET /mappings. The full list is returned in one call; the API does not page. In depends_on_dataset_fields, a column name (address) also matches the fields nested under it, and a full path (address.postal_code) matches that field alone. Rows carry attribute ids only. Resolve names with narrative_attributes_describe. Derived mappings are marked source: derived and render as derived (no id). The platform computes them from a stored mapping and a derivation rule. They are not stored, so you cannot fetch, edit, or delete them, and you should never create them by hand. To change a derived mapping, change the mapping it is derived from. An explicit mapping to the same attribute replaces the derived one, so create one only when the dataset holds a better column for that attribute. Call narrative_derivations_describe with the derivation ids to read each rule’s transformation and fidelity note.

narrative_mapping_create

Creates a mapping from a dataset to an attribute in the currently selected company. The mapping defines how each of the attribute’s properties is built from a row of the source dataset, using NQL expressions over the dataset’s columns. The mapping argument accepts one of three shapes:
  • object_mapping — for attributes whose value is an object. Supply type: "object_mapping" and property_mappings, a list of { path, expression } entries where path is a dotted path to an attribute property (e.g. product.brand) and expression is an NQL expression over dataset columns (e.g. itemBrand). Provide a mapping for each of the attribute’s required properties. Quote string literals like 'SKU'.
  • value_mapping — for scalar attributes. Supply type: "value_mapping" and a single expression that produces the attribute’s value.
  • cached_mapping — compiles into a dataset join at query time. Supply type: "cached_mapping" and one or more input_expressions — NQL expressions over the source dataset’s columns that form the join key. The cache dataset is created automatically when the mapping is created, so no cache_dataset_id is supplied. Not permitted on opt-out attributes (data_privacy_request_identifier, unique_id, identifier_relation). See cached_mapping for details.
The dataset must be active and owned by the current company, and you must have map permission on the attribute. The created mapping’s id, scope, source, status, and creation timestamp are returned in the response. The result ends with a derived mappings unlocked section. It lists each derived mapping the new mapping produced, with its attribute, source mapping, derivation ids, and fidelity flags, or states that none were unlocked. Call narrative_mappings_list first to check what the dataset already covers, including derived mappings, so you do not create a mapping the platform already derives.
Before committing to a target attribute, check its derivation edges with narrative_attributes_describe and map to the attribute closest to the root of the derivation graph that the column actually contains. One mapping to the source attribute of a derivation rule covers every derived attribute automatically; a mapping created directly to a descendant covers only that one attribute. The tool’s description carries this same guidance for connected AI assistants.
Use narrative_nql_validate to test a candidate mapping expression before submitting it. Run SELECT <expression> FROM company_data."<dataset_id>" — if it compiles, the expression is valid against the dataset’s schema.
See mapping types for the full schema and Mapping schemas for guidance on writing mappings by hand.

Derivation tools

Derivation tools let you list, describe, and (for Narrative global admins) create derivation rules — the transformations that compute one Rosetta Stone attribute from another. Use narrative_attributes_describe first to see which rules already touch an attribute; each edge names the rule and its id.

narrative_derivations_list

Lists the derivation rules the currently selected company can use — the ones it owns plus the ones shared with it. Wraps GET /derivations. The full list is returned in one call; the API does not page. Filters combine with AND. Omit both filters to list every usable rule.

narrative_derivations_describe

Describes one or more derivation rules by id, transformation included. Accepts multiple ids in a single call and fetches them in parallel. Wraps GET /derivations/{id}. Any id the current company cannot use is reported as not found. Available include values (shared by both read tools):

narrative_derivation_create

Creates a derivation rule owned by the currently selected company. Wraps POST /derivations.
This tool is only visible and callable for Narrative global admins. For every other session the tool is hidden from tools/list and tools/call reports it as an unknown tool. Non-admins who name it directly still receive a permission error.
The mapping argument accepts one of two shapes:
  • object_mapping — for attributes whose value is an object. Supply type: "object_mapping" and property_mappings, a list of { path, expression } entries where path is a dotted path into the target attribute (e.g. value) and expression is an NQL expression over the source attribute read through $source (e.g. SHA2(LOWER($source.value), 256)). Provide a mapping for each of the target’s required properties.
  • value_mapping — for scalar targets. Supply type: "value_mapping" and a single expression producing the target’s value.
Before adding a rule, call narrative_attributes_describe on both attributes (derivations are on by default) and check that no existing rule already covers the same source and target pair — the API rejects duplicates with a conflict. Every expression is validated against the source attribute’s shape and the target’s declared type before the rule is written; failures come back as a descriptive error. A rule that closes a cycle in the derivation graph is still created, and the cycle is returned as a warning on the response.
Global admin status is carried by the caller’s user, not the token — an MCP token minted for a global admin can create rules without any explicit admin grant. See Derivation rules permissions.

Connector tools

Connector tools let you inspect a company’s installed apps and create connections that route dataset data to external connectors. See the connection creation flow below for the recommended order.

narrative_installations_list

Lists the apps installed by the currently selected company and flags which ones are connectors. Apps whose capabilities include destination_connector can receive dataset data through a connection; model_connector apps connect models instead and do not accept dataset connections. Each result shows the installation id, the app id, the app’s name, and its capabilities. Use the installation id with narrative_app_profiles_list to find the profile a connection is created against.

narrative_app_profiles_list

Lists the profiles of an app installation in the currently selected company. A profile’s id is the profile_id that a dataset connection is created against, and only profiles with status enabled can back a connection. If no enabled profile exists, the user must create and enable one in the app’s UI before a connection can be created.

narrative_app_interfaces_list

Lists a connector app’s interfaces and their quick-settings JSON Schemas. Use the returned schema to construct the quick_settings object that narrative_connection_create accepts. Interface ids match the ones narrative_dataset_get_compatible_interfaces reports. Available include values:
Omit include=["collaboration_policy"] unless you need to explain why a specific dataset was rejected. Use narrative_dataset_get_compatible_interfaces to find accepted interfaces first, then call this tool for their quick_settings schemas only.

narrative_dataset_get_compatible_interfaces

Reports which installed connector interfaces accept a dataset’s schema. Run this before narrative_connection_create: an accepted (app_id, interface_id) pair means that connector can receive the dataset’s data. Available include values: Returns two sections: Accepted — the interfaces that can receive the dataset — and Incompatible — the ones that rejected the schema.

narrative_connection_create

Creates a connection from a dataset to a connector app, routing the dataset’s data to that destination. Returns the created connection’s id, app, dataset, profile, status, and creation timestamp. The connector validates the schema again at create time and rejects datasets that no longer match an interface.
Connections activate immediately. Confirm the dataset and profile with the user before calling this tool.

NQL tools

NQL tools let you validate, simulate, execute, and track NQL queries.

narrative_nql_validate

Compile-checks an NQL query without executing it. Returns the compiled SQL on success, or validation errors pointing to the offending part of the query.
Use narrative_nql_validate to test Rosetta Stone mapping expressions cheaply. Validate a candidate expression by running SELECT expression FROM company_data."dataset_id" through the tool — if it compiles, the expression is valid against the dataset’s schema.

narrative_nql_simulate

Reports which query policies of a chosen set of access rules would deny a SELECT or MERGE statement, without running it. Wraps POST /v2/nql/simulate. Nothing is stored, no data is read, no job is created, and no credits are charged. Use it to test a policy against a query before you save it with narrative_access_rule_set_query_policy, or to find out why a query reads no rows from an access rule. Each entry of context.access_rules sets exactly one of:
  • access_rule_id — a stored access rule that the current company owns or can query.
  • access_rule — a draft access rule with name, nql, and query_policy. It’s checked like a new access rule and isn’t saved. Its nql must reference the company’s datasets by ID, such as company_data."2001", and can’t read views.
Every entry also needs a placeholder_owner_slug. For the length of the call, the access rule and the datasets it reads belong to a temporary company with that slug, and the statement reads the access rule as <placeholder_owner_slug>."<access_rule_name>" or through narrative.rosetta_stone. Any valid company slug works except company_data and narrative, including a real company’s; that company’s data is never involved. Two access rules that read the same dataset need the same slug. The statement runs as the current company, in the role of a buyer. It reads the company’s own active datasets only through company_data, by ID, by name, or through company_data.rosetta_stone. Views and derived mappings aren’t available. The result lists each denied access rule by its position in context.access_rules and the table of the statement it was denied on, with every violation’s type, field, usage, operator, required join keys, and reason. A listed access rule that isn’t in the result wasn’t denied: its policy allowed the statement, or the statement didn’t read it. A statement that doesn’t parse, or an access rule the company can’t query, returns the API’s error. See Test a query against the policy for the request and response in full.

narrative_nql_execute

Submits an NQL query to POST /v1/nql/execute for asynchronous execution. Supported statements are INSERT, UPDATE, DELETE, EXPLAIN, and CREATE MATERIALIZED VIEW; SELECT and MERGE are rejected. Returns the id of the workflow that runs the query and the id of the workflow run. Poll the run with narrative_workflow_runs_list(workflow_id=...), find the enqueued job with narrative_jobs_search(workflow_run_id=...), then read the result with narrative_jobs_describe. The same two ids are also returned as structuredContent, workflow_id and workflow_run_id, so a view can follow the run.
The tool was previously named narrative_nql_run. The old name is still accepted and transparently routed to narrative_nql_execute, but new integrations should call narrative_nql_execute directly.

narrative_nql_run_result

Returns the job that a run from narrative_nql_execute enqueued: its id, type, state, result, and failures. A run enqueues one job, nql-forecast for an EXPLAIN query or materialize-view for CREATE MATERIALIZED VIEW. A forecast’s result is {rows, cost}, with cost in micro-cents USD. While the run hasn’t enqueued its job yet, job is null.
Only an MCP Apps view calls this tool. tools/list marks it _meta.ui.visibility: ["app"] so the host keeps it from the model, and leaves it out for clients that don’t render views. An assistant reads the same job with narrative_jobs_search and narrative_jobs_describe.

Job tools

Job tools let you discover and follow Narrative jobs — the asynchronous units of work spawned by narrative_nql_execute, dataset operations, and workflow runs. Jobs are generic across types; the type field on each response distinguishes nql-forecast, materialize-view, datasets_sample, and others.

narrative_jobs_describe

Describes one or more jobs by id in a single call. Use this to poll jobs through to completion — re-invoke until each job’s state is completed, failed, or cancelled. Available include values:
Reading job timings: created_at to dequeued_at is time spent queued, and dequeued_at to ended_at is execution (cluster launch plus the work itself). Do not report ended_at - created_at as the job’s runtime; it includes queue time. An attempt_version greater than 1 means the job was retried, and attempted_at is when the latest attempt started.
Searches jobs by tags, state, type, dataset, or data plane. At least one filter must be supplied — calling with no filters returns an error rather than dumping the full corpus. Pass the returned ids to narrative_jobs_describe for full per-job detail. To find workflow-enqueued jobs, filter with workflow_run_id or workflow_id rather than the older tag convention. Matches carry the same metadata fields as narrative_jobs_describe, and both tools carry the timing guidance above in their descriptions.

Model training tools

Model training tools let you train models on Narrative datasets. Training runs asynchronously as a job — the tool returns the job id, and the agent polls completion with narrative_jobs_describe.

narrative_classifier_train

Enqueues a classifier training run against a dataset. Submits to POST /v1/model-training/train-classifier. The dataset must be owned by the active company, active, and materialized on a Snowflake data plane; the trained model is saved to the Snowflake ML Registry in that data plane’s account. The API validates model_name, feature names, and every column reference against the dataset’s schema before enqueueing a job — bad references fail this tool call rather than the job. The model hyperparameters and each feature’s settings block are validated later by the training procedure inside the job, so a bad value there surfaces as a failed job that you read through narrative_jobs_describe. Feature types. Each feature_inputs entry picks one of: Classifiers. model.type picks the variant; every variant also accepts random_state: Returns the id of the enqueued job. Poll it with narrative_jobs_describe(job_ids=["..."]).
A successful classifier training job returns a large result payload (full metrics, per-class breakdowns, and the echoed config). Polling such a job through narrative_jobs_describe can return a lot of text.

Data plane tools

Data plane tools let you discover the data planes your company has access to. The ids returned here are used by workflow tools and the optional data_plane_id argument on narrative_nql_execute.

narrative_data_planes_list

Lists every data plane available to the active company, including Narrative-hosted and any company-owned planes.

narrative_data_planes_describe

Describes one or more data planes by id. Accepts multiple ids in a single call and fetches them in parallel. Available include values (shared by both data plane tools): Both tool descriptions carry usage guidance for connected AI assistants: compute pools with always_on: true skip cold-start cluster spin-up, making small always-on pools ideal for lightweight jobs like narrative_dataset_request_sample. The pool with a non-null default_source is where the company’s jobs run when they don’t name a pool themselves: company means the company set its own default for the data plane, data_plane means the default was set by the data plane’s owner. See reading the effective default for the full behavior.

Workflow tools

Workflow tools let you submit, inspect, and track runs of workflows. The workflow YAML is passed as a free-form string — see the workflow task reference for the YAML shape.

narrative_workflows_create

Submits a new workflow from a YAML specification. Returns the created workflow’s id and metadata. When trigger_immediately=true, the response also includes a run_id you can poll with narrative_workflow_runs_list.
Agents started by a workflow’s RunConversation or InferRosettaStoneMappings task cannot call this tool — the platform refuses the call and returns a tool error the model can adapt to. This keeps a workflow from nesting another workflow through its own agent.

narrative_workflows_trigger

Triggers a new run of an existing workflow. Returns immediately with the new run’s id; poll the run’s status via narrative_workflow_runs_list.
Workflows created through this tool are automatically tagged with created_by_mcp_server so you can filter and audit agent-created workflows in the Narrative app. If the agent supplies the tag explicitly, it is not duplicated.

narrative_workflows_describe

Describes one or more workflows by id. Accepts multiple ids in a single call and fetches them in parallel. Available include values:
Avoid include=["specification"] when scanning many workflows. Request it only after you have narrowed to the ones you actually want to inspect.

narrative_workflow_runs_list

Lists runs of a single workflow, in the order the upstream returns them (typically most recent first). Mirrors the upstream paging surface — opaque cursor pagination via page_token. To find the jobs spawned by a specific run, call narrative_jobs_search with workflow_run_id=<run-uuid>.

View tools

View tools open an interactive MCP Apps view in clients that render them. Each tool names its view in the tool’s _meta.ui.resourceUri and returns structuredContent for the view to draw. Each tool also returns a text summary of the same result, so clients that don’t render views still show the answer.

narrative_marketplace_show

Opens the audience explorer view (ui://narrative/audience-explorer) on an audience the assistant proposes for a buyer’s goal, built from marketplace data the active company can buy. The tool runs no query. The assistant does the matching: it works out who the buyer is after, finds sources with narrative_attributes_search and narrative_access_rules_search, and passes a proposal of building blocks and filters to this tool. The tool checks the proposal and refuses it if it breaks a rule. Each block is one access rule: Each filter has an id, a short label, a one-sentence description, and the field it filters on, plus an optional condition and icon. A source without the filter’s field drops out when the filter is on. A condition tests one field with an op. A field is a mapped attribute, such as hl7_gender, or attribute.property for a property the access rule maps, such as hl7_gender.gender. The same goes for a filter’s field. The tool refuses a proposal when a required value is blank, an id repeats, a limit is exceeded, an access rule is one the company can’t see or has no name to query by, or a condition tests a field the access rule doesn’t map. The refusal lists every problem at once, so the assistant can fix them all in one retry. The result holds the proposal, the active company, and each source’s access rule id, NQL name, provider name and slug, description, CPM price in USD, and fields. A query reads the source as <provider_slug>.<access_rule_name>. fields lists each mapped attribute, then attribute.property for each property the access rule maps. The explorer sizes the audience itself, and only when the buyer asks. Run forecast runs an NQL EXPLAIN forecast for each source and one for the whole audience, through narrative_nql_execute and narrative_nql_run_result. Each filter offers Forecast it to show how many records it would leave. Every forecast is charged to the active company, and the explorer shows what the forecasts so far have cost. Nothing runs when the view opens or when the buyer edits it: after a change, the numbers dim and the explorer offers Re-run forecast. A source that carries none of the proposal’s identifiers can’t be sized.

narrative_chart_show

Opens the dashboard view (ui://narrative/dashboard) with a chart or dashboard that the assistant built from rows it already has from earlier tool calls. The tool fetches no data, so it doesn’t require a selected company. The server passes the spec to the view without validating it. The view validates the spec and shows any validation messages. Aggregate the rows before calling the tool, so the call sends only what the chart draws.

Usage patterns

The most effective pattern for running queries is validate → execute → poll:
  1. Validate the query with narrative_nql_validate to catch syntax errors before enqueuing a workflow.
  2. Execute the validated query with narrative_nql_execute to submit it. The tool returns the workflow id and run id.
  3. Poll the run with narrative_workflow_runs_list(workflow_id=...) until it reaches a terminal state, then use narrative_jobs_search(workflow_run_id=...) and narrative_jobs_describe to read the result.
This avoids enqueuing work that would fail at compile time and keeps long-running executions out of the synchronous request path.

Dataset inspection flow

To understand a dataset’s structure and content:
  1. Search with narrative_datasets_search to find datasets by name or description.
  2. Describe with narrative_datasets_describe using include=["metadata", "schema"] for an overview, or add "sample" and "stats" for deeper inspection.
  3. Inspect columns with narrative_dataset_get_column_stats for detailed per-column statistics.

Access rule discovery flow

To find and inspect the access rules available to your company:
  1. Search with narrative_access_rules_search, providing at least one filter (e.g. search_term, exposed_attribute_names, tags, dataset_ids).
  2. Describe shortlisted rules with narrative_access_rules_describe using the default include (metadata, mappings, and query_policy) for an overview, or add "nql", "schema", "collaborators", or "pricing" for deeper detail.
  3. Reference in NQL using <owning_company_slug>.<access_rule_name>.

Workflow submission flow

To submit and track a workflow from an AI assistant:
  1. Discover available data planes with narrative_data_planes_list to pick a data_plane_id.
  2. Create the workflow with narrative_workflows_create, passing the YAML as specification. Set trigger_immediately=true to start a run right away, or call narrative_workflows_trigger later.
  3. Poll runs with narrative_workflow_runs_list until the most recent run reaches a terminal state.
  4. Inspect job-level progress by calling narrative_jobs_search with workflow_run_id=<run-uuid>, then narrative_jobs_describe on the returned ids.
  5. Describe the workflow with narrative_workflows_describe to inspect its specification or current status.

Connection creation flow

To route a dataset’s data to a destination connector from an AI assistant:
  1. List installed connectors with narrative_installations_list and pick one whose capabilities include destination_connector.
  2. Find an enabled profile with narrative_app_profiles_list on the installation id. Only enabled profiles can back a connection.
  3. Check compatibility with narrative_dataset_get_compatible_interfaces for the target dataset. The accepted (app_id, interface_id) pairs are the ones a connection will succeed against.
  4. Build quick_settings (optional) with narrative_app_interfaces_list on the accepted interface’s app to retrieve the interface’s quick-settings JSON Schema.
  5. Create the connection with narrative_connection_create, passing dataset_id, the enabled profile_id, and any quick_settings.

Multi-company sessions

If you belong to multiple companies:
  1. List your companies with narrative_context_get_companies.
  2. Switch with narrative_context_set_company to set the active company.
  3. All subsequent tool calls operate against the selected company until you switch again.

Naming conventions

  • Plural names (datasets_describe, attributes_describe) accept multiple ids per call.
  • Singular names (dataset_get_column_stats, dataset_request_sample) operate on a single entity.
  • All tools use the narrative_ prefix.

Connecting to the Narrative MCP Server

Set up your MCP client

Data Collaboration MCP Server

How the MCP server works

NQL Design Philosophy

Understand the query language behind NQL tools

Rosetta Stone

The schema normalization system behind attribute tools