MCP tool reference
Every capability in Semanticus, exposed as a typed operation your AI assistant can call.
Semanticus has two doors onto one live model: the Studio UI you drive, and an MCP server your AI assistant drives. This page lists every operation on that second door. All 240 of them are typed operations your own Claude Code, or any MCP client, can call, and they are the same operations the Studio UI uses. A change made through either door lands on the same model, the same undo timeline and the same live broadcast, so you and your assistant always see each other's work.
Use the filter to find an operation by name or by what it does. Each entry shows a lead line; open "more" for the full description as the engine reports it. Operations are grouped into families below. The engine itself runs no inference and holds no AI credentials: the intelligence is your assistant, on your account.
No operations match that filter.
#Orientation & reading 12
Start here. These read-only operations let your assistant get its bearings on a model it has never seen: a cheap summary first, then the objects, expressions and dependencies underneath. Nothing in this family changes the model.
model_overview
Summarize the open semantic model: name, source, table/measure counts, and whether there are unsaved changes.
more
Call this first.
get_model_summary
CALL THIS FIRST – the blessed session-start primer (you arrive amnesiac: fresh session, post-compaction, or handoff).
more
ONE round-trip, token-budgeted (≤~2k tokens), giving the whole map: connection state · entitlement tier · model overview (name/source/table-measure counts/unsaved-changes) · AI-readiness grade + category scores + finding counts · structural graph (relationship counts, disconnected visible tables) · in-flight work (active workflow runs, a loaded change-plan, a loaded spec) · the last few experience-log entries for continuity · deterministic suggestedNextActions. Each section names its DRILL-DOWN op: connection_status · get_entitlement · ai_readiness_scan (findings) · get_model_graph (full ER) · get_workflow_run · get_plan · get_spec · list_calendars. Deliberately OMITS the full findings list, per-object detail, and DAX bodies – fetch those with the named ops. Sections are null/omitted when they don't apply (no connection, no in-flight work, no log).
model_graph_summary
CHEAP structural overview – START HERE on a large model before get_model_graph.
more
Table/relationship counts, tables by type (date/calculated/hidden), relationship breakdown (many-to-many, bidirectional, inactive counts), and the names of DISCONNECTED visible tables (in no relationship – the key star-schema smell) – without the full per-table/per-relationship detail. Call get_model_graph for the full graph when you need it.
get_model_graph
Get the model's structure as a graph for relationship/ER analysis: every table (with column/measure counts, key columns, date-table & hidden flags) and every relationship (endpoints, cardinality, cross-filter direction, active/inactive).
more
Use it to reason about the star schema, find isolated tables, or audit bidirectional/inactive relationships. On a LARGE model, model_graph_summary is the cheaper first call.
get_object
Get an object's properties by ref (e.g. 'measure:Sales/Total Sales', 'column:Sales/Amount', 'table:Sales').
get_properties
List an object's editable properties (the property grid surface).
more
Each: name, displayName, category, kind (string/bool/number/enum), current value, enum options, read-only. Pass any ref (table/column/measure/relationship/function). Pair with set_property.
get_dax
Get the DAX expression of a measure or calculated column/table by ref (e.g. 'measure:Sales/Total Sales').
list_objects
List child objects of a node.
more
Pass an empty/null parentRef to list tables; pass a table ref (e.g. 'table:Sales') to list its measures and columns.
list_columns
List every column (excluding the internal RowNumber) with the metadata that drives column AI-readiness/authoring: ref, name, table, data type, display folder, format string, summarize-by, data category, and flags for key / hidden / calculated / has-description (+ description, + DAX expression for calculated columns).
more
One call to audit smells like a visible key column, a key with SummarizeBy != None, or a missing description/format.
list_measures
List every measure in the model with the metadata that drives AI-readiness and authoring: ref, name, owning table, display folder, format string, hidden flag, whether it has a description (+ the description), and its DAX expression.
more
One call to audit naming/folders/formats/descriptions across all measures (e.g. find measures missing a description or a format string).
list_functions
List the model's DAX user-defined functions (UDFs).
more
Each has a ref like 'function:MyFunc' – read its body with get_dax, edit with update_measure, rename with rename_object.
search_model
Find objects whose Name, Description, or DAX Expression contains a substring (case-insensitive).
more
Searches tables, measures, columns (incl. calculated), hierarchies, calculation items, functions, roles, and perspectives. Returns each hit's ref (so you can act on it), kind, owning table, which field matched, and a short snippet. Use it to locate a measure by a word in its formula, find every object referencing a column, or audit naming. `max` caps the results (default 100); Truncated tells you if there were more.
#Connections & sessions 10
Open a model from a PBIP or TMDL folder, snapshot a running Power BI Desktop instance, or load a deployed Power BI, Fabric or Azure Analysis Services model over XMLA. One model drives the tree, the Studio and the assistant at the same time.
open_model
Open a semantic model from a Power BI PBIP (point at the .pbip file, the project folder, or the .SemanticModel folder), a TMDL folder, or a .bim file path.
more
Returns basic counts.
open_local
UNIFIED open of a running local Power BI Desktop model: makes the SAME instance both editable in the tree (its metadata is snapshotted into the session) AND queryable live (DAX/DMV).
more
Localhost uses integrated Windows auth – no token. Leave dataSource empty to auto-pick the running instance, or pass 'localhost:51234' (see list_local_instances).
open_live
LOAD the full editable model from a Power BI / Fabric / Azure AS XMLA endpoint into the session, so the WHOLE workbench – AI-readiness scan, BPA, the change-plan, and every edit – operates on the LIVE deployed model.
more
Unlike connect_xmla (which only enables read-only DAX/DMV), this loads the model's metadata via TOM, exactly as Tabular Editor attaches to a deployed model. Edits stay IN-MEMORY and undoable; push them back with deploy_live (the write half – dry-run by default) or persist to a TMDL folder with save_model for review/deployment. endpoint e.g. 'powerbi://api.powerbi.com/v1.0/myorg/<Workspace>'. Leave database empty to load the workspace's only/first dataset. authMode: interactive (browser/MFA via Azure.Identity) | serviceprincipal (AZURE_*/FABRIC_* env – most reliable for Fabric) | azcli (default) | devicecode. tenantId optional – target a specific Entra tenant when your `az login` is a different tenant than the model's.
create_model
Create a brand-new, EMPTY semantic model from scratch and make it the current session (replaces any open model).
more
Default compatibility level 1604 (Direct-Lake-capable, Power BI mode). The model is UNSAVED – the first save_model MUST be given a path. Build it with create_data_source / create_named_expression / create_import_table / create_directlake_table / create_column / create_measure / create_relationship, etc. Returns the new session.
save_model
Persist the model.
more
Pass a target folder path (TMDL) or null to overwrite the source. format defaults to TMDL.
connect_local
Connect (read-only) to a local Analysis Services instance (an open Power BI Desktop).
more
Pass a Data Source like 'localhost:51234', or leave it empty to auto-pick the running Power BI Desktop instance.
connect_xmla
Connect (read-only) to a Power BI / Fabric / Azure AS XMLA endpoint to run DAX/DMV against the LIVE deployed model while you edit files offline.
more
endpoint e.g. 'powerbi://api.powerbi.com/v1.0/myorg/<Workspace>'. authMode: azcli (default, uses your `az login`), interactive (browser), or devicecode.
connection_status
Report the current live connection (connected, kind, data source).
disconnect
Close the live connection.
list_local_instances
List running local Power BI Desktop Analysis Services instances (port + workspace).
more
Use one with connect_local.
#Authoring: tables, columns, measures & scripts 21
The typed create, edit, rename and delete primitives for the model’s core objects, plus the script-and-apply route for editing many objects as text. Every write is change-tracked and undoable.
create_table
Create a new (empty) table.
more
Add columns with create_column/create_calculated_column; it needs a partition before it can be deployed/refreshed. Returns the new ref ('table:Name'). Undoable.
create_column
Add a DATA column (a physical/source column) to a table.
more
dataType: String|Int64|Decimal|Double|DateTime|Boolean (default String). sourceColumn is the underlying physical column name (defaults to the column name). Returns the new ref ('column:Table/Name'). Undoable.
create_calculated_column
Add a DAX calculated column to a table.
more
Returns the new ref ('column:Table/Name'). Undoable.
create_calculated_table
Create a DAX calculated table (its single partition is a DAX expression, e.g. a date dimension or bridge).
more
Returns the table ref ('table:Name'). Undoable.
create_measure
Create a new measure on a table.
more
Returns the new object ref. Undoable.
create_function
Create a DAX user-defined function (UDF).
more
The expression is a lambda, e.g. '(x: INT64, y: INT64) => x + y'. Names cannot contain spaces. Requires model compatibility level >= 1702 (call set_compatibility_level first if needed). Returns the new ref ('function:Name'). Undoable.
duplicate_object
Duplicate a measure, calculated/data column, or hierarchy (a deep clone).
more
newName optional (auto-named if omitted). Returns the new ref. Undoable.
delete_object
Delete any model object by ref (measure/column/table/hierarchy/relationship/calculation-group/calculation-item/role…).
more
Deleting an absent ref is a net-zero no-op. DAX references to a deleted object are NOT auto-rewritten – they will error; check dependents first. Undoable.
rename_object
Rename a measure/column/table.
more
ALL DAX references to it are automatically rewritten (safe rename). Returns the new ref. Undoable. (Report-layer bindings outside the model can't be updated – review for renames used in reports.)
update_measure
Set the DAX expression of a measure (or calculated column/table).
more
The change is applied to the live shared session, appears immediately in the VS Code UI, and is a single undoable step.
set_measure_format
Set a measure's format string (e.g. '0.0%', '\$#,0', '#,0').
more
Deterministic, undoable.
set_column_data_type
Set a data (source) column's data type: String|Int64|Decimal|Double|DateTime|Boolean.
more
Only applies to physical/source columns (a calculated column derives its type from its DAX). Undoable.
set_summarize_by
Set a column's default aggregation (None/Sum/Average/Min/Max/Count/DistinctCount).
more
Use None for keys/years/codes. Deterministic, undoable.
set_data_category
Set a column's data category (e.g. 'City','Country','StateOrProvince','PostalCode','WebUrl','ImageUrl').
more
Helps Copilot/maps. Deterministic, undoable.
set_sort_by_column
Set a column's sort-by column (e.g. sort 'Month Name' by 'Month Number').
more
Deterministic, undoable.
set_description
Set an object's description (measure/table/column).
more
Keep it <=200 chars and front-loaded – Copilot truncates. Applies as a reviewable, undoable change tagged as the agent. Use after get_grounding.
set_property
Set one property of an object by name (from get_properties).
more
value is the string form: 'true'/'false' for bool, the enum NAME for enum, the number for numeric. Setting 'Name' renames (DAX refs auto-rewritten). Undoable.
script_objects
Script one or MANY objects to text (read-only – never mutates).
more
format: 'dax' (annotated expressions for measures/calc columns/calc tables/calc items/UDFs), 'tmdl' (per-object TMDL – the model's native, readable on-disk format; the preferred export), or 'tmsl' (createOrReplace JSON; TMSL's unit is the table/role, so a child object scripts its containing table – deduped to containers). Pass several refs to capture a whole batch (e.g. all of a table's measures) in one document. Unresolvable refs are skipped.
apply_dax_script
Apply an edited DAX script (the 'dax' output of script_objects, with '// @object <ref>' headers) back to the model: each block's expression is set on its object in ONE undoable batch.
more
Lets you bulk-edit many measures/calc columns/calc items in one document and commit together. Refs that don't resolve or aren't DAX-expression objects are skipped and reported. Returns {applied[], skipped[]}.
apply_tmdl
Apply an edited TMDL script (the 'tmdl' output of script_objects – native TMDL for one or more TOP-LEVEL objects, e.g. tables) back to the model IN PLACE, the same way Power BI Desktop's TMDL view applies edits.
more
One undoable batch; fully tracked – structural changes (adding a measure/calculated column inside a table) surface, and the apply is undoable. Edits EXISTING top-level objects (you can add child measures/columns); a brand-new table is skipped and reported (create it with create_table first). Returns {applied[], skipped[]}.
#Relationships, hierarchies & model structure 14
The shape of the model: relationships with their cardinality and cross-filter direction, hierarchies, perspectives, calculation groups and their items, and field parameters.
create_relationship
Create a single-column relationship from a foreign-key column (the MANY side) to a lookup column (the ONE side).
more
crossFilter: OneDirection|BothDirections (optional). isActive optional. Returns the new ref ('relationship:Name'). Undoable.
set_relationship_active
Activate or deactivate a relationship.
more
Only ONE active relationship can exist on a given path between two tables – inactive ones are reached on demand via USERELATIONSHIP in DAX (e.g. role-playing date relationships like Order Date vs Ship Date). isActive=true activates it, false deactivates it. Deterministic, undoable.
set_relationship_cardinality
Set a single-column relationship's end cardinalities.
more
fromCardinality is the FK/from side, toCardinality the lookup/to side; each is 'Many' or 'One' (a null/empty end is left unchanged). A normal star-schema relationship is Many→One. Use this to fix a mis-shaped relationship in place instead of deleting and recreating it. Deterministic, undoable.
set_relationship_crossfilter
Set a relationship's cross-filter direction (OneDirection or BothDirections).
more
Prefer OneDirection in a star schema – bidirectional can confuse AI filter context. Undoable.
create_hierarchy
Create a hierarchy on a table from an ordered list of its column names (top level first).
more
Returns the new ref. Undoable.
create_perspective
Create a perspective – a named, curated subset of the model's tables/columns/measures/hierarchies (a focused Q&A or report view).
more
Add members with set_perspective_member; delete with delete_object and rename with rename_object. Returns the new ref ('perspective:Name'). Undoable.
set_perspective_member
Include (or exclude) one object in a perspective.
more
The object ref is a table/column/measure/hierarchy. Including a TABLE cascades to all its columns/measures/hierarchies. Undoable.
get_perspectives
List the model's perspectives and the object refs currently shown in each (the objects×perspectives membership matrix).
more
Read-only.
create_calculation_group
Create a calculation group (a special table).
more
Add calculation items with create_calculation_item. Requires compatibility level >= 1470. Returns the new ref ('table:Name'). Undoable.
create_calculation_item
Add a calculation item to a calculation group.
more
The expression typically uses SELECTEDMEASURE(), e.g. 'CALCULATE(SELECTEDMEASURE(), DATESYTD(...))'. Returns the new ref. Undoable.
list_calculation_groups
List the model's calculation groups with their precedence and ordered items (each item's DAX expression + dynamic format-string).
more
Read-only – author with create_calculation_group / create_calculation_item / set_calc_group_precedence / set_calc_item_format_string.
set_calc_group_precedence
Set a calculation group's precedence (an integer; a HIGHER precedence is applied FIRST when multiple calculation groups combine).
more
Give each calc group a distinct precedence so their combination order is deterministic. Undoable.
set_calc_item_format_string
Set (or clear) a calculation item's DYNAMIC format-string expression – the DAX that overrides the format string of measures evaluated under this item (e.g. a '% of Total' item rendering 0.0%, or a currency item).
more
Pass an empty string to clear it (the item falls back to the base/model format). Undoable.
create_field_parameter
Create a Power BI FIELD PARAMETER: a calculated table of NAMEOF(...) rows that drives a slicer to swap which measures/columns a visual shows.
more
Builds the full Power-BI-Desktop-identical structure (the 3 columns, the ParameterMetadata marker, sort-by, hidden plumbing columns, and the field-switch key). Items are measure/column refs in display order; each label defaults to the object's name. Requires a Power BI-mode model at compatibility level >= 1400. Returns the table ref ('table:Name'). Undoable.
#Data sources, partitions & refresh 15
Where the data comes in: structured data sources, import and Direct Lake tables, partition M source, shared M expressions and parameters, and incremental-refresh policy.
create_data_source
Create a structured (M) data source pointing at a Fabric SQL endpoint / Lakehouse-or-Warehouse SQL analytics endpoint (protocol 'tds').
more
Needs compatibility level >= 1400. Referenced by NAME from create_directlake_table or inside an M expression. Returns the data source name. Undoable. (Credentials are supplied out-of-band at refresh – none are stored here.)
create_import_table
Create an IMPORT-mode table whose data is loaded via an M partition – e.g. from a Fabric SQL endpoint via Sql.Database(...).
more
Bundles the table + its M partition (no orphaned placeholder). Add columns with create_column. Returns the table ref ('table:Name'). Undoable.
create_directlake_table
Create a DIRECT LAKE table backed by a Fabric Lakehouse/Warehouse entity (Parquet/Delta, no data copy).
more
Needs compatibility level >= 1604. Bind it to a source created first with create_named_expression (M to the SQL endpoint) OR create_data_source (structured), referenced by name. Returns the table ref ('table:Name'). Undoable.
create_named_expression
Create a shared (model-level) M expression / parameter – the source target for a Direct Lake partition, or reusable M referenced by name (#"Name") inside import partitions.
more
Returns the expression name. Undoable.
update_named_expression
Replace the M of an existing shared expression / parameter (create it first with create_named_expression).
more
Undoable.
get_named_expression
Get one shared M expression / parameter's M text by name (e.g. 'RangeStart').
list_named_expressions
List the model's shared M expressions + parameters (name, kind, M, description).
more
RangeStart/RangeEnd parameters show here. Edit one with update_named_expression, create with create_named_expression.
list_partitions
List a table's partitions (ref, mode, source type, data source).
more
Read a partition's M with get_partition_m, edit it with set_partition_m.
get_partition_m
Get a partition's M source expression.
more
Errors if the partition is not an M source (e.g. a Direct Lake Entity or DAX calculated partition).
set_partition_m
Replace a partition's M source expression (M partitions only).
more
Use to add an incremental-refresh RangeStart/RangeEnd date filter, or to edit the query. Undoable.
refresh_partition
Refresh ('process') a SINGLE partition of the live model.
more
Types: Full (reload + recalc, the default), DataOnly (reload, no recalc), Calculate (recalc only), ClearValues (empty it – destructive), Automatic (refresh only if stale), Add (append rows). LIVE DATA WRITE against the Analysis Services engine – runs as a DRY RUN by default (reports what would run, connects to nothing); pass commit=true to actually execute. Leave endpoint EMPTY to target the live model this session was opened from (open_live/open_local binds it); a file model has nothing to refresh. See list_refresh_types for full explanations.
list_refresh_types
List the partition refresh ('process') options, each with a plain-language explanation: Full (reload + recalc), DataOnly (reload, no recalc), Calculate (recalc only), ClearValues (empty it), Automatic (refresh if stale), Add (append rows), plus the table-level Defragment / Indexes.
more
Read-only – use it to pick a type for refresh_partition.
get_incremental_refresh_policy
Read a table's incremental refresh policy (rolling-window store + incremental window, granularity, mode).
more
Returns enabled=false if no policy is defined. Read-only.
set_incremental_refresh_policy
Define/update a table's incremental refresh policy (TOM BasicRefreshPolicy): store N periods of history, re-import the last M periods on each refresh.
more
PREREQUISITES (validated, refused if missing): two M parameters named exactly RangeStart and RangeEnd, and a partition whose M filters the date column on them. Metadata only – does NOT trigger a data refresh. Deterministic, undoable. On an EXISTING policy, omitted fields are PRESERVED (so you can change one knob); the defaults (store 5 Year, refresh 10 Day, offset 0, Import) apply only when first creating one.
remove_incremental_refresh_policy
Remove a table's incremental refresh policy (sets RefreshPolicy = null).
more
Leaves RangeStart/RangeEnd and the partition M intact. Deterministic, undoable.
#Calendars & time intelligence 8
Calendar-based time intelligence with the modern calendar objects, plus the classic date-table and time-intelligence generators, and marking a table as the model’s date table.
define_calendar
Create a calendar on a table (calendar-based time intelligence, CL 1701+): map its columns to TimeUnit categories (Year, Quarter, Month, Week, Date, MonthOfYear, DayOfWeek, … – absolute units and recurring '…OfYear' variants), with optional associated columns per unit and a 'timeRelated' bucket for untagged time columns (e.g. IsWorkingDay).
more
Enables calendar-aware DAX: TOTALYTD(expr, '<calendar>'). A table can hold several calendars (Gregorian + Fiscal + ISO…) over the same columns. One undoable step; persist with save_model. Requires CL 1701+ (set_compatibility_level).
define_calendar_from_template
One-step calendar setup (the modern replacement for generate_date_table): generate a template's calculated columns (only where absent – existing columns are kept and mapped as-is) AND the calendar with its TimeUnit mappings, as one undoable step.
more
Templates: gregorian (Year/Quarter/Month/Day + name-by-number sort pairing) · fiscal (fiscalStartMonth, FY labeled by ENDING year) · iso (ISO-8601 weeks, Thursday rule) · 445 (4-4-5 retail periods over ISO weeks) · 13period (13 four-week periods). Targets an existing table with a date column (dateColumn, auto-detected when unambiguous), or creates a fresh CALENDAR() calculated table when tableName doesn't exist. The week-based templates (iso/445/13period) share ISO scaffolding columns so they coexist on one table. Requires CL 1701+.
delete_calendar
Delete a calendar from a table (the columns themselves are untouched).
more
Undoable.
list_calendars
List the model's calendars (calendar-based time intelligence, CL 1701+): per table, each calendar's column→TimeUnit mappings (Year/Quarter/Month/Week/Date/…, primary + associated) and its time-related (untagged) bucket.
more
Pure offline metadata read – no connection needed. Also reports whether the model's compatibility level supports calendars at all.
tag_calendar_column
Incrementally edit one column mapping on an existing calendar: tag a column to a TimeUnit (replacing that unit's primary if it has one), add it as an ASSOCIATED column of a unit, put it in the 'timeRelated' bucket, or remove=true to untag it.
more
Undoable.
generate_date_table
CLASSIC approach: create a calculated date table (Date, Year, Quarter, Month Number/Name, Year-Month, Day, Day-of-Week) over a date range and mark it as the model's date table (DataCategory='Time').
more
For calendar-based time intelligence (CL 1701+, the modern approach with calendar-aware DAX like TOTALYTD(expr, 'Fiscal')), prefer define_calendar_from_template. Defaults: name 'Date', range 5 years back to end of this year. Columns materialize on deploy/process. Undoable.
generate_time_intelligence
Generate a suite of time-intelligence measures for a base measure, each correctly written against the given date column, named '<base> <variant>', placed in a 'Time Intelligence' display folder, and inheriting the base format.
more
Default suite: YTD, QTD, MTD, PY (prior year), YoY, YoYPct. Additional opt-in variants (pass in 'variants'): ROLL12/R3M/R6M (rolling 12/3/6-month windows), SPLY (same period last year), PYTD (prior-year YTD), PM (prior month), MoM + MoM% (month-over-month delta and %). Undoable.
mark_date_table
Mark a table as the model's date table (DataCategory='Time').
more
Required for good time-intelligence and Copilot date handling. Deterministic, undoable.
#Security: roles, RLS & OLS 8
Row-level and object-level security: roles and their members, model permissions, per-table row-filter DAX, and table or column visibility per role.
create_role
Create a security role.
more
modelPermission defaults to None (Read is auto-applied once you add an RLS filter). Then use set_table_permission to add per-table row filters and set_role_member to add members. Undoable.
delete_role
Delete a security role (and its RLS filters + members).
more
Undoable.
list_roles
List the model's security roles – each role's name, model permission (None/Read/ReadRefresh/Refresh/Administrator), per-table RLS row-filter DAX, and members.
more
RLS gates what data a Copilot / data-agent persona can see, so it matters for AI grounding.
set_role_member
Add or remove an (Azure AD / external) member of a role, by name (e.g. a UPN or group).
more
add=true adds, add=false removes. NOTE: adding members is blocked on a governed Power BI model (V3Restricted) – members are then managed in the Power BI service; removing/listing always works. Undoable.
set_role_permission
Set a role's model-level permission: None | Read | ReadRefresh | Refresh | Administrator.
more
Undoable.
set_table_permission
Set (or clear) a table's RLS ROW-FILTER DAX for a role – the boolean filter applied to that table's rows for members of the role, e.g. "[Region] = LOOKUPVALUE(...)" or "[Owner] = USERPRINCIPALNAME()".
more
Pass an empty filter to remove it. Setting a filter auto-promotes the role's permission from None to Read – the result echoes the resulting ModelPermission and a Promoted flag so the elevation is explicit. RLS row-filters cannot target a calculation group. The filter is a DAX expression and participates in rename fixup. Undoable.
set_column_ols
Set a column's OBJECT-LEVEL (metadata) security for a role – controls whether the role can SEE the column.
more
'None' hides the column from the role; 'Read' grants it; 'Default' removes the override (visible). Requires model compatibility level >= 1400 (errors clearly below). Surfaced via list_roles → ObjectPermissions[].Columns. Undoable.
set_table_ols
Set a table's OBJECT-LEVEL (metadata) security for a role – controls whether the role can SEE the table at all (distinct from set_table_permission's row filter).
more
'None' hides the table's metadata + data from the role; 'Read' grants it; 'Default' removes the override (visible). Requires model compatibility level >= 1400 (errors clearly below). A calculation group cannot carry OLS. Surfaced via list_roles → ObjectPermissions. Undoable.
#DAX: query, validate, benchmark & profile 14
The DAX lab as operations: run queries and DMVs, validate and lint before you write, benchmark cold and warm, profile the formula-engine and storage-engine split, and read VertiPaq storage.
run_dax
Run a DAX query (EVALUATE / DEFINE...EVALUATE) against the connected live model and return columns + rows (capped).
more
Returns {error} if not connected or the query fails. Read-only.
run_dmv
Run a DMV query (e.g. SELECT * FROM $SYSTEM.TMSCHEMA_MEASURES) against the connected live model.
more
Read-only.
preview_table
Preview the first N rows of a table on the connected live model (EVALUATE TOPN(N, 'Table')).
more
Accepts a table name or a 'table:Name' ref. Read-only; requires a live connection.
validate_dax
Validate a DAX expression against the OPEN model BEFORE you write it (create_measure/set_dax).
more
Catches unbalanced brackets (error) and unknown table/column/measure references (warning), with line:column. Offline/read-only – no live engine needed. Valid=false only on a structural error.
lint_dax
Deterministic DAX best-practice lint (SQLBI/DAX-Patterns) – ~15 token-path rules over one DAX expression: IFERROR/ISERROR plus the DIVIDE- and SEARCH/FIND-specific forms, ERROR() as control flow, EARLIER/EARLIEST, extended columns inside SUMMARIZE, comparison-to-BLANK(), hand-rolled zero guards, VAR-as-live-alias inside CALCULATE, unused VARs, the SELECTEDVALUE / DISTINCTCOUNT / REMOVEFILTERS idioms, a measure in a boolean filter predicate, and bare-table CALCULATE filters.
more
With an open session the table-identity rules activate (bare-table filter). Token-based, so comments / strings / [bracketed names] never false-fire. Read-only, free, advisory per-expression – the model-scored layer is the AI-readiness BestPractice category (ai_readiness_scan). Run it on a rewrite before applying.
benchmark_dax
Benchmark a DAX query's wall-clock cost on the connected live model: runs it N times and returns first-run, warm-min and warm-median ms plus each run.
more
Use it to measure a query/measure BEFORE and AFTER an optimization to prove the rewrite is actually faster. Read-only.
benchmark_dax_coldwarm
DAX-Studio 'Run Benchmark': measure a query COLD (the SE cache is cleared before each run) and WARM (no clear), and return Average/StdDev/Min/Max for BOTH total query time and storage-engine time, split by cold vs warm, plus per-run detail.
more
This is the way to prove an optimization helps the worst case. Needs a local Power BI Desktop or admin XMLA endpoint for the cold runs + SE split; on a shared/cloud endpoint pass confirm=true to allow clearing (it affects all users) or it degrades to warm-only. Read-only.
profile_dax
Profile a DAX query's SERVER timings on the connected live model: total ms, the Formula-Engine vs Storage-Engine split, the number of SE scans, SE CPU and parallelism, and the heaviest scans (xmSQL).
more
Use it to understand WHY a query is slow (FE-bound vs SE-bound) when optimizing. Needs a local Power BI Desktop or an admin XMLA endpoint; falls back to wall-clock only otherwise. Read-only.
capture_query_plan
Capture a DAX query's LOGICAL and PHYSICAL query plans (the DAXQueryPlan trace) to understand WHY it's slow – the Formula Engine builds the logical plan, the Storage Engine the physical plan (with #Records per operator).
more
Use it alongside profile_dax when a query is FE-bound (a tall physical plan / huge intermediate records points at the costly operators). Needs a local Power BI Desktop or an admin XMLA endpoint; degrades to 'unavailable' otherwise. Read-only.
clear_cache
Clear the Storage-Engine (VertiPaq) cache for the connected model – the DAX-Studio 'Clear Cache' primitive that makes cold-vs-warm benchmarking meaningful (run it before a query to measure the cold/worst-case cost).
more
NON-DESTRUCTIVE: it only evicts the cache (the engine rebuilds it on the next query); no data or metadata changes. SAFETY: on a SHARED/cloud endpoint this evicts the cache for ALL users (their next queries run cold), so it is REFUSED there unless you pass confirm=true. Needs a local Power BI Desktop or an admin XMLA endpoint.
evaluate_and_log
Debug a DAX query that contains EVALUATEANDLOG(<expr>, "label") calls: runs it and returns the query result PLUS every logged intermediate (label, the sub-expression, and its evaluated rows/values) captured from the engine.
more
Wrap the sub-expressions you want to inspect in EVALUATEANDLOG to see what they actually evaluate to. Needs a local Power BI Desktop or admin XMLA. Read-only.
pivot_measure
Test a measure (or any scalar DAX) across a pivot: EVALUATE SUMMARIZECOLUMNS(rowFields..., colField?, filters..., "value", measureExpr).
more
Returns long-form rows the caller pivots into a row x column matrix. Use it to sanity-check a measure's values by category/date before trusting it. Read-only; requires a live connection.
vpaq_scan
VertiPaq storage analysis of the connected live model: total model size, per-table sizes, and the biggest columns (data + dictionary + index bytes, % of model, encoding).
more
Use it to find what to drop/hide/optimize. Requires a live connection.
export_vpax
Export the open model to a VertiPaq-Analyzer .vpax file (the interchange format for VertiPaq Analyzer, DAX Studio, and the SQLBI ecosystem), using Microsoft/SQLBI's official Dax.Vpax.
more
Writes the model METADATA (tables, columns, measures, relationships) – works offline. Storage statistics (column sizes / cardinality) require a processed/live model and are not included yet. Returns the path, table count, and a note; door-safe (a bad path returns .Error rather than throwing).
#Verified edits & equivalence 9
The deterministic referee. Prove a rewrite is behaviour-preserving, gather evidence for a new measure across many contexts, capture values before a risky edit and compare after, and read the audit trail. See the Pro page for how these become enforced.
capture_baseline
VERIFIED EDITS – value-capture at edit-START (run this BEFORE a risky structural edit: rename, retype, relationship change, delete, M rewrite).
more
Freezes the MEASURED values of the object's blast radius – the lineage-downstream measures, evaluated BY REFERENCE over the SUMMARIZECOLUMNS(groupBy) grid you supply – into a session-held baseline, and returns a captureId. After the edit, compare_baseline re-evaluates the same grid and reports exactly which numbers moved. Pass representative groupBy columns: a grand-total-only baseline is thin evidence (disclosed in the result). Over-cap measures are listed in Skipped, never silently dropped. Pro; needs a live connection (a baseline is measured values, not metadata).
compare_baseline
VERIFIED EDITS – the edit-END half of capture_baseline: re-evaluates a captured baseline's grid on the LIVE model and reports per measure whether its numbers are unchanged, MOVED (with the exact contexts and before→after values), or MISSING (the measure no longer resolves – that is an impact, not a skip).
more
Safe=true only when everything is unchanged, nothing is missing/errored, AND coverage wasn't truncated – honesty first. IMPORTANT: it reads the LIVE model, so run it AFTER the edit is deployed (deploy_live) – an undeployed local edit is not validated (the result discloses session edits since capture). The verdict (safe/impact) is recorded in the Verified Edits audit trail. Pro; needs the live connection the baseline came from.
probe_measure
VERIFIED EDITS: run a measure across MANY filter contexts to gather EVIDENCE before you trust it – value/BLANK/ERROR per member, non-blank coverage, additivity – across a scenario matrix.
more
DAX context-dependence bugs (missing time-intel guards, blanks, non-additivity) are INVISIBLE until you run the measure in different contexts. It replicates a real visual (SUMMARIZECOLUMNS with your filter args as the OUTER/slicer context + a group-by axis) so ALLSELECTED / SELECTEDVALUE / ISINSCOPE resolve correctly – a naive one-context test lies about those. Pass a primaryAxis to auto-generate grand/single/multi/empty/boundary scenarios, and/or scenarios[] for cross-filter cases (name columns + members; do NOT hand-write DAX). Reports BEHAVIOR across contexts, NEVER 'correct' – you judge it against intent. Read-only; needs a live connection.
verify_dax_equivalence
PROVE a candidate DAX rewrite is behavior-preserving before applying it: evaluates exprA (original) and exprB (rewrite) side by side across SUMMARIZECOLUMNS(groupBy...), where each group-by row is a distinct filter context, and reports whether ALL values match plus any mismatching contexts.
more
ALWAYS run this (over a representative group-by matrix) before replacing a measure with an optimized version. Read-only.
optimize_measure
VERIFIED EDITS – an evidence-gated way to optimize a measure.
more
Give >=2 candidate DAX rewrites; the engine validates each, checks each returns identical values to the current body across the SUMMARIZECOLUMNS(verifyGroupBy) matrix YOU supply, benchmarks only the ones that matched (warm wall-clock over that same grid – not a server SE/FE trace), and applies the fastest that beats the current body beyond a measured noise band – recording the proof + benchmark as evidence. Equivalence is only as strong as verifyGroupBy: a grand-total-only match is downgraded to unverified (not accepted), so pass representative group-by columns. REFUSES to finalize without >=2 candidates, without a live connection, or with nothing proven (correctness always gates speed – a faster-but-wrong candidate can never win). Prefer this over update_measure for rewrites/optimization. Auto-apply is Pro; on free it returns the full evidence (paused) so you can apply the winner with update_measure. Needs a live connection (open_live / open_local).
get_verified_mode
Is Verified Mode on? When ON, single-edit DAX ops (set_dax + create measure/calc column/calc table/calc item/function) are strictly validated before they commit – invalid syntax OR an unknown table/column/measure reference is refused (validity only, not an equivalence/drift proof; bulk script/plan paths aren't gated yet).
more
Session-scoped (resets on reconnect). 'available' = whether the tier can turn it on (Pro). Check this so you know whether an edit will be gated.
set_verified_mode
Turn Verified Mode on/off.
more
When ON, single-edit DAX (set_dax + create measure/calc column/calc table/calc item/function) is strictly validated before it commits – invalid syntax or unknown table/column/measure refs refused (validity only, not an equivalence proof). This is the human's guarantee switch – turning it ON is a Pro feature (returns a Pro-required error on free); turning it OFF is always allowed. Prefer the human sets this; if you turn it off, do so deliberately.
list_verified_edits
VERIFIED EDITS: read the append-only, hash-chained audit trail persisted ON the model – every verified op (or accountable override) with its verdict, evidence, and any override reason, in chain order.
more
Each record links the previous by hash, so the trail self-checks: ChainIntact=false (with FirstBrokenSeq) means a record was edited, removed, or reordered after it was written. Read-only, free.
export_verified_edits
VERIFIED EDITS: export the model's audit trail as a shareable report – 'md' (default) for a human-readable markdown summary (boss/auditor) or 'json' for the raw serialized chain (CI/tooling).
more
Read-only. Pro.
#AI-Readiness & Best Practice 17
Score the model A to F for AI readiness, run the Best Practice Analyzer, apply deterministic safe fixes, and waive findings honestly (an accepted finding stays visible and counted, never hidden).
ai_readiness_scan
Score the open model A-F for AI readiness (Copilot / Q&A / Fabric data agents): overall grade + 0-100, per-category scores, coverage KPIs, gating reasons, and a prioritized findings list.
more
Each finding is tagged SafeFix (deterministic), AiContent (you generate it), or Proposal (human review). On a LARGE model call ai_readiness_summary first, then filter here. Optional filters: category (e.g. 'Naming','Descriptions','DataAgentConfig'), severityMin ('Info'|'Medium'|'High'|'Critical' – keep this severity and above), maxFindings (cap the returned findings; 0 = all, the default – capping is explicit so nothing is hidden silently). Scores/categories/counts are always for the FULL model; only the returned findings list is filtered.
ai_readiness_scan_live
Like ai_readiness_scan, PLUS the live cardinality rules: it reads per-column distinct-value counts (COLUMNSTATISTICS) from the attached connection and applies the Q&A-index rules – SCALE-QNA-INDEX (total indexed unique values vs the Microsoft-documented 5,000,000-value Q&A ceiling, beyond which Copilot/Q&A drop values) and SCALE-HICARD-COLUMN (a single visible column whose cardinality dominates the index).
more
Requires a live connection (connect_xmla / connect_local) – read-only. Use this instead of ai_readiness_scan when connected to grade scale/cardinality too.
ai_readiness_summary
CHEAP overview – START HERE on a large model.
more
Returns the A-F grade + 0-100 overall, per-category score/applicable/violations, coverage KPIs, gating reasons, the total finding count, and counts by severity / fix-kind / top rule – WITHOUT the (potentially large) findings list. Token-light regardless of model size. Then call ai_readiness_scan with a category or severityMin filter to pull only the findings you'll act on.
make_model_ai_ready
The one-shot flow: apply ALL deterministic safe fixes, then return the new scorecard PLUS a prioritized AI-content work queue (each item has the finding + grounding: DAX, table, siblings).
more
Iterate the queue: for each, author a description/name and call set_description (renames need review). Re-scan when done.
apply_fix
Apply the deterministic safe fix for ONE finding (by ruleId + objRef).
more
Supports VIS-FK (hide a foreign-key column), FMT-SUMMARIZE / SUMMARIZE-DIMENSION (SummarizeBy=None), CAT-GEO (geographic data category). For content findings use get_fix_prompt + the matching tool instead. Undoable.
apply_safe_fixes
Apply ALL deterministic, low-risk AI-readiness fixes (hide foreign-key columns, set SummarizeBy=None on key/relationship + non-additive identifier columns, set geographic data categories) in one undoable batch, then return what was applied + the new scorecard.
more
No renames, no generated content.
get_fix_prompt
Get a ready-made remediation instruction (with grounding baked in) for an AI-content finding – which tool to call and what to author (description/name/format/synonyms).
more
Useful when iterating a scorecard's findings.
bpa_scan
Run the Best Practice Analyzer (general modeling best practices: performance, DAX, formatting, naming, layout).
more
Uses the bundled Power BI standard ruleset merged with any rules embedded in the model (load your own with load_bpa_rules / clear them with reset_bpa_rules). Returns violations (rule, category, severity, object, message) flagged CanAutoFix (deterministic) or not. For AI-specific readiness use ai_readiness_scan instead. On a LARGE model call bpa_summary first, then filter here. Optional filters: category, ruleId, autoFixableOnly (true = only deterministically fixable), maxViolations (0 = all, the default; capping is explicit so nothing is hidden silently). RuleCount/ViolationCount/AutoFixable are always for the FULL model; only the returned violations list is filtered.
bpa_summary
CHEAP overview – START HERE on a large model.
more
Rule count, total violation count, auto-fixable count, any rule errors, and violation COUNTS by category / rule / severity – WITHOUT the (potentially large) violations list. Then call bpa_scan with a category / ruleId / autoFixableOnly filter to pull only the violations you'll act on (or bpa_fix_all for all deterministic fixes).
bpa_fix
Apply a BPA rule's deterministic fix to ONE violating object (only for CanAutoFix violations – e.g. bi-directional relationship -> single, key column SummarizeBy -> None).
more
For non-auto-fixable rules use bpa_get_fix_prompt. Undoable.
bpa_fix_all
Apply ALL deterministic BPA auto-fixes in one undoable batch, then return how many were applied + the new scorecard.
more
Does not touch content/naming rules (those need bpa_get_fix_prompt).
bpa_get_fix_prompt
Get a remediation instruction (with the rule + object context) for a NON-auto-fixable BPA violation, so you can fix it with the right tool (set_description / set_measure_format / update_measure / rename_object).
more
This is how Semanticus exceeds Tabular Editor: every rule is fixable – deterministically or by you.
load_bpa_rules
Load Best Practice rules from a file path, an http(s) URL, or inline JSON (standard BPARules.json schema – an array of {ID, Name, Category, Severity, Scope, Expression, FixExpression?, Description}).
more
They layer on TOP of the bundled Power BI standard ruleset and are persisted on the model (so they travel with it and are undoable). replace=false MERGES with any rules already on the model (by id); replace=true sets the model's custom rules to exactly this set. Use reset_bpa_rules to clear them. Returns the new active rule counts.
reset_bpa_rules
Clear all custom/model-embedded BPA rules, reverting bpa_scan to the bundled Power BI standard ruleset only.
more
Undoable.
waive_finding
WAIVE (accept) a finding so it stops counting against the score – for findings you've consciously decided not to fix (e.g. 'we keep these unused columns').
more
system: 'bpa' or 'air'. objRef set = waive THIS instance (free); objRef empty/'*' = waive the ENTIRE rule, every instance model-wide (the bulk lever – Pro). A reason is REQUIRED: a waiver is an audited decision (stored with who+when on the model), never a silent suppression – the finding is still surfaced (tagged 'waived' with its reason) and the scorecard reports a waived count, so the grade is honest. Hard gates (Q&A scale ceiling, >50% measures undescribed) are NOT lifted by waivers. Persisted on the model (undoable, travels with it); per-instance BPA waivers also write Tabular Editor's BestPracticeAnalyzer_IgnoreRules so TE3 honours them. Re-scan to see the score move.
unwaive_finding
Remove a waiver so the finding counts against the score again (re-instates it).
more
system: 'bpa' or 'air'. objRef set = un-waive that instance; empty/'*' = remove the rule-level waiver. Never gated (it makes the model more compliant). Undoable; also clears Tabular Editor's ignore annotation for a per-instance BPA waiver.
list_waivers
List every accepted (waived) finding on the model – system, rule id, object ref (null = rule-level/model-wide), the reason, who waived it and when.
more
The audit trail behind the scorecard's waived count.
#Grounding & Prep-for-AI content 6
Author the grounding an AI consumer needs: Q&A linguistic schema, synonyms, model instructions and the AI data schema, plus a grounding helper for writing good descriptions.
enable_qna
Enable a Q&A / Copilot linguistic schema (synonyms) on the model by seeding a culture's linguistic metadata.
more
Call once before set_synonyms. Pass null culture for the default (en-US).
set_synonyms
Set the synonyms (alternate words users might say) for a measure/column/table, e.g. Total Sales -> ['revenue','turnover','sales amount'].
more
Auto-enables the linguistic schema if needed. Helps Copilot/Q&A map natural language to the right field.
set_ai_instructions
Set the model's Prep-for-AI AI instructions – business context, terminology and analysis rules that guide Copilot/data agents (stored on the model as the LSDL 'CustomInstructions' string).
more
Pass empty/null to clear. Max 10,000 chars (the service ignores anything beyond; the call is rejected if over). Auto-enables the linguistic schema if needed; the write is round-trip verified, live in the shared session, and a single undoable step. CAVEAT: for a DEPLOYED model an LSDL edit syncs to the service only after a model refresh – it is not instant. Persist to disk with save_model.
get_ai_instructions
Read the model's Prep-for-AI AI instructions (the LSDL 'CustomInstructions' string set_ai_instructions writes): the text, its length vs the 10,000-char cap, and the culture read.
more
Read-only. Call BEFORE editing instructions so an append/update doesn't clobber what's already there.
set_ai_data_schema
Include or exclude a field (measure/column/table) from the Prep-for-AI 'AI data schema' – the focused field set Copilot/data agents reason over.
more
included=false EXCLUDES it (marks it Hidden in the LSDL); included=true restores it. Excluding noise (keys, sort/helper columns, intermediate measures) sharpens AI answers without hiding the field from report authors. Auto-enables the linguistic schema if needed; round-trip verified, live, a single undoable step. CAVEAT: for a DEPLOYED model the LSDL edit syncs only after a model refresh. Persist with save_model.
get_grounding
Get grounding context for an object (name, table, DAX expression, format string, existing description, sibling names) so YOU can author a high-quality business description or a clearer name.
more
Call this before set_description.
#Lineage & impact 7
Trace any object end to end, see everything that would break before you change it, find what nothing uses, and check safe-to-remove report-aware against local or published reports.
get_lineage
Read-only LINEAGE GRAPH of the open model (offline, from TOM): every node (data source, table, column, measure) and every directed edge – source→table (resolved from partition M / shared expressions), table→column/measure (contains), dependant→dependency (DAX), and FK→PK (relationship).
more
Use it to trace where a field comes from and what flows from it. NOTE (Phase 1): model-only – published-report field usage is not yet included (see .Caveat).
impact_of
Read-only forward IMPACT analysis: everything that breaks (transitively) if the given object changes or is removed – its DAX dependents (measures/calc columns/calc tables/calc items/KPIs/RLS) plus, for a column, the relationships, hierarchies, and sort-by columns that use it.
more
Returns the impacted set with BFS depth + counts by kind. Call BEFORE editing or deleting a measure/column. NOTE (Phase 1): downstream published reports/visuals are not yet included (see .Caveat).
get_dependencies
DAX dependency edges for an object (measure, calculated column/table, calculation item, UDF, column).
more
direction='dependsOn' (default) lists what its DAX consumes – check before editing; direction='dependents' lists what REFERENCES it – check before delete_object/rename_object to see what would dangle. Returns each ref/name/kind; empty when the object has no DAX edges.
unused_objects
Read-only reverse SAFE-TO-REMOVE sweep (the 'Measure Killer'): every measure/column that NO model object references – a deletion-candidate list.
more
CONSERVATIVE – a column used by a relationship, hierarchy, sort-by, or RLS is never listed. Tri-state verdict per item: 'safe' (nothing references it), 'usedByUnusedOnly' (referenced only by other unused/dead objects – surfaced with BlockedBy), 'caution' (report read failed – Phases 2-3). IMPORTANT (Phase 1): MODEL-ONLY – a field used ONLY by a published report (not by any model object) will still appear here; verify report usage before deleting (see .Caveat).
analyze_reports
REPORT-AWARE lineage (the safe-to-remove gap-closer): parse one or more LOCAL Power BI report definitions in PBIR format (a PBIP '<Report>.Report' folder, its 'definition' folder, a .pbip file, or a project root) and return which model fields each report uses, PLUS a safe-to-remove sweep that EXCLUDES anything a report uses.
more
This closes the model-only blind spot where a descriptive column a report displays – but no measure references – wrongly looks unused. Report field references are reconciled to the open model BY NAME (the model must be the one the reports bind to). Offline (local files); the cloud 'Get Report Definition' path will reuse the same parser. Legacy .pbix / RDL are not parsed yet (reported as unreadable → result stays model-only with a caveat).
analyze_cloud_reports
REPORT-AWARE safe-to-remove over CLOUD (published) reports – the Measure-Killer headline against the live service.
more
Fetches each report's PBIR via the Fabric 'Get Report Definition' API, reconciles its field usage to the OPEN model BY NAME, and recomputes safe-to-remove EXCLUDING any field a report uses. reportIds empty = every non-paginated report in the workspace. Behaviour is READ-ONLY (Semanticus never modifies the report), BUT getDefinition requires a WRITE-CAPABLE Fabric scope (Item.ReadWrite.All / Report.ReadWrite.All) + the Contributor role – so you MUST pass consent=true to acknowledge that (tell the user first). Per-report failures (paginated/RDL, a report blocked by an encrypted sensitivity label, a download error) are reported as unreadable with a reason – never silently dropped, so 'safe' is never overstated. A model must be open and must be the one these reports bind to.
list_reports
List the published reports in a Fabric/Power BI workspace (id, name, datasetId, reportType, webUrl) via the non-admin per-workspace path.
more
The datasetId tells you which reports bind to a given semantic model – match it to the open model to find the reports that use it. reportType 'PaginatedReport' = RDL (its field usage can't be parsed). Live read against api.powerbi.com using your Entra identity. Read-only. Pair with analyze_cloud_reports to close the safe-to-remove blind spot using real published-report usage.
#Change plans, diffs & undo 9
The pull request for your model: propose a plan, review each item as a before-and-after, and apply the approved subset. Also dry-run any single edit, and step the shared undo timeline. Applying more than one item at once is a Pro feature; see the Pro page.
propose_plan
Analyse the model and assemble a CHANGE PLAN (a 'pull request for your model') WITHOUT mutating anything: deterministic safe fixes + BPA auto-fixes are fully specified; AI-content items (descriptions, formats, names, synonyms) come back as a work queue with grounding for YOU to fill via set_plan_item.
more
Review with get_plan, then apply_plan. scope null = whole model; 'table:Name' = just that table. This is the flagship: fix the whole model in one reviewed, undoable transaction.
get_plan
Get the current change plan: every proposed item with its before→after, source (deterministic/bpa/ai), risk, status, and a summary.
more
Use it to see what still needs content (status 'needs_content') and what is approved/ready to apply.
add_plan_item
Add a custom change to the plan (an incremental edit, or a DAX rewrite you want verified before applying).
more
kind is the operation: set_dax | set_description | set_measure_format | set_summarize_by | set_column_hidden | set_data_category | rename | set_synonyms | set_relationship_crossfilter | mark_date_table | set_ai_instructions (model-level: objRef is the model, after = the instructions text) | set_ai_data_schema (objRef a measure/column/table, after = 'Excluded' or 'Included'). For a set_dax rewrite, ALWAYS pass verifyGroupBy so apply_plan PROVES equivalence (and skips it if results change). A set_dax item WITHOUT verifyGroupBy is added as 'proposed' (opt-in, like a rename) – it will NOT be applied unless you explicitly approve it via set_plan_item, and if applied it goes in UNVERIFIED. Nothing is mutated until apply_plan.
set_plan_item
Fill an AI-content plan item with your authored value (and/or approve/reject it).
more
Authoring a value moves the item to 'approved' (renames stay 'proposed' – they need an explicit approve because they're riskier). e.g. set_plan_item('ci-0007', after='Total revenue recognised in the period.'). Use get_plan to see item ids + grounding first.
clear_plan
Discard the current change plan (nothing in the model is affected – the plan never mutated it).
apply_plan
Execute the APPROVED subset of the change plan as ONE undoable transaction.
more
Only approved items are applied – passing approvedIds narrows the approved set (it never applies rejected/proposed/needs_content items). DAX rewrites carrying a verify matrix are proven equivalent first and skipped if they'd change results or can't be proven; renames apply last. Returns a report: applied/skipped/failed counts + before→after BPA violations and AI-readiness grade. A single undo reverts everything; re-run propose_plan to iterate the tail.
dry_run
PLAN MODE for the model: rehearse ANY single model-mutating op through its REAL code path and get back the EXACT change set it would make (the model/didChange deltas) plus the op's own return value – with a hard guarantee of NO mutation, NO undo entry, NO broadcast, and NO audit record (the edit is applied, then rolled back).
more
Preview a create_measure / update_measure / rename_object / set_property / define_calendar before committing, or check whether an op WOULD fail – a rehearsal that finds the failure is still a SUCCESSFUL dry-run (WouldSucceed=false with the op's real teaching error). 'argsJson' is a JSON object of the op's arguments by name, e.g. {"tableRef":"table:Sales","name":"Margin","expression":"[Sales]-[Cost]"}. Entitlement gates stay ACTIVE (a Pro refusal is the real answer you'd get). DENIED (each refusal names the right path): external/system I/O + lifecycle (save_model/open_*/connect_*/refresh_partition/export_vpax/clear_cache/evaluate_and_log/benchmark_*), deploy/cloud/git/fabric/cicd/daxlib/data-agent (already commit-gated – run directly), the undo timeline (undo_change/redo_change), multi-mutate composites whose later steps read earlier writes (apply_plan/apply_safe_fixes/bpa_fix_all/make_model_ai_ready/apply_model_diff/cherry_pick/build_model_from_spec/apply_dax_script/apply_tmdl – use propose_plan / preview paths / apply one typed op), and workflow/knowledge/waiver bookkeeping. After a green rehearsal, run the op itself to apply.
undo_change
Undo the most recent change on the shared session – steps back one entry on the model's SINGLE undo timeline.
more
A whole batch (apply_plan / bpa_fix_all / apply_safe_fixes / a generator) undoes as ONE step. The timeline is shared across both drivers, so this reverts the last change regardless of who made it (your edits or the human's in the VS Code UI). The revert is live – it broadcasts to the UI immediately. Returns CanUndo / CanRedo / AtCheckpoint. Use it to back out a change you just applied.
redo_change
Re-apply the change most recently undone with undo_change – steps forward one entry on the shared undo timeline.
more
Live (broadcasts to the UI). Returns CanUndo / CanRedo / AtCheckpoint. Making a NEW edit after an undo clears the redo stack.
#Multi-model compare & merge 3
Compare the open model against another version, merge selected changes across models, and copy objects from one model into another.
model_diff
ALM-Toolkit-grade SEMANTIC compare of the open model against another version – by default the git ref 'HEAD' (i.e. what you changed since the last commit).
more
Returns an object-level diff (per table/column/measure/relationship/role/...: Create/Update/Delete) with each object's before/after text. Pass a different gitRef to compare against a branch/commit, or targetFile to compare against a model on disk, or sourceFile to compare two files. Read-only.
apply_model_diff
Selectively MERGE the open model's changes INTO a target model file (the ALM-Toolkit 'Update'): makes the target match the open model for the chosen objects.
more
DRY RUN by default (commit=false reports what WOULD apply). Pass commit=true to write the target file. selectedRefs limits to specific object refs (e.g. ['measure:Sales/Total']); omit to apply all differences.
cherry_pick
Copy objects FROM another model INTO the OPEN model (cross-model copy/paste) – e.g. copy a measure from a teammate's model into yours.
more
DRY RUN by default (commit=false reports what would copy, what already exists (would overwrite), and what can't). Pass commit=true to apply as ONE undoable batch. Source is a model on disk (sourceFile) or a git ref of the open model's repo (gitRef). refs are object refs like ['measure:Sales/Margin %']. Supported into the open model: measures, calculated columns, and calculation items (into an existing group). For a whole table or calculation group, use apply_model_diff to a file target instead.
#Workflows 22
Enforced playbooks: read the stock library, start a run, submit or skip a step with a reason, and inspect run state. Curate which workflows are on the menu, require one for a task, and read the whole policy in one call. Templates are workflows with blanks you fill with your own process, then turn into a runnable workflow. Reading a playbook is free; an enforced run is a Pro feature. See the Pro page.
list_workflows
WORKFLOWS: list the available enforced playbooks – the stock library shipped with the engine plus this project's own `.semanticus/workflows/*.md` (a user file shadows a stock one of the same name; files are re-read on every call, so edits are live).
more
Each entry shows step count, whether it is GATED (starting it needs Pro – enforcement is what's paid, reading is free) and any parse error (a malformed file is surfaced here, never hidden). Free, read-only.
get_workflow
WORKFLOWS: read one workflow's FULL definition – every step's instruction text, gate inputs (the questions you must ask the user), and verify checks.
more
Free: use it to follow a playbook manually, or to preview what start_workflow will enforce. To customise a stock workflow, copy it into `.semanticus/workflows/<name>.md` and edit – the user copy shadows the stock one.
start_workflow
WORKFLOWS: start an ENFORCED run of a workflow.
more
Returns the run id plus step 1's full instructions and its gate questions – ask the USER those questions (do not invent answers), do the step's work with the normal tools, then submit_workflow_step. The engine – not you – evaluates each gate: required inputs must be answered or explicitly declined, and verify checks (probe / equivalence / BPA / readiness) run against the live model. Every transition broadcasts to the Studio UI; the finished run's full record (answers, declines, evidence) is appended to the experience log. Pro when any gate enforces; a workflow whose gates are all 'off' runs free.
get_workflow_run
WORKFLOWS: the live state of a run – per-step status (pending/in_progress/passed/skipped/failed), recorded answers and declines, verify evidence, and the CURRENT step's full instructions + unanswered questions.
more
Omit runId for the most recent run. Free, read-only.
submit_workflow_step
WORKFLOWS: submit the run's CURRENT step.
more
answers is a JSON object keyed by gate-input name: a value, or the explicit decline sentinel {"declined": true, "reason": "..."} (answer-or-decline inputs accept a reasoned decline; required ones do not). The ENGINE then runs the step's verify checks against the live model – a hard gate that fails blocks the step with the failure evidence (fix and re-submit, or skip_workflow_step with a reason); a warn gate records it and passes. Answers accumulate run-wide: a later step's probe can reference an input recorded earlier. On success you get the NEXT step's instructions.
skip_workflow_step
WORKFLOWS: skip the run's current step WITH A REASON.
more
The accountable-override shape: never a hard wall, never a silent bypass – the reason is recorded on the run and lands in the experience log with the terminal record. Prefer fixing and re-submitting over skipping a failed hard gate.
abort_workflow
WORKFLOWS: abort a run.
more
The partial record (steps passed, answers, declines, evidence so far) is preserved and appended to the experience log – an abandoned run is data, not a deletion.
save_workflow
WORKFLOWS: author or edit a workflow – write the full markdown (frontmatter + '## Step N:' sections + optional yaml-gate fences with inputs/verify/ops) to this project's `.semanticus/workflows/<name>.md`.
more
The engine PARSE-VALIDATES FIRST: a file the parser refuses is never written and the parse error comes back verbatim – fix and retry. Saving a stock workflow's name creates your project's customised copy (it shadows the stock one). A workflow is a SKILL definition: gate-free = pure instructions (runs free); gates make it Pro-enforced. Free; broadcasts workflow/libraryDidChange so the Studio library updates live.
delete_workflow
WORKFLOWS: delete a USER workflow from `.semanticus/workflows`.
more
Stock workflows are read-only (deleting a customised copy reverts to the stock version). Free.
check_workflow
WORKFLOWS (Learning Loop L4): the admission dry-run for a learned/authored workflow – replay-of-deterministic-steps is a later layer.
more
Parses the file (parse errors surface as usual), then statically resolves it against the live op surface and its own gate inputs: every triggers:/ops: entry must be a real op; every verify when/probe must name an input some gate collects; probe/equivalence (and object-scoped bpa_clean) verifies need a target objectRef input. Returns Ok plus info/warn findings (a distilled workflow's derived_from provenance surfaces as an info). Ok = parses AND no warn. Free, read-only.
replay_check_workflow
WORKFLOWS (Learning Loop L4): the admission layer's EXPENSIVE half – runs check_workflow (parse + op-catalog resolution) THEN a dry_run REHEARSAL of every step op the workflow's exemplar run can drive.
more
Args come from the distilled workflow's `exemplar_answers` frontmatter (the L0 log has no op args; /distill-workflow embeds the exemplar). Each op is REHEARSED (dry_run ran – wouldSucceed + delta count, or the op's own error; the model is untouched, guaranteed rollback), SKIPPED-DENIED (deny-listed/unknown – not a failure), or SKIPPED-UNBINDABLE (a required param the exemplar can't supply – named). Returns Admissible = parses clean AND no rehearsed op would fail. Deliberately does NOT: execute live DAX probes (marked replayable – they need a connection), touch the model, or run sidecar/bookkeeping ops. No exemplar → replay is SKIPPED with an instructive note, never a failure. Free, read-only.
get_op_catalog
WORKFLOWS: the engine's own MCP tool catalog (name + one-line description), reflected from the live tool surface – use it to fill a workflow step's `ops:` action chain or `triggers:` with real op names.
more
Free, read-only.
get_workflow_enforcement
WORKFLOWS: read the model-wide enforcement mode – the user's kill-switch over gate strictness.
more
null mode = no override (each workflow's own strictness applies, engine default hard); 'off' = every gate is skipped (runs record no verified evidence and gated runs start without Pro); 'warn'/'hard' force that strictness everywhere. Free, read-only.
set_workflow_enforcement
WORKFLOWS: set (or clear) the model-wide enforcement mode.
more
mode='off' disables every gate – for quick tasks where the user explicitly doesn't want enforced workflows; mode='default' (or null) restores per-definition strictness; 'hard'/'warn' force that level everywhere. Sits at the TOP of the strictness resolution (above per-gate and per-workflow overrides), is persisted in .semanticus/workflow-settings.json beside the model, and re-broadcasts the library so both doors see gated flags flip. Ask the user before turning enforcement off – it is their accountability lever, not yours.
set_workflow_enabled
WORKFLOWS: turn a workflow ON or OFF for this project – the availability toggle (which workflows are on the menu).
more
Disabled = hidden from the run picker and refused by start_workflow, but STILL listed (marked enabled:false) so it can be re-enabled. Persisted in .semanticus/workflow-settings.json beside the model (git-tracked, so the curation travels with the repo) and re-broadcast to both doors. Orthogonal to strictness (how hard gates bite) and to whether a workflow is required for a task. Free – curating your menu is content.
set_workflow_binding
WORKFLOWS: require an op to route through a workflow – the "Required for…" control (the third axis: availability · REQUIRED · strictness).
more
require is the allowed workflow set (you pick among them by whenToUse); mode 'hard' REFUSES the bare op and steers you to start_workflow, 'warn' allows it but records a compliance advisory, 'off' (or an empty require) CLEARS the binding. The bare op is exempt only while an active run of a required workflow is AT a step that performs it (start-and-freestyle does not satisfy the mandate). Persisted in .semanticus/workflow-settings.json beside the model (git-tracked, so the mandate travels with the repo) and re-broadcast to both doors. Independent of the strictness kill-switch – a mandate is whether you must ENTER a run, not how hard its gates bite. Pro for 'hard'/'warn' (mandatory routing is the enforcement); clearing is free unless the binding is locked team policy. get_workflow_policy shows the current rules.
get_workflow_policy
WORKFLOWS: this project's whole workflow POLICY in one compact read – the model-wide enforcement mode, one row per workflow (on the menu? gated? its whenToUse hint, and the ops that REQUIRE it), and the raw op→workflow bindings (op, required set, mode, whether locked team policy).
more
Token-lean (no step bodies): read it BEFORE authoring so you self-route into a required workflow instead of hitting a mandate by rejection. Free, read-only.
list_workflow_templates
TEMPLATES: list the workflow-template shelf – the fill-in-your-own-process recipes (stock shipped with the engine + this project's `.semanticus/workflow-templates/*.md`; a user file shadows a stock one of the same name).
more
A template is NOT a runnable workflow: it has declared SLOTS you fill once (your KPI dictionary, your close checklist, your freeze window) and instantiate into a concrete workflow. Each entry shows the slot count + names and any parse error (surfaced, never hidden). Free, read-only. Next: get_workflow_template to read one, instantiate_workflow_template to fill it in.
get_workflow_template
TEMPLATES: read one template's full definition – its slot declarations (the questions to ask the user, each with an example) plus the raw markdown body with the {{slot}} references intact, so you can see exactly what will render.
more
Free, read-only. To fill it in, collect a value for each slot (ask the user the slot's question verbatim) and call instantiate_workflow_template.
instantiate_workflow_template
TEMPLATES: fill a template into a concrete, runnable workflow.
more
valuesJson is a JSON object keyed by slot name (ask the user each slot's question – do not invent org process). The engine renders by DETERMINISTIC text substitution (no inference), then enforces the STRUCTURE-PRESERVING INVARIANT: it renders once with your values and once with dummy values, parses both, and REFUSES if your values changed anything the engine ENFORCES – a step, a gate, a check, strictness (slot values may change what a step SAYS and what a question ASKS, never what it enforces); the refusal names exactly what changed where. It then runs the same admission check a saved workflow gets, and saves the instance with provenance (template, version, date, slot values) so it can be re-instantiated later. FREE (authoring is content; the paid line is ENFORCING the instance via start_workflow). A missing required slot is refused with the slot's own question. Next: start_workflow(newName) to run it.
save_workflow_template
TEMPLATES: author or edit a USER template – write the full markdown (frontmatter with `kind: template` + a `slots:` block + '## Step N:' sections whose prose/questions reference each slot as {{slotName}}) to `.semanticus/workflow-templates/<name>.md`.
more
PARSE-VALIDATES FIRST (a file the parser refuses is never written; the error returns verbatim), and slot-validates: every {{ref}} must name a declared slot, and every slot needs an example (the trial instantiation renders with it). Saving a stock template's name creates your customised copy (it shadows the stock one). Free – authoring is content. Next: check_workflow(name) to trial-instantiate, then instantiate_workflow_template to fill it in.
delete_workflow_template
TEMPLATES: delete a USER template from `.semanticus/workflow-templates`.
more
Stock templates are read-only (deleting a customised copy reverts to the stock version). Free.
#Knowledge & learning loop 10
The learning loop’s memory: record and curate insights, recall prior experience for a model of this shape, and read the model’s fingerprint. Capture and recall are free for everyone.
add_insight
KNOWLEDGE (L1): record ONE actionable lesson – a distilled insight or a post-mortem root cause.
more
Insights are the USER'S OWN DATA: plain append-only JSONL (`.semanticus/knowledge/insights.jsonl` for project scope, `~/.semanticus/knowledge/` for global), readable without us, never rewritten. Give deterministic match keys (rule ids, gate signatures, error types, op names, domain tokens) so recall can find it. Write-gated (SSGM): it lands 'pending' until approve_insight, UNLESS the auto-approve setting is on – which DEFAULTS TO TRUE for single-user local mode (set knowledge-settings.json {"autoApprove": false} to force review). fingerprintScoped=true pins it to the CURRENT model's shape (needs an open model); false = a user-level lesson that travels across all models. Free.
edit_insight
KNOWLEDGE (L1): refine an insight's text and/or match keys – a delta append (the store is never rewritten; constraint against context collapse).
more
Provide new text and/or keys; omit one to leave it unchanged. Free.
approve_insight
KNOWLEDGE (L1): approve a 'pending' insight so recall_experience can surface it (the SSGM write-gate release).
more
No-op-safe on an already-approved insight. Free.
upvote_insight
KNOWLEDGE (L1): +1 an insight's importance counter (ExpeL – the engine counts, you judge).
more
An insight that keeps proving useful ranks higher and resists decay. Free.
downvote_insight
KNOWLEDGE (L1): -1 an insight's importance counter.
more
When the score falls to 0 the insight is materialized OUT of the live set (the delta trail is kept – nothing is erased). Use it to retire a lesson that stopped applying. Free.
delete_insight
KNOWLEDGE (L1): tombstone an insight (delta append; the JSONL is not rewritten).
more
It vanishes from the live set and recall. Prefer downvote for a lesson that merely lost relevance. Free.
list_insights
KNOWLEDGE (L1): list the live insight set with counters (score/uses/retrievals) and provenance (who/when/session/source-runs).
more
Filter by scope ('project'|'global'; omit for both) and/or status ('pending'|'approved'). Reports the count of any corrupt JSONL lines it skipped – the store never bricks. Free, read-only.
recall_experience
KNOWLEDGE (L2): before starting work on the open model, recall prior experience for THIS model shape.
more
The engine computes the model's fingerprint, reads BOTH scopes' APPROVED insights, and returns a DETERMINISTICALLY-ranked candidate set (key-term overlap with your query + same-shape fingerprint bonus + importance score + temporal decay) – each with WHY it matched (matchedKeys). This is retrieval, not judgment: YOU do the semantic ranking over the candidates and decide what applies. Returns the fingerprint too, and says so plainly when there is no prior experience for this shape. Needs an open model. Free.
get_model_fingerprint
KNOWLEDGE: the open model's deterministic fingerprint – table/measure/column counts, source types, fact/dim classification, a naming-convention hash, and the top domain-word tokens, plus the stable FingerprintKey used to scope insights to matching model shapes.
more
No inference, no embeddings. Use it to reason about 'have I seen a model like this before'. Needs an open model. Free, read-only.
purge_knowledge
KNOWLEDGE (L1): scoped one-op purge (the MemoryGraft safety valve).
more
DRY RUN by default: confirm=false returns how many live insights WOULD be erased and changes nothing; confirm=true appends a purge marker so everything before it in that scope becomes invisible on replay (the file is not rewritten). Free.
#DaxLib packages 6
Install, list, inspect and remove DAX user-defined-function packages from the DaxLib feed as atomic, undoable transactions.
daxlib_search
Search the DaxLib feed (daxlib.org – the 'app store for DAX UDFs') for packages.
more
Anonymous + read-only; no model needs to be open. Omit 'text' to list all. Returns package summaries (id, latest version, description, authors, downloads). Then use daxlib_package_info to preview a package's functions, and daxlib_install to add them.
daxlib_versions
List the published versions of a DaxLib package (newest-first, including -prerelease tags).
more
Anonymous + read-only.
daxlib_package_info
Get a DaxLib package's detail: metadata, dependencies, and the list of UDF names it would install (the blast radius to review before installing).
more
Anonymous + read-only. Omit 'version' for the latest stable.
daxlib_install
Install a DaxLib package's DAX UDFs into the OPEN model as ONE atomic, undoable transaction (raises compatibility level to 1702 if needed; pulls in dependency packages, deps-first).
more
Free. By default existing functions of the same name are left untouched (reported as skipped); pass replaceExisting=true to overwrite. Provenance is recorded so daxlib_list_installed / daxlib_uninstall work. Undoable in one step.
daxlib_uninstall
Remove a DaxLib package previously installed by Semanticus – deletes the UDFs it owns (per provenance) in one undoable batch and clears its provenance record.
more
Free.
daxlib_list_installed
List the DaxLib packages installed in the open model (from the Semanticus_DaxLibInstalled provenance annotation): id, version, and the UDF names each owns.
more
Offline – no network.
#Documentation & model spec 12
Author and read the model’s documentation narrative, and work with the declarative model spec you can build a model from or generate from an existing model or a Fabric SQL endpoint.
get_doc_model
Get the complete documentation snapshot of the model that the exporter renders: header (name, compatibility level, culture, counts), the relationship graph, every table's detail (description, hierarchies, partitions with their source – M/SQL/DAX or, for Direct Lake, the Entity binding – calc-group items), all measures & columns (with DAX), KPIs, roles/RLS, data sources, shared expressions, the Prep-for-AI surface, the AI-readiness + BPA scorecards, and (when live-connected) VertiPaq storage stats – PLUS any authored Documentation narrative.
more
Read-only. Use it to understand the whole model at once or to see what the built docs will contain.
get_doc_outline
List the model objects that can carry Documentation NARRATIVE (the model, every table, every measure) and which narrative sections each already has.
more
Use this to discover WHERE to add business context for the exported documentation. The narrative is ADDITIONAL context for the docs – separate from each object's first-class Description (which you set with set_description).
get_doc_section
Read one Documentation narrative section (Markdown) for an object.
more
objRef is 'model' for the model-wide narrative, or 'table:Name' / 'measure:Table/Name' (narrative is supported on the model, tables and measures). Common sectionKeys: 'overview', 'businessContext', 'notes' (per object); 'overview', 'glossary', 'methodology' (model). Returns null if empty.
set_doc_section
Author/insert a Documentation narrative section (Markdown) for an object – ADDITIONAL business context that merges into the exported documentation, SEPARATE from the model's Descriptions.
more
objRef is 'model' or 'table:Name' / 'measure:Table/Name' (narrative is supported on the model, tables and measures; other refs are rejected). Common sectionKeys: 'overview', 'businessContext', 'notes' (per object); 'overview', 'glossary', 'methodology' (model). Set markdown to empty/null to clear the section. This is the collaborate-on-the-docs path: it's stored as a model annotation, broadcasts live to the human's Documentation tab, and is undoable.
get_spec
Get the current MODEL SPEC – the structured plan for the model to build (storage mode + Fabric source, tables with columns/types/role, relationships, core measures, time-intelligence).
more
The spec is an authoring artifact (NOT the model itself); build_model_from_spec materialises it. Returns { version, source, spec } (spec is null if none is loaded). Read-only.
set_spec
Replace the current model spec with the supplied JSON (the whole ModelSpec document).
more
Use this to author or refine the spec; it broadcasts live to the Spec tab. Shape: { name, compatibilityLevel, storageMode: 'import'|'directLake', source: { kind:'fabric-sql', server, database, schema }, tables: [{ name, role:'fact'|'dimension'|'date'|'calculated'|'isolated', entity, schema, mExpression, calculatedExpression, sourceName, columns: [{ name, dataType, sourceColumn, isKey, hidden, summarizeBy }] }], relationships: [{ fromTable, fromColumn, toTable, toColumn, crossFilter, isActive }], measures: [{ table, name, dax, formatString, displayFolder }], timeIntelligence: ['YTD','PY',...], timeIntelligenceBaseMeasures: [...], dateTable: { name, startExpr, endExpr, markAsDate } }. Does NOT touch the model. Returns the new spec view.
save_spec
Save the current model spec to a JSON file (for version control / sharing).
more
Pass an absolute path, e.g. '.../model.spec.json'. Returns the spec view.
load_spec
Load a model spec from a JSON file (written by save_spec) and make it the current spec.
more
Broadcasts live to the Spec tab. Returns the loaded spec view.
clear_spec
Discard the current model spec (nothing in the model is affected – the spec never mutated it).
more
Returns the empty spec view.
autogenerate_spec_from_model
Auto-generate a starter model SPEC from the currently OPEN model (read-only – does not change the model): classifies each table fact/dimension/date/calculated by its relationship roles, captures columns + data types + keys + relationships + existing measures, PROPOSES additive 'Total <col>' measures for numeric fact columns, and suggests a time-intelligence set + date table.
more
The autogen is a FIRST DRAFT – refine it (set_spec / the Spec tab), then build_model_from_spec. Returns the spec view.
autogenerate_spec_from_fabric
Auto-generate a starter model SPEC by introspecting a FABRIC SQL ENDPOINT (Warehouse / Lakehouse SQL analytics endpoint) over TDS – reads INFORMATION_SCHEMA (tables, columns + types, declared PK/FK) using your Entra identity (a deterministic, read-only schema read; no data is copied).
more
Classifies fact/dimension from FK topology, maps SQL types to TOM types, hides key columns, and proposes additive measures + a time-intelligence set. storageMode 'import' (M) or 'directLake'. authMode: azcli (default) | serviceprincipal | interactive | devicecode. The result is a FIRST DRAFT – refine it, then create_model + build_model_from_spec. (Fabric often declares no enforced keys, so relationships may be empty – add them in the spec.) Returns the spec view.
build_model_from_spec
Materialise the current model spec INTO the open model as ONE undoable transaction (a single undo reverts the whole build).
more
Composes the authoring primitives in dependency order: data source + shared M -> tables (import/Direct Lake/calculated, with columns + data types + keys) -> relationships (FK->PK) -> date table -> measures -> time-intelligence. Existing objects are skipped (re-run safe); per-row failures are reported without aborting. Build INTO the current session – call create_model first for a from-scratch build. Returns a report (created/skipped/errors + before->after counts).
#Data agents 7
Create, read, update, publish and delete Fabric data-agent items, and generate a data-agent configuration from the open model. Writes are dry-run by default.
create_data_agent
Create a new (empty draft) Fabric data agent – data_agent.json + a minimal draft stage_config with aiInstructions.
more
DRY RUN by default: commit=false returns the exact request and changes NOTHING; commit=true creates it. aiInstructions capped at 15000 chars.
get_data_agent
Get one data agent's decoded configuration: the draft (and published, if any) stage – aiInstructions, each data source (type, ids, descriptions, the raw elements tree, few-shots), and the publish description.
more
Live read; read-only.
list_data_agents
List the Fabric data agents in a workspace (id, name, description, type).
more
Live read against api.fabric.microsoft.com with your Entra identity; read-only. [verify-at-build]: the item type string isn't documented yet, so this filters items whose type CONTAINS 'dataagent' (case-insensitive) – if none match, ObservedItemTypes lists every item type in the workspace so you can confirm the real one.
update_data_agent
Update a data agent's DRAFT – replace only the parts you pass (null = keep).
more
Read-modify-write: fetches the current definition and re-emits ALL existing parts plus your changes (never drops unknown parts). aiInstructions capped at 15000 chars. datasourceJson/fewshotsJson go under the draft/{datasourceFolder}/ folder (folder = 'semantic_model-<name>'). DRY RUN by default: commit=false returns the exact request and changes NOTHING.
publish_data_agent
Publish a data agent: copy every draft/* part to published/* and write publish_info.json with a description ([verify-at-build] – v1 publishes via the documented definition-write path).
more
DRY RUN by default: commit=false returns the exact request and changes NOTHING; commit=true publishes.
delete_data_agent
Delete a Fabric data agent item.
more
DRY RUN by default: commit=false returns the exact request and changes NOTHING; commit=true deletes it (irreversible).
generate_data_agent_config
PRO.
more
Build a complete semantic_model datasource config FROM the open model in one shot – an element tree of every table/column/measure with model descriptions carried and is_selected honoring hidden objects + the Prep-for-AI AI-data-schema exclusions; aiInstructions seeded from the model's LSDL instructions. Returns the JSON for review (feed it to update_data_agent) – writes NOTHING. artifactId/workspaceId come back as placeholders (resolve the real Fabric ids first – see the Note). Free alternative: assemble the datasource.json by hand and call update_data_agent.
#Deploy, pipelines, ALM & Fabric 17
Ship the model: the deploy gate, live metadata deploy, Fabric deployment pipelines, Fabric Git sync, and a CI/CD scaffold. Cloud writes are dry-run by default and gated.
deploy_gate
The deploy-readiness gate: runs the BPA + AI-readiness scans (and, if a target is given, the pending-change count) and returns pass/block + the blockers.
more
This is the guardrail the deploy/publish actions check before a live write. Read-only. WAIVED BPA findings never block (they're audited acceptances – bpaWaivedBlocking counts them); readiness hard-gates ignore waivers by design.
deploy_live
DEPLOY the session's metadata edits back to the live Power BI / Fabric / Azure AS model over XMLA (the write half of open_live).
more
Metadata only – names/descriptions/visibility/categories/format strings/folders/summarize-by, measure + calc-column DAX, partition sources (M / calc-table DAX / legacy), shared expressions, and the linguistic schema – via Model.SaveChanges(), matched by LineageTag so renames land on the right object. NO data refresh and NO deletes; structural changes (new tables/data columns/partitions, source-type or Direct Lake rebinds, incremental-refresh policy) are reported in Unmatched/LiveOnly, never silently dropped. Empty endpoint = deploy back to the model this session opened (the round-trip); or pass endpoint + database. DRY RUN by default – commit=true writes. Needs a Read-Write XMLA endpoint and a write principal (authMode=serviceprincipal is the reliable one).
preview_deploy
Preview what promoting a model between pipeline stages WOULD change (New vs Update per item, by source→target pairing) + the readiness gate.
more
Read-only – deploys nothing. ('Update' items may be identical; Different-vs-NoDifference is only known after a real deploy.)
deploy_stage
Promote items between Fabric deployment-pipeline stages.
more
DRY RUN by default (the New/Update preview + the readiness gate); commit=true deploys. An agent may deploy to NON-production stages only – promoting to PRODUCTION needs a human confirming from the Deploy tab with the confirmToken their own dry-run shows. A failing gate blocks unless forceOverride=true. items = source item ids (empty = all supported).
deployment_history
List a deployment pipeline's recent deployments (status, source→target stages, item counts, who deployed).
more
Read-only.
get_pipeline_stages
List a deployment pipeline's stages in order (Dev=0, Test=1, Prod=2…) with each stage's assigned workspace.
more
Needs an Admin role on the pipeline. Live read; read-only.
get_stage_items
List the items in a pipeline stage (itemType e.g. SemanticModel/Report, with source/target item ids + last deployment time) – use it to resolve the SemanticModel itemId to deploy.
more
Needs Contributor on the stage workspace. Live read; read-only.
list_deployment_pipelines
List the Fabric deployment pipelines you can access (id, displayName, description).
more
Use get_pipeline_stages then get_stage_items to drill into a pipeline's Dev/Test/Prod stages. Live read; read-only.
list_workspaces
List the Fabric workspaces you can access (id, displayName, type, capacity).
more
Live read against api.fabric.microsoft.com using your Entra identity. Read-only.
cicd_generate
Generate a ready-to-run fabric-cicd CI scaffold (parameter.yml + a GitHub Actions or Azure DevOps workflow + deploy.py) running the real publish_all_items in CI.
more
Pure file authoring – no Fabric call. Returns the contents; write=true also writes them into the repo.
cicd_publish
Publish the OPEN model's on-disk definition (PBIP/TMDL) to a Fabric workspace via updateDefinition – a FULL OVERWRITE of the target semantic model.
more
DRY RUN by default (enumerates parts + target, writes nothing); the live publish (commit=true) is human-only from the Deploy tab – an agent's commit is refused, previewing is allowed.
fabric_git_connect
Connect a workspace to a git repo (Azure DevOps or GitHub).
more
DRY RUN by default (commit=false). Pass commit=true to connect. Needs workspace Admin. After connecting, initialize + fabric_git_update/commit to sync.
fabric_git_connection
The workspace's Fabric Git connection: provider (Azure DevOps / GitHub), repo/branch/directory, connection state, last-synced commit.
more
Read-only.
fabric_git_status
The workspace ⇄ git diff: each changed item (workspace change vs remote change vs conflict), plus the workspace + remote commit hashes.
more
Read-only.
fabric_git_update
Update the WORKSPACE from git (git→workspace) – OVERWRITES workspace items with the git version.
more
DRY RUN by default (commit=false reports the incoming change count + any conflicts). Pass commit=true to apply. conflictPolicy = PreferRemote (default) | PreferWorkspace; allowOverride=true permits overwriting items that have workspace changes.
fabric_git_commit
Commit the WORKSPACE's changes to git (workspace→git).
more
DRY RUN by default (commit=false reports the pending change count; writes nothing). Pass commit=true to commit. items = item objectIds for a selective commit (empty = all).
fabric_git_disconnect
Disconnect a workspace from git.
more
DRY RUN by default (commit=false). Pass commit=true to disconnect. Needs workspace Admin.
#Git (model source control) 9
Source control for the model’s files: clone, status, diff, log, branch, checkout, pull, commit and push. Outward writes are dry-run or confirm-gated.
git_clone
Clone a git repository (load a model FROM source control) and locate the semantic model inside it.
more
Returns the model path to open with open_model. Uses the user's git credential helper.
git_status
Source control status of the OPEN model's git repository: current branch, ahead/behind, and the changed TMDL files (staged/worktree).
more
Also flags whether the open model has unsaved in-memory edits (git_commit saves them to disk first). Read-only.
git_diff
The unified text diff of the open model's git working tree (the on-disk TMDL diff).
more
Pass a file path to scope it; staged=true for the staged diff. Read-only.
git_log
Recent commits on the open model's repository (hash, author, date, subject).
more
Read-only.
git_branch
List branches (no name), create a branch (create=true), and/or switch to it (checkout=true).
more
Switching changes the on-disk model files – reopen the model afterward (the result flags modelReloadNeeded).
git_checkout
Switch to a git ref (branch / tag / commit).
more
Changes the on-disk model files – reopen the model afterward (modelReloadNeeded).
git_pull
Fast-forward pull the current branch from its upstream.
more
Changes the on-disk model files – reopen afterward (modelReloadNeeded).
git_commit
Commit the open model to git.
more
DRY RUN by default (commit=false returns the file set that WOULD be committed and whether the model needs saving first; nothing changes). Pass commit=true to actually commit – it SAVES the open model's unsaved edits to disk first, stages the model folder, then commits. Returns the commit hash + files.
git_push
Push commits to the remote.
more
DRY RUN by default (confirm=false reports what would push). Pass confirm=true to push. Uses the user's git credential helper – the engine never handles git credentials.
#Utilities 4
The odds and ends: the current entitlement tier, saved diagram positions, and the one-way compatibility-level upgrade.
get_entitlement
Get the current Semanticus tier (free | pro).
more
The free tier is fully usable one edit at a time; Pro unlocks the one-click BULK apply (apply_plan with >1 item, bpa_fix_all, apply_safe_fixes). Check this before attempting a bulk apply so you can fall back to applying items individually on free.
get_layout
Get the saved diagram positions for the model's tables (x/y, and width/height when set).
more
Returns only tables that HAVE a stored position – tables not listed are unplaced (auto-laid-out by the UI). Positions are engine-owned (a .semanticus/layout.json sidecar beside the model), keyed by a stable LineageTag so a position survives a table RENAME, and excluded from the model diff. Read it to render or reason about the table layout the human sees.
save_layout
Persist diagram positions for tables (x/y, optional width/height).
more
Identify each table by its `ref` (preferred) or `name`. MERGES with existing positions (tables you omit keep theirs; deleted tables are pruned) and the engine re-keys each by its stable LineageTag, so the layout survives renames. Writes the .semanticus/layout.json sidecar beside the model – this is NOT a model edit (it does not touch the model definition or its diff). The model must be saved on disk first; otherwise returns an Error.
set_compatibility_level
Raise the model's compatibility level (a ONE-WAY upgrade).
more
Needed for newer features – DAX user-defined functions require 1702+. Refuses to lower it. Undoable within the session, but re-deploying an upgraded model to an older runtime may fail.
Semanticus