Labsco
microsoft logo

fabriciq-ontology-consumption-cli

✓ Official729

by microsoft · part of microsoft/skills-for-fabric

Explore Fabric IQ Ontology (preview) items (read-only) from the CLI to ground an agent before it queries data. Explore, describe, and summarize what an ontology exposes — its entity types, keys, relationships, and the bindings that map each concept onto a lakehouse or Eventhouse source — then route the underlying data query to the matching per-datasource consumption skill (eventhouse-consumption-cli, spark-consumption-cli, sqldw-consumption-cli). Read-only discovery via Get Item Definition; neve

🧩 One of 7 skills in the microsoft/skills-for-fabric package — works on its own, and pairs well with its siblings.

This is the playbook your agent receives when the skill activates — you don't need to read it to use the skill, but it's here to audit before installing.

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-updates skill (e.g., /fabric-skills:check-updates).
  • Claude Code / Cowork / Cursor / Windsurf / Codex: read the local package.json version, then compare against remote via git 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

  1. Ontology is preview. The item type value is Ontology. Wire format and limitations may change; validate against the current docs before production use.
  2. This skill is read-only. It never calls createItem or updateDefinition. For schema changes, delegate to fabriciq-ontology-authoring-cli.
  3. 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).
  4. Projections (a semantic query layer over ontology entities) are not yet GA. Until they ship, all data queries run against the source table (LakehouseTable or KustoTable) using the columns declared in the binding's propertyBindings[].
  5. To find the workspace details (including its ID) from workspace name: list all workspaces and use JMESPath filtering.
  6. To find the ontology item ID from workspace ID and item name: list all items of type Ontology in that workspace and use JMESPath filtering.

fabriciq-ontology-consumption-cli — Fabric Ontology Consumption via CLI

Table of Contents

TaskReferenceNotes
Finding Workspaces and Items in FabricCOMMON-CLI.md § Finding Workspaces and Items in FabricMandatory — resolve workspace/item IDs before enumerating
Fabric Topology & Key ConceptsCOMMON-CORE.md § Fabric Topology & Key ConceptsWorkspace → Item hierarchy
Authentication & Token AcquisitionCOMMON-CORE.md § Authentication & Token AcquisitionUse https://api.fabric.microsoft.com audience for control plane
Core Control-Plane REST APIsCOMMON-CORE.md § Core Control-Plane REST APIsGet Item Definition
Long-Running Operations (LRO)COMMON-CORE.md § Long-Running Operations (LRO)getDefinition returns an LRO
Rate Limiting & ThrottlingCOMMON-CORE.md § Rate Limiting & Throttling
Authentication RecipesCOMMON-CLI.md § Authentication Recipesaz login; token acquisition
Fabric Control-Plane API via az restCOMMON-CLI.md § Fabric Control-Plane API via az restAlways pass --resource https://api.fabric.microsoft.com
Long-Running Operations (LRO) PatternCOMMON-CLI.md § Long-Running Operations (LRO) PatternPoll 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 EnvelopeInlineBase64 parts pattern — the ontology returns this shape
Ontology Definition TreeONTOLOGY-AUTHORING-CORE.md § Definition TreeAuthoritative file/folder layout of parts you will decode
EntityType & EntityTypeProperty schemaONTOLOGY-AUTHORING-CORE.md § EntityType filevalueType catalog, key / display-name contracts
DataBinding schema + source-type mappingONTOLOGY-AUTHORING-CORE.md § DataBinding fileLakehouseTable vs KustoTable; propertyBindings[] shape
RelationshipType + ContextualizationONTOLOGY-AUTHORING-CORE.md § RelationshipType fileSource/target + linking-table contract
Connection Fundamentals (EH source queries)EVENTHOUSE-CONSUMPTION-CORE.md § Connection FundamentalsCluster URI + DB discovery for KustoTable bindings
Performance Best Practices (EH source queries)EVENTHOUSE-CONSUMPTION-CORE.md § Performance Best PracticesTime filters, has vs contains
Spark consumption patterns (Lakehouse sources)SPARK-CONSUMPTION-CORE.mdFor LakehouseTable bindings, delegate read
SQL consumption patterns (SQL endpoint / DW)SQLDW-CONSUMPTION-CORE.mdFor LakehouseTable SQL-endpoint reads and Warehouse reads
Ontology ConceptsSKILL.md § Ontology Consumption ConceptsEntity / relationship / binding / grounding context
Tool StackSKILL.md § Tool Stack
ConnectionSKILL.md § ConnectionDiscover workspace, ontology ID; Get Item Definition
Consumption ScopeSKILL.md § Consumption ScopeWhat this skill does / does not do
Grounding Context Extraction (deep reference)grounding-extraction.mdDecode parts → grounding JSON for agents
Query Routing (deep reference)routing.mdBinding kind → per-datasource skill + query shape
Worked Examplesexamples.mdEnd-to-end bash recipes (enumerate → route → query)
Graph Walks (N-hop neighborhood from anchor)graph-walks.mdAnchor entity + hop budget → composed inline reads, no scripts
Snappy-Response DisciplineSKILL.md § Snappy-Response DisciplineInline-first; script only when stateful or re-runnable
Must / Prefer / Avoid / TroubleshootingSKILL.md § Must / Prefer / Avoid / TroubleshootingLLM decision rules
Agentic WorkflowsSKILL.md § Agentic WorkflowsGround-then-query loop, schema-aware query generation
Agent Integration NotesSKILL.md § Agent Integration NotesHow this skill composes with authoring / per-datasource skills

