Skip to main content
Glama

create_model

Create a reusable semantic model from a database table or SQL query, defining columns and measures so AI agents can query data by intent.

Instructions

Create a new semantic model, either from a database table or from a query.

Host a column/measure on the model whose row grain is 1:1 with what it describes — not merely one where its input columns live. Choose join keys by column Description (author intent); on ties take the shortest declared join path (long chains through lookup/log tables fan out rows). Encode definitions in dependency order, referencing already-defined entities by name rather than re-deriving them inline; in row-level SQL parenthesise weighted sums in comparisons ((a*w1 + b*w2) > t).

From a table or sql query (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(*)", "sum(amount)"], "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": "sum(revenue) / 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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sqlNo
nameYes
queryNo
columnsNo
measuresNo
sql_tableNo
variablesNo
data_sourceNo
descriptionNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.10.0

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that query becomes source_queries, that query is mutually exclusive with other source parameters, and that columns are auto-introspected. It also provides deep guidance on row grain and join key selection, which is exceptionally transparent for a creation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-organized, with examples and a structured parameter list. It front-loads the core purpose and then elaborates. The opening paragraph on row grain is dense but directly relevant to correct usage, so it earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (9 params, two modes, mutual exclusivity), the description covers all necessary details: examples, parameter semantics, auto-introspection, and mutual exclusivity. An output schema exists, so return values are not needed. Nothing essential is missing for an agent to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

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 fully. It does so by detailing every parameter: name conventions, types for columns and measures, mutual exclusivity, and the role of variables. Examples for both modes make the semantics concrete and actionable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise statement: 'Create a new semantic model, either from a database table or from a query.' It immediately distinguishes two modes and provides concrete examples, making the tool's purpose unambiguous and clearly separated from siblings like edit_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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives two usage modes with examples and notes that data_source comes from list_datasources, implying a prerequisite. However, it does not explicitly state when not to use this tool or contrast it with edit_model, though the purpose makes the primary usage clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.