From fabric-consumption
Read-only exploration of Fabric IQ Ontology entities, relationships, and bindings. Routes data queries to per-datasource consumption skills (eventhouse, spark, sqldw).
How this skill is triggered — by the user, by Claude, or both
Slash command
/fabric-consumption:fabriciq-ontology-consumption-cliThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Update Check — ONCE PER SESSION (mandatory)**
Update Check — ONCE PER SESSION (mandatory) The first time this skill is used in a session, run the check-updates skill before proceeding.
- GitHub Copilot CLI / VS Code: invoke the
check-updatesskill (e.g.,/fabric-skills:check-updates).- Claude Code / Cowork / Cursor / Windsurf / Codex: read the local
package.jsonversion, then compare against remote viagit fetch origin main --quiet && git show origin/main:package.json(or the GitHub API). If remote is newer, show the changelog and update instructions.- Skip if the check was already performed earlier in this session.
CRITICAL NOTES
- Ontology is preview. The item type value is
Ontology. Wire format and limitations may change; validate against the current docs before production use.- This skill is read-only. It never calls
createItemorupdateDefinition. For schema changes, delegate tofabriciq-ontology-authoring-cli.- This skill does not query source data directly. It enumerates ontology grounding context, then delegates the actual data read to the per-datasource consumption skill that matches the binding source kind (see Query Routing).
- Projections (a semantic query layer over ontology entities) are not yet GA. Until they ship, all data queries run against the source table (
LakehouseTableorKustoTable) using the columns declared in the binding'spropertyBindings[].- To find the workspace details (including its ID) from workspace name: list all workspaces and use JMESPath filtering.
- To find the ontology item ID from workspace ID and item name: list all items of type
Ontologyin that workspace and use JMESPath filtering.
| Task | Reference | Notes |
|---|---|---|
| Finding Workspaces and Items in Fabric | COMMON-CLI.md § Finding Workspaces and Items in Fabric | Mandatory — resolve workspace/item IDs before enumerating |
| Fabric Topology & Key Concepts | COMMON-CORE.md § Fabric Topology & Key Concepts | Workspace → Item hierarchy |
| Authentication & Token Acquisition | COMMON-CORE.md § Authentication & Token Acquisition | Use https://api.fabric.microsoft.com audience for control plane |
| Core Control-Plane REST APIs | COMMON-CORE.md § Core Control-Plane REST APIs | Get Item Definition |
| Long-Running Operations (LRO) | COMMON-CORE.md § Long-Running Operations (LRO) | getDefinition returns an LRO |
| Rate Limiting & Throttling | COMMON-CORE.md § Rate Limiting & Throttling | |
| Authentication Recipes | COMMON-CLI.md § Authentication Recipes | az login; token acquisition |
Fabric Control-Plane API via az rest | COMMON-CLI.md § Fabric Control-Plane API via az rest | Always pass --resource https://api.fabric.microsoft.com |
| Long-Running Operations (LRO) Pattern | COMMON-CLI.md § Long-Running Operations (LRO) Pattern | Poll operations/{x-ms-operation-id} until Succeeded |
| Gotchas & Troubleshooting (CLI-Specific) | COMMON-CLI.md § Gotchas & Troubleshooting (CLI-Specific) | Token audience, shell escaping |
| Definition Envelope (parts, payloadType) | ITEM-DEFINITIONS-CORE.md § Definition Envelope | InlineBase64 parts pattern — the ontology returns this shape |
| Ontology Definition Tree | ONTOLOGY-AUTHORING-CORE.md § Definition Tree | Authoritative file/folder layout of parts you will decode |
| EntityType & EntityTypeProperty schema | ONTOLOGY-AUTHORING-CORE.md § EntityType file | valueType catalog, key / display-name contracts |
| DataBinding schema + source-type mapping | ONTOLOGY-AUTHORING-CORE.md § DataBinding file | LakehouseTable vs KustoTable; propertyBindings[] shape |
| RelationshipType + Contextualization | ONTOLOGY-AUTHORING-CORE.md § RelationshipType file | Source/target + linking-table contract |
| Connection Fundamentals (EH source queries) | EVENTHOUSE-CONSUMPTION-CORE.md § Connection Fundamentals | Cluster URI + DB discovery for KustoTable bindings |
| Performance Best Practices (EH source queries) | EVENTHOUSE-CONSUMPTION-CORE.md § Performance Best Practices | Time filters, has vs contains |
| Spark consumption patterns (Lakehouse sources) | SPARK-CONSUMPTION-CORE.md | For LakehouseTable bindings, delegate read |
| SQL consumption patterns (SQL endpoint / DW) | SQLDW-CONSUMPTION-CORE.md | For LakehouseTable SQL-endpoint reads and Warehouse reads |
| Ontology Concepts | SKILL.md § Ontology Consumption Concepts | Entity / relationship / binding / grounding context |
| Tool Stack | SKILL.md § Tool Stack | |
| Connection | SKILL.md § Connection | Discover workspace, ontology ID; Get Item Definition |
| Consumption Scope | SKILL.md § Consumption Scope | What this skill does / does not do |
| Grounding Context Extraction (deep reference) | grounding-extraction.md | Decode parts → grounding JSON for agents |
| Query Routing (deep reference) | routing.md | Binding kind → per-datasource skill + query shape |
| Worked Examples | examples.md | End-to-end bash recipes (enumerate → route → query) |
| Graph Walks (N-hop neighborhood from anchor) | graph-walks.md | Anchor entity + hop budget → composed inline reads, no scripts |
| Snappy-Response Discipline | SKILL.md § Snappy-Response Discipline | Inline-first; script only when stateful or re-runnable |
| Must / Prefer / Avoid / Troubleshooting | SKILL.md § Must / Prefer / Avoid / Troubleshooting | LLM decision rules |
| Agentic Workflows | SKILL.md § Agentic Workflows | Ground-then-query loop, schema-aware query generation |
| Agent Integration Notes | SKILL.md § Agent Integration Notes | How this skill composes with authoring / per-datasource skills |
A Fabric Ontology item carries its schema as a tree of JSON files inside the item definition (same shape as authoring). Get Item Definition returns the parts as base64-encoded payloads; the consumption flow is always: fetch → decode → parse → ground → delegate.
| Concept | Definition part | What it tells an agent |
|---|---|---|
| Entity type | EntityTypes/{entityTypeId}/definition.json | Logical type name, key properties (entityIdParts), display-name property, static properties[], timeseriesProperties[], value-type catalog |
| Data binding | EntityTypes/{entityTypeId}/DataBindings/{guid}.json | Which physical table backs this entity type, the source kind (LakehouseTable / KustoTable), dataBindingType (NonTimeSeries / TimeSeries), column-to-property map, and — for timeseries — the timestamp column |
| Relationship type | RelationshipTypes/{relTypeId}/definition.json | Link between two entity types (source/target); name; cardinality hints |
| Contextualization | RelationshipTypes/{relTypeId}/Contextualizations/{guid}.json | Which Lakehouse linking table holds the (source key, target key) pairs to realize the relationship |
Grounding context = the flattened, agent-ready projection of that tree: a JSON summary an LLM can read to decide which entity type to query, which column holds the key, which table to hit, and which consumption skill to invoke. Full shape + extraction recipe: grounding-extraction.md.
Property valueType allowed values (exact): String, Boolean, DateTime, Object, BigInt, Double. Integers are BigInt (not Int64); GUIDs are modelled as String. See ONTOLOGY-AUTHORING-CORE.md § EntityTypeProperty for the full source-column → valueType mapping.
Ontology consumption uses the same Fabric control-plane tool stack as every other CLI skill — see COMMON-CLI.md § Tool Selection Rationale for the canonical list (install commands, prerequisite checks, base64 helpers, JSON tooling) and COMMON-CLI.md § Authentication Recipes for az login + token acquisition.
Per-datasource reads are delegated — you do not need the Kusto, Spark, or SQL CLI tools installed to use this skill for enumeration. They are only needed if you also invoke the downstream consumption skill in the same session.
Ontology consumption targets the Fabric control plane. You need the workspace ID and the ontology item ID; everything else (entity types, bindings, source tables, cluster URIs) is recovered by decoding the definition.
--resource https://api.fabric.microsoft.com).displayName and the ontology item ID via GET /v1/workspaces/{WS_ID}/items?type=Ontology filtered by displayName → COMMON-CLI.md § Finding Workspaces and Items in Fabric (covers pagination + JMESPath filtering).az rest invocation template → COMMON-CLI.md § Fabric Control-Plane API via az rest.Get Item Definition is Long-Running-Operation-capable. Depending on tenant/SKU, the POST may return the definition envelope inline (200 OK) or return 202 Accepted with an x-ms-operation-id header; for the 202 case, poll https://api.fabric.microsoft.com/v1/operations/{operationId} until Succeeded, then GET …/operations/{operationId}/result to receive the parts[] array. The generic LRO recipe (capture x-ms-operation-id, poll, fetch result) is in COMMON-CLI.md § Long-Running Operations (LRO) Pattern.
Ontology-preview gotcha — prefer polling the
operations/{id}endpoint over theLocationheader. The public Fabric LRO contract supports either, but on this Ontology LRO theLocationheader has been observed redirecting to an*.analysis.windows.nethost; polling it with a Fabric-audience token is flaky (intermittent401/403). Pollhttps://api.fabric.microsoft.com/v1/operations/{operationId}on the Fabric host instead. If you must followLocation, use the audience required by that URL. If a poll ever returns a non-2xx, read the operation.errorand stop — never blind-retry the POST.
The full fetch-and-decode flow for this skill (LRO capture + part decode + tree reconstruction, Bash + PowerShell + Python helpers) lives in grounding-extraction.md § Fetch and Decode. The sibling fabriciq-ontology-authoring-cli documents the same redirect-host workaround in its LRO Header Capture section — keep the two in sync if you change one.
Running the data query itself (KQL / Spark SQL / T-SQL) uses the connection patterns owned by the sibling consumption skills:
KustoTable bindings) → EVENTHOUSE-CONSUMPTION-CORE.md § Connection Fundamentals + eventhouse-consumption-cliLakehouseTable bindings) → sqldw-consumption-cli (default, SQL analytics endpoint) or spark-consumption-cli (only when user explicitly wants PySpark / DataFrame work)LakehouseTable and KustoTable only); if encountered, surface to user rather than silently assuming sqldw-consumption-cliThe clusterUri, databaseName, workspaceId, and itemId your delegate needs are all already inside the decoded binding payload — do not rediscover them via the item APIs.
| Operation | This skill | Delegate to |
|---|---|---|
| Enumerate entity types, properties, keys, display names | ✅ | — |
| Enumerate bindings (source kind, target item, property map, timestamp) | ✅ | — |
| Enumerate relationships and contextualizations | ✅ | — |
| Produce an LLM-facing grounding JSON | ✅ | — |
| Decode the full definition tree for diff / review | ✅ | — |
| Query ontology-backed data in an Eventhouse | Route | eventhouse-consumption-cli |
| Query ontology-backed data in a Lakehouse via SQL endpoint (default) | Route | sqldw-consumption-cli |
| Query ontology-backed data in a Lakehouse via Spark (explicit Spark ask only) | Route | spark-consumption-cli |
| Query ontology-backed data in a Warehouse | Surface (❓ binding shape not in shared schema) | — |
| Create / alter / rebind entity types / relationships | ❌ | fabriciq-ontology-authoring-cli |
| Refresh an ontology's indexed state | ❌ | Not in preview CLI scope |
Until projections ship, all data reads are source queries — they run against the physical
LakehouseTableorKustoTableusing the columns listed inpropertyBindings[]. Semantic features (inferred joins, derived measures) that require projections are not available from this skill; flag them to the user and proceed with source-level filtering.
Deep recipe + full JSON shape: grounding-extraction.md. Quick index:
| Topic | Reference |
|---|---|
| Fetch + LRO + decode parts | grounding-extraction.md § Fetch and Decode |
| Reconstruct the definition tree in memory | grounding-extraction.md § Tree Reconstruction |
| Produce a grounding JSON summary (entities + bindings + relationships) | grounding-extraction.md § Grounding Summary Schema |
| Diff two ontology versions | grounding-extraction.md § Diff Two Ontologies |
Grounding JSON contract — the authoritative shape lives in grounding-extraction.md § Grounding Summary Schema. Routing decisions read these fields per binding:
source.kind (LakehouseTable | KustoTable) — picks the delegate family.source.workspaceId + source.itemId — read from the binding, not the ontology (cross-workspace bindings are legal).source.sourceSchema + source.sourceTableName — Lakehouse-only has schema.source.clusterUri + source.databaseName — Kusto-only.dataBindingType (NonTimeSeries | TimeSeries) + timestampColumnName — required for TS routing.propertyBindings[].sourceColumnName — the ontology-property → physical-column remap; applied before any query is composed.relationshipTypes[].contextualizations[].sourceKeyRefBindings[] / targetKeyRefBindings[] — arrays; composite keys are legal. Join on all entries.Hand a trimmed subset of this JSON (not the raw base64 definition.parts[]) to downstream skills.
Deep recipe + per-skill invocation templates: routing.md. Quick decision table:
| Binding source kind | dataBindingType | Delegate (default / alternate) | Query shape |
|---|---|---|---|
LakehouseTable | NonTimeSeries | sqldw-consumption-cli (default, SQL endpoint) — spark-consumption-cli only when user explicitly wants PySpark / DataFrames | SELECT <propertyColumns> FROM <schema>.<sourceTableName> WHERE <keyColumn> = <value> |
LakehouseTable | TimeSeries | sqldw-consumption-cli (default) — spark-consumption-cli for Spark-only features | SELECT ..., <timestampColumn> FROM <schema>.<sourceTableName> WHERE <keyColumn> = <v> AND <timestampColumn> >= DATEADD(hour,-1,SYSUTCDATETIME()) |
KustoTable | TimeSeries | eventhouse-consumption-cli | <sourceTableName> | where <keyColumn> == "<v>" | where <timestampColumn> > ago(1h) | project <propertyColumns> |
KustoTable | NonTimeSeries | Invalid — preview forbids this | Reject and tell the user the ontology is mis-bound |
| Any relationship contextualization | — | sqldw-consumption-cli (default; linking tables are Lakehouse, joins cleaner in T-SQL) — spark-consumption-cli alternate | SELECT <targetKeyColumns> FROM <linkTable> WHERE <sourceKeyColumns> = <source-values> then join target-side bindings in a follow-up call |
Invocation contract when handing off — this skill resolves the source metadata and composes the query in the target dialect, then hands both to the delegate. The delegate (sibling skill) owns the actual connection + execution.
clusterUri, databaseName) + composed KQL text targeting sourceTableName with timestampColumnName filter + key predicate.workspaceId, itemId, sourceSchema) + composed T-SQL text.current_timestamp() - INTERVAL 1 HOUR); do not emit T-SQL DATEADD / SYSUTCDATETIME to Spark.propertyBindings[].sourceColumnName inside the composed query text. The delegate sees only physical columns and will not resolve ontology identifiers.sourceKeyRefBindings[] / targetKeyRefBindings[] — join on every element, not just the first.Because projections are not yet GA (see Critical Note #4), always translate the ontology property names the user mentions back into physical source column names (via
propertyBindings[]) before composing the delegate query. Do not pass ontology property names to the sibling skill — it will not resolve them.
powerbi-consumption-cli for Power BI reports). This keeps the shared "Fabric IQ" brand from over-triggering this skill.WS_ID and ONT_ID before fetching the definition — hardcoded GUIDs are a top failure mode.getDefinition — a 202 with x-ms-operation-id is normal; do not treat it as success. Poll operations/{operationId} until Succeeded, then GET …/operations/{operationId}/result. Prefer operations/{operationId} over raw Location polling (analysis.windows.net redirect can be flaky with a Fabric-audience token); if you follow Location, use the audience required by that URL. On a Failed/non-2xx poll, read .error and stop — never blind-retry.propertyBindings[] before generating any KQL / Spark SQL / T-SQL. The sibling consumption skills see only physical columns.TimeSeries requires a time filter on timestampColumnName. Omitting it is a full scan and often rejected by the downstream skill.workspaceId + itemId per binding — ontology bindings can reference source items in different workspaces from the ontology itself; do not assume collocation.clusterUri, and databaseName from grounding, not from a fresh list items / get eventhouse round trip. Re-fetching metadata you already have is the #1 cause of bloated call counts.FriendlyNameSupportDisabled, which silently rejects names like MyLakehouse.Lakehouse in OneLake DFS / Fabric REST URLs. Always pull the GUID from grounding and substitute it into the URL.az rest with --body @file.json for any downstream KQL / SQL payload that contains |, ", or newlines. Inline --body breaks under shell escaping — see EVENTHOUSE-CONSUMPTION-CORE.md.definition.json dumps when handing context to another agent.take 100 / TOP 100 on first read of any entity's data, then refine.az rest / curl over Python scripts for read-only consumption work — graph walks, single-entity lookups, and ad-hoc fan-out reads should compose ≤ ~15 REST calls in the shell. Reach for a script only when the work is stateful (envelope assembly, ID maps, LROs that the user wants re-runnable). See Snappy-Response Discipline and graph-walks.md.project / SELECT only the bound source columns, not the full physical table — ontology bindings imply an explicit column whitelist.propertyBindings[].where <timestampColumn> > ago(...) on TimeSeries / KustoTable reads — full scans on streaming tables are the #1 query failure.fabriciq-ontology-authoring-cli.| Symptom | Fix |
|---|---|
az rest returns 401 Unauthorized | az login; confirm --resource "https://api.fabric.microsoft.com" on the control-plane call (and the matching downstream audience when delegating — https://kusto.kusto.windows.net for EH). |
getDefinition returns 202 with no body | Expected — follow the LRO pattern; capture x-ms-operation-id and poll operations/{operationId} until Succeeded, then GET …/operations/{operationId}/result. Prefer operations/{operationId}; if polling Location, use the audience required by that URL (analysis.windows.net redirects can fail with a Fabric-audience token). |
403 Forbidden on getDefinition | Ontology requires Contributor or Reader on the ontology item plus workspace access. Ask for role assignment. |
definition.parts[] is empty | The item was created but no entity types were added. Tell the user and suggest running fabriciq-ontology-authoring-cli first. |
| Downstream KQL returns 0 rows but source table has data | Check the binding's sourceTableName casing and that clusterUri / databaseName in the binding match the live cluster. Casing mismatches cause silent empty results. |
SELECT <propertyName> fails with "invalid column" | You passed an ontology property name, not a source column name. Remap via propertyBindings[].sourceColumnName. |
| Relationship traversal returns unexpectedly few rows | Contextualization's sourceTableName (Lakehouse linking table) may be empty or stale; inspect via sqldw-consumption-cli before blaming the ontology. |
Mismatched itemId / clusterUri between binding and live Eventhouse | The backing Eventhouse was recreated; the ontology needs an authoring update. Hand off to fabriciq-ontology-authoring-cli. |
| Base64 decode produces binary junk | Part payload was not InlineBase64; check payloadType. If it's VsixPackage or an unknown kind, skip and warn. |
Consumption is read-only and should feel fast. The default mode is inline composition in the shell — not a Python wrapper. Use this checklist before reaching for a script:
| Situation | Inline (az rest / curl) | Python / shell script |
|---|---|---|
| Single-entity lookup | ✅ | ❌ |
| Time-series window read | ✅ | ❌ |
| Graph walk, hop ≤ 2 (see graph-walks.md) | ✅ | ❌ |
| Cross-source relationship traversal (LH keys → KQL fan-out) | ✅ | ❌ |
| Grounding-JSON extraction (one-shot) | ✅ | ❌ |
LRO getDefinition poll loop the user wants to re-run | ➖ | ✅ |
| Ontology authoring / mutation (35-part envelope, ID cross-refs) | ❌ | ✅ (handoff to fabriciq-ontology-authoring-cli) |
| Long-lived seeding / batch loads with retry & checkpoint | ❌ | ✅ |
Inline-first principles
&& / | / jq rather than wrapping in a .py.& with wait, not sequential for loops.WHERE id IN (...) not N×WHERE id = '...'.If a task starts to look like it needs > ~20 REST calls, > 2 hops, or persistent state across calls, surface this to the user before scripting — it usually means the question should be narrowed, not automated.
When the user asks to query data through an ontology lens:
Step 1 → Resolve WS_ID + ONT_ID (list workspaces, list items type=Ontology)
Step 2 → getDefinition (LRO) → decode all parts → reconstruct tree
Step 3 → Build grounding JSON (entities, properties, bindings, relationships)
Step 4 → Disambiguate with the user if multiple entity types / bindings could satisfy the intent
Step 5 → For the chosen entity type + binding:
a. Remap ontology property names → source column names
b. Compose the source query (KQL / Spark SQL / T-SQL)
c. Hand off to the matching sibling consumption skill with minimal fields
Step 6 → Post-process results back into ontology-property naming for the user (optional but helpful)
After a grounding pass, generate queries using the physical columns recorded in propertyBindings[], never the ontology names:
Entity type "Aircraft" with binding:
source kind = KustoTable
sourceTableName = "AircraftReadings"
timestampColumnName = "PreciseTimestamp"
propertyBindings: { AltitudeFt → SourceColumn "Temp_C", TailNumber → SourceColumn "AssetId" }
User intent: "show altitude excursions on aircraft N42ZA in the last hour"
Generated KQL (delegated to eventhouse-consumption-cli):
AircraftReadings
| where AssetId == "N42ZA"
| where PreciseTimestamp > ago(1h)
| project PreciseTimestamp, Temp_C
| where Temp_C > 80
Relationship "operates" (Airline → Aircraft)
Contextualization: LakehouseTable "HubAircraftAssignment" with (AirlineId, TailNumber) columns
AND two entity-type bindings (Airline on LakehouseTable "Airlines", Aircraft on KustoTable "AircraftReadings")
User intent: "which aircraft does Airline 'ZA' operate and what's their latest reading?"
Step 1: sqldw-consumption-cli → SELECT TailNumber FROM HubAircraftAssignment WHERE AirlineId = 'ZA'
Step 2: eventhouse-consumption-cli → AircraftReadings | where AssetId in (<TankIds>) | summarize arg_max(PreciseTimestamp, *) by AssetId
Step 3: Merge results in the agent; present with ontology-level column names.
Full end-to-end bash recipes (enumerate → ground → route → query) live in examples.md. For "show me everything related to X" prompts, jump straight to the N-hop walk in graph-walks.md.
When the user gives an instance ("Panel7", "aircraft N42ZA", "customer 1234") and asks for its neighborhood — not a single column — use the dedicated graph walk pattern instead of inventing a recipe per question.
Anchor → relationships touching anchor (from grounding JSON, in-memory)
→ linking-table reads (parallel, one per relationship)
→ IN-list reads of neighbor entities (one per EntityType)
→ optional KustoTable telemetry sweep (one per EntityType with TS binding)
For hop=1 this is typically ≤ 10 round trips and stays inline. Full algorithm, fan-out template, hop budget, and a worked Panel7 example live in graph-walks.md.
End-to-end worked examples (enumerate an ontology → build grounding JSON → route a source-table query to the correct sibling consumption skill → traverse a relationship across Lakehouse + Eventhouse) live in examples.md. N-hop neighborhood walks from an anchor instance (Panel7-style) live in graph-walks.md. Complete fetch-and-decode scripts live in grounding-extraction.md. Per-binding-type invocation templates live in routing.md.
fabriciq-ontology-authoring-cli — delegate there.eventhouse-consumption-cli, spark-consumption-cli, sqldw-consumption-cli. A standalone graph consumption skill does not yet exist — if the user asks for a graph-shaped query over relationships, surface that limitation and fall back to per-edge joins via Lakehouse / SQL.fabriciq-ontology-authoring-cli and then comes back to query), re-run the grounding pass — the cached definition is stale.az rest on the Eventhouse delegate leg. The repo's default mcp-setup/mcp-config-template.json does not register a fabric-kql server, so do not assume that name exists. Either way it does not cover ontology control-plane calls, so the fetch / grounding step still uses az rest.npx claudepluginhub microsoft/skills-for-fabric3plugins reuse this skill
First indexed Jun 26, 2026
Read-only exploration of Fabric IQ Ontology entities, relationships, and bindings. Routes data queries to per-datasource consumption skills (eventhouse, spark, sqldw).
Creates and evolves Fabric IQ Ontology items from CLI — define entity types, properties, timeseries, relationships, and bind them to OneLake lakehouse or Eventhouse tables using the Fabric REST API.
Builds, validates, governs RDF/OWL ontologies and knowledge graphs using Open Ontologies MCP server with Oxigraph triple store. For creating, modifying, querying, or managing RDF data.