plugins/powerbi-master/skills/tmdl-mastery/SKILL.md
TMDL (Tabular Model Definition Language) mastery for Power BI semantic models. PROACTIVELY activate for: (1) writing or editing TMDL files, (2) TMDL syntax (model.tmdl, database.tmdl, relationships.tmdl, table folders), (3) TMDL serialization (TmdlSerializer, folder-based vs single-file), (4) TMDL view in Power BI Desktop, (5) TMDL vs TMSL vs BIM format selection, (6) TMDL expressions, calculation groups, perspectives, cultures, translations, annotations, (7) TMDL roles and security, (8) TMDL ref keyword and createOrReplace scripts, (9) TMDL CI/CD integration (Git, deployment), (10) TMDL hierarchies and partitions. Provides: TMDL syntax reference, folder-layout templates, serialization patterns, ref/createOrReplace recipes, and Git integration setup.
npx skillsauth add JosiahSiegel/claude-plugin-marketplace tmdl-masteryInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
TMDL reference for language syntax, folder structure, object types, expressions, serialization API, CI/CD, and deployment. TMDL is the human-readable, source-control-friendly format for Power BI and Analysis Services semantic models at compatibility level 1200+.
| Aspect | Status (as of April 2026) |
|--------|---------------------------|
| TMDL language GA | GA since August 2024 -- no longer preview |
| TMDL view in Power BI Desktop | GA -- semantic highlighting, autocomplete, code actions, diff preview, compatibility prompts |
| TMDL as default PBIP semantic-model format | Default -- model.bim is the legacy BIM format; new PBIP projects write definition/*.tmdl files |
| Fabric Git integration | Exports semantic models as TMDL (not TMSL/BIM) |
| TMSL / BIM | Not deprecated -- still supported for XMLA scripting commands and tools that require JSON. Use TMDL for source control, TMSL for XMLA createOrReplace command scripting |
| Compatibility level | 1550+ recommended; 1601+ required for some newer properties (e.g., formatStringDefinition, calculation group multi/empty selection expressions) |
| Tabular Editor 2 (free) | TMDL read/write support (2.17+) |
| Tabular Editor 3 (paid) | Full TMDL IDE with DAX debugger and diagram view |
| VS Code TMDL extensions | Microsoft analysis-services.TMDL and community CPIM.TMDL-language-support (DAX + M highlighting, code actions, formatting, breadcrumbs) |
| Report Server | No TMDL support -- continues to use legacy PBIX binary format |
Bottom line: Use TMDL for new Power BI / Fabric semantic models under source control. Retain TMSL for XMLA scripting or tools that require model.bim.
| Aspect | TMDL (.tmdl folder) | TMSL / BIM (model.bim) | |--------|---------------------|------------------------| | Format | YAML-like text, indentation-based | Single JSON file | | Files | One file per table, role, culture, perspective | One monolithic file | | Git friendliness | Excellent -- granular diffs, minimal merge conflicts | Poor -- entire model in one diff | | Human readability | High -- minimal delimiters, DAX/M inline | Low -- escaped JSON strings | | Tooling | VS Code extension, TMDL view in Desktop, Tabular Editor 3 | Any JSON editor, Tabular Editor 2/3 | | API | TmdlSerializer (.NET) | JsonSerializer (.NET), TMSL commands | | Migration | Can convert from BIM via Tabular Editor or Desktop | Default legacy format |
When to use TMDL: Any new source-controlled, CI/CD, or team PBIP project.
When to use TMSL/BIM: Legacy projects, Report Server (no TMDL support), or tools that only accept BIM.
Declare objects by specifying the TOM object type followed by its name:
model Model
culture: en-US
table Sales
measure 'Sales Amount' = SUM(Sales[Amount])
formatString: $ #,##0
column 'Product Key'
dataType: int64
sourceColumn: ProductKey
summarizeBy: none
Key rules:
'My ''Special'' Table'Properties use colon delimiter; expressions use equals delimiter:
column Category
dataType: string /// colon for non-expression properties
sortByColumn: 'Cat Order' /// colon for object references
isHidden /// boolean shortcut (true implied)
isAvailableInMdx: false /// explicit boolean
measure Total = SUM(Sales[Amount]) /// equals for default expression
formatString: $ #,##0 /// colon for properties after expression
Text property values: Leading/trailing double-quotes optional and auto-stripped. Required if value has leading/trailing whitespace. Escape internal double-quotes by doubling them.
| Object Type | Default Property | Language | |-------------|-----------------|----------| | measure | Expression | DAX | | calculatedColumn | Expression | DAX | | calculationItem | Expression | DAX | | partition (M) | Expression | M | | partition (calculated) | Expression | DAX | | tablePermission | FilterExpression | DAX | | namedExpression | Expression | M | | annotation | Value | Text | | jsonExtendedProperty | Value | JSON |
Default properties use equals (=) on the same line or as multi-line expression on the following lines.
/// Single-line expression
measure 'Sales Amount' = SUM(Sales[Amount])
/// Multi-line expression (indented one level deeper than parent properties)
measure 'YoY Growth %' =
VAR CurrentSales = [Sales Amount]
VAR PYSales = CALCULATE([Sales Amount], SAMEPERIODLASTYEAR('Date'[Date]))
RETURN DIVIDE(CurrentSales - PYSales, PYSales)
formatString: 0.00%
/// Triple-backtick block for verbatim content (preserves whitespace exactly)
partition 'Sales-Part' = m
mode: import
source = ```
let
Source = Sql.Database("server", "db"),
Sales = Source{[Schema="dbo",Item="Sales"]}[Data]
in
Sales
```
Expression rules:
/// This table contains all sales transactions
/// Updated daily via incremental refresh
table Sales
/// Total revenue across all product lines
measure 'Sales Amount' = SUM(Sales[Amount])
Triple-slash comments above an object become its TOM Description property. No whitespace between description block and object type keyword.
Reference another TMDL object or define collection ordering:
/// In model.tmdl -- defines table ordering for deterministic roundtrips
model Model
culture: en-US
ref table Calendar
ref table Sales
ref table Product
ref table Customer
ref culture en-US
ref culture pt-PT
ref role 'Regional Manager'
Rules: Objects referenced but missing their file are ignored on deserialization. Objects with files but no ref are appended to collection end.
definition/
database.tmdl # Database properties (compatibilityLevel, etc.)
model.tmdl # Model properties, ref declarations
relationships.tmdl # All relationships
expressions.tmdl # Shared/named expressions (Power Query parameters)
functions.tmdl # DAX user-defined functions
dataSources.tmdl # Legacy data sources
tables/
Sales.tmdl # Table + all its columns, measures, partitions, hierarchies
Product.tmdl
Calendar.tmdl
roles/
RegionalManager.tmdl # Role definition with permissions and members
Admin.tmdl
cultures/
en-US.tmdl # Translations for all objects in this culture
pt-PT.tmdl
perspectives/
SalesView.tmdl # Perspective definition
One file per table, role, culture, and perspective. All inner metadata (columns, measures, partitions, hierarchies) lives inside the parent table file.
Apply changes to a live semantic model using the TMDL view in Power BI Desktop:
createOrReplace
table 'Time Intelligence'
calculationGroup
precedence: 1
calculationItem Current = SELECTEDMEASURE()
calculationItem YTD =
CALCULATE(SELECTEDMEASURE(), DATESYTD('Calendar'[Date]))
calculationItem PY =
CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date]))
column 'Time Calc'
dataType: string
sourceColumn: Name
sortByColumn: Ordinal
column Ordinal
dataType: int64
sourceColumn: Ordinal
summarizeBy: none
Only one command verb per script execution. The createOrReplace command creates or replaces specified objects and all descendants.
TMDL uses strict whitespace indentation with a default single tab per level:
table, measure, column)dataType, formatString)Database-level and model-level direct children (table, relationship, role, culture, perspective, expression) do not require indentation since they are implicitly under the root. Incorrect indentation produces a TmdlFormatException.
using Microsoft.AnalysisServices.Tabular;
// Serialize model to TMDL folder
TmdlSerializer.SerializeDatabaseToFolder(database, @"C:\output\model-tmdl");
// Deserialize TMDL folder back to TOM
var db = TmdlSerializer.DeserializeDatabaseFromFolder(@"C:\output\model-tmdl");
// Serialize single object to string
string tmdl = TmdlSerializer.SerializeObject(table.Measures["Total Sales"]);
NuGet package: Microsoft.AnalysisServices.NetCore.retail.amd64 (or .NET Framework equivalent)
Error types: TmdlFormatException (invalid syntax) and TmdlSerializationException (valid syntax but invalid TOM metadata). Both include Document, Line, and LineText properties.
Before deploying any TMDL you've generated, run the four-layer validation pipeline from the powerbi-master:validation-testing skill:
TmdlSerializer.DeserializeDatabaseFromFolder catches TmdlFormatException (bad indentation, invalid keywords)TmdlSerializationException (invalid property combinations) and model.Validate() catches dangling references-A switch or semantic-link-labs.run_model_bpa runs the standard Microsoft BPA rule setmodel.Validate().Errors plus custom Tabular Editor C# scripts catch sortByColumn / measure-references-column issuesThe validation-testing skill provides ready-to-run recipes (C#, Python, GitHub Actions YAML) for each layer. Always validate before recommending a deploy.
The TMDL view is an integrated code editor inside Power BI Desktop for scripting semantic-model changes. As of the 2026 release wave its feature set includes:
formatStringDefinition), Desktop prompts to upgrade automaticallyTMDLScripts/ folder in PBIP projects (one file per tab)createOrReplace; multi-select with Ctrl before draggingsourceColumn (Power Query editor still shows the source name)fact_, dim_) or case changesLimitation: Desktop does not hot-reload TMDL files changed externally. After editing .tmdl files in VS Code, restart Power BI Desktop to pick up the changes.
For scripting semantic models from Python without a .NET toolchain, use semantic-link-labs (PyPI: semantic-link-labs) inside a Fabric notebook. It provides a Pythonic wrapper over TOM:
%pip install semantic-link-labs -q
import sempy_labs as labs
from sempy_labs.tom import connect_semantic_model
with connect_semantic_model(dataset="SalesModel", workspace="Sales-Dev", readonly=False) as tom:
# Add a measure
tom.add_measure(
table_name="Sales",
measure_name="Sales Amount",
expression="SUM(Sales[Amount])",
format_string="$ #,##0.00",
display_folder="Revenue",
)
# Add an incremental refresh policy
tom.add_incremental_refresh_policy(
table_name="Sales",
column_name="OrderDate",
start_date="2020-01-01T00:00:00",
end_date="2025-12-31T00:00:00",
incremental_granularity="Day",
incremental_periods=30,
rolling_window_granularity="Month",
rolling_window_periods=36,
)
# tom.save_changes() is called automatically on context exit
See references/tmdl-programmatic-python.md for a full cookbook.
references/tmdl-syntax-reference.md -- Complete TMDL syntax and grammar reference with all object types, properties, and expression rulesreferences/tmdl-examples-cookbook.md -- Copy-pasteable TMDL examples for every object type: tables, columns, measures, partitions, relationships, roles, perspectives, cultures, calculation groups, hierarchies, KPIs, annotations, and field parametersreferences/tmdl-cicd-patterns.md -- CI/CD pipelines, Git integration, deployment patterns, Tabular Editor CLI, Azure DevOps and GitHub Actions workflows, and merge conflict strategiesreferences/tmdl-programmatic-python.md -- semantic-link-labs / SemPy TOM scripting from Fabric Python notebooks: measures, calc groups, incremental refresh, RLS, Direct Lake, BPA, and model export patternspowerbi-master:validation-testing -- Validate TMDL artifacts before deployment: TmdlSerializer parser, TOM Validate, BPA via Tabular Editor CLI / semantic-link-labs, custom C# rule scriptscreateOrReplace command documentationdevelopment
This skill should be used when the user asks to train, debug, scale, or improve ML models. PROACTIVELY activate for: (1) PyTorch, TensorFlow/Keras, JAX, Flax, Hugging Face Trainer/Accelerate training loops, (2) distributed training, DDP/FSDP/DeepSpeed, TPU/GPU setup, (3) mixed precision AMP/bf16, gradient accumulation, checkpointing, seeding, (4) overfitting, imbalance, loss functions, regularization, LR schedules, warmup, (5) memory optimization, gradient checkpointing, offloading, quantization-aware training. Provides: reproducible training best practices across deep learning and classical ML.
development
This skill should be used when the user asks to productionize, track, version, govern, monitor, or automate ML systems. PROACTIVELY activate for: (1) MLflow, Weights & Biases, Neptune, Comet, ClearML experiment tracking, (2) model registry, model versioning, artifact lineage, reproducibility, (3) Kubeflow, SageMaker Pipelines, Vertex AI Pipelines, Azure ML pipelines, Databricks workflows, (4) CI/CD, continuous training/evaluation, A/B tests, canary/shadow deployments, (5) drift detection, model monitoring, data validation, responsible AI governance. Provides: end-to-end MLOps architecture and operational safeguards.
development
This skill should be used when the user asks to optimize, export, serve, compress, or accelerate ML inference. PROACTIVELY activate for: (1) latency, throughput, p95/p99, batching, concurrency, KV cache, memory, or cost issues, (2) quantization INT8/INT4, GPTQ, AWQ, bitsandbytes, pruning, sparsity, distillation, (3) ONNX export, ONNX Runtime, TensorRT, TorchScript, torch.compile, XLA, OpenVINO, Core ML, TFLite, (4) Triton, TorchServe, TF Serving, BentoML, Seldon, KServe configuration, (5) edge deployment, CPU/GPU/TPU/Inferentia serving. Provides: hardware-aware inference optimization and safe benchmarking.
testing
This skill should be used when the user asks to tune hyperparameters, run sweeps, optimize search spaces, or use AutoML. PROACTIVELY activate for: (1) Optuna, Ray Tune, FLAML, AutoGluon, Hyperopt, Nevergrad, KerasTuner, W&B sweeps, (2) grid search, random search, Bayesian optimization, TPE, Gaussian processes, evolutionary search, (3) ASHA, Hyperband, successive halving, multi-fidelity optimization, population-based training, (4) learning-rate finder, batch-size search, early stopping, pruning, (5) reproducible sweep design and experiment analysis. Provides: budget-aware hyperparameter search strategy.