Ontology Consumption Concepts

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.

ConceptDefinition partWhat it tells an agent
Entity typeEntityTypes/{entityTypeId}/definition.jsonLogical type name, key properties (entityIdParts), display-name property, static properties[], timeseriesProperties[], value-type catalog
Data bindingEntityTypes/{entityTypeId}/DataBindings/{guid}.jsonWhich 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 typeRelationshipTypes/{relTypeId}/definition.jsonLink between two entity types (source/target); name; cardinality hints
ContextualizationRelationshipTypes/{relTypeId}/Contextualizations/{guid}.jsonWhich 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.


Tool Stack

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.


Connection

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.

Fetching the definition (Ontology-preview LRO gotcha)

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 the Location header. The public Fabric LRO contract supports either, but on this Ontology LRO the Location header has been observed redirecting to an *.analysis.windows.net host; polling it with a Fabric-audience token is flaky (intermittent 401/403). Poll https://api.fabric.microsoft.com/v1/operations/{operationId} on the Fabric host instead. If you must follow Location, use the audience required by that URL. If a poll ever returns a non-2xx, read the operation .error and 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.

Source-data connections (delegated)

Running the data query itself (KQL / Spark SQL / T-SQL) uses the connection patterns owned by the sibling consumption skills:

  • Eventhouse (KustoTable bindings) → EVENTHOUSE-CONSUMPTION-CORE.md § Connection Fundamentals + eventhouse-consumption-cli
  • Lakehouse (LakehouseTable bindings) → sqldw-consumption-cli (default, SQL analytics endpoint) or spark-consumption-cli (only when user explicitly wants PySpark / DataFrame work)
  • Warehouse bindings → ❓ not documented in the current shared ontology schema (LakehouseTable and KustoTable only); if encountered, surface to user rather than silently assuming sqldw-consumption-cli

The clusterUri, databaseName, workspaceId, and itemId your delegate needs are all already inside the decoded binding payload — do not rediscover them via the item APIs.


Consumption Scope

OperationThis skillDelegate 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 EventhouseRouteeventhouse-consumption-cli
Query ontology-backed data in a Lakehouse via SQL endpoint (default)Routesqldw-consumption-cli
Query ontology-backed data in a Lakehouse via Spark (explicit Spark ask only)Routespark-consumption-cli
Query ontology-backed data in a WarehouseSurface (❓ binding shape not in shared schema)
Create / alter / rebind entity types / relationshipsfabriciq-ontology-authoring-cli
Refresh an ontology's indexed stateNot in preview CLI scope

Until projections ship, all data reads are source queries — they run against the physical LakehouseTable or KustoTable using the columns listed in propertyBindings[]. 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.


Grounding Context

