Semantic Rails MCP Server
OfficialA guided Architect MCP server that lets an agent inspect, author, validate and query Semantic Rails packages safely.
Get oriented:
architect_guidancereturns the recommended workflow;mcp_client_configgives copy-ready client config hints.Set up and read projects:
setup_project_dialogandcreate_projectbootstrap aschema_version: 1package;project_status,list_project_filesandread_project_fileinspect it and return the revision for safe edits.Author the semantic model:
upsert_model,upsert_relationship,upsert_metric,upsert_segment,upsert_example,upsert_test,record_route_decision,remove_object, plus raw-filewrite_project_files— all transactional, with diffs, dry runs and idempotency keys.Modernize packages:
upgrade_projectrewrites legacy forms while refusing rewrites that change an answer.Explore warehouse data:
list_tables,describe_table,profile_columnsandpreview_query(real warehouse data, row-capped).Bootstrap from data or dbt:
suggest_model,suggest_one_per_key,suggest_links,suggest_models_from_dbt(read-only, with confidence and draft arguments), thenimport_dbt_projectto write those models.Validate and review:
validate_project(parse/runtime/examples/tests/impact/release),promotion_check,diff_projectandimpact_projectfor behavior-change risk and reviewer teams.
Allows Semantic Rails to use ClickHouse as a warehouse target for governed semantic queries, metric discovery, validation, and execution.
Enables Semantic Rails to connect to Databricks as a warehouse target for running and validating semantic layer queries against Databricks data.
Provides DuckDB as the built-in local warehouse for Semantic Rails, supporting semantic queries, validation, and execution without additional connectors.
Enables Semantic Rails to use Snowflake as a warehouse target for governed metric queries, semantic validation, and query execution.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Semantic Rails MCP Servershow me total revenue by month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Semantic Rails
Semantic Rails is an open-source, agent-first semantic layer, licensed Apache-2.0. You define metrics, dimensions and join paths once, in YAML. Agents then discover those definitions, plan a query and run it as governed SQL through an MCP server, a CLI or an HTTP API, instead of writing joins and metric formulas by hand.
Runs locally on DuckDB with no account or server. Optional connectors cover Snowflake, BigQuery, Databricks, Postgres, Athena, ClickHouse, MotherDuck and DuckLake.
No telemetry and no update checks. The engine makes network connections only for what you configure; see Telemetry and network access.
Beta. See Project status for what is supported and what isn't yet.
Try it in one command
You need uv. It fetches a compatible Python (3.11 or newer) if your system Python is older.
uvx semantic-rails ask --package jaffle_shop "revenue by store name" --runuvx runs Semantic Rails without installing it; the next section shows how to install it.
--package names a bundled sample package; pass your own package with --path.
This groups revenue by store name in the synthetic Jaffle Shop sample, then validates, compiles and runs the plan on DuckDB. It prints how it interpreted the question, the rows and any warnings, then the query call. Check that interpretation before you rely on the numbers; see Known limitations. Without uv, try the browser demo or the hosted MCP endpoint below.
Related MCP server: governed-analytics-agent
Install
To keep a semantic-rails command on your PATH instead of running it through uvx:
uv tool install semantic-railsIf uv warns that its tool directory isn't on your PATH, run uv tool update-shell and
open a new terminal.
Or install it into a project environment. Pin the Python version: on a machine without
a uv-managed Python, a bare uv venv can pick up the system Python (3.9 on stock macOS,
3.10 on Ubuntu 22.04), and then the install fails.
uv venv --python 3.12
source .venv/bin/activate
uv pip install semantic-railsWith pip, run python -m pip install semantic-rails inside a Python 3.11+
environment. On Windows, activate the environment with .venv\Scripts\activate; see the
agent quickstart
for how MCP differs there. CI doesn't cover Windows yet.
Quickstart with your own package
Pass --path on commands that use your own package, or run them inside the package
directory. Without either, and without a saved profile, commands stop with
no_package_selected and list the ways to choose a package; at an interactive terminal,
ask first offers the bundled sample package.
uvx semantic-rails init my_package --yes
uvx semantic-rails project validate --path ./my_package
uvx semantic-rails ask --path ./my_package "total amount by event type" --runinit writes a runnable starter package (YAML models, metrics, examples, tests and
CSV data). Edit it to describe your own tables, then rerun project validate.
The interactive wizard, semantic-rails setup --interactive, walks through the same
steps and can register the MCP server with Claude Desktop or Codex. Run it from an
installed semantic-rails, not through uvx, for the reason given under
Claude Desktop below.
Inside semantic-rails repl, type author to add models, dimensions, measures, metrics and
segments with previews and validation.
Connect your agent
MCP clients may start in another directory, so give the package's absolute path.
Claude Code
claude mcp add semantic-rails -- uvx semantic-rails mcp stdio --path "$PWD/my_package"Codex CLI
codex mcp add semantic-rails -- uvx semantic-rails mcp stdio --path "$PWD/my_package"Claude Desktop. Install the command, then let Semantic Rails write the client config:
uv tool install semantic-rails
"$(uv tool dir --bin)/semantic-rails" mcp setup --path "$PWD/my_package" --client claude --mcp query --install --yesuv tool dir --bin finds the command even when uv's tool directory isn't on your
PATH yet. Run mcp setup without --install --yes to preview the change.
--client codex, --client claude-code (registers the server at user scope),
--client cursor (writes ~/.cursor/mcp.json, so the manual Cursor config below is
optional) and --client both (Claude Desktop and Codex) also work, and --mcp both
adds the Architect MCP, which can edit package files. Don't run mcp setup --install
through uvx: the config would point into uv's cache, which uv cache clean deletes.
Cursor. Install the command and print the two absolute paths the config needs:
uv tool install semantic-rails
echo "$(uv tool dir --bin)/semantic-rails"
echo "$PWD/my_package"Then add the server to .cursor/mcp.json:
{
"mcpServers": {
"semantic-rails": {
"command": "/absolute/path/to/semantic-rails",
"args": ["mcp", "stdio", "--path", "/absolute/path/to/my_package"]
}
}
}Hosted demo (no install). https://semantic-rails.com/mcp is a public Streamable
HTTP endpoint over the same synthetic Jaffle Shop data. It is anonymous and
rate-limited, and it can't load your package.
claude mcp add --transport http semantic-rails-demo https://semantic-rails.com/mcp
codex mcp add semantic-rails-demo --url https://semantic-rails.com/mcpThe agent loop, tool policy and HTTP routes are in
docs/AGENT_QUICKSTART.md.
The full MCP contract, including semantic-rails serve --port 8091 for a local /mcp endpoint, is in
docs/MCP_INTERFACE.md.
How it works
An agent works through separate, inspectable steps instead of one SQL string:
discover -> plan -> executediscovermaps business terms to governed metric, dimension and segment IDs.inspectopens one object's card when the agent needs its aggregations, values or time roles.plandrafts a query call from a natural-language question and checks the draft against the question. Run the draft when its status isokand it has no warnings; otherwise the response says what the draft misses.valid-values(and, over HTTP and the CLI,build-options) guide step-by-step builders instead.execute(the CLI'squery, HTTP/api/v1/query) validates, compiles and runs the call where the package's connection lives. It rejects unknown fields, dimension mismatches, bad filters and policy failures with structured errors and, where possible, recovery hints.validateandcompileare optional dry runs of the same checks.validatereturns the diagnostics without running anything;compilealso renders SQL for the target warehouse. Atcompactverbosity (the CLI's default) orfull,compilereturns anexplainpayload: the chosen join path to each entity, the candidate paths it considered and the relationship contracts along the chosen path. On MCP they areexecutemodesvalidateandsql, which default tominimaland leaveexplainout.
The engine design is in docs/ARCHITECTURE.md, and the supported modeling surface is in docs/CAPABILITIES.md.
How it compares
dbt's Semantic Layer (MetricFlow), Cube, LookML and Malloy are more mature, and they
reach warehouses Semantic Rails doesn't support yet: Cube alone connects
to Redshift, SQL Server,
Microsoft Fabric, MySQL and Trino. dbt, Cube and Looker also connect to far more BI
tools and offer caching or pre-aggregation. Semantic Rails is narrower: an engine
built around the agent loop above, which you can run locally or embed in Python through
semantic_rails.embedding.
The comparison pack asks the same 24 questions of six modeled layers: Semantic Rails, MetricFlow, Cube, Malloy, Snowflake Semantic Views and KtX. Sixteen are answered with models written for them, nine of them chosen to exercise primitives Semantic Rails ships. Eight more change one parameter of a metric those models already use, and each layer answers them with its model unchanged, through its query-time interface only. The pack compares capability, not performance; its support labels describe the authored models, not each layer's limits. The output consistency check compares five layers on the current shared dataset, including Semantic Rails, against an independent SQL answer key: all five match it on all 16, and every frozen-model answer a layer executed matches it too. Those five layers ran live from this repo. Snowflake Semantic Views is a stale capture on an older dataset and is excluded from that count; it matches 14 questions and differs on q07 and q16. The authored models and shared data leave some intended semantics weakly tested, so matching outputs are not a ranking.
Warehouses
DuckDB 1.5.6 or newer is included; this minimum version fixes parallel window execution over empty input blocks used when filling time buckets. Add a connector only when you need it, for example Postgres:
uv tool install 'semantic-rails[postgres]'Postgres keeps connection.kind: postgres_native and uses ADBC with PyArrow.
The other connector extras are snowflake, snowflake-adbc, bigquery, databricks,
athena and clickhouse, and all installs every connector. In a project environment, use
uv pip install 'semantic-rails[all]'. MotherDuck and DuckLake use the core duckdb
dependency. Keep secrets in environment
variables or files, not in package YAML. See
docs/DEPLOYMENT.md and
docs/ADDING_A_DIALECT.md.
What is tested live
CI checks every warehouse's SQL with dialect rendering tests. Only some warehouses also run the conformance battery against a live server, which compares each answer with DuckDB's; DuckDB and Postgres also run the correctness suite against independent reference SQL. A warehouse without a recent live run is compile-tested only: its SQL is checked, but nothing has executed it lately.
Warehouse | Row filters | Live runs |
DuckDB | yes | every engine change in CI |
Postgres 16 | yes | every engine change in CI |
ClickHouse | no | daily, on the latest release |
DuckLake | no | daily, on the latest release |
BigQuery | no | weekly, on the latest release |
Athena | no | weekly, on the latest release |
Snowflake ( | no | paused for lack of a test account; last passed on 2026-10-12 |
Snowflake through ADBC ( | yes | on demand only, paused for lack of a test account; CI runs its adapter tests against stubbed connections |
Snowflake CLI ( | no | none: compile-tested only |
Databricks | no | paused for lack of a test account |
MotherDuck | no | paused for lack of a test account |
Row filters bind the caller's trusted values as statement parameters, so the values never
enter SQL text; a warehouse without parameter binding refuses a request that a row filter
applies to (POLICY_DENIED). See row-filter
authoring.
Redshift is not supported.
Telemetry and network access
Semantic Rails collects no telemetry and has no update check. The engine opens network connections only to:
the warehouses configured in your package's
connectionblock;DuckDB's extension repository (extensions.duckdb.org): DuckDB downloads an extension it doesn't bundle the first time a query needs one, for example for MotherDuck, DuckLake or remote files.
The hosted demo at semantic-rails.com is a separate deployment with its own privacy notice.
Project status
Semantic Rails is beta software. The supported core is the open-source runtime, the
CLI, the MCP stdio and HTTP servers, the /api/v1/* HTTP API, and execution on DuckDB and
Postgres, which are tested live on every pull request. The other connectors are supported
with guardrails: see what is tested live for each one's live runs. The
agent quickstart
lists what is experimental or out of scope.
Known limitations
In the current release:
planreports the parts of a question its draft doesn't honor, aslow_confidenceor aPLAN_UNMATCHED_TERMSwarning, but its checks don't cover every phrasing, so a draft can still misread a question and reportok, andaskruns it. Check the query call, orask's "Interpreted as" line, before you rely on the numbers.askruns one query, so it refuses a question thatplananswers as several parts (PLAN_PARTS) and lists them: ask each part on its own.askrounds its tables, but JSON results (query,ask --json, MCPexecuteand the HTTP API) return the warehouse's floating-point values as they are, for example486468.17999985756for a currency total.Answers trust the data as it is stored: an orphan foreign key counts in entity filters, a join on columns of different types or collations can double totals, and a parent grouped by a value only its children carry counts under each; see known limitations.
The text filter words refuse search text holding letters that warehouses lower differently, such as Greek sigma,
ßandİ, and need ICU on Postgres; see the text words' known limitations.A warehouse table named like one of the engine's generated query steps (
leaf_<n>,guarded_base,projected, …) can be shadowed by that step: rename the table, or name it with its schema in the model'srelation:(analytics.projected).
Roadmap
Work in progress, without dates:
Packaged agent integrations: Claude Code and Codex plugins and a Claude Desktop bundle.
mcp setupalready writes the client configs.A flagship example: a dbt project on an open dataset, modeled end to end.
Broader native-model coverage in the comparison pack and a refreshed Snowflake capture on the current dataset.
Apache Ossie, the incubating Open Semantic Interchange specification: 0.1.1 export and import ship today (docs/OSSIE.md). Next are tested imports of the dbt and Snowflake converters' output, and writing Ossie 0.2.
Questions and proposals are welcome in GitHub Discussions.
Docs
Embedding the engine:
semantic_rails.embedding, the one public Python API
Contributing
CONTRIBUTING.md covers scope, architecture ownership and the validation commands. To work from a source checkout:
git clone https://github.com/semantic-rails/semantic-rails.git
cd semantic-rails
uv sync --group dev
uv run semantic-rails packages
uv run semantic-rails query --package jaffle_shop --query-json '@examples/jaffle_shop_revenue_by_store.json' --verbosity minimal --sql-profile offExpected package output includes the bundled synthetic fixture:
jaffle_shopContributor release smoke for the bundled package:
uv run semantic-rails parse-config --path configs/semantic_rails/jaffle_shop
uv run semantic-rails validate-config --path configs/semantic_rails/jaffle_shop --quietBuild and verify the exact wheel and sdist before publishing:
uv build --out-dir dist
uv pip install --python .venv/bin/python --reinstall dist/semantic_rails-0.3.4-py3-none-any.whl
uv run python scripts/verify_package_distribution.py --dist-dir dist --no-buildPackage naming
Semantic Rails is the public product name. The PyPI distribution is
semantic-rails, the Python import package is semantic_rails, and the CLI is
semantic-rails.
Support, security and license
Support, issue reporting, conduct and security reporting are documented in SUPPORT.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md.
Semantic Rails is licensed under Apache 2.0; see LICENSE. Everything in this repository is open source, with no gated features. Semantic Rails, Inc., which runs semantic-rails.com, also offers a hosted service; nothing here requires it.
Available Tools
30 toolsarchitect_guidanceBRead-onlyIdempotent
Return the recommended Architect MCP workflow and safety guidance.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows this is a safe, read-only call. The description adds the content focus on 'safety guidance' and 'workflow,' but does not reveal any behavioral details beyond what the annotations already provide (e.g., output size, rate limits, or effects of params). No contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one direct sentence with no filler, front-loading the verb and object. It is concise while still making the tool's purpose identifiable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The definition is adequate for a simple, safe meta-guidance tool with an output schema, so return format need not be spelled out. However, it omits any usage context and fails to explain the two optional parameters, leaving meaningful gaps in what the agent needs to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description never mentions goal or project_path, leaving both parameters completely unexplained. Although their names suggest a purpose, the description fails to explain how, or whether, they influence the returned guidance or what values are valid.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and a clear resource ('recommended Architect MCP workflow and safety guidance'). It distinguishes this meta-guidance tool from the operational sibling tools (create_project, upsert_model, validate_project, etc.), so an agent can tell at a glance it is asking for guidance rather than performing a project operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no indication of when to call this tool instead of a sibling, nor any exclusions or prerequisites. 'Recommended workflow' weakly implies a general or pre-flight use, but the definition does not state that the agent should consult it before project operations or how it relates to the alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_projectBDestructiveIdempotent
Create a strict schema_version: 1 project. DuckDB packages use a two-row starter CSV (data=starter) or read a database another tool builds, such as dbt (data=external); other warehouses need connection_kind, with secrets named by environment variable only.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | starter | |
| dry_run | No | ||
| relation | No | raw_events | |
| overwrite | No | ||
| warehouse | No | duckdb | |
| default_db | No | ||
| package_id | Yes | ||
| description | No | Semantic Rails package managed through Architect MCP. | |
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| primary_key | No | event_id | |
| time_column | No | occurred_at | |
| first_entity | No | event | |
| project_path | No | ||
| amount_column | No | ||
| connection_kind | No | ||
| connection_name | No | ||
| idempotency_key | Yes | ||
| dimension_column | No | ||
| expected_revision | Yes | ||
| connection_options | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds genuinely new behavioral context: secrets must be referenced by environment variable name only, and the underlying data-source branching rules. It does not, however, explain what destructive/overwrite behavior actually removes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single dense sentence with the purpose front-loaded, which is good, but it packs three separate configuration branches and a credential rule into one clause chain, making it harder to parse than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex (20 params, destructive, creates persistent state) yet the description covers only a fraction of the configuration surface, and the destructive/overwrite semantics flagged by annotations go unexplained. An output schema exists, so return values need not be described, but the input-side gaps remain significant.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 5% across 20 parameters, so the description carries most of the burden. It explains the data enum, connection_kind, and secret naming, but leaves roughly fifteen parameters (primary_key, time_column, expected_revision, idempotency_key, overwrite, dry_run, project_path, etc.) undocumented in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource ("Create a strict schema_version: 1 project") that an agent can distinguish from siblings like import_dbt_project or upgrade_project. It is slightly obscured by the unexplained "strict schema_version: 1" qualifier, so it stops short of a clean 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent among parameter modes (data=starter vs data=external vs connection_kind for other warehouses) but never states when to choose this tool over siblings such as import_dbt_project or setup_project_dialog. The guidance is real but parameter-level rather than tool-level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_tableCRead-onlyIdempotent
Columns (type, nullability, default) and declared primary, unique and foreign keys.
| Name | Required | Description | Default |
|---|---|---|---|
| relation | Yes | ||
| duckdb_path | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the main safety profile is covered. The description adds no behavioral detail beyond the returned content — no mention of whether it opens a database, how paths are used, or what happens when the relation is missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a short, front-loaded phrase that gets directly to what is returned and has no filler. It is a fragment, not a sentence, and misses a verb, but it is appropriately compact for a simple read-only tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, not describing return values is acceptable, and annotations cover read-only behavior. However, the tool has three parameters whose meaning is unresolved, and there is no guidance on when to choose this tool over related siblings, so the definition is incomplete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not clarify relation, duckdb_path, or project_path. An agent cannot tell what the two path parameters mean or how they interact, so the description fails to compensate for the schema's lack of parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates the returned metadata — columns with type/nullability/default and primary, unique, foreign keys — which makes the tool's purpose clear without being a tautology. It also differentiates from siblings like list_tables and profile_columns because it targets schema structure. It lacks an explicit verb like 'describe' or 'retrieve', so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement about when to use this tool versus siblings such as list_tables, profile_columns, or preview_query, and no mention of prerequisites or context. The intended use is only implied by the name and the listed output.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_projectARead-onlyIdempotent
Diff one project against another path or a git base ref.
| Name | Required | Description | Default |
|---|---|---|---|
| base_ref | No | ||
| compare_path | No | ||
| project_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description does not need to repeat safety traits. It adds useful context about the two modes of comparison (path vs git ref) and implies the operation is a read-only diff. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler. The core verb and resource are front-loaded, and the two comparison modes are clearly stated. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only diff tool with an output schema, the description covers the essential purpose and the two optional parameters. It does not mention edge cases like mutual exclusivity, but given the output schema exists and annotations cover safety, this is sufficiently complete for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must add meaning. It does explain that compare_path and base_ref are two alternative comparison targets, which clarifies their purpose. However, it does not specify whether they are mutually exclusive, precedence, or what happens if both are provided, leaving ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Diff') and resource ('one project') and clearly distinguishes between two comparison targets ('another path' vs 'a git base ref'), which differentiates it from sibling tools like project_status or list_project_files. It is unambiguous about the operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool (when you need to compare a project to another path or a git ref) but does not explicitly name alternatives or conditions that would select this over another tool. No exclusions or 'use this instead' guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
impact_projectBRead-onlyIdempotent
Return behavior-change impact, reviewer teams, and risk for a package change.
| Name | Required | Description | Default |
|---|---|---|---|
| base_ref | No | ||
| compare_path | No | ||
| project_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds that the tool returns three named categories of results, but it does not disclose additional behavioral context such as failure modes, perf expectations, or input constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler or repetition of annotation details. Every word contributes to the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with three parameters, zero schema descriptions, and many closely related siblings, the one-line description is insufficient. It relies on the output schema for return shape but leaves parameter semantics and tool-selection context unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needed to clarify project_path, base_ref, and compare_path; it mentions none of them. An agent cannot determine what base_ref and compare_path mean or how they relate to 'package change' from the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Return') and a concrete resource: behavior-change impact, reviewer teams, and risk for a package change. This clearly distinguishes it from siblings like diff_project or validate_project by naming its unique outputs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus related siblings such as diff_project, validate_project, or promotion_check. The phrase 'for a package change' gives only weak context, with no exclusions, prerequisites, or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_dbt_projectADestructiveIdempotent
Create or update package models from the selected dbt models in one transaction, writing their foreign keys as entity references. Review with suggest_models_from_dbt first; dry_run=true previews without writing. skipped_models and skipped_references say what was left out.
| Name | Required | Description | Default |
|---|---|---|---|
| group | No | dbt | |
| select | Yes | ||
| dry_run | No | ||
| target_dir | No | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| catalog_path | No | ||
| project_path | Yes | ||
| manifest_path | No | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered structurally. The description adds real context beyond them: atomic one-transaction writes, automatic foreign-key-to-entity-reference conversion, and the dry_run no-write path, plus which output fields report omissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly packed sentences with the atomic-write behavior front-loaded, followed by the review prerequisite and preview flag, then the omission-reporting note. No filler text at all.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be re-explained. However, for a destructive, revision-guarded, idempotency-keyed write tool with 10 mostly undocumented parameters, the description omits the concurrency/required-parameter contract that an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 10% across 10 parameters, so the schema documents almost nothing. The description explains dry_run and hints at skip reporting, but leaves critical parameters unexplained: select syntax, expected_revision (a concurrency guard), idempotency_key, project_path/manifest_path/catalog_path relationships, and group/target_dir defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (Create or update), the resource (package models from selected dbt models), and the distinctive behavior (single transaction, foreign keys rewritten as entity references). This clearly separates it from bulk-tuning siblings like upsert_model and from the review-only suggest_models_from_dbt.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to 'Review with suggest_models_from_dbt first' and explains dry_run=true as a preview mode. It gives concrete when-to-use context but does not state boundaries against other write tools such as upsert_model or upsert_relationship.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_project_filesBRead-onlyIdempotent
List files inside a Semantic Rails project directory.
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, idempotentHint=true, openWorldHint=false, and destructiveHint=false, so the safety profile is fully covered. The description adds no extra behavioral detail (e.g., recursion, filtering, or path requirements) beyond restating the listing action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every word contributes to understanding the tool's purpose, and the phrasing is direct and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has one simple parameter, output schema exists, and annotations cover behavioral safety. The description supplies the key domain context (Semantic Rails project directory) and enough information for an agent to invoke it correctly. Minor gaps like recursion behavior are acceptable given the output schema and simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter project_path is not described in the schema (0% coverage) and the description only implies it is the path to the Semantic Rails project directory. This is a reasonable inference, but the description does not explicitly define the parameter format, semantics, or constraints, leaving some room for ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a resource ('files inside a Semantic Rails project directory'), and naturally distinguishes this from siblings like read_project_file (which reads a single file) and list_tables (which lists tables). The purpose is unambiguous and immediately actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as read_project_file or list_tables. There is no mention of prerequisites, when not to use it, or which scenarios call for a different tool. The usage context is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesARead-onlyIdempotent
List tables and views (read-only) in a DuckDB package's database or a DuckDB file.
| Name | Required | Description | Default |
|---|---|---|---|
| schema | No | ||
| duckdb_path | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The '(read-only)' phrasing and safety profile are already covered by readOnlyHint/idempotentHint/destructiveHint. The description does add the useful context that it can target either a DuckDB package database or a standalone DuckDB file, but it does not disclose behavior such as how the source is resolved when both parameters are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, no filler, and the core object ('List tables and views') is front-loaded before the source scoping. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The short description is simple, and output schema plus read-only annotations reduce the burden, but the three optional parameters are unexplained and the two-target 'or' leaves ambiguity about when to supply duckdb_path versus project_path. An agent cannot reliably choose invocation arguments from this text alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description needed to explain schema, duckdb_path, and project_path, but it only mentions 'database or DuckDB file.' It never maps parameters to those targets, clarifies the optional schema filter, or explains the all-empty-default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('List tables and views') and scopes it to 'a DuckDB package's database or a DuckDB file.' This distinguishes it from siblings like describe_table, which targets individual tables, and list_project_files, which targets project files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the obvious use—enumerating tables/views before working with them—but does not explicitly state when to choose this tool over describe_table or preview_query. It gives no exclusion criteria or alternative routing, leaving usage to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mcp_client_configCRead-onlyIdempotent
Return copy-ready client configuration hints for running Architect MCP.
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | 127.0.0.1 | |
| port | No | ||
| transport | No | stdio |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds only the 'copy-ready' aspect, which hints at output formatting but does not explain what the hints contain or whether they are exhaustive. It does not contradict annotations, but it adds minimal behavioral context beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, short sentence that front-loads the purpose. It is concise and free of filler, though it is arguably too sparse to be maximally useful. Structure is fine, but content is minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with three optional parameters and an output schema, the description is inadequate. It does not explain the parameters' meanings, defaults, or how the output should be used. Although an output schema exists (not shown here), the description still needs to state that parameters are optional and what they control. An agent cannot correctly invoke this tool without external knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for undocumented parameters. The description does not mention host, port, or transport at all, nor does it hint at their purpose or defaults. An agent has no idea what values to provide or why they matter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and names a precise resource ('copy-ready client configuration hints') with a clear context ('for running Architect MCP'). It is unambiguous and distinct from sibling tools, which focus on queries, projects, models, or validation. An agent can immediately understand what this tool produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives, nor does it mention any exclusions or prerequisites. It does not explain that it is a configuration helper or that it might be used before setting up clients. No context about typical use cases is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_queryARead-onlyIdempotent
Run a semantic query on the package's warehouse, as the query server's execute does, and return at most max_rows rows (1-200); truncated is true when there are more, which are not counted (total_row_count null). Values are real warehouse data.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_rows | No | ||
| project_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, and the description adds genuinely new behavior: an enforced 1-200 row cap, the meaning of 'truncated', the fact that extra rows are not counted (total_row_count null), and the critical disclosure that 'Values are real warehouse data' rather than mock preview data. These are traits an agent cannot derive from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the core action before the truncation details. All clauses earn their place, though the run-on construction packing limits, truncation, and count semantics together slightly reduces readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be re-explained, and the description still usefully covers truncation semantics. However, for a tool whose primary parameter is an undocumented nested 'query' object and whose project_path is unexplained, the definition leaves the caller guessing on the most important input.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It explains max_rows bounds (though the schema already encodes min/max/default) and gives a conceptual gloss for 'query' as a semantic query, but it says nothing about project_path and nothing about the shape of the query object, which is an open nested object (additionalProperties: true). Partial compensation only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Run a semantic query on the package's warehouse', and clarifies the mechanism by likening it to 'the query server's execute'. Distinct from the sibling set, which is dominated by model/project CRUD tools and none of which execute queries. It stops short of 5 only because it never contrasts itself with a near-neighbor tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use guidance or when-not, and no named alternative. The reference to 'as the query server's execute does' describes equivalence of behavior, not a routing condition, so the agent gets no help deciding when to reach for preview_query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_columnsBRead-onlyIdempotent
Per-column counts, min/max and up to 20 samples (sample_limit=0 for none), sampling tables above max_rows (at most one million). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| columns | No | ||
| max_rows | No | ||
| relation | Yes | ||
| duckdb_path | No | ||
| project_path | No | ||
| sample_limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description's 'Read-only' is redundant. However, it adds real behavioral context about sampling limits, sample_limit=0 disabling samples, and the max_rows cap, which goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence, but the parenthetical stacking makes it awkward and slightly ambiguous. Every phrase is information-dense, yet the lack of clear structure reduces readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return-value documentation is not required, but the description leaves several parameters unexplained and does not clarify the relationship between 'up to 20 samples' and the sample_limit default. For a tool with six parameters, this is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter semantics, but it only explains sample_limit and max_rows. Required parameters like relation and important optional parameters like columns, duckdb_path, and project_path are not described. The 'up to 20 samples' claim is also potentially confusing given the default sample_limit of 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool produces: per-column counts, min/max, and samples. This is specific enough to identify it as a data-profiling tool rather than a schema or row-preview tool, though it never explicitly names a sibling to distinguish itself from.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The read-only and sampling behavior implies this is for quick exploratory profiling, but there is no explicit guidance on when to choose it over alternatives like describe_table or preview_query. The description gives context but no exclusions or comparison to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_statusARead-onlyIdempotent
Return the package's revision (pass it as expected_revision), files and parse report. Use first, and again when the package may have changed. Gotcha: include_runtime_checks also runs runtime validation, examples and tests, which query the warehouse.
| Name | Required | Description | Default |
|---|---|---|---|
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| include_runtime_checks | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and openWorld, so safety is covered. The description still adds real value beyond those fields: it warns that include_runtime_checks triggers runtime validation, examples, and tests that query the warehouse, a side-effect and external-access trait not captured by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the primary purpose and followed by usage timing and a caveat. Every sentence carries information; the phrasing is dense but not padded. Slightly cryptic 'pass it as expected_revision' costs it a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is not required, and annotations carry the safety profile. Between the purpose, usage timing, and the warehouse-query warning, an agent has enough to call this correctly; the only lingering ambiguity is which downstream tool consumes expected_revision.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%. The description meaningfully explains include_runtime_checks behavior and hints that the returned revision should be passed as expected_revision elsewhere, but it never clarifies full_report (only the schema does) or project_path. It partially compensates for the coverage gap, consistent with a 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource set: return the package's revision, files, and parse report. That is concrete and lets an agent know it is a read/status tool rather than a mutation tool like upsert_model. It stops short of explicitly distinguishing itself from the sibling list_project_files, which also concerns files, so this is not a full 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear temporal guidance: 'Use first, and again when the package may have changed.' That tells the agent both the initial and refresh conditions. It offers no when-not guidance or named alternatives (e.g., when to prefer list_project_files or describe_table), so it misses the top tier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
promotion_checkARead-onlyIdempotent
Return whether the package is ready for an environment: parse, runtime, examples, tests. Pass compare_path or base_ref to include impact. Gotcha: it queries the warehouse.
| Name | Required | Description | Default |
|---|---|---|---|
| base_ref | No | ||
| environment | Yes | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| compare_path | No | ||
| project_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds non-obvious operational context annotations cannot express: the check reaches out and queries the warehouse, which warns the agent about latency/cost and external dependency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with zero filler: purpose first, optional-parameter behavior second, caveat last. Every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the description covers the checks, the optional impact path, and the warehouse caveat. What is missing is guidance on valid environment values and the boundary with the validate_project/impact_project siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 20% (only full_report is documented inline). The description compensates for two of the five parameters by explaining that compare_path and base_ref trigger impact analysis, and full_report's summary-vs-full distinction is covered by the schema. environment and project_path remain unexplained, so coverage is partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource – returns whether a package is ready for an environment – and enumerates the four checks (parse, runtime, examples, tests). It is distinguishable from sibling reads like validate_project or project_status, though it never directly contrasts itself with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies when to use the optional impact behavior ('Pass compare_path or base_ref to include impact'), which is genuine routing guidance. It gives no explicit when-to-use/when-not-to-use against siblings such as validate_project or diff_project, so usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_project_fileBRead-onlyIdempotent
Read a UTF-8 project file by relative path.
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | Yes | ||
| relative_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds a small behavioral constraint by specifying UTF-8 encoding, but does not disclose behavior for missing files, permission issues, or invalid paths. No contradictions with annotations exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler or redundancy. It is front-loaded with the primary verb and resource, and every word contributes to the core meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read operation with an output schema and rich safety annotations, the description is minimally adequate. However, it lacks key contextual details such as how project_path should be specified fairly, what happens when the file does not exist, and when to use sibling tools for discovering file paths.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies that relative_path is a relative path, but project_path is left completely undefined. No information is provided about path formatting, separators, accepted encodings, or how the project path relates to the file path.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read') with a clear resource ('project file') and a precise scope ('by relative path'). It is immediately distinguishable from siblings like write_project_file, archive_project_file, and list_project_files, especially when combined with the tool name and title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives. It does not mention that list_project_files should be used to discover available relative paths, or that write_project_file is the counterpart for modifications. Usage context is only implicit through the verb 'read'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_route_decisionADestructiveIdempotent
Record which route a question between two entities means, as the package default: write or replace the pair's graph.path_preferences row (pass the decision of an AMBIGUOUS_PATH clarification option). An off-route path or an unknown entity or relationship is INVALID_CONFIG with nothing written. Returns replaced (the previous row) and summary, one sentence for the review. For several pairs, pass decisions=[{source_entity, target_entity, relationship_path, label?}, ...] instead of single-pair fields. All rows are validated together in one transaction; one invalid or conflicting row refuses all.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | ||
| dry_run | No | ||
| decisions | No | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| source_entity | No | ||
| target_entity | No | ||
| idempotency_key | Yes | ||
| expected_revision | Yes | ||
| relationship_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the mutation profile (write or replace a stored row), the validation failure mode (INVALID_CONFIG with nothing written for off-route paths or unknown entities/relationships), and the all-or-nothing transaction semantics ('one invalid or conflicting row refuses all'). The annotations only carry destructive/idempotent hints; the description adds the atomicity and failure behavior an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose first, then failure semantics, then return values, then the bulk alternative, then atomicity. Every clause carries information, though the nested decisions syntax makes it slightly harder to scan than a cleaner single-purpose sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values (replaced row, summary) need not be spelled out, yet the description still flags them. Combined with the validation and transaction behavior, an agent has enough to call it correctly; the only real gap is that half the input parameters receive no textual explanation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 10% across 10 parameters, so the description must compensate. It usefully explains the single-pair fields (source_entity, target_entity, relationship_path, label) and the exact shape of the nested decisions array, but leaves expected_revision, idempotency_key, dry_run, full_report, and project_path entirely undefined in text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: record/replace a pair's graph.path_preferences row from a route decision, and specifies the default write-or-replace semantics. It is clearly distinguishable from the upsert_* siblings in subject matter, though it does not explicitly name an alternative tool an agent might confuse it with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Tells the agent when to reach for it ('pass the decision of an AMBIGUOUS_PATH clarification option') and how to choose between the single-pair and bulk 'decisions' forms. It stops short of naming an alternative tool or an explicit when-not-to-use condition, so it is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_objectADestructiveIdempotent
Remove a model, dimension, time, measure, metric, segment or relationship (a model's foreign key, keyed by its entity), archiving its YAML. model picks the model when several hold the key. A model takes its entity and relationships along. Refused if a metric would still name it; impact lists the behavior changes and the files still naming a removed id.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | ||
| kind | Yes | ||
| model | No | ||
| reason | No | ||
| dry_run | No | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint/idempotentHint/readOnlyHint, so the safety profile is covered. The description adds genuinely new behavior: the YAML is archived rather than lost, cascading deletion ('A model takes its entity and relationships along'), and a refusal condition tied to remaining metric references. It doesn't mention dry_run or the revision/idempotency protocol.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the action and target kinds, then layers disambiguators and preconditions in subsequent sentences; nothing is padded. Four dense sentences pack a lot without wasted framing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, and the cascade/archive/refusal semantics are well covered for a destructive operation. Still, with 9 params at 11% coverage and a destructive default (dry_run=false), the omission of dry_run and revision/confirmation mechanics is a real gap for an agent deciding how to call it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 11%, so the description carries most of the burden, yet it only illuminates two of nine params ('model' selection and the entity-keyed 'key'). Ambiguous fields like kind, dry_run, reason, expected_revision and idempotency_key are left entirely to the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Remove') and enumerates the resource kinds (model, dimension, time, measure, metric, segment, relationship), which cleanly separates it from the upsert_* siblings. The parenthetical clarifies what a 'relationship' is here (a model's foreign key keyed by its entity), removing ambiguity about the target object.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description discloses the precondition ('Refused if a metric would still name it') and a disambiguation rule ('model picks the model when several hold the key'), which imply when the call will succeed. However, it never states when to prefer this over or pair it with sibling tools such as impact_project or validate_project, nor recommends a pre-check workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setup_project_dialogBRead-onlyIdempotent
Start a guided project setup dialog, using MCP elicitation when requested and supported.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | ||
| package_id | No | ||
| interactive | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnly, idempotent, and non-destructive hints, and the description adds the interactive 'guided dialog' nature plus the conditional MCP elicitation behavior. This is useful context beyond the annotations strands, though it does not explain whether the dialog can produce side effects outside the session.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, repetition, or unnecessary detail. It front-loads the core action ('Start a guided project setup dialog') and adds the condition about MCP elicitation compactly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with four optional but undocumented parameters, the description is too thin. It lacks an explanation of what inputs mean, what a successful dialog returns, or how the guided process advances. The read-only annotation helps, but the strong parameter coverage gap makes the description insufficient on its own.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description gives no information about goal, package_id, interactive, or project_path. With no parameter explanations in either the schema or the description, the agent has no way to know how to populate these fields correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action and object: 'Start a guided project setup dialog.' It conveys a distinct interactive behavior, but it does not explicitly differentiate itself from sibling tools like create_project or import_dbt_project, so an agent might still wonder exactly what the dialog produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives such as create_project. The only conditional mentioned is 'when requested and supported' for MCP elicitation, which is about a sub-behavior, not about selecting the tool itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_linksARead-onlyIdempotent
Propose relationships from a table to other tables' keys from their values: per candidate column, the distinct values and rows found among the target's keys (coverage), a few not found, and the cardinality. proposals reach min_coverage (default 0.95, stated as threshold); below_threshold lists the rest with the same evidence for you to decide. columns tries those columns against every key whatever their names. With project_path the targets are the package's entities and each carries draft upsert_relationship arguments. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| columns | No | ||
| relation | Yes | ||
| duckdb_path | No | ||
| min_coverage | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive, closed-world), and the description reinforces that while adding real behavior: proposals above min_coverage versus a below_threshold bucket with the same evidence, and that project_path drafts upsert_relationship arguments. That output-shaping behavior is not derivable from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense and front-loaded, with the core mechanic in the first sentence and parameter-specific notes following. A few phrasings are terse to the point of opacity ('stated as threshold', 'a few not found'), but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still usefully sketches the result shape (proposals vs below_threshold vs draft arguments). The main residual gap is the two unexplained parameters (relation, duckdb_path) in a 0%-coverage schema, which the description should have covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load. It explains min_coverage (default 0.95, threshold semantics), columns ('tries those columns against every key whatever their names'), and project_path (targets become package entities), but leaves relation and duckdb_path entirely unaddressed — notably duckdb_path is non-obvious.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Propose relationships from a table to other tables' keys from their values', and explains the evidence basis (coverage, misses, cardinality). It doesn't explicitly differentiate itself from the sibling suggest_one_per_key, so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains behavioral conditions of parameters (min_coverage threshold, columns overriding name matching, project_path switching targets to package entities) but never states when to prefer this over suggest_one_per_key or suggest_model, nor any preconditions/exclusions. Usage is implied through the threshold story rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_modelBRead-onlyIdempotent
Propose a key, times, dimensions, measures and foreign keys for a relation, with confidences, reasons and draft upsert_model arguments. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| relation | Yes | ||
| duckdb_path | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful behavioral context by mentioning confidences, reasons, and draft upsert_model arguments, and it reaffirms read-only behavior without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence that front-loads the action and output substance. 'Read-only' is redundant with the annotations but harmless; otherwise there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return values and the annotations cover side-effect behavior, but the description still leaves unresolved questions about parameter semantics and when to invoke this tool instead of related siblings. It is minimally viable but not fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needed to explain the three parameters. It only implies that 'relation' is the target relation and says nothing about duckdb_path or project_path, leaving the agent without enough information to set those correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Propose') with a clear resource ('a relation') and lists the concrete outputs: key, times, dimensions, measures, and foreign keys. This distinguishes it from write/sibling tools like upsert_model, though it does not explicitly differentiate it from the closely named suggest_models_from_dbt.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives such as suggest_models_from_dbt, describe_table, or upsert_model. The only contextual hint is 'Read-only', which implies it is a non-mutating exploration step, but no explicit conditions or alternatives are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_models_from_dbtBRead-onlyIdempotent
suggest_model for each dbt model, from manifest.json and catalog.json (dbt never runs); keys, links and value sets come from dbt tests and contracts. select narrows by model name. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| select | No | ||
| target_dir | No | ||
| catalog_path | No | ||
| manifest_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: 'dbt never runs' and that keys/links/value sets come from dbt tests and contracts. It does not describe output format or error behavior, but the output schema exists to cover return values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, two sentences, and front-loads the core purpose. The read-only note is useful and the parenthetical about dbt never running is valuable context. Minor redundancy with annotations (read-only) but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only suggestion tool with an output schema and strong annotations, the description covers the main inputs and behavior. However, target_dir is unexplained, and there is no guidance on how the tool relates to suggest_model or when to prefer one over the other. Given the 0% schema coverage, the description should do more to document parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the four parameters. It only explains 'select' (narrows by model name) and mentions manifest.json and catalog.json as sources, which maps to manifest_path and catalog_path, but target_dir is left unexplained. The description adds some meaning but leaves half the parameters undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'suggest_model for each dbt model' from manifest.json and catalog.json, and notes that dbt never runs. It distinguishes from the sibling 'suggest_model' by the dbt-specific context, though it doesn't explicitly name the sibling. The read-only note and source files add clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context: it is for dbt models using manifest and catalog files, and 'select narrows by model name' gives a filtering condition. However, it does not explicitly state when to use this tool versus alternatives like suggest_model or import_dbt_project, nor does it mention prerequisites like having a dbt project already imported.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_one_per_keyBRead-onlyIdempotent
For a table with no key of its own, propose reading it one row per a key it repeats (one_per_key): per candidate key, the rows, NULL-key rows, distinct keys, keys with several rows, and each column fixed or varying within a key; the proposal's coverage, draft upsert_model arguments and, with project_path, the upsert_relationship that links the table's row-grain model to it. key tries one column set. Read-only: apply the drafts with dry_run, then expected_revision.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | ||
| relation | Yes | ||
| duckdb_path | No | ||
| project_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotent, non-destructive), so the description's repetition of "Read-only" adds little; however it goes further by describing what the proposal contains (NULL-key rows, distinct keys, keys with several rows, per-column fixed vs varying, coverage) and by disclosing a side effect that is easy to miss — passing project_path additionally emits an upsert_relationship linking the row-grain model. That is real behavioral context beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The key precondition is correctly front-loaded and the text is short, but it is one semicolon-chained run-on with heavy internal jargon, forcing the reader to re-parse clauses like "each column fixed or varying within a key" before reaching the actionable sentence about dry_run and expected_revision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still spends most of its length enumerating return contents while leaving two input parameters (relation, duckdb_path) undefined and never stating how this differs from the sibling suggest_model. Adequate for the read-only safety story, but an agent could still misuse the entry parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden for four parameters. It only illuminates two: project_path (triggers the upsert_relationship output) and key ("tries one column set"). Neither relation (what identifier format?) nor duckdb_path (when to supply it) is explained anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb-and-resource pair: it proposes a "one_per_key" model for a table that has no key of its own, and it enumerates the artifacts produced (diagnostics per candidate key, coverage, draft upsert_model args, and an upsert_relationship). It is dense jargon ('one_per_key', 'row-grain model') and never names the sibling suggest_model as the alternative, so differentiation is only implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"For a table with no key of its own" gives a real precondition, and "Read-only: apply the drafts with dry_run, then expected_revision" sketches a follow-up workflow. But there is no explicit when-not, no reference to suggest_model / suggest_links as the alternative for tables that do have a key, and "key tries one column set" is the only hint about how to steer candidate selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upgrade_projectADestructiveIdempotent
Rewrite a package's legacy forms to the current ones in one transaction, refusing any rewrite that changes an answer; dry_run (the default) previews the rules, proof and diff, and choices ({key: option}) answers pending choices.
| Name | Required | Description | Default |
|---|---|---|---|
| choices | No | ||
| dry_run | No | ||
| project_path | Yes | ||
| idempotency_key | No | ||
| expected_revision | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so the mutation and safety profile is known. The description goes beyond that with genuinely additive behavior: the rewrite happens in one transaction (atomicity), it refuses any rewrite that changes an answer (a semantic-preservation invariant), and it details what dry_run previews. It omits failure/rollback specifics when dry_run=false, keeping it out of the top band.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that leads with the verb and resource, then appends the safety invariant and parameter notes. Dense but no filler; the semicolon-packed clause about dry_run and choices is slightly overloaded, which is the only thing keeping it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and annotations cover the safety profile. Still, for a destructive, transactional mutation with 0% schema coverage, the two undocumented concurrency/safety parameters (idempotency_key, expected_revision) are a real gap an agent would need to call this correctly in repeated or concurrent use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for 5 parameters, so the description must carry the load. It explains dry_run (the default, previews rules/proof/diff) and choices ({key: option} answers pending choices), two parameters well. It says nothing about idempotency_key or expected_revision, which matter a lot for a destructive mutation, leaving 3 of 5 parameters undocumented in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: rewrite a package's legacy forms to the current ones, with the safety constraint that answer-changing rewrites are refused. This is clearly distinguishable from siblings like validate_project or diff_project. It stops short of naming those siblings explicitly, so it doesn't reach the top band.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the intended workflow by noting that dry_run is the default and that it previews rules, proof and diff, which guides an agent toward preview-then-apply. However, it never says when to prefer upgrade_project over validate_project, diff_project or impact_project, nor when a caller should pass dry_run=false.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upsert_exampleBDestructiveIdempotent
Upsert an example question in examples/<file_name>: spec has query, and optionally question and expected_shape (columns, min_rows, max_rows). The query must validate. spec merges into an existing example.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | ||
| dry_run | No | ||
| file_name | No | core.yml | |
| example_key | Yes | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=true). The description adds useful context beyond them — that the spec is merged into an existing example rather than replacing it, and that the query must validate — but does not explain what merge-overwrite destroys or any auth/permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the verb and resource, then the spec contract. Little waste, though it could be slightly tighter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described. However, for a destructive, 8-parameter, nested-object upsert tool, the description omits the concurrency semantics of expected_revision, idempotency_key behavior, and dry_run, leaving real gaps an agent would want closed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 13% across 8 parameters. The description usefully expands the opaque 'spec' object (query, question, expected_shape with columns/min_rows/max_rows) and ties file_name to examples/<file_name>, but leaves example_key, project_path, expected_revision, idempotency_key, and dry_run completely undocumented, so it only partially compensates for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (upsert) and resource (an example question in examples/<file_name>), and enumerates the spec's contents. An agent can distinguish it from sibling upsert_* tools like upsert_model and upsert_metric by the resource it targets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: 'spec merges into an existing example' conveys upsert semantics and 'The query must validate' gives a prerequisite, but there is no explicit when-to-use, when-not-to-use, or named alternative among the many sibling upsert tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upsert_metricADestructiveIdempotent
Upsert a metric from spec (kind, measure or inputs, value_type, label, synonyms, description). A new metric goes in metrics/<file_name>, or metrics//<metric_key>.yml; an existing one stays in its file. Fields merge; replace: true rewrites it, keeping its id. Gotcha: strict packages need an explicit value_type.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | ||
| group | No | core | |
| dry_run | No | ||
| replace | No | ||
| file_name | No | ||
| metric_key | Yes | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered; the description adds genuinely non-derived context: merge-on-default semantics, that replace:true rewrites while keeping the id, file placement rules, and the strict-package value_type gotcha. It omits dry_run behavior and expected_revision conflict semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences that front-load the operation and its field list, then behavior, then the gotcha. No filler, though the path/template fragment is slightly compressed at the cost of readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, which helps. But for a destructive, 10-param, 5-required tool, the absence of any explanation for expected_revision (optimistic locking) and idempotency_key leaves a real gap in what an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 10% across 10 params, so the description must carry the load. It partially does — explaining spec fields, file_name/group via the path template, and replace — but leaves dry_run, expected_revision, idempotency_key, and project_path entirely unexplained in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Upsert a metric') and enumerates the spec fields (kind, measure or inputs, value_type, label, synonyms, description), so an agent knows exactly what is being created or updated. It does not explicitly contrast itself with the many upsert_* siblings (upsert_model, upsert_segment, etc.), so differentiation rests on the resource noun alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it ('a new metric goes in X, an existing one stays in its file') and offers a conditional hint ('replace: true rewrites it'), but never states when to prefer this over upsert_model/upsert_segment or what prerequisites (e.g. an existing package) are needed. Usage is inferred rather than directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upsert_modelADestructiveIdempotent
Upsert a model and its graph entity. calendar: true makes it the package calendar for calendar_id (default "default", which a package with calendars needs): its columns are ordinary dimensions; time.fill and every time bucket use the implicit Gregorian calendar. calendar: false reverts that. On a regular model, calendar_id binds its times to a calendar; a non-default calendar is refused in this release. Fields merge into an existing model. An existing dimension, time or measure given only label, description, synonyms or meta keeps its other fields; given anything else it is rewritten, and dropped_fields lists what that drops. replace: true rewrites the model from the arguments, keeping only its id, entities, calendar_id, zero_through (how far its tables are loaded) and one_per_key, and lists what it drops in dropped_fields. one_per_key: true reads a relation whose rows repeat the key as one row per primary_key, each column the key's one value (NULL where its rows disagree); keep the columns that vary on a row-grain model of the same relation. primary_key [] makes a row-grain model (no key); entities ({parent: {} or {expr: column}}) merges the model's parent entities. Relationships also go through upsert_relationship.
| Name | Required | Description | Default |
|---|---|---|---|
| group | No | core | |
| label | No | ||
| times | No | ||
| dry_run | No | ||
| replace | No | ||
| calendar | No | ||
| entities | No | ||
| measures | No | ||
| model_id | Yes | ||
| relation | Yes | ||
| dimensions | No | ||
| entity_key | Yes | ||
| calendar_id | No | ||
| description | No | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| one_per_key | No | ||
| primary_key | Yes | ||
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the baseline is lower. The description adds rich behavioral detail beyond annotations: how replace rewrites a model and lists dropped_fields, how merge semantics preserve other fields, how calendar behaves, and that a non-default calendar is refused in this release.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and every clause adds semantic detail, with no obvious filler. However, it is a single dense, run-on paragraph that is difficult to scan, especially for a tool with 20 parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and annotations cover the safety profile. Still, for a complex upsert tool with 20 parameters and only 5% schema description coverage, the description is incomplete because it omits semantics for several required parameters and operational fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 5%, so the description must carry the parameter burden. It explains the most ambiguous optional parameters (calendar, replace, one_per_key, primary_key, entities) well, but leaves many required and operational parameters unexplained, including project_path, model_id, entity_key, relation, expected_revision, idempotency_key, dry_run, and group.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Upsert a model and its graph entity.' It also differentiates scope from the related sibling by stating 'Relationships also go through upsert_relationship.' An agent can identify the tool's core purpose immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use through the verb 'upsert' and gives substantial parameter behavior, but it does not explicitly state when to choose this tool over other upsert or model-related siblings. The only routing guidance is 'Relationships also go through upsert_relationship,' which is useful but limited to one alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upsert_relationshipADestructiveIdempotent
Relate two entities: columns on from_entity's model hold to_entity's key, in key order. cardinality: many_to_one or one_to_one. from_entity may be a row-grain model's id. name writes graph.relationships. with these columns as its via: a second role on the pair (a buyer and a seller), or that role again; a pair with two roles needs it. Set keep_existing_routes=true to record every moved pair's previous route in this transaction; otherwise unrecorded route changes refuse the write.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| columns | Yes | ||
| dry_run | No | ||
| to_entity | Yes | ||
| cardinality | No | many_to_one | |
| from_entity | Yes | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes | ||
| keep_existing_routes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds real behavioral depth beyond that: it discloses the write-refusal failure mode ('otherwise unrecorded route changes refuse the write') and the side effect that name writes graph.relationships.<name>. It does not explain the implications of destructive/upsert behavior or rollback, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact but written as dense, jargon-heavy run-on sentences that are hard to parse on first read, and the most critical constraint (write refusal) is buried at the end. Sentences mostly earn their place, but front-loading and readability suffer.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and annotations cover safety. Still, for an 11-parameter mutation tool the definition omits concurrency (expected_revision) and idempotency_key semantics and any sibling routing, leaving the agent to guess how this fits alongside upsert_model and record_route_decision.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 9%, so the description must carry parameter meaning. It does add genuine semantics for cardinality (many_to_one / one_to_one), columns (key-order significance), from_entity (may be a row-grain model's id), name (target path), and keep_existing_routes (failure-mode semantics). But it leaves project_path, to_entity, expected_revision, idempotency_key, dry_run, and full_report undocumented in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening 'Relate two entities: columns on from_entity's model hold to_entity's key' names a specific verb and resource, and the relationship-vs-model distinction separates it from upsert_model/upsert_metric. However it never names a sibling or states the boundary explicitly, so differentiation relies on inference from the resource noun.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Conditional guidance is present in the body ('a pair with two roles needs it', 'Set keep_existing_routes=true to...'), which tells the agent when certain fields matter. But there is no when-to-use/when-not-to-use guidance relative to sibling tools such as upsert_model or record_route_decision, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upsert_segmentADestructiveIdempotent
Upsert a segment in segments/<file_name>: entity, basis_metric, label, membership. Fields merge; replace: true rewrites it, keeping its id. Gotcha: membership needs where, metric_filters or a time window, and fields outside membership: are refused.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | ||
| dry_run | No | ||
| replace | No | ||
| file_name | No | core.yml | |
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| segment_key | Yes | ||
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, yet the description adds real beyond-schema behavior: fields merge by default, replace:true rewrites the object while preserving its id, and membership requires where/metric_filters/time-window or the call is refused. It omits concurrency behavior for expected_revision, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact and front-loaded: destination and payload first, then merge/replace semantics, then the fatal validation gotcha. The 'Gotcha:' framing is informal but signals priority well; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, 5-required mutation tool with a nested free-form spec, the description covers the essential write semantics and key validation, and an output schema exists so return values need not be explained. It remains thin on the required expected_revision/idempotency_key contract and dry_run, which matter for a destructive, idempotent upsert.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 11% across 9 params, so the description must compensate. It usefully characterizes the otherwise opaque spec object (entity, basis_metric, label, membership) and the replace/file_name flags, but leaves project_path, segment_key, expected_revision, idempotency_key, dry_run, and full_report unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (upsert), the exact resource (a segment) and its destination (segments/<file_name>), plus the fields it carries (entity, basis_metric, label, membership). This clearly separates it from siblings like upsert_metric, upsert_model, and upsert_relationship without needing the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use vs alternatives guidance, but usage is implied through the merge/replace conditional and the membership validation rule, which tells the agent when a given call shape will succeed. An agent must infer the alternatives from sibling names rather than being routed by the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upsert_testADestructiveIdempotent
Upsert a package test in tests/<file_name>. spec.kind is query_returns_columns (query, columns), query_row_count_bounds (query, min_rows and/or max_rows), query_matches_snapshot (query, expected_rows), validate_fails_with_code (query, code), explain_contains (query, text) or metric_equals_query (metric_query, expected_query). Queries must validate; a validate_fails_with_code query must fail with its code. spec merges into an existing test.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | ||
| dry_run | No | ||
| test_key | Yes | ||
| file_name | No | core.yml | |
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the bar is lower, but the description adds real value by explaining that 'spec merges into an existing test' (clarifying the upsert/destructive semantics) and by stating validation preconditions ('Queries must validate'). It does not disclose what is lost on overwrite or auth/permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and file location, then spends its length on the only genuinely opaque parameter. Dense but every clause about the spec kinds earns its place; could be tightened with the field list in a more scannable form.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be covered, and the complex nested spec is well documented. It is still incomplete for a destructive 5-required-param mutation because revision/idempotency/dry_run semantics go unmentioned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 13%, so the description must carry the load, and it does so for the opaque 'spec' object (additionalProperties:true) by documenting all six kinds and their required fields. It leaves test_key, expected_revision, idempotency_key, file_name and dry_run unexplained, which is the remaining gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Upsert a package test in tests/<file_name>') that cleanly distinguishes it from the sibling upsert_model/upsert_metric/upsert_segment tools. An agent knows exactly what artifact is being written and where.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the enumeration of spec.kind variants and the note that queries must validate, but there is no explicit when-to-use versus when-not guidance and no alternative tool is named (e.g. vs upsert_example or validate_project). Adequate but incomplete routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_projectARead-onlyIdempotent
Validate the package: mode parse, runtime, examples, tests, impact or release. Use parse after each change and runtime (compiles and queries every measure and metric) before trusting answers. Gotcha: runtime, examples, tests and release query the warehouse and may build a seeded DuckDB file; impact needs compare_path or base_ref.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | parse | |
| base_ref | No | ||
| environment | No | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| compare_path | No | ||
| project_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuinely useful behavior beyond the annotations: several modes query the warehouse and may build a seeded DuckDB file, and impact has a parameter prerequisite. This side-effect disclosure is the kind of context readOnlyHint/idempotentHint do not convey, though there is mild tension with readOnlyHint=true since a file is created as a byproduct. It omits auth requirements and per-mode failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the mode list, then usage guidance, then the gotcha. Every sentence carries distinct information (modes, when-to-use, side effects/prerequisites) with no filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the modes plus prerequisites plus side effects cover the core invocation path for a 6-parameter tool. The unexplained 'environment' parameter and the unaddressed overlap with impact_project/diff_project keep it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 17% (only full_report is documented), so the description must compensate and largely does: it enumerates the valid mode values (the schema has no enum), explains what parse/runtime do, and links compare_path/base_ref to the impact mode. The 'environment' parameter is never explained anywhere, leaving a gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Validate the package') and enumerates the six modes (parse, runtime, examples, tests, impact, release), so an agent knows what the tool does and its scope. However, it does not differentiate itself from siblings that clearly overlap, notably impact_project and diff_project, even though the 'impact' mode covers the same ground. Terminology also drifts between 'package' and the tool's 'project'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit sequencing advice ('Use parse after each change', 'runtime ... before trusting answers') and states a prerequisite for the impact mode ('needs compare_path or base_ref'). It stops short of naming when NOT to use it or pointing to the overlapping sibling tools (impact_project, diff_project) that an agent might otherwise pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_project_filesBDestructiveIdempotent
Write or archive files in one transaction, validating the final package as a whole.
| Name | Required | Description | Default |
|---|---|---|---|
| files | Yes | ||
| reason | No | ||
| dry_run | No | ||
| full_report | No | true: the whole report (default: a summary; see its report field) | |
| project_path | Yes | ||
| idempotency_key | Yes | ||
| expected_revision | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| error | No | |
| parse | No | |
| errors | No | |
| status | Yes | |
| changes | Yes | |
| dry_run | Yes | |
| revision | Yes | |
| project_path | Yes | |
| base_revision | Yes | |
| changed_files | Yes | |
| route_changes | No | |
| workspace_root | No | |
| idempotency_key | Yes | |
| current_revision | Yes | |
| expected_revision | Yes | |
| idempotent_replay | Yes | |
| proposed_revision | Yes | |
| route_decisions_added | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive=true, idempotent=true, readOnly=false, so the safety profile is covered. The description adds genuinely useful non-annotation context: writes are atomic ('one transaction') and the final package is validated as a whole. However, it never says what 'archive' destroys, how expected_revision conflicts are handled, or what happens when validation fails.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the core action first and the qualifying constraint second. No filler, no restated title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, but with 7 parameters at 14% schema coverage and zero usage guidance, the description is far too thin for a destructive, revision-guarded batch write. Conflict handling and failure/rollback behavior are unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 14% across 7 parameters (only full_report is documented), so the description must compensate but adds nothing about files, project_path, expected_revision, idempotency_key, reason, or dry_run. Critical inputs like the optimistic-concurrency revision and the idempotency key are left entirely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb pair (write or archive) and resource (files), plus a distinguishing scope detail (single transaction with whole-package validation). An agent can separate it from read_project_file and list_project_files. It stops short of naming the sibling tools it is a counterpart to.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or when-not-to-use guidance. Nothing tells the agent how this relates to diff_project, validate_project, or read/remove_object, nor when to prefer it over those tools. Usage is only implied by the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.3.3- Added
suggest_links - Added
suggest_one_per_key
17 tool updates
v0.3.2- Removed
archive_project_file - Changed
create_project4 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
import_dbt_project4 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
project_status1 field changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +}
- Changed
promotion_check1 field changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +}
- Added
record_route_decision - Changed
remove_object4 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Added
upgrade_project - Changed
upsert_example4 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
upsert_metric5 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Input schema / properties / spec / propertiesAdded value: +{ + "synonyms": { + "description": "Other declared names for this metric.", + "items": { + "type": "string" + }, + "type": "array" + } +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
upsert_model7 fields changed- added
Input schema / properties / entitiesAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - removed
Input schema / properties / joinsRemoved value: -{ - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null -} - added
Input schema / properties / one_per_keyAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
upsert_relationship6 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Input schema / properties / keep_existing_routesAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / properties / nameAdded value: +{ + "default": "", + "type": "string" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
upsert_segment4 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
upsert_test4 fields changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +} - added
Output schema / $defs / ArchitectFileChange / properties / diff_truncatedAdded value: +{ + "default": false, + "type": "boolean" +} - added
Output schema / properties / route_changesAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / route_decisions_addedAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +}
- Changed
validate_project1 field changed- added
Input schema / properties / full_reportAdded value: +{ + "default": false, + "description": "true: the whole report (default: a summary; see its report field)", + "type": "boolean" +}
- Removed
write_project_file - Added
write_project_files
27 tool updates
v0.3.1- Changed
architect_guidance4 fields changed- removed
Input schema / properties / goal / titleRemoved value: -"Goal" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"architect_guidanceArguments" - removed
Output schema / titleRemoved value: -"architect_guidanceDictOutput"
- Changed
archive_project_file38 fields changed- removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / properties / reason / titleRemoved value: -"Reason" - removed
Input schema / properties / relative_path / titleRemoved value: -"Relative Path" - removed
Input schema / titleRemoved value: -"archive_project_fileArguments" - removed
Output schema / $defs / ArchitectFileChange / properties / after_bytes / titleRemoved value: -"After Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / after_sha256 / titleRemoved value: -"After Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / before_bytes / titleRemoved value: -"Before Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / before_sha256 / titleRemoved value: -"Before Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / content_encoding / titleRemoved value: -"Content Encoding" - removed
Output schema / $defs / ArchitectFileChange / properties / diff / titleRemoved value: -"Diff" - removed
Output schema / $defs / ArchitectFileChange / properties / operation / titleRemoved value: -"Operation" - removed
Output schema / $defs / ArchitectFileChange / properties / path / titleRemoved value: -"Path" - removed
Output schema / $defs / ArchitectFileChange / properties / proposed_content / titleRemoved value: -"Proposed Content" - removed
Output schema / $defs / ArchitectFileChange / titleRemoved value: -"ArchitectFileChange" - removed
Output schema / $defs / ArchitectMutationIssue / properties / code / titleRemoved value: -"Code" - removed
Output schema / $defs / ArchitectMutationIssue / properties / details / titleRemoved value: -"Details" - removed
Output schema / $defs / ArchitectMutationIssue / properties / message / titleRemoved value: -"Message" - removed
Output schema / $defs / ArchitectMutationIssue / titleRemoved value: -"ArchitectMutationIssue" - removed
Output schema / properties / base_revision / titleRemoved value: -"Base Revision" - removed
Output schema / properties / changed_files / titleRemoved value: -"Changed Files" - removed
Output schema / properties / changes / titleRemoved value: -"Changes" - removed
Output schema / properties / current_revision / titleRemoved value: -"Current Revision" - removed
Output schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Output schema / properties / errors / titleRemoved value: -"Errors" - removed
Output schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Output schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Output schema / properties / idempotent_replay / titleRemoved value: -"Idempotent Replay" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / parse / titleRemoved value: -"Parse" - removed
Output schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Output schema / properties / proposed_revision / titleRemoved value: -"Proposed Revision" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / status / titleRemoved value: -"Status" - removed
Output schema / properties / workspace_root / titleRemoved value: -"Workspace Root" - removed
Output schema / titleRemoved value: -"ArchitectMutationResult"
- Changed
create_project52 fields changed- changed
Input schema / properties / amount_column / defaultPrevious value: -"amount"New value: +"" - removed
Input schema / properties / amount_column / titleRemoved value: -"Amount Column" - added
Input schema / properties / connection_kindAdded value: +{ + "default": "", + "type": "string" +} - added
Input schema / properties / connection_nameAdded value: +{ + "default": "", + "type": "string" +} - added
Input schema / properties / connection_optionsAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / dataAdded value: +{ + "default": "starter", + "enum": [ + "starter", + "external" + ], + "type": "string" +} - added
Input schema / properties / default_dbAdded value: +{ + "default": "", + "type": "string" +} - removed
Input schema / properties / description / titleRemoved value: -"Description" - added
Input schema / properties / dimension_columnAdded value: +{ + "default": "", + "type": "string" +} - removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / first_entity / titleRemoved value: -"First Entity" - removed
Input schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / properties / package_id / titleRemoved value: -"Package Id" - removed
Input schema / properties / primary_key / titleRemoved value: -"Primary Key" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / properties / relation / titleRemoved value: -"Relation" - removed
Input schema / properties / time_column / titleRemoved value: -"Time Column" - added
Input schema / properties / warehouseAdded value: +{ + "default": "duckdb", + "type": "string" +} - removed
Input schema / titleRemoved value: -"create_projectArguments" - removed
Output schema / $defs / ArchitectFileChange / properties / after_bytes / titleRemoved value: -"After Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / after_sha256 / titleRemoved value: -"After Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / before_bytes / titleRemoved value: -"Before Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / before_sha256 / titleRemoved value: -"Before Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / content_encoding / titleRemoved value: -"Content Encoding" - removed
Output schema / $defs / ArchitectFileChange / properties / diff / titleRemoved value: -"Diff" - removed
Output schema / $defs / ArchitectFileChange / properties / operation / titleRemoved value: -"Operation" - removed
Output schema / $defs / ArchitectFileChange / properties / path / titleRemoved value: -"Path" - removed
Output schema / $defs / ArchitectFileChange / properties / proposed_content / titleRemoved value: -"Proposed Content" - removed
Output schema / $defs / ArchitectFileChange / titleRemoved value: -"ArchitectFileChange" - removed
Output schema / $defs / ArchitectMutationIssue / properties / code / titleRemoved value: -"Code" - removed
Output schema / $defs / ArchitectMutationIssue / properties / details / titleRemoved value: -"Details" - removed
Output schema / $defs / ArchitectMutationIssue / properties / message / titleRemoved value: -"Message" - removed
Output schema / $defs / ArchitectMutationIssue / titleRemoved value: -"ArchitectMutationIssue" - removed
Output schema / properties / base_revision / titleRemoved value: -"Base Revision" - removed
Output schema / properties / changed_files / titleRemoved value: -"Changed Files" - removed
Output schema / properties / changes / titleRemoved value: -"Changes" - removed
Output schema / properties / current_revision / titleRemoved value: -"Current Revision" - removed
Output schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Output schema / properties / errors / titleRemoved value: -"Errors" - removed
Output schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Output schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Output schema / properties / idempotent_replay / titleRemoved value: -"Idempotent Replay" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / parse / titleRemoved value: -"Parse" - removed
Output schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Output schema / properties / proposed_revision / titleRemoved value: -"Proposed Revision" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / status / titleRemoved value: -"Status" - removed
Output schema / properties / workspace_root / titleRemoved value: -"Workspace Root" - removed
Output schema / titleRemoved value: -"ArchitectMutationResult"
- Added
describe_table - Changed
diff_project5 fields changed- removed
Input schema / properties / base_ref / titleRemoved value: -"Base Ref" - removed
Input schema / properties / compare_path / titleRemoved value: -"Compare Path" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"diff_projectArguments" - removed
Output schema / titleRemoved value: -"diff_projectDictOutput"
- Changed
impact_project5 fields changed- removed
Input schema / properties / base_ref / titleRemoved value: -"Base Ref" - removed
Input schema / properties / compare_path / titleRemoved value: -"Compare Path" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"impact_projectArguments" - removed
Output schema / titleRemoved value: -"impact_projectDictOutput"
- Added
import_dbt_project - Changed
list_project_files3 fields changed- removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"list_project_filesArguments" - removed
Output schema / titleRemoved value: -"list_project_filesDictOutput"
- Added
list_tables - Changed
mcp_client_config5 fields changed- removed
Input schema / properties / host / titleRemoved value: -"Host" - removed
Input schema / properties / port / titleRemoved value: -"Port" - removed
Input schema / properties / transport / titleRemoved value: -"Transport" - removed
Input schema / titleRemoved value: -"mcp_client_configArguments" - removed
Output schema / titleRemoved value: -"mcp_client_configDictOutput"
- Added
preview_query - Added
profile_columns - Changed
project_status4 fields changed- removed
Input schema / properties / include_runtime_checks / titleRemoved value: -"Include Runtime Checks" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"project_statusArguments" - removed
Output schema / titleRemoved value: -"project_statusDictOutput"
- Changed
promotion_check6 fields changed- removed
Input schema / properties / base_ref / titleRemoved value: -"Base Ref" - removed
Input schema / properties / compare_path / titleRemoved value: -"Compare Path" - removed
Input schema / properties / environment / titleRemoved value: -"Environment" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"promotion_checkArguments" - removed
Output schema / titleRemoved value: -"promotion_checkDictOutput"
- Changed
read_project_file4 fields changed- removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / properties / relative_path / titleRemoved value: -"Relative Path" - removed
Input schema / titleRemoved value: -"read_project_fileArguments" - removed
Output schema / titleRemoved value: -"read_project_fileDictOutput"
- Added
remove_object - Changed
setup_project_dialog6 fields changed- removed
Input schema / properties / goal / titleRemoved value: -"Goal" - removed
Input schema / properties / interactive / titleRemoved value: -"Interactive" - removed
Input schema / properties / package_id / titleRemoved value: -"Package Id" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"setup_project_dialogArguments" - removed
Output schema / titleRemoved value: -"setup_project_dialogDictOutput"
- Added
suggest_model - Added
suggest_models_from_dbt - Added
upsert_example - Changed
upsert_metric41 fields changed- removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - added
Input schema / properties / file_nameAdded value: +{ + "default": "", + "type": "string" +} - removed
Input schema / properties / group / titleRemoved value: -"Group" - removed
Input schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Input schema / properties / metric_key / titleRemoved value: -"Metric Key" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - added
Input schema / properties / replaceAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / spec / titleRemoved value: -"Spec" - removed
Input schema / titleRemoved value: -"upsert_metricArguments" - removed
Output schema / $defs / ArchitectFileChange / properties / after_bytes / titleRemoved value: -"After Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / after_sha256 / titleRemoved value: -"After Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / before_bytes / titleRemoved value: -"Before Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / before_sha256 / titleRemoved value: -"Before Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / content_encoding / titleRemoved value: -"Content Encoding" - removed
Output schema / $defs / ArchitectFileChange / properties / diff / titleRemoved value: -"Diff" - removed
Output schema / $defs / ArchitectFileChange / properties / operation / titleRemoved value: -"Operation" - removed
Output schema / $defs / ArchitectFileChange / properties / path / titleRemoved value: -"Path" - removed
Output schema / $defs / ArchitectFileChange / properties / proposed_content / titleRemoved value: -"Proposed Content" - removed
Output schema / $defs / ArchitectFileChange / titleRemoved value: -"ArchitectFileChange" - removed
Output schema / $defs / ArchitectMutationIssue / properties / code / titleRemoved value: -"Code" - removed
Output schema / $defs / ArchitectMutationIssue / properties / details / titleRemoved value: -"Details" - removed
Output schema / $defs / ArchitectMutationIssue / properties / message / titleRemoved value: -"Message" - removed
Output schema / $defs / ArchitectMutationIssue / titleRemoved value: -"ArchitectMutationIssue" - removed
Output schema / properties / base_revision / titleRemoved value: -"Base Revision" - removed
Output schema / properties / changed_files / titleRemoved value: -"Changed Files" - removed
Output schema / properties / changes / titleRemoved value: -"Changes" - removed
Output schema / properties / current_revision / titleRemoved value: -"Current Revision" - removed
Output schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Output schema / properties / errors / titleRemoved value: -"Errors" - removed
Output schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Output schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Output schema / properties / idempotent_replay / titleRemoved value: -"Idempotent Replay" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / parse / titleRemoved value: -"Parse" - removed
Output schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Output schema / properties / proposed_revision / titleRemoved value: -"Proposed Revision" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / status / titleRemoved value: -"Status" - removed
Output schema / properties / workspace_root / titleRemoved value: -"Workspace Root" - removed
Output schema / titleRemoved value: -"ArchitectMutationResult"
- Changed
upsert_model50 fields changed- added
Input schema / properties / calendarAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / calendar_idAdded value: +{ + "default": "", + "type": "string" +} - removed
Input schema / properties / description / titleRemoved value: -"Description" - removed
Input schema / properties / dimensions / titleRemoved value: -"Dimensions" - removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / entity_key / titleRemoved value: -"Entity Key" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / group / titleRemoved value: -"Group" - removed
Input schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Input schema / properties / joins / titleRemoved value: -"Joins" - added
Input schema / properties / labelAdded value: +{ + "default": "", + "type": "string" +} - removed
Input schema / properties / measures / titleRemoved value: -"Measures" - removed
Input schema / properties / model_id / titleRemoved value: -"Model Id" - removed
Input schema / properties / primary_key / titleRemoved value: -"Primary Key" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / properties / relation / titleRemoved value: -"Relation" - added
Input schema / properties / replaceAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / times / titleRemoved value: -"Times" - removed
Input schema / titleRemoved value: -"upsert_modelArguments" - removed
Output schema / $defs / ArchitectFileChange / properties / after_bytes / titleRemoved value: -"After Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / after_sha256 / titleRemoved value: -"After Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / before_bytes / titleRemoved value: -"Before Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / before_sha256 / titleRemoved value: -"Before Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / content_encoding / titleRemoved value: -"Content Encoding" - removed
Output schema / $defs / ArchitectFileChange / properties / diff / titleRemoved value: -"Diff" - removed
Output schema / $defs / ArchitectFileChange / properties / operation / titleRemoved value: -"Operation" - removed
Output schema / $defs / ArchitectFileChange / properties / path / titleRemoved value: -"Path" - removed
Output schema / $defs / ArchitectFileChange / properties / proposed_content / titleRemoved value: -"Proposed Content" - removed
Output schema / $defs / ArchitectFileChange / titleRemoved value: -"ArchitectFileChange" - removed
Output schema / $defs / ArchitectMutationIssue / properties / code / titleRemoved value: -"Code" - removed
Output schema / $defs / ArchitectMutationIssue / properties / details / titleRemoved value: -"Details" - removed
Output schema / $defs / ArchitectMutationIssue / properties / message / titleRemoved value: -"Message" - removed
Output schema / $defs / ArchitectMutationIssue / titleRemoved value: -"ArchitectMutationIssue" - removed
Output schema / properties / base_revision / titleRemoved value: -"Base Revision" - removed
Output schema / properties / changed_files / titleRemoved value: -"Changed Files" - removed
Output schema / properties / changes / titleRemoved value: -"Changes" - removed
Output schema / properties / current_revision / titleRemoved value: -"Current Revision" - removed
Output schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Output schema / properties / errors / titleRemoved value: -"Errors" - removed
Output schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Output schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Output schema / properties / idempotent_replay / titleRemoved value: -"Idempotent Replay" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / parse / titleRemoved value: -"Parse" - removed
Output schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Output schema / properties / proposed_revision / titleRemoved value: -"Proposed Revision" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / status / titleRemoved value: -"Status" - removed
Output schema / properties / workspace_root / titleRemoved value: -"Workspace Root" - removed
Output schema / titleRemoved value: -"ArchitectMutationResult"
- Added
upsert_relationship - Changed
upsert_segment40 fields changed- removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / file_name / titleRemoved value: -"File Name" - removed
Input schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - added
Input schema / properties / replaceAdded value: +{ + "default": false, + "type": "boolean" +} - removed
Input schema / properties / segment_key / titleRemoved value: -"Segment Key" - removed
Input schema / properties / spec / titleRemoved value: -"Spec" - removed
Input schema / titleRemoved value: -"upsert_segmentArguments" - removed
Output schema / $defs / ArchitectFileChange / properties / after_bytes / titleRemoved value: -"After Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / after_sha256 / titleRemoved value: -"After Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / before_bytes / titleRemoved value: -"Before Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / before_sha256 / titleRemoved value: -"Before Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / content_encoding / titleRemoved value: -"Content Encoding" - removed
Output schema / $defs / ArchitectFileChange / properties / diff / titleRemoved value: -"Diff" - removed
Output schema / $defs / ArchitectFileChange / properties / operation / titleRemoved value: -"Operation" - removed
Output schema / $defs / ArchitectFileChange / properties / path / titleRemoved value: -"Path" - removed
Output schema / $defs / ArchitectFileChange / properties / proposed_content / titleRemoved value: -"Proposed Content" - removed
Output schema / $defs / ArchitectFileChange / titleRemoved value: -"ArchitectFileChange" - removed
Output schema / $defs / ArchitectMutationIssue / properties / code / titleRemoved value: -"Code" - removed
Output schema / $defs / ArchitectMutationIssue / properties / details / titleRemoved value: -"Details" - removed
Output schema / $defs / ArchitectMutationIssue / properties / message / titleRemoved value: -"Message" - removed
Output schema / $defs / ArchitectMutationIssue / titleRemoved value: -"ArchitectMutationIssue" - removed
Output schema / properties / base_revision / titleRemoved value: -"Base Revision" - removed
Output schema / properties / changed_files / titleRemoved value: -"Changed Files" - removed
Output schema / properties / changes / titleRemoved value: -"Changes" - removed
Output schema / properties / current_revision / titleRemoved value: -"Current Revision" - removed
Output schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Output schema / properties / errors / titleRemoved value: -"Errors" - removed
Output schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Output schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Output schema / properties / idempotent_replay / titleRemoved value: -"Idempotent Replay" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / parse / titleRemoved value: -"Parse" - removed
Output schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Output schema / properties / proposed_revision / titleRemoved value: -"Proposed Revision" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / status / titleRemoved value: -"Status" - removed
Output schema / properties / workspace_root / titleRemoved value: -"Workspace Root" - removed
Output schema / titleRemoved value: -"ArchitectMutationResult"
- Added
upsert_test - Changed
validate_project7 fields changed- removed
Input schema / properties / base_ref / titleRemoved value: -"Base Ref" - removed
Input schema / properties / compare_path / titleRemoved value: -"Compare Path" - removed
Input schema / properties / environment / titleRemoved value: -"Environment" - removed
Input schema / properties / mode / titleRemoved value: -"Mode" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / titleRemoved value: -"validate_projectArguments" - removed
Output schema / titleRemoved value: -"validate_projectDictOutput"
- Changed
write_project_file39 fields changed- removed
Input schema / properties / content / titleRemoved value: -"Content" - removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Input schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Input schema / properties / relative_path / titleRemoved value: -"Relative Path" - removed
Input schema / titleRemoved value: -"write_project_fileArguments" - removed
Output schema / $defs / ArchitectFileChange / properties / after_bytes / titleRemoved value: -"After Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / after_sha256 / titleRemoved value: -"After Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / before_bytes / titleRemoved value: -"Before Bytes" - removed
Output schema / $defs / ArchitectFileChange / properties / before_sha256 / titleRemoved value: -"Before Sha256" - removed
Output schema / $defs / ArchitectFileChange / properties / content_encoding / titleRemoved value: -"Content Encoding" - removed
Output schema / $defs / ArchitectFileChange / properties / diff / titleRemoved value: -"Diff" - removed
Output schema / $defs / ArchitectFileChange / properties / operation / titleRemoved value: -"Operation" - removed
Output schema / $defs / ArchitectFileChange / properties / path / titleRemoved value: -"Path" - removed
Output schema / $defs / ArchitectFileChange / properties / proposed_content / titleRemoved value: -"Proposed Content" - removed
Output schema / $defs / ArchitectFileChange / titleRemoved value: -"ArchitectFileChange" - removed
Output schema / $defs / ArchitectMutationIssue / properties / code / titleRemoved value: -"Code" - removed
Output schema / $defs / ArchitectMutationIssue / properties / details / titleRemoved value: -"Details" - removed
Output schema / $defs / ArchitectMutationIssue / properties / message / titleRemoved value: -"Message" - removed
Output schema / $defs / ArchitectMutationIssue / titleRemoved value: -"ArchitectMutationIssue" - removed
Output schema / properties / base_revision / titleRemoved value: -"Base Revision" - removed
Output schema / properties / changed_files / titleRemoved value: -"Changed Files" - removed
Output schema / properties / changes / titleRemoved value: -"Changes" - removed
Output schema / properties / current_revision / titleRemoved value: -"Current Revision" - removed
Output schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Output schema / properties / errors / titleRemoved value: -"Errors" - removed
Output schema / properties / expected_revision / titleRemoved value: -"Expected Revision" - removed
Output schema / properties / idempotency_key / titleRemoved value: -"Idempotency Key" - removed
Output schema / properties / idempotent_replay / titleRemoved value: -"Idempotent Replay" - removed
Output schema / properties / ok / titleRemoved value: -"Ok" - removed
Output schema / properties / parse / titleRemoved value: -"Parse" - removed
Output schema / properties / project_path / titleRemoved value: -"Project Path" - removed
Output schema / properties / proposed_revision / titleRemoved value: -"Proposed Revision" - removed
Output schema / properties / revision / titleRemoved value: -"Revision" - removed
Output schema / properties / status / titleRemoved value: -"Status" - removed
Output schema / properties / workspace_root / titleRemoved value: -"Workspace Root" - removed
Output schema / titleRemoved value: -"ArchitectMutationResult"
16 tool updates
v0.2.0- First observed
architect_guidance - First observed
archive_project_file - First observed
create_project - First observed
diff_project - First observed
impact_project - First observed
list_project_files - First observed
mcp_client_config - First observed
project_status - First observed
promotion_check - First observed
read_project_file - First observed
setup_project_dialog - First observed
upsert_metric - First observed
upsert_model - First observed
upsert_segment - First observed
validate_project - First observed
write_project_file
TDQS
Scored across 30 tools
Most tools target distinct objects or lifecycle stages, but several validation/readiness tools overlap: validate_project, impact_project, promotion_check, and project_status all report package health from slightly different angles. The detailed descriptions help, but an agent must still choose carefully between validation, impact, and promotion workflows.
The set is overwhelmingly snake_case and readable, with clear verb_noun patterns such as create_project, list_tables, upsert_model, and remove_object. Minor deviations exist in noun-first names like project_status, impact_project, promotion_check, and architect_guidance, but they do not seriously hinder interpretation.
Thirty tools is heavy for this server, especially because project validation, impact, promotion, and status are split across several related tools. While the domain is broad, the surface feels overgrown and includes multiple near-adjacent lifecycle and checking operations.
The server covers project creation, file reading/writing, modeling object upserts, relationship and route decisions, metrics, segments, examples, tests, validation, impact, promotion, import, and removal. Minor gaps remain around direct object inspection/listing without file reads, but core semantic-model lifecycle workflows are well covered.
Maintenance
Related MCP Connectors
Answer questions using your semantic layer and company knowledge graph.
The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.
Define, ship & query your analytics tracking from one source of truth, trusted by humans and agents.
Query your Betterlytics web analytics from AI agents: traffic, funnels, journeys, errors, uptime.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables agents to perform controlled enterprise data queries through semantic intent, with runtime validation of statistics, filters, granularity, permissions, and physical bindings. Exposes tools like semantic_query for safe, fail-closed access to data horizons and capabilities.-
- AlicenseNot gradedqualityCmaintenanceEnables agents to answer analytics questions with provable correctness by resolving metrics through the semantic layer, tracing lineage, traversing knowledge graphs, checking freshness, and searching glossary definitions, while enforcing access controls and logging every call.MIT
- AlicenseAqualityBmaintenanceEnables agents to query curated metrics through a registry-backed semantic layer, preventing ad-hoc SQL and enforcing consistent definitions. Every numeric claim is verified against the underlying query result before it is allowed to be sent.4MIT
- AlicenseAqualityBmaintenanceEnables agents to query governed metrics through MCP, including describing metrics, running deterministic SQL against a warehouse, explaining join path preferences, and searching semantically ambiguous terms.8MIT