Skip to content

MCP Tools Reference

All tools are available through the project MCP endpoint at POST /mcp/<project-slug>/mcp. Tools operate within the scope of the project identified by the URL slug.

Semantic models are stored internally as OSI YAML, but all tools that return model information (get_semantic_model, get_datasets) serve a compressed markdown digest instead of raw YAML. This digest uses 3–5× fewer tokens while preserving field types, descriptions, enums, examples, relationships, and instructions.

List semantic models the authenticated token has access to.

Parameters: None

Returns: A list of model names and descriptions, filtered by the token’s scopes. Reads from published (assembled) YAML files.


Get an overview of a semantic model with datasets, relationships, and metrics. Supports scoped pagination to drill into a specific section independently.

Parameters:

ParameterTypeRequiredDescription
modelNamestringYesThe semantic model name (filename without .yaml)
scope"datasets" | "relationships" | "metrics"NoSection to retrieve independently. Omit for full overview (first page of each section).
pagenumberNoPage number within the scope (default 1, items per page configured per project). Only meaningful with scope.

Returns: Compressed markdown digest (not raw YAML). Each dataset row includes its table name (the quoted dataset name, e.g. "orders") for use in queries. Agents write bare dataset names in SQL — the correct schema is resolved automatically via DuckDB’s search_path.


Get one or more datasets with all their fields as compact markdown lists with types, examples, enums, synonyms, and instructions. Pass up to 10 datasets in a single call to reduce round-trips. Each dataset entry specifies its own page for independent field pagination.

Parameters:

ParameterTypeRequiredDescription
modelNamestringYesThe semantic model name (filename without .yaml)
datasets{ name: string, page?: number }[]YesDatasets to retrieve (1–10), each with an optional page (default 1)

Returns: Compressed markdown digest with compact field lists including data types, expressions, dimension info, enums, examples, and AI context.


Run a read-only SQL query scoped to a semantic model’s VIEWs.

Parameters:

ParameterTypeRequiredDescription
modelNamestringYesThe semantic model to query against
sqlstringYesDuckDB SQL using bare dataset names (e.g. FROM "orders"), with $1, $2, … placeholders
paramsstring[]NoParameter values for positional placeholders (defaults to [])
storebooleanNoWhen true (default), the query is stored and a storedQueryId is included in the response for later re-execution via execute_stored_query

Returns: JSON with columns, rows, and optionally storedQueryId (when store is true). Results capped at 1,000 rows (includes truncated: true flag when exceeded). 30-second timeout.

Every query is parsed with DuckDB’s own parser via json_serialize_sql and rejected unless its abstract syntax tree matches a strict allowlisted shape:

  • Exactly one top-level statement (multi-statement payloads are rejected even when separators sit inside string literals — the parser distinguishes them, the validator doesn’t have to)
  • Top-level node must be a SELECT / set-operation / recursive CTE; EXPLAIN is allowed as a wrapper around any of these
  • EXPLAIN ANALYZE is rejected — including comment-evasion variants such as EXPLAIN /* ... */ ANALYZE — because DuckDB executes the wrapped statement
  • Every base-table reference must use bare dataset names (no schema, no catalog); system catalogs (information_schema, pg_catalog, sqlite_master, main, temp, system) are rejected by name regardless of quoting variant ("information_schema", U&"…", dollar-quoted, mixed-case, …)
  • Any reference whose schema or table name begins with _scope_ or duckdb_ is rejected (covers SELECT * FROM duckdb_columns, SELECT * FROM "_scope_other"."x", etc.)
  • Table functions are restricted to a small allowlist (generate_series, range, unnest, repeat, from_json, values); read_csv*, read_parquet*, read_json*, read_blob*, parse_sql, json_serialize_sql, and any function whose name begins with duckdb_ are rejected
  • Scalar function calls covering read_*, pg_read_*, pg_ls_dir, duckdb_*, nextval, currval, parse_sql, and json_serialize_sql are rejected anywhere in the tree
  • Parser failures, malformed input, and empty / comment-only inputs are surfaced verbatim in the rejection message

This is the sole SQL-safety layer on the execute_query path. There is no fallback validator and no kill-switch — using DuckDB’s own parser eliminates the class of regex bypasses where the validator and the engine disagreed about how to tokenize a query. If json_serialize_sql ever rejects a query the validator returns a parse-error message; recovery is a code fix, not a config flag.

Each query runs in a DuckDB connection with:

  • enable_external_access = false: no file reads, network access, or COPY operations
  • threads = 2, memory_limit = '512MB': resource limits
  • search_path set to the model’s scoped schema so bare dataset names resolve to the correct VIEWs

Re-execute a previously stored query by its ID. The storedQueryId is returned by execute_query when store is true (the default). Optionally override the original parameter values.

Parameters:

ParameterTypeRequiredDescription
storedQueryIdstringYesThe stored query ID returned by a previous execute_query call
paramsstring[]NoOverride parameter values; if omitted, the original stored params are used

Returns: JSON with columns and rows in the same format as execute_query. Same result limits (1,000 rows) and timeout (30s) apply.


Submit an improvement request for a semantic model. Use this when you or a user discover issues like missing fields, incorrect descriptions, wrong relationships, or any other quality problem with a semantic model.

Parameters:

ParameterTypeRequiredDescription
modelNamestringYesThe semantic model this improvement applies to
titlestringYesShort summary of the improvement (max 200 chars)
descriptionstringYesDetailed description of the issue or requested change (max 2,000 chars)

Returns: Confirmation that the improvement request was submitted.