Deep recipe + full JSON shape: grounding-extraction.md. Quick index:

TopicReference
Fetch + LRO + decode partsgrounding-extraction.md § Fetch and Decode
Reconstruct the definition tree in memorygrounding-extraction.md § Tree Reconstruction
Produce a grounding JSON summary (entities + bindings + relationships)grounding-extraction.md § Grounding Summary Schema
Diff two ontology versionsgrounding-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.itemIdread 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.


Query Routing

Deep recipe + per-skill invocation templates: routing.md. Quick decision table:

Binding source kinddataBindingTypeDelegate (default / alternate)Query shape
LakehouseTableNonTimeSeriessqldw-consumption-cli (default, SQL endpoint) — spark-consumption-cli only when user explicitly wants PySpark / DataFramesSELECT <propertyColumns> FROM <schema>.<sourceTableName> WHERE <keyColumn> = <value>
LakehouseTableTimeSeriessqldw-consumption-cli (default) — spark-consumption-cli for Spark-only featuresSELECT ..., <timestampColumn> FROM <schema>.<sourceTableName> WHERE <keyColumn> = <v> AND <timestampColumn> >= DATEADD(hour,-1,SYSUTCDATETIME())
KustoTableTimeSerieseventhouse-consumption-cli<sourceTableName> | where <keyColumn> == "<v>" | where <timestampColumn> > ago(1h) | project <propertyColumns>
KustoTableNonTimeSeriesInvalid — preview forbids thisReject and tell the user the ontology is mis-bound
Any relationship contextualizationsqldw-consumption-cli (default; linking tables are Lakehouse, joins cleaner in T-SQL) — spark-consumption-cli alternateSELECT <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.

  • Eventhouse delegate → resolved connection (clusterUri, databaseName) + composed KQL text targeting sourceTableName with timestampColumnName filter + key predicate.
  • SQL endpoint delegate (default for Lakehouse) → resolved connection (workspaceId, itemId, sourceSchema) + composed T-SQL text.
  • Spark delegate (alternate for Lakehouse) → same resolved connection + composed Spark SQL text — use Spark-native time functions (current_timestamp() - INTERVAL 1 HOUR); do not emit T-SQL DATEADD / SYSUTCDATETIME to Spark.
  • Always translate ontology property names → propertyBindings[].sourceColumnName inside the composed query text. The delegate sees only physical columns and will not resolve ontology identifiers.
  • Always pass composite 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.


Agentic Workflows

Snappy-Response Discipline

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:

SituationInline (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

  1. Compose, don't script. Each REST call is independently meaningful; chain with && / | / jq rather than wrapping in a .py.
  2. Parallelize fan-out. Independent reads (linking-table queries, per-entity-type IN-list reads) go in & with wait, not sequential for loops.
  3. One round trip per group. WHERE id IN (...) not N×WHERE id = '...'.
  4. Cache the grounding JSON for the session — it does not change between queries, and refetching it doubles every walk's latency.
  5. Stream early. Show the anchor row and first neighbor group as soon as they return; don't block presentation on the full walk.
  6. No script unless asked. If the user says "save this for later" or "re-run nightly", then package as a script. Otherwise keep the work in chat-replayable shell.

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.

"Ground then Query" Sequence

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)

Schema-Aware Query Generation

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 Traversal

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.

Graph Walks (N-hop from an anchor)

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.


Examples

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.


Agent Integration Notes

  • This skill is read-only on the ontology item. All authoring operations (create, alter, rebind, rename) belong to fabriciq-ontology-authoring-cli — delegate there.
  • This skill does not execute data queries itself. It produces grounding context and a routing decision; the actual source query runs inside the per-datasource consumption skill you delegate to.
  • Supported downstream skills (preview): 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.
  • Orchestrator agents should hand this skill the workspace name / ID and the ontology display name / ID; it will return a grounding JSON they can reuse for subsequent delegate calls without re-fetching the definition.
  • When authoring activity is suspected mid-session (e.g., the user runs fabriciq-ontology-authoring-cli and then comes back to query), re-run the grounding pass — the cached definition is stale.
  • If a Fabric KQL MCP server is configured in the user's environment, it can substitute for 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.