SLayer
Provides semantic layer capabilities for ClickHouse databases, allowing AI agents to query data using measures, dimensions, and filters instead of writing SQL directly, with automatic SQL compilation and dialect handling.
Integrates with dbt's semantic layer concepts and is positioned as an alternative to raw SQL generation by AI agents, with references to dbt's benchmark analysis comparing semantic layers to text-to-SQL approaches.
Provides semantic layer capabilities for MySQL databases, allowing AI agents to query data using measures, dimensions, and filters instead of writing SQL directly, with automatic SQL compilation and dialect handling.
Provides semantic layer capabilities for SQLite databases, allowing AI agents to query data using measures, dimensions, and filters instead of writing SQL directly, with automatic SQL compilation and dialect handling.
SLayer
An expressive, embeddable semantic layer for AI agents and humans.
SLayer enables AI-powered data analytics on top of your warehouse. Agents get a governed, shared surface through which they access your data and metrics and give you reliable answers.
SLayer handles database connectivity (read-only), SQL translation, common data transformations, and row-level security, so LLMs and humans don't have to. Adapt it to your workflows, not the other way around. Manage definitions easily with an agent or by yourself.
SLayer can be used as a standalone tool or imported as a Python library, easily embeddable into any Python app. Use it for powering analytical MCP servers or APIs or simply to query databases semantically.
How SLayer is different
Traditionally, semantic layers were a part of the BI stack, where every metric and its aggregation had to be predefined. Agents need more flexibility because users ask questions that involve metric combinations (like ratios), transforms (like time shifts), or different aggregations of the same metric (like average instead of sum).
SLayer allows to define a column revenue once and query it using expressions like revenue:sum, revenue:avg, revenue:sum / *:count, time_shift(revenue:sum, -1, 'year') etc.; multi-stage queries are also supported.
SLayer is focused on the common agentic search → inspect → query flow. It has a search tool for efficient discovery and a memory store for linking the relevant business context.
Agents, apps and humans can talk to SLayer via MCP, REST API, CLI, Python, Flight SQL, or Postgres-based SQL API. SLayer supports most popular databases.
SLayer fits next to your existing data stack. It also provides importers for dbt, Cube, and Ossie configs.
See docs for more.
Example
Question (run on the built-in demo Jaffle Shop database): "show monthly revenue by store, with month-over-month % change"
Side by side, here's LLM-generated SQL and the equivalent SLayer query.
Related MCP server: Foggy Data MCP Bridge
Quickstart
We recommend using uv, especially if you don't work in a Python project.
uv tool install 'motley-slayer[all]'If slayer isn't found on PATH afterwards, run uv tool update-shell and reopen your terminal.
Using demo dataset
# With the Jaffle Shop demo preloaded (zero-config quickstart)
claude mcp add slayer_demo -- slayer mcp --demoUsing your own data
Set up your datasource, substituting the correct database, username, hostname, and db_name.
slayer datasources create 'postgresql://user:${DB_PASSWORD}@hostname/db_name'The password will be read by SLayer at init time, not saved to disk nor exposed to Claude.
Then add SLayer to Claude Code:
claude mcp add slayer -- slayer mcp --ingest-on-startupNow SLayer MCP will be visible in Claude Code next time you start it. Make sure to launch Claude Code from a shell where DB_PASSWORD is exported — the MCP subprocess inherits its environment from the launching process.
Read more on how to get started with MCP, CLI, REST API, Python in the docs.
License
MIT
Available Tools
21 toolscreate_datasourceA
Create a database connection, verify it, and auto-ingest models. Use ${ENV_VAR} syntax in credentials to reference environment variables.
Args: name: Unique datasource name. type: Database type — postgres, mysql, sqlite, bigquery, or snowflake. host: Database host (default: localhost). port: Database port (e.g. 5432 for Postgres). database: Database name. username: Database username. password: Database password. connection_string: Full connection string as alternative to individual fields. schema_name: Default schema name. Also used as the single schema for auto-ingestion. schemas: Comma-separated schemas to ingest. Mutually exclusive with schema_name / all_schemas. all_schemas: Ingest every non-system schema. Mutually exclusive with schema_name / schemas. auto_ingest: Automatically ingest models from the database schema (default: true). Set to false to skip.
Example: create_datasource(name="mydb", type="postgres", host="localhost", port=5432, database="app", username="user", password="pass")
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | ||
| name | Yes | ||
| port | No | ||
| type | Yes | ||
| schemas | No | ||
| database | No | ||
| password | No | ||
| username | No | ||
| all_schemas | No | ||
| auto_ingest | No | ||
| schema_name | No | ||
| connection_string | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses key side effects: verification of the connection, auto-ingestion of models, environment variable substitution in credentials, and defaults like auto_ingest. It stops short of explaining failure behavior, whether an existing datasource is overwritten, or how connection_string interacts with individual credentials.
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 purpose is front-loaded in the first two sentences, followed by a compact Arg list and a useful invocation example. Every element earns its place: the summary, parameter explanations, constraints, defaults, and example. There is no redundant or filler content.
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?
Given the tool's complexity, the description is nearly complete: all parameters are explained, constraints are noted, and a concrete example is provided. It does not need to explain return values because an output schema exists. Minor gaps remain around credential precedence when connection_string is used alongside individual fields and the exact behavior when auto_ingest is false.
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%, but the description compensates fully by documenting all 12 parameters with additional meaning: supported type values, defaults, an example port, schema mutual exclusivity, and connection_string as an alternative. This goes well beyond the bare input schema and gives an agent what it needs to construct valid arguments.
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 action and resource: 'Create a database connection, verify it, and auto-ingest models.' This clearly distinguishes it from sibling tools like list_datasources, edit_datasource, and ingest_datasource_models. It also lists supported database types, making the tool's scope unambiguous.
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 clearly conveys when to use the tool: when creating a datasource and optionally ingesting models. It also provides parameter-level usage guidance, such as connection_string being an alternative to individual fields and schemas/schema_name/all_schemas being mutually exclusive. However, it does not explicitly name alternative tools or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_modelA
Create a new semantic model, either from a database table or from a query.
From a table (provide sql_table or sql): create_model(name="orders", sql_table="public.orders", data_source="mydb", columns=[...], measures=[...])
From a query (provide query): create_model(name="monthly_summary", query={"source_model": "orders", "measures": ["*:count", "amount:sum"], "time_dimensions": [{"dimension": "created_at", "granularity": "month"}]}) Columns are auto-introspected from the query result.
Args:
name: Unique model name (lowercase, underscores).
sql_table: Database table name, e.g. "public.orders".
sql: Alternative to sql_table — a custom SQL expression for the model's source.
data_source: Name of the datasource (from list_datasources).
description: What this model represents.
columns: List of column definitions. Each: {"name": "col", "sql": "col", "type": "string"}.
Types: string, number, time, date, boolean. Optional fields: primary_key,
unique (single-column uniqueness that is not the PK; primary_key
already implies it), allowed_aggregations (whitelist), filter
(CASE WHEN inside aggregation), label, description, hidden,
meta.
measures: List of named formula definitions on the model. Each:
{"name": "aov", "formula": "revenue:sum / *:count", "label": "...",
"description": "...", "meta": {...}}.
Queries can reference these by bare name (e.g. {"formula": "aov"}).
meta is an optional opaque dict for caller bookkeeping
(e.g. linking the formula back to a source identifier).
query: A SLayer query dict (or list of stage dicts for a multi-stage backing
query). When provided, the query is saved as the model's source_queries
and the model becomes query-backed. Mutually exclusive with sql_table, sql,
columns, and measures.
variables: Default values for {var} placeholders in the backing query.
Saved as query_variables on the model. Only meaningful when query
is provided.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | No | ||
| name | Yes | ||
| query | No | ||
| columns | No | ||
| measures | No | ||
| sql_table | No | ||
| variables | No | ||
| data_source | No | ||
| description | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations to lean on, the description carries the full burden for behavioral disclosure. It explains mutual exclusivity, that query-backed models save source_queries, that columns are auto-introspected from query results, and how variables map to query_variables. It does not detail failure conditions, idempotency, duplicate-name behavior, or permission requirements, but it is substantially transparent for a create operation.
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 long, but the tool's complexity justifies most of the length. It is well-structured with clear mode examples followed by an Args section. Some examples partially duplicate the function signature, but overall the information is organized and front-loaded with the core decision between table-based and query-based creation.
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?
Given the tool's complexity, the absence of annotations, and 0% schema description coverage, the description provides nearly everything needed to invoke the tool correctly: parameter semantics, nested dict schemas, mode selection, mutual exclusivity, auto-introspection behavior, and variable handling. The output schema covers return-value expectations, so the description need not explain them.
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 input schema has 0% description coverage, so the description is the only documentation for all 9 parameters. It comprehensively explains each parameter with examples, nested object structures, allowed types, constraints like uniqueness, and mutual exclusivity rules. This far exceeds what the bare schema provides.
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 the tool's purpose: creating a new semantic model. It also disambiguates from siblings by describing the two supported inputs (table-backed vs query-backed) and explicitly calling them 'new' models, which distinguishes this from edit_model and other sibling tools.
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 clear context on when to use table-based vs query-based creation, and references list_datasources as the source for data_source values. However, it does not explicitly state when not to use this tool versus closely related siblings like edit_model or ingest_datasource_models, so the guidance is strong but not explicit about exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_datasourceB
Delete a datasource configuration.
Args: name: Datasource name to delete.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the deletion action but does not mention whether deletion is irreversible, whether it only removes configuration or also underlying data, whether it cascades to dependent models, or what happens if the datasource name does not exist. For a destructive tool, this is a meaningful gap.
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 short and front-loaded with the core purpose. The Args section is brief but repeats what the schema already structurally conveys. It earns its place by adding parameter context, 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?
For a simple one-parameter tool this is close to minimally viable, but the destructive nature of the operation requires more context. The description does not explain the scope of deletion, reversibility, side effects, or error behavior. Without annotations, an agent cannot fully assess the consequences of invoking this tool.
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 bare 'name' property in the schema. The Args section clarifies that the name is the datasource name to delete, which provides actionable meaning beyond the schema's generic 'Title: Name'. It fully covers the single required parameter.
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: 'Delete a datasource configuration.' This clearly distinguishes it from sibling tools like create_datasource, edit_datasource, and delete_model. The agent knows exactly what action this tool performs.
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, such as edit_datasource or delete_model. There are no explicit conditions, prerequisites, or warnings about when deletion is appropriate. Usage is only implied by the tool's name and one-line description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_modelA
Delete a semantic model.
Args: name: Model name to delete. data_source: Datasource the model belongs to. Required when the same name exists in multiple datasources (otherwise the priority list / single-match rules apply).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| data_source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility for disclosing behavioral traits. It states that a semantic model is deleted, but it does not mention whether deletion is irreversible, whether it cascades to dependent objects, whether permissions are required, or what side effects may occur. This is a significant gap for a destructive operation.
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 purpose is front-loaded in a single clear sentence, and the Args section adds only relevant parameter details. There is no filler or redundant wording; every line supports correct invocation.
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 description covers the tool's purpose and both parameters, and an output schema exists so return-value details need not be explained. However, for a destructive tool with no annotations, the absence of behavioral consequences and the vague priority-list reference leave the description incomplete for an agent that needs to invoke it safely in edge cases.
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, and it does. It explains that `name` identifies the model to delete and that `data_source` serves as a disambiguator when the same name exists in multiple datasources. The reference to priority list / single-match rules adds meaning, though those rules are not fully defined.
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 and resource ('Delete a semantic model'), making it immediately clear what the tool does. It naturally distinguishes this from sibling tools like delete_datasource and create_model/edit_model, so there is no ambiguity about its core 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 provides useful conditional guidance for when `data_source` is required, but it does not explicitly address when to use delete_model versus alternatives such as delete_datasource. The intended usage is implied by the tool name and first sentence rather than backed by clear selection rules.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_datasourceA
Show datasource details: connection status, available schemas, and (by default) the tables in the given or default schema.
Use this after create_datasource to verify the connection and explore what's queryable before calling ingest_datasource_models.
Args:
name: Datasource name (from list_datasources).
list_tables: If True (default), append a list of tables from the
schema named by schema_name (or the dialect's default
schema when empty).
schema_name: Database schema to list tables from (e.g. "public").
Empty uses the dialect default. Ignored when list_tables=False.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| list_tables | No | ||
| schema_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It accurately explains the default behavior (tables are included by default), the logic for list_tables, and the handling of schema_name including the edge case 'Ignored when list_tables=False.' This goes beyond the schema and gives the agent meaningful behavioral expectations.
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 well-structured: a one-sentence summary, a one-sentence usage context, and a concise Args list. Every sentence adds necessary information, and the most important scoping detail (verify before ingest) is front-loaded.
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 describe tool with an output schema, the description covers all needed call context: what it returns at a high level, how to use it in the datasource workflow, and complete parameter semantics. The presence of an output schema lessens the need to document return values in prose, so nothing critical is missing.
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 fully compensate for the bare parameter titles. It does: 'name' is sourced from list_datasources, 'list_tables' is explained with its default and effect, and 'schema_name' gets an example ('public'), its default behavior, and its interaction with list_tables. All three parameters are richly documented.
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 and resource: 'Show datasource details: connection status, available schemas, and (by default) the tables.' It clearly distinguishes this from sibling tools like list_datasources and ingest_datasource_models by framing it as the verification/exploration step between 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?
The description explicitly states when to use the tool: 'Use this after create_datasource to verify the connection and explore what's queryable before calling ingest_datasource_models.' This gives an agent a clear workflow position and eliminates ambiguity about where this tool fits among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_datasourceB
Update a datasource's metadata.
Args: name: Datasource name to update. description: New description for the datasource.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| description | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It only says 'Update' and does not explain what happens when 'description' is omitted (leave unchanged vs clear to null), whether the datasource must already exist, or what side effects occur. This ambiguity is significant because the schema gives 'description' a default of null.
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 short, front-loaded with the purpose, and includes only a compact Args list that adds necessary parameter semantics. There is no filler or redundancy.
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 two-parameter tool with an output schema, the description is mostly adequate. However, it lacks guidance on optional parameter behavior, error cases, and when to prefer this tool over related datasource/model tools, leaving minor but real gaps for an agent deciding 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%, so the description must define the parameters. It does add meaning: 'Datasource name to update' clarifies that 'name' is an identifier, and 'New description for the datasource' clarifies the intended value. It stops short of explaining null/omission semantics, but still compensates for 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?
The description states a specific action ('Update') on a resource ('a datasource's metadata') and the Args section clarifies that 'name' identifies the target while 'description' supplies the new value. It is clear enough to distinguish from create/delete/describe datasource tools, though 'metadata' is somewhat broad.
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: use this when you want to update an existing datasource's metadata. However, there is no explicit when-to-use vs alternatives, no mention of when not to use it, and no comparison to sibling tools like edit_model or delete_datasource.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_modelA
Edit an existing model in a single call — update metadata, upsert columns/measures/aggregations/joins, manage filters, and remove entities.
Args:
model_name: Name of the model to edit.
description: New model description.
data_source: Lookup key — the datasource the model belongs to.
Required when the same name exists in multiple datasources
(otherwise the priority list / single-match rules apply).
new_data_source: Move the model to a different datasource (rare;
renames its storage location). Pass None (default) to
leave the data_source unchanged.
default_time_dimension: Default time dimension (a column of type date/time) for
time-dependent transforms.
sql_table: Database table name. Setting this clears sql and source_queries.
sql: Custom SQL expression for the model source. Setting this clears sql_table and source_queries.
source_queries: Replace the model's backing query with this list of stages.
Each stage is a SlayerQuery dict; non-final stages must have a name.
Setting this clears sql_table and sql, makes the model query-backed,
and refreshes the cached columns and backing_query_sql.
query_variables: Replace the model's default {var} placeholder values for
its backing query. Pass null/None to clear. Only meaningful for
query-backed models.
hidden: Whether this model is hidden from discovery.
meta: Arbitrary JSON metadata for the model (replaces existing meta). Pass null/None to clear.
columns: Columns to create or update (upsert by name). Each dict:
{"name": "col", "type": "string", "sql": "col", "description": "...",
"primary_key": false, "unique": false, "hidden": false,
"allowed_aggregations": ["sum", "avg"],
"filter": "status = 'active'", "label": "..."}.
If a column with this name exists, only the provided fields are updated.
Types: string, number, time, date, boolean.
unique marks single-column uniqueness that is not the primary key
(primary_key already implies it); it is used to infer join
cardinality.
measures: Named formula measures to create or update (upsert by name). Each dict:
{"name": "aov", "formula": "revenue:sum / *:count", "label": "...",
"description": "...", "meta": {...}}.
Queries can reference these by bare name (e.g. {"formula": "aov"}).
meta is an optional opaque dict for caller bookkeeping.
aggregations: Aggregations to create or update (upsert by name). Each dict:
{"name": "weighted_avg", "formula": "SUM({value} * {weight}) / NULLIF(SUM({weight}), 0)",
"params": [{"name": "weight", "sql": "quantity"}], "description": "...",
"meta": {...}}.
meta is an optional opaque dict for caller bookkeeping.
joins: Joins to create or update (upsert by target_model). Each dict:
{"target_model": "customers", "join_pairs": [["customer_id", "id"]],
"cardinality": "many_to_one", "description": "...", "meta": {...}}.
A composite key is one join with several join_pairs entries, not
one join per column. cardinality is the join's arity read
source->target, one of one_to_one / one_to_many /
many_to_one / many_to_many; omit it when undetermined. It is
descriptive metadata only — it changes neither join_type nor
query results.
add_filters: SQL filter strings to add (e.g. ["deleted_at IS NULL"]). Duplicates ignored.
remove_filters: SQL filter strings to remove (exact match).
remove: Named entities to delete, keyed by type:
{"columns": ["col_name"], "measures": ["measure_name"],
"aggregations": ["agg_name"], "joins": ["target_model_name"]}.
Removals are processed before upserts.
Example — update a column and add a named measure: edit_model(model_name="orders", columns=[{"name": "status", "type": "string"}], measures=[{"name": "aov", "formula": "revenue:sum / *:count"}]) Example — remove a measure: edit_model(model_name="orders", remove={"measures": ["old_metric"]})
| Name | Required | Description | Default |
|---|---|---|---|
| sql | No | ||
| meta | No | ||
| joins | No | ||
| hidden | No | ||
| remove | No | ||
| columns | No | ||
| measures | No | ||
| sql_table | No | ||
| model_name | Yes | ||
| add_filters | No | ||
| data_source | No | ||
| description | No | ||
| aggregations | No | ||
| remove_filters | No | ||
| source_queries | No | ||
| new_data_source | No | ||
| query_variables | No | ||
| default_time_dimension | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden — and it does so thoroughly. It explicitly documents side effects: setting sql_table clears sql and source_queries; source_queries refreshes cached columns; new_data_source renames storage location; removals are processed before upserts; cardinality is descriptive only and does not affect join_type or query results. These are exactly the non-obvious behaviors an agent needs to predict outcomes.
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 long, but the tool has 18 complex, interdependent parameters. The summary line is front-loaded, each parameter entry earns its place by explaining semantics and interactions, and the two examples clarify common usage patterns. The structure is logical: summary, parameter details, examples.
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?
Given 18 parameters, no schema descriptions, no annotations, and complex cross-parameter clearing rules, the description provides everything needed to call the tool correctly. It covers all parameters, side effects, valid values, and usage examples. An output schema exists, so explaining return values is unnecessary.
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%, but the description documents every parameter in depth. It provides dict shapes for columns, measures, aggregations, joins, and remove; explains mutual exclusivity and clearing behavior; and gives concrete examples. This far exceeds the bare type/title info in the input 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?
The description opens with a specific verb and resource: 'Edit an existing model in a single call', followed by a precise list of capabilities: update metadata, upsert columns/measures/aggregations/joins, manage filters, and remove entities. The word 'existing' and the mutation-focused operations clearly distinguish it from siblings like create_model, delete_model, and inspect_model.
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 phrase 'Edit an existing model' gives clear context that this tool is for modifying already-created models, not for creating or deleting them. It does not explicitly name alternatives or state 'use create_model for new models', but the usage context is strong enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forget_memoryA
Delete a memory by id.
Cascades: every other memory's memory:<id> reference to
this id is automatically stripped from its entities list.
Args:
id: The memory_id returned by save_memory. Accepts
strings (the canonical form, including user-supplied
"kb.policy"-style ids) as well as legacy ints
(coerced to their decimal string form).
Raises a friendly error if the id is invalid or the memory does not exist.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and it discloses the key side effect (cascading removal of memory:<id> references from entities lists) and the error behavior for invalid or missing ids. It does not discuss reversibility or permissions, but the destructive action and cascade are clearly stated.
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 action, then efficiently explains cascade behavior, parameter formats, and error handling. No sentence is wasted, and the structure is scannable.
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 one-parameter deletion tool with an output schema, the description covers the operation, parameter semantics, side effects, and errors. The only minor gap is that it does not describe the output or return value, but that is already covered by the output schema.
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 0% and the description fully compensates: it defines id as the memory_id returned by save_memory, lists accepted forms (canonical strings including kb.policy-style ids and legacy ints), and explains int coercion. This is more precise than the bare 'Id' property in the 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 action ('Delete a memory by id') with the exact resource and identifier. This clearly distinguishes it from sibling deletion tools like delete_model and delete_datasource because it targets memories.
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 establishes clear context: use this when you have a memory_id from save_memory and need to remove that memory. It does not explicitly name alternatives or exclusions, but the resource distinction plus the save_memory relationship makes the appropriate use obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_datasource_priorityA
Return the configured datasource priority list (most-preferred
first), or [] if none is set.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does reasonably well: it states the return value, the ordering convention, and the empty-list default when unset. It does not explicitly say the operation is read-only, but 'Return' and the absence of side-effect language make that sufficiently clear.
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 wasted words. The core action and resource are front-loaded, and the ordering and default behavior are provided in a compact parenthetical.
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 zero-parameter, getter-style tool with an output schema present, this description is complete. It communicates what is returned, the ordering, and the fallback value, leaving no meaningful ambiguity for an agent invoking the tool.
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 tool takes zero parameters, so the baseline of 4 applies. There are no parameter semantics to document, and the description does not need to compensate for any schema gaps.
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 well-defined resource ('configured datasource priority list'), and clarifies ordering as most-preferred first. It is clearly distinguishable from siblings like list_datasources and set_datasource_priority.
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 tool is used when the agent needs the current datasource priority ordering, but it does not explicitly mention when to prefer this over alternatives or any exclusions. The context is clear enough for a simple getter, but no alternative routing is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ingest_datasource_modelsA
Auto-discover tables in a database and create / additively update semantic models from them.
Idempotent (DEV-1356): re-runs are additive only. New columns and joins
are appended to existing models; existing column / join definitions
are never overwritten. After the additive pass, returns the pending
validate_models deletes alongside the additions.
Args: datasource_name: Name of an existing datasource (from list_datasources). include_tables: Comma-separated list of table names to include. If empty, all tables are ingested. schema_name: A single database schema to inspect (e.g. "public"). Empty uses the default schema. schemas: Comma-separated schemas to inspect. Mutually exclusive with schema_name / all_schemas. all_schemas: Ingest every non-system schema. Mutually exclusive with schema_name / schemas.
| Name | Required | Description | Default |
|---|---|---|---|
| schemas | No | ||
| all_schemas | No | ||
| schema_name | No | ||
| include_tables | No | ||
| datasource_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It clearly states idempotence, that re-runs are additive only, that existing definitions are never overwritten, and that the result includes pending validate_models deletes. This is substantial transparency for a mutating tool, though it does not cover failure modes or permissions.
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 the crucial idempotence guarantee, followed by the necessary parameter documentation. The wording around 'pending validate_models deletes' is slightly awkward, but every sentence earns its place given the lack of schema descriptions.
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 five parameters, mutual exclusions, and a mutating/additive behavior, the description provides enough context to invoke it correctly: source datasource, table filtering, schema selection, and the additive result. It does not explain return structure in detail, but an output schema exists and the behavioral guarantee is clear.
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 with parameter details. The Args section explains each parameter, gives examples, defines empty-string behavior, and documents mutual exclusivity among schema_name, schemas, and all_schemas. This fully compensates for the missing schema descriptions.
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 action ('Auto-discover tables in a database') and a clear outcome ('create / additively update semantic models'). It clearly differentiates from sibling tools like create_model and edit_model by focusing on automatic discovery rather than manual construction.
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 clear context: it operates on an existing datasource from list_datasources and is additive/idempotent, so it is safe to re-run. It does not explicitly enumerate when to choose this over create_model/edit_model, but the auto-discovery language makes the intended use case clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspectA
Inspect EXACTLY one entity by reference and kind, a homogeneous
BATCH when reference is a list — or the whole COLLECTION at a kind
when reference is omitted / None.
A clean point-lookup: no fusion / ranking / cypher, and no bundled
memories. Use search instead when you want an entity surfaced in
context (with related memories and ranked neighbours).
Collection (DEV-1667): omit reference (or pass None / [])
to list a whole kind. entity_type="model" lists all models grouped
by datasource (compact=True: one terse line per model; compact=False:
the full per-model tables). entity_type="datasource" lists all
datasources. Only model / datasource support the collection
view; other kinds raise. This subsumes models_summary /
list_datasources.
Batch (DEV-1612): pass a list of references that all share the one
entity_type. Returns one rendered block per id, in input order,
each echoing its resolved canonical id (a ## <canonical> header in
markdown; a JSON array under format="json"). Per-id resolution
errors are isolated — one bad id does not sink the batch (in JSON it
becomes a {"reference": ..., "error": ...} element). A single
str keeps its byte-for-byte single output; a one-element list is
still batch-framed.
Args:
reference: The entity reference, or a list of references (batch).
Accepts canonical forms (mydb, mydb.orders,
mydb.orders.amount), bare names, join paths
(orders.customers.region → resolved to the owning model),
and memory:<id> for memories. Normalised via the shared
resolver; the normalised canonical id is echoed in the JSON
shape.
entity_type: REQUIRED. One of datasource, model,
column, measure, aggregation, memory.
Disambiguates the 3-part canonical collision (a name
shared by, e.g., a column and an aggregation) and asserts
the resolved kind — a mismatch returns a detailed error.
compact: When true (default): description-only for
column/measure/aggregation/datasource/memory; for
entity_type="model" a cheap schema skeleton (column /
measure / aggregation names + join targets, zero DB calls).
False returns the full render (and, for the datasource kind,
a per-model skeleton for each visible model).
format: "markdown" (default) or "json".
num_rows: Sample-data rows for entity_type="model". Ignored
(with a warning) for other kinds.
show_sql: Include generated SQL for entity_type="model".
Ignored (with a warning) for datasource/memory; a silent
no-op for column/measure/aggregation.
sections: Section subset for entity_type="model". Ignored
(with a warning) for other kinds.
descriptions_max_chars: Truncate description fields to this many
characters. Applies to every kind.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | markdown | |
| compact | No | ||
| num_rows | No | ||
| sections | No | ||
| show_sql | No | ||
| reference | No | ||
| entity_type | Yes | ||
| descriptions_max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and meets it thoroughly. It discloses that the tool is a clean point-lookup with no fusion/ranking/cypher or bundled memories, explains batch error isolation ('one bad id does not sink the batch'), and details per-parameter behavior such as warnings vs silent no-ops and compact rendering differences. This is far beyond what the input schema alone would convey.
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 long but highly structured and front-loaded: core semantics first, then Collection and Batch mode specifics, then a well-organized Args section. Each sentence adds unique information and there is no filler or tautology. The length is justified by the tool's multiple modes and eight 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?
Given the absence of annotations and the presence of only minimal structural schema, the description is remarkably complete. It covers all three invocation modes, output framing in markdown and JSON, error handling in batches, collection-view restrictions, per-parameter conditional behavior, and relationships to sibling tools. An agent has everything needed to invoke the tool 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 compensate, and it does. Every parameter receives meaningful explanation: reference formats including canonical forms, bare names, join paths, and memory:<id>; the required entity_type and its disambiguation role; compact behavior per kind; format options; num_rows/show_sql/sections being ignored with warnings for non-model entity types; and descriptions_max_chars applying to every kind. This is exemplary 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 opens with a precise statement of what the tool does: 'Inspect EXACTLY one entity by reference and kind, a homogeneous BATCH when reference is a list — or the whole COLLECTION at a kind when reference is omitted / None.' It also distinguishes itself from search and notes that it subsumes models_summary and list_datasources. This leaves no ambiguity about the tool's purpose.
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 explicitly routes agents to search when they need contextual results and states that the collection view raises for unsupported kinds. It also names models_summary and list_datasources as subsumed by this tool. However, it does not mention the closely named sibling inspect_model or describe_datasource, leaving some uncertainty about when those should be chosen instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_modelA
DEPRECATED: use the inspect tool. Return a complete-yet-compact view of a semantic model.
Always emitted (regardless of sections): model header + description,
metadata bullets (data_source, sql_table, default_time_dimension,
hidden, row_count), backing-query structure for query-backed models,
and — when show_sql=True — the custom SQL block, model-level
filters, and the cached backing-query SQL.
Section-gated parts (subset selectable via sections):
columns— unified row-level columns table with asampledcolumn (distinct values for string/boolean,min .. maxfor number/date/time, ortop20 ... (N distinct)for high- cardinality categoricals).measures— named-formula library.aggregations— custom aggregation definitions. Theformulacolumn and thesqlfield of eachparams[]entry are gated byshow_sql.joins— join definitions.samples— live sample-data query (COUNT(*)plus one aggregation per column).learnings— learning-only memories whose canonical entities reference this model.
When a section is omitted from sections: columns, measures,
aggregations and joins collapse to a one-line backticked CSV
of names; samples and learnings are dropped entirely.
A footer at the end of the response lists what was trimmed and how
to fetch more.
Args:
model_name: Name of the model to inspect.
num_rows: Max sample-data rows (default: 3).
show_sql: When true, include the generated SQL for the sample-data
query, the custom SQL block, model-level filters, the cached
backing-query SQL, and aggregation formulas/param SQL.
format: Output format — "markdown" (default) or "json".
Case-insensitive.
sections: Subset of ["columns", "measures", "aggregations", "joins", "samples", "learnings"]. Default (None
or empty list) renders all six. Unknown names are ignored
with a warning line at the end of the response. A non-empty
list of only unknown names resolves to no sections (not
all six) — "all sections" is reserved for None/[] so
a typo can't silently trigger the full expensive payload.
descriptions_max_chars: When set, every description field (model,
column, measure, aggregation) longer than this is truncated
with a ... [truncated] suffix. Must be >= 0. None
(default) means no truncation.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | markdown | |
| compact | No | ||
| num_rows | No | ||
| sections | No | ||
| show_sql | No | ||
| model_name | Yes | ||
| data_source | No | ||
| descriptions_max_chars | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden and does so thoroughly. It details always-emitted content, section-gated behavior, collapse behavior for omitted sections, the footer, unknown-section handling, SQL gating via `show_sql`, and truncation semantics. This gives the agent strong awareness of response shape and edge-case 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?
The description is long but tightly structured and front-loaded with the deprecation warning and core purpose. Every major behavior is organized under clear headers, defaults and edge cases are explicit, and there is no filler or vague wording.
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 an 8-parameter introspection tool with no annotations and an output schema, the description is unusually complete: it explains output composition, section subsetting, collapse behavior, SQL inclusion, format, and truncation. The only real gap is the undocumented `compact` and `data_source` parameters, which prevents a perfect score.
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 raw schema has no parameter descriptions, so the description compensates substantially for `model_name`, `num_rows`, `show_sql`, `format`, `sections`, and `descriptions_max_chars`, including a nuanced explanation of unknown `sections` values. However, `compact` and `data_source` are absent from the Args section, leaving their semantics to inference from titles and context.
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 resource ('semantic model') and defines the output as a 'complete-yet-compact view.' It also explicitly distinguishes itself from the sibling `inspect` tool by flagging DEPRECATED and directing the agent to use `inspect` instead, leaving no ambiguity about what this tool does.
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 is explicit about usage: it begins with 'DEPRECATED: use the inspect tool,' naming the alternative and telling the agent when not to choose this tool. It also gives clear guidance on section selection, defaults, and edge cases, so an agent knows exactly how to request the desired subset of output.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_datasourcesA
List all configured database connections (names and types only, credentials are not shown). Use describe_datasource for connection details and status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior. It states that credentials are not shown, which is an important privacy/security behavior beyond the basic 'list' semantics. The read-only nature is implied by 'List' but not explicitly stated; a small gap, but the redaction disclosure adds meaningful transparency.
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 concise sentences with no filler. The main purpose is front-loaded, and the second sentence adds routing guidance. 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 parameterless list tool with an output schema present, the description fully covers what the agent needs to decide whether to call it and what to expect. It also gives a pointer to the appropriate sibling for more detail, making the context 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?
The tool has zero parameters, so there is no parameter documentation needed. The description focuses on the output content instead, clarifying that only names and types are returned, which is the relevant semantic information for an agent.
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 the action ('List all configured database connections') and the scope of the result ('names and types only'), immediately distinguishing it from connection detail operations. It also explicitly differentiates from describe_datasource.
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 explicitly tells the agent when to use this tool versus an alternative: use describe_datasource for connection details and status. This is clear, direct routing guidance with no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
models_summaryA
Brief summary of all (non-hidden) models in a datasource.
DEV-1549: compact-by-default rendering. Under compact=True
each model section emits its name, description, the column count
(Columns: N), the comma-separated measure NAMES
(Measures: a, b, c) and the Joins to: list — no
per-column table, no per-measure formula block. Pass
compact=False to restore the verbose markdown / JSON shape
with full column and measure payloads.
Args: datasource_name: Name of the datasource (from list_datasources). format: Output format — "markdown" (default, compact and LLM-friendly) or "json" (structured array of model summaries). Case-insensitive. compact: Default True — drop per-column / per-measure detail. Set False to surface the full per-model tables.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | markdown | |
| compact | No | ||
| datasource_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well by detailing exactly what compact=True emits (name, description, column count, measure names, joins list) and what it omits. It also discloses the default behavior and the compact=False alternative. It doesn't discuss errors or side effects, but none are expected for a read-only summary tool.
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 well-structured with a clear opening sentence followed by rendering details and an Args list. The DEV-1549 ticket reference is noise for an AI agent, but all other sentences earn their place by clarifying output behavior and parameter choices.
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 description fully covers the parameters and output rendering modes, and an output schema exists to define the structured return shape. It could improve by naming sibling alternatives or noting datasource-not-found behavior, but for a summary tool with this complexity it is largely 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 0%, so the description must compensate, and it does. Each parameter is explained in the Args section: datasource_name references list_datasources, format names valid values and case-insensitivity, and compact explains default and behavioral impact. This adds substantial meaning beyond the bare input 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?
The description clearly identifies the tool's purpose: 'Brief summary of all (non-hidden) models in a datasource.' It specifies the resource scope (all non-hidden models) and gives a distinct action, though it doesn't explicitly contrast with siblings like inspect_model or describe_datasource.
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 clear context for when the tool would be useful—summarizing all models in a datasource—but it never explicitly states when to prefer this over siblings such as inspect_model or describe_datasource. It does explain usage for compact versus verbose output and format selection, but tool-alternative guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
queryA
Query data from a semantic model. Call inspect(reference=".", entity_type="model") first to see available columns and measures.
Args:
source_model: One of three forms:
- Model name (string) — name of a saved model from models_summary, e.g. "orders".
- Inline ModelExtension (dict) — extend an existing model with extra columns/joins/measures
for this one query: {"source_name": "orders", "columns": [{"name": "double_amount", "sql": "amount * 2", "type": "DOUBLE"}]}.
- Inline SlayerModel (dict) — define a model ad-hoc:
{"name": "ad_hoc", "sql_table": "things", "data_source": "test", "columns": [...]}.
measures: Aggregated values to return. Each is a formula: {"formula": "*:count"},
{"formula": "revenue:sum / *:count", "name": "aov"} (arithmetic),
{"formula": "cumsum(revenue:sum)"} (cumulative sum),
{"formula": "change(revenue:sum)"} (period-over-period difference),
{"formula": "change_pct(revenue:sum)"} (period-over-period % change, e.g. month-over-month growth),
{"formula": "time_shift(revenue:sum, -1)"} (the shifted value itself, one time bucket back),
{"formula": "time_shift(revenue:sum, -1, 'year')"} (value from one year earlier, for custom arithmetic),
{"formula": "lag(revenue:sum, 1)"} (previous row via window function; shifts by row position, NULL at edges),
{"formula": "lead(revenue:sum, 1)"} (next row via window function), {"formula": "last(revenue:sum)"} (most recent),
{"formula": "rank(revenue:sum)"} (ranking). A bare name like {"formula": "aov"} resolves to a saved ModelMeasure on the model.
change / change_pct / time_shift are calendar-aware and partition-safe: change and change_pct compare
each row against the prior time bucket (one step back at the query's own granularity), while time_shift
compares at its explicitly requested offset and granularity. All three join on the same non-time
dimension values, so per-group series reset cleanly — safe for grouped queries like month-over-month
revenue by store.
For period-over-period growth, prefer change_pct (or change for the absolute delta); use time_shift
only when you need the shifted value itself as a term in your own arithmetic.
dimensions: List of dimension names to group by, e.g. ["status", "region"].
filters: Filter conditions as formula strings. Examples: "status == 'completed'",
"amount > 100", "status in ('a', 'b')", "status is None",
"name like '%acme%'". Filters on measures are automatically routed to HAVING.
Supports and/or: "status == 'a' or status == 'b'".
Filters can also reference computed measure names or contain inline transforms:
"change(revenue:sum) > 0", "last(change(revenue:sum)) < 0".
time_dimensions: Time grouping. Format: {"dimension": "created_at", "granularity": "day|week|month|quarter|year", "date_range": ["2024-01-01", "2024-12-31"]}.
order: Sorting. Format: {"column": "measure_or_dim_name", "direction": "asc|desc"}.
limit: Max rows to return.
offset: Number of rows to skip.
whole_periods_only: When true, snap date filters to time bucket boundaries based on granularity, exclude the current incomplete time bucket.
show_sql: When true, include the generated SQL in the response for debugging.
strict: Error instead of warn when a cross-model measure would broadcast or a producer filter would be dropped. Rejected with run-by-name execution — declare it on the stored query instead.
dry_run: When true, generate and return the SQL without executing it.
explain: When true, run EXPLAIN ANALYZE and return the query plan.
format: Output format — "markdown" (default, compact and LLM-friendly), "json" (structured), or "csv" (most compact). Case-insensitive.
distinct_dimension_values: Default True (Cube.js-style auto-dedup for dim-only queries — emits GROUP BY ). Set False to emit raw rows: no top-level GROUP BY, just SELECT <dimensions/time_dimensions> with the usual WHERE/ORDER BY/LIMIT. Any measure reference (in measures, filters, or order) raises an error in this mode.
Example: query(source_model="orders", measures=[{"formula": "*:count"}], dimensions=["status"], filters=["status == 'completed'"])
Before calling this tool, run search first, supplying the entities you're thinking of using (and/or the query itself via the query arg, or a free-text question). Read the returned memories and consider any matching example queries before formulating the final query.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| order | No | ||
| format | No | markdown | |
| offset | No | ||
| strict | No | ||
| dry_run | No | ||
| explain | No | ||
| filters | No | ||
| measures | No | ||
| show_sql | No | ||
| variables | No | ||
| dimensions | No | ||
| source_model | Yes | ||
| time_dimensions | No | ||
| whole_periods_only | No | ||
| distinct_dimension_values | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers richly: filters on measures are "automatically routed to HAVING," change/change_pct/time_shift are disclosed as calendar-aware and partition-safe with clean per-group resets, lag/lead are described as window functions with "NULL at edges," strict mode's error/drop behaviors and run-by-name rejection are stated, distinct_dimension_values' auto-dedup GROUP BY behavior and error-on-measure-reference are detailed, and dry_run/explain/show_sql modes are all explained.
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 long (~600 words), but the length is justified by 16 parameters and a complex formula grammar. It is well-structured with a front-loaded purpose sentence, per-parameter 'Args' sections, and a worked example. The 'run search first' precondition is buried at the end rather than near the front, which costs it a perfect score.
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 16-parameter tool with no annotations and zero schema descriptions, the description is remarkably complete: preconditions, parameter semantics, formula grammar, edge cases, error modes, and output format options are all covered, and the output schema covers return values. Minor gaps are the undocumented `variables` parameter and the unaddressed relationship to query_nested.
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 — and it nearly does. It explains all three source_model forms with inline dict examples, enumerates measure formula functions with concrete examples, defines filter syntax and HAVING routing, specifies time_dimensions format, and adds meaning to order, whole_periods_only, strict, format, and distinct_dimension_values. Only the `variables` parameter receives no descriptive coverage.
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 first sentence, "Query data from a semantic model," states a specific verb plus resource, and the detailed parameter documentation (three source_model forms, measure formulas, filters, time dimensions) makes the operation unambiguous. It is clearly distinguishable from the introspection siblings (inspect, inspect_model, models_summary) and DDL siblings (create_model, edit_model).
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?
Explicit orchestration guidance is given: "Call inspect(reference="<ds>.<model>", entity_type="model") first" and "Before calling this tool, run search first... Read the returned memories and consider any matching example queries." However, it never names alternatives or exclusions — notably, it does not say when to use the sibling query_nested instead, so the when-not dimension is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_nestedA
Run a multi-stage query as a DAG. Use this when one stage depends on the output of another.
queries is a list of query dicts forming a DAG. Each entry has the
same shape as the regular query tool's arguments
(source_model, measures, dimensions, filters,
time_dimensions, order, limit, offset,
whole_periods_only) plus an optional name. Stages reference
each other by name via source_model: "<sibling_name>" or
joins.target_model.
Order doesn't matter — the engine auto-sorts so every stage
appears after the siblings it references. The last entry of
the input is always the entry point / DAG root (its result is
what's returned); only the non-final entries are reordered.
Every non-final entry must have a name. Cycles,
self-references, and a non-final stage referencing the root are
rejected with a clear error. Stages that aren't reachable from
the root are accepted as utility sub-queries — they're silently
dropped from the emitted SQL.
Args:
queries: Ordered list of stage dicts. Earlier stages must be
named; the last stage is the one whose rows return.
variables: Variable values for {var} placeholder
substitution in filters. Runtime kwarg precedence:
runtime > stage.variables > outer query.variables > model.query_variables.
show_sql: When true, include the generated SQL in the response.
dry_run: When true, generate the SQL without executing it.
explain: When true, run EXPLAIN ANALYZE and return the plan.
format: markdown (default), json, or csv.
Example: queries=[ {"name": "monthly", "source_model": "orders", "measures": [{"formula": ":count"}, {"formula": "revenue:sum"}], "time_dimensions": [{"dimension": "created_at", "granularity": "month"}]}, {"source_model": "monthly", "measures": [{"formula": ":count"}]} ]
For a single-stage query, prefer the regular query tool — its
typed arguments give a more discoverable schema.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | markdown | |
| dry_run | No | ||
| explain | No | ||
| queries | Yes | ||
| show_sql | No | ||
| variables | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavioral burden. It discloses engine auto-sorting, the last entry being the DAG root, required names for non-final stages, rejection of cycles/self-references/root references, silent dropping of unreachable stages, variable precedence, and the effects of `show_sql`, `dry_run`, and `explain`.
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 long but appropriately so for a complex DAG-based tool. It is front-loaded with the core purpose, then structured into semantics, arguments, an example, and an alternative-tool recommendation. Every section adds useful information without fluff.
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 description is complete for a tool of this complexity: it covers DAG semantics, ordering, naming rules, error cases, variable precedence, flags, formats, and includes an end-to-end example. An output schema exists, so detailed return-value documentation is not required from the description.
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, and it does. Each parameter is explained, including defaults, placeholder substitution, precedence, and format options. It also explains that each query dict follows the same shape as the regular `query` tool's arguments and provides a concrete example.
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 line clearly states the tool's function: 'Run a multi-stage query as a DAG.' It also states the exact use case—when one stage depends on another—which distinguishes it from the sibling `query` tool for single-stage queries.
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 explicitly says when to use this tool: 'Use this when one stage depends on the output of another.' It also gives an explicit alternative and exclusion: 'For a single-stage query, prefer the regular query tool—its typed arguments give a more discoverable schema.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recommend_root_modelA
Recommend the root model (query source_model) for a set of
model.column / model.metric items, and give each item's
join-qualified reference path from that root.
Introspects the join graph and picks the model from which every
requested item is reachable (LEFT joins are directional; INNER
joins traverse both ways), minimizing total join hops. The returned
paths are ready to drop into a query whose source_model is the
recommended root — e.g. a joined column comes back as
customers.regions.name and a root-owned one as status;
aggregation suffixes (:sum) are preserved.
When no single model reaches everything, root_model is null and
coverage lists the best partial roots so you can split the
request into a multi-stage query.
Args:
items: entity references (orders.revenue, customers.name,
orders.revenue:sum, bare aov for a saved metric...).
data_source: optional datasource scope; when omitted, names
resolve via the datasource-priority list. All items must
resolve to a single datasource.
root_hint: optional intended root — a bare model name or
<data_source>.<model> within the resolved datasource.
Honored when it reaches every item (overriding the min-hops
pick, so you can force a bridge model that owns none of the
items); otherwise the auto-pick is used and a warning
explains why. Resolved after the datasource is determined,
so it cannot pick the datasource.
format: "markdown" (default) or "json".
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | ||
| format | No | markdown | |
| root_hint | No | ||
| data_source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries full responsibility, and it delivers: it discloses join directionality rules, the min-hop objective, root_hint override semantics, and failure behavior. It also exposes the important constraint that root_hint cannot select a datasource.
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 long, but it is organized into purpose, algorithm, edge-case, and Args sections with no filler. The essential 'what it returns' and failure mode are front-loaded.
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?
Despite no annotations and an output schema that isn't shown, every decision-relevant behavior is covered: output examples, multi-stage fallback, and constraints on arguments. An agent has enough to call it correctly and interpret results.
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%, but the Args block documents all four parameters with concrete examples and nuances: item syntax variants, datasource resolution, root_hint precedence, and format defaults. This fully compensates for the empty schema descriptions.
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 ('Recommend') and resource ('root model'), and states the second output ('join-qualified reference path'). This clearly distinguishes it from query/query_nested siblings, which execute queries rather than recommend a source_model.
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 context: use when you need a source_model for a set of items, and it explains edge behavior like null root_model with coverage for partial roots and root_hint override. It does not explicitly name sibling alternatives or state when not to use it, but the intended use is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_memoryA
Save an agent memory: a free-form note plus the SLayer entities it concerns.
linked_entities accepts either:
a list of entity reference strings — each item is resolved to the canonical
<datasource>.<model>[.<leaf>]form. Bare names use the datasource priority list; ambiguous bare-column matches are rejected.memory:<id>is also valid here (cross-memory references; the target memory must exist).a
SlayerQuery(dict) — entities are auto-extracted fromsource_model,dimensions,time_dimensions,measures, andfilters; resolution warnings are non-fatal. The query itself is stored alongside the learning, so the memory surfaces insearch'sexample_querieslist (vs thememorieslist for entity-list memories).
DEV-1428: id is an optional canonical memory id. Omit to
auto-allocate a monotonic int-shaped id ("1", "2", ...);
supply a string for a stable user-controlled id
("kb.policy.42"). Charset excludes :, /, ?,
#, whitespace. Duplicate id → unconditional upsert,
created_at preserved.
Returns the assigned memory_id (string), the canonical
entities stored, and any non-fatal warnings.
Cascade-on-delete: when a model / datasource / measure is
deleted, every memory:<id> and <ds>.<model>[.<leaf>]
reference under it is automatically stripped from every other
memory's entities list. Memories with zero entities after
the strip are kept (the learning text stands alone).
Search is lenient: stale entity tags in saved memories are filtered out at retrieval time rather than raising.
Args:
learning: The note text. Required, non-empty.
linked_entities: List of entity strings, or an inline
SlayerQuery payload.
id: Optional canonical memory id (see above).
Examples: save_memory( learning="orders.is_returned in {0,1,NULL}; treat NULL as not returned", linked_entities=["orders.is_returned"], )
save_memory(
learning="Paid revenue by status",
linked_entities={
"source_model": "orders",
"measures": [{"formula": "amount:sum"}],
"filters": ["status = 'paid'"],
},
id="kb.paid-revenue",
)
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| learning | Yes | ||
| description | No | ||
| linked_entities | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden—and it does so thoroughly. It discloses id auto-allocation and upsert semantics, charset restrictions, cascade-on-delete stripping of entity references, preservation of zero-entity memories, lenient stale-tag filtering at retrieval time, and the exact return payload. This is far beyond what a naive 'save' description would provide.
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 long, but the length is justified by the polymorphic input and complex side effects. It is front-loaded with a clear purpose, then structured into short labeled sections and examples. Nearly every sentence carries distinct behavioral or semantic information needed for correct invocation.
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 description is nearly complete for a tool of this complexity: return values, id behavior, search integration, cascade deletion, and examples are all covered. The main omission is the `description` parameter, and there is no explicit pointer to `forget_memory` for cleanup, though the sibling list makes that relation inferable.
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 richly explains `learning`, both forms of `linked_entities` (string list and SlayerQuery) with resolution rules, and `id` with allocation and upsert behavior. The one clear gap is the optional `description` property present in the schema but never mentioned in the description, leaving its semantics 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?
The description opens with a precise verb-resource pair: 'Save an agent memory' and immediately defines what a memory consists of (free-form note plus SLayer entities). It also differentiates the two memory forms by how they surface in search, which helps an agent distinguish this tool from read/search and forget siblings.
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 text gives strong contextual guidance: it explains cross-memory references, query-auto-extraction, and how memories appear in `search`'s `example_queries` vs `memories` lists. However, it never explicitly states when not to use this tool or names alternatives like `forget_memory` for deletion, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
Up to three-channel semantic search over memories + canonical entities.
Call this BEFORE query to surface any notes or example
queries previously saved against the entities you're
considering.
Channel 1 (entity-overlap BM25 over memories): runs when
entities and/or query is supplied. Memories whose
canonical entity tags overlap the resolved input are ranked.
Channel 2 (tantivy full-text over memories ∪ entities): runs
when question is supplied. The in-memory index covers every
memory + every searchable entity (datasource / non-hidden model /
non-hidden column / named measure / aggregation).
Channel 3 (dense embedding similarity, optional): runs when
question is supplied AND the advanced_search extra is
installed AND a provider API key is configured for the active
embedding model. Cosine similarity between the question
embedding and persisted entity/memory embeddings. Skipped with
a single warning into SearchResponse.warnings when any
precondition fails — tantivy + BM25 continue to work.
All hits (memories, example queries, entities) are fused via
Reciprocal Rank Fusion (k=60) into a single ranked
results list capped at max_results.
Empty input (no entities, no query, no question) returns the
newest memories capped at max_results, with a warning.
Args:
entities: Canonical entity reference strings.
query: Optional SlayerQuery (dict). Entities are
auto-extracted to broaden channel-1 input.
question: Free-text query for the tantivy full-text channel.
datasource: Optional datasource name. When set, scope all
three channels to that one datasource. Entity hits are
limited to docs rooted at the datasource (exact match
or dotted-path descendant). Memories surface when any
of their tagged entities is rooted at the datasource —
a memory spanning multiple datasources surfaces from
each. BM25 / IDF stats reflect only the filtered subset.
Unknown datasource raises ValueError.
max_results: Maximum total number of hits to return (default 10).
cypher_filter: Optional openCypher MATCH query returning
… AS id that pre-filters all three channels to the
returned canonical IDs. When advanced_search is not
installed, only simple
MATCH (n:Label1:Label2) RETURN n.id AS id patterns are
supported as a kind filter (multi-label uses union
semantics; allowed labels: Memory, Datasource, Model,
Column, Measure, Aggregation).
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| compact | No | ||
| entities | No | ||
| question | No | ||
| datasource | No | ||
| max_results | No | ||
| cypher_filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full transparency burden, and it excels: it discloses channel preconditions, advanced_search/API-key fallback behavior, Reciprocal Rank Fusion, max_results capping, datasource scoping rules, ValueError conditions, cypher_filter restrictions, and warning emission. This level of behavioral disclosure is unusually complete.
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 long but well-structured: a front-loaded purpose, a bolded usage directive, numbered channel explanations, fusion/empty-input behavior, and an Args list. Each segment maps to a decision the agent must make or a behavior it should know. It is dense yet not padded.
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 complex tool with no annotations and a bare input schema, this description covers the essential surface: optional channels, installation/API-key prerequisites, datasource scoping, unknown-datasource errors, and cypher_filter limitations. Since an output schema exists, omitting detailed return-shape documentation is acceptable. The only minor gap is the undocumented `compact` parameter, already penalized under parameter semantics.
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 Args section is essential, and it adds real meaning to entities, query, question, datasource, max_results, and cypher_filter. However, the `compact` boolean parameter is never mentioned in the description, leaving its effect undocumented. The description compensates strongly for the bare schema but does not fully cover every parameter.
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 sentence names a specific operation: three-channel semantic search over memories and canonical entities. The description further enumerates the channels, fusion method, and result capping, and distinguishes the tool from the `query` sibling with the instruction to call it before `query`. This is far more specific than a generic verb-plus-resource statement.
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 explicitly says 'Call this BEFORE `query`' and explains the exact input conditions under which each channel runs. It also documents empty-input behavior so an agent knows this tool still returns newest memories when no search terms are provided. This gives clear guidance on when to use the tool without requiring inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_datasource_priorityA
Configure how SLayer disambiguates bare model names that exist in multiple datasources.
When two datasources both define a model named users, calling
edit_model("users") (no data_source=) is ambiguous. SLayer
walks this priority list and picks the first datasource that has
the requested name. If none of the candidates appear in the list,
an AmbiguousModelError is raised.
Args:
priority: Datasource names, most-preferred first. Each entry
must already exist (run list_datasources first). Pass
an empty list to clear the priority.
| Name | Required | Description | Default |
|---|---|---|---|
| priority | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral disclosure and does so well: it explains the priority-list walk, first-match selection, AmbiguousModelError when no candidate matches, and empty-list clearing 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?
The description is front-loaded with the core purpose, then uses a concrete ambiguous-model example to make the behavior intuitive. Every part—purpose, example, resolution rules, parameter semantics—earns its place without redundancy.
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 one-parameter configuration tool, the description covers the scenario, prerequisites, error behavior, and clearing semantics. The output schema can handle return details, and no critical information is missing.
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 schema only specifies 'priority' as an array of strings, so the description is essential. It adds ordering semantics (most-preferred first), the requirement that names already exist, and the empty-list clearing 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?
States a specific verb and resource: 'Configure how SLayer disambiguates bare model names.' The description clearly distinguishes this from sibling tools like get_datasource_priority and list_datasources by focusing on the configuration/set behavior.
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?
Provides clear context for when this tool is needed—when bare model names exist in multiple datasources—and gives an actionable prerequisite (run list_datasources first). It does not explicitly contrast with get_datasource_priority, but the read/write pairing is implied by the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_modelsA
Diff persisted SLayer models against the live database schema(s).
Returns a JSON-serialized list of pending delete operations (column drops, measure drops, join drops, filter removals, whole models) needed to keep stored models valid against the current live state. Read-only — does not modify storage.
Args: data_source: Datasource name to validate. When omitted, every datasource is validated concurrently and results are concatenated.
| Name | Required | Description | Default |
|---|---|---|---|
| data_source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it explicitly states 'Read-only — does not modify storage', describes what the returned list contains, and discloses the behavior when data_source is omitted (validates all datasources concurrently and concatenates results).
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, followed by return behavior, safety note, and parameter semantics. Every sentence earns its place; no filler or repetition.
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 one optional parameter and an output schema, the description is complete: it explains the input, the output shape, the no-modification guarantee, and the default all-datasources behavior. Nothing needed to call it correctly is missing.
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 fully explains the single parameter: 'Datasource name to validate', including the omission behavior and result concatenation. This adds meaning well beyond the raw 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 and resource: 'Diff persisted SLayer models against the live database schema(s)'. It also clarifies the concrete output—a JSON list of pending delete operations—which distinguishes it from siblings like query, inspect_model, and delete_model.
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 clear context for when to use the tool: to validate persisted models against live schemas and preview required deletions. It does not explicitly name alternative tools or exclusions, but the purpose is specific enough that an agent can select it appropriately among the sibling tools.
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. Dates show when Glama detected each change.
21 tool updates
v0.10.0- First observed
create_datasource - First observed
create_model - First observed
delete_datasource - First observed
delete_model - First observed
describe_datasource - First observed
edit_datasource - First observed
edit_model - First observed
forget_memory - First observed
get_datasource_priority - First observed
ingest_datasource_models - First observed
inspect - First observed
inspect_model - First observed
list_datasources - First observed
models_summary - First observed
query - First observed
query_nested - First observed
recommend_root_model - First observed
save_memory - First observed
search - First observed
set_datasource_priority - First observed
validate_models
TDQS
Most tools target distinct resources/actions, but the inspection surface overlaps: inspect, inspect_model, and models_summary all expose model metadata, with inspect_model explicitly deprecated and inspect subsuming models_summary/list_datasources. Descriptions do help disambiguate, but the redundancy still creates avoidable misselection risk.
The set is predominantly verb_noun (create_model, edit_model, delete_datasource, query_nested, recommend_root_model), with consistent CRUD families. Minor deviations like models_summary (instead of list_models/summarize_models) and the deprecated inspect_model alongside inspect keep it from a perfect score.
21 tools puts this in the heavy range, and several are redundant: inspect_model is deprecated, and models_summary and list_datasources are subsumed by inspect. The count is not unreasonable for a semantic-layer server covering querying, model management, datasource management, and memory/search, but trimming the overlapping tools would tighten it.
The surface covers the domain well: datasource lifecycle (create/list/describe/edit/delete/ingest/validate), model CRUD plus validation and root-model recommendation, single and multi-stage querying, and memory save/forget/search. Minor gaps like not being able to update datasource connection details are workarounds rather than dead ends.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.
- busabaseOAuthcom.busabase
Database for your AI agent. Turn its output into data, docs, skills, and apps you can actually use.
Verified, sourced, real-time intelligence layer for AI agents.
Your company's brain for AI agents. Cited, permission-aware knowledge across every system.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceSecurely connects AI agents to multiple databases simultaneously while enabling collaborative learning from team query patterns, all while keeping data private by running locally.25871MIT
- AlicenseNot gradedqualityDmaintenanceA semantic layer query engine with MCP support, enabling AI assistants to query structured data through natural language and declarative interfaces.2Apache 2.0

EnrichMCPofficial
AlicenseNot gradedqualityDmaintenanceTurns your data model into a semantic layer for AI agents, automatically generating typed, discoverable tools with entity relationships and schema discovery.644Apache 2.0- AlicenseNot gradedqualityCmaintenanceEnables AI agents to understand and query your database safely by providing a semantic layer of metadata, with tools to search, explain, validate, and generate safe SQL.2MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MotleyAI/slayer'
If you have feedback or need assistance with the MCP directory API, please join our Discord server