Skip to main content
Glama

edit_model

Update a semantic model in one call: modify metadata, upsert columns, measures, aggregations, and joins, manage filters, and remove entities to adjust your data layer.

Instructions

Edit an existing model in a single call — update metadata, upsert columns/measures/aggregations/joins, manage filters, and remove entities.

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).

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": "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. 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": "sum(revenue) / count(*)"}]) Example — remove a measure: edit_model(model_name="orders", remove={"measures": ["old_metric"]})

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sqlNo
metaNo
joinsNo
hiddenNo
removeNo
columnsNo
measuresNo
sql_tableNo
model_nameYes
add_filtersNo
data_sourceNo
descriptionNo
aggregationsNo
remove_filtersNo
source_queriesNo
new_data_sourceNo
query_variablesNo
default_time_dimensionNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.10.0

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden, and it does so thoroughly. It discloses mutation semantics, upsert-by-name behavior, mutual clearing between sql_table/sql/source_queries, refresh of cached columns, removal-before-upsert ordering, and the fact that join cardinality is descriptive metadata only.

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

Conciseness5/5

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

The description is long but earned: it covers 18 parameters, complex side effects, design guidance, and two examples in an organized, front-loaded structure. The purpose statement and key behavioral principles come first, followed by an Args list and examples.

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?

For a complex 18-parameter mutation tool with zero schema descriptions and no annotations, the description is exceptionally complete. It covers parameter semantics, ordering, side effects, disambiguation rules, design principles, and usage examples; the presence of an output schema means return-value documentation is not required.

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 fully compensate. Every parameter is explained with real meaning: lookup rules for data_source, side effects for new_data_source, structure examples for columns/measures/aggregations/joins, and the exact clearing interactions among sql/sql_table/source_queries.

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 specific verb and resource, 'Edit an existing model in a single call,' and enumerates the full set of operations: update metadata, upsert columns/measures/aggregations/joins, manage filters, and remove entities. This clearly distinguishes it from siblings like create_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 context is clear: this is the tool for editing an existing model, and the examples demonstrate typical use cases. It does not explicitly state when to prefer a sibling tool or when not to use it, but the 'edit existing model' framing makes the intended use unambiguous.

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