Onelake Catalog CLI
MicrosoftOfficialPublished by Microsoft
- Skill
- Workflow
- Automation and integrations
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The onelake-catalog-cli skill provides a structured interface for managing the Microsoft Fabric OneLake catalog. It operates through distinct modes for governance auditing and metadata curation, ensuring that actions are performed with appropriate permissions and safety gates. The skill supports tenant-wide admin audits, data-owner governance checks, and item-level metadata curation, including descriptions, tags, and table/column metadata. It enforces strict write-gating and requires explicit owner approval for all changes to ensure data integrity and security.
What it does
- Audits tenant-wide or workspace-specific governance posture.
- Curates item metadata including descriptions, display names, and tags.
- Manages table and column descriptions for items with OneLake Tables.
- Performs guarded remediation for domains, workspace assignments, and capacities.
- Provides dry-run capabilities for governance and remediation tasks.
- Enforces strict write-gates requiring explicit user approval for all changes.
When to use it
- When you need to audit governance posture across a Fabric tenant or specific workspaces.
- When an item owner needs to improve discoverability through metadata curation.
- When a data owner needs to remediate workspace domain, capacity, or tag assignments.
- When a tenant admin needs to perform bulk governance updates or policy enforcement.
Advantages
- Provides a unified, mode-based workflow for both auditing and remediation.
- Enforces safety by requiring explicit approval for all write operations.
- Supports granular, least-privileged access for data owners.
- Includes built-in logic for handling long-running operations and API rate limits.
- Ensures governance findings are actionable and prioritized.
Usage examples
- “Propose a better description for the semantic model Sales Model in the Finance workspace.”
- The agent will read the current item metadata, draft a suggested description based on content, and present it for owner approval before applying the change.
- “Audit our tenant's OneLake catalog governance posture and prioritize the findings.”
- The agent will perform a tenant-wide audit, applying the necessary scope filters, and report findings categorized by pillar with recommended actions.
- “Which workspaces I administer are not assigned to a domain?”
- The agent will identify and list all workspaces within the caller's scope that lack a domain assignment.
- “Show a dry run for assigning these workspaces to the Finance domain, including current assignments.”
- The agent will perform a read-only check to display the current domain assignments and the proposed changes for the specified workspaces.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/onelake-catalog-cli/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip onelake-catalog-cli.zip -d .agents/skills
Documentation by Microsoft
Telemetry — MANDATORY. Every
api.fabric.microsoft.comcall must carryx-ms-fabric-skill: onelake-catalog-cli(az rest:--headers "x-ms-fabric-skill=onelake-catalog-cli"), including every LRO poll,fabric_lroand retry. Snippets omit it — add it anyway.
CRITICAL NOTES
To find the workspace ID from its name, one call:
az rest --method get --resource "https://api.fabric.microsoft.com" --url "https://api.fabric.microsoft.com/v1/workspaces" --query "value[?displayName=='<name>'] | [0].id" -o tsv(followcontinuationTokenonly if it isn't on the first page; details in COMMON-CLI.md § Finding Workspaces and Items in Fabric).To find an item's ID, one call: the same on
.../v1/workspaces/{ws}/items?type=<Type>with--query "value[?displayName=='<name>'] | [0].id".Write-gated skill — never call a write API before its gate below has passed. For curation that means the owner reviewed every proposed change and explicitly confirmed — not even a "test" write to check whether a change is allowed or what is already applied.
The item list and Get Item both return an item's
tags. An item with no tags has notagsfield — that absence means untagged.
OneLake Catalog — CLI Skill (mode dispatcher)
One skill for the OneLake catalog. Govern (catalog health, protection and trust: audits and guarded remediation, by permission tier) and curate (an owner improving specific items' discoverability metadata) are modes, each detailed in a reference loaded on demand. This file picks the mode, holds every write gate, and indexes the references.
Mode selection
| Mode | Use when | Load | Writes |
|---|---|---|---|
| curate | An owner wants specific items easier to find: a description, a clearer display name, tags, or table and column descriptions (items with a OneLake Tables folder) — one item, an explicit list, or one named workspace's weakly-described items | references/curate.md | ✅ after the owner approves each suggestion |
| dataowner-audit | A non-admin workspace or domain owner wants governance posture for workspaces they administer (widen to accessible on request; Core API) | references/dataowner-audit.md | ❌ |
| dataowner-remediate | A data owner who is also a domain / workspace / capacity admin fixes a governance finding — single-workspace domain or capacity assignment, workspace tags, refresh, item identity (Core & Power BI APIs, no tenant admin), including dry runs of these | references/dataowner-remediate.md | ✅ self-service |
| admin-audit | A Fabric tenant admin wants tenant-wide governance posture (/v1/admin/*) | references/admin-audit.md; any tenant count starts from admin-audit-scope.md | ❌ |
| admin-remediate | A Fabric tenant admin makes tenant-wide writes — domains, bulk assignment, domain roles, bulk labels, tenant tag definitions, tenant settings | references/admin-remediate.md | ✅ |
Govern is a 2×2 grid — tier (which API surface the caller can reach) × action (audit vs
remediate) — covering the health, protect and trust pillars. Choose the tier by API surface,
not job title: the admin-* modes need the Fabric tenant administrator role (Fabric admin /
Power Platform admin / M365 global admin); domain, capacity and workspace admins who are not
tenant admins live entirely in the dataowner-* modes.
Mode boundary rules
A direct curation request goes straight to curate. Read the target item's current state — don't run a governance audit first. Curation needs neither tenant admin nor workspace Admin; each change has its own permission (see curate.md).
Governance starts with an audit. Never remediate before establishing the current state; audit → remediate within the same tier unless the caller's rights change.
Curate is the only writer of item metadata. Item descriptions and display names, applying or removing an item's tags, and table and column descriptions are written only in curate. Workspace tags stay in dataowner-remediate; tenant tag definitions in admin-remediate.
Govern finds, curate fixes. Govern reports description and tag coverage — presence, with scope, denominator and freshness caveats, not proof the text is accurate; curate judges content and proposes. To fix selected gaps, hand off to curate with: a bounded target (an explicit item list with workspace ID, item ID and type, or one named workspace — never the whole tenant: ask the user to pick), the observed gap with its source and time (a candidate to recheck, not current truth), only the fields the user chose ("fix missing descriptions" = description only), and known access limits and owner contacts. A remediation is done only when curate has verified the write.
Audit modes never write. If a write is asked for in an audit mode, switch explicitly to the matching remediate mode or to curate — don't improvise a write.
A dry run or preflight of a fix loads that fix's remediate mode and stays read-only there — it isn't an audit. Moving one workspace to a domain is
dataowner-remediate; bulk assignment isadmin-remediate.Finding items when the workspace isn't known belongs to
search-consumption-cli. Looking up a workspace or domain by name, or an item by name inside a known workspace, is not discovery: use the lookups in CRITICAL NOTES and don't loadsearch-consumption-clifor it.
⚠️ Known Fabric gap. A domain or workspace admin who is not a tenant admin has no API for their scoped governance posture:
/v1/admin/*rejects them and the Core API can't list a domain's workspaces.dataowner-auditcovers only workspaces the caller can access — say so up front rather than routing into anadmin-*mode that will 401/403.
Terminal write — the step you must not skip
Reading a reference, drafting suggestions or building a dry run is NOT completing a write. Each writing mode ends with the state-changing call(s) below, issued only after the gate for that write passes. If you did not issue it, nothing changed — say so rather than reporting success.
| Mode | Terminal write |
|---|---|
curate | PATCH /v1/workspaces/{ws}/items/{id} (description; display name in a separate call), POST .../items/{id}/applyTags or unapplyTags, and for a table POST https://onelake.table.fabric.microsoft.com/common/v1/{ws}/{item}/schemas/{schema}/tables/{table}/additionalMetadata with the complete set from a fresh read — only for suggestions the owner accepted |
dataowner-remediate | POST /v1/workspaces/{id}/assignToDomain / unassignFromDomain (synchronous 200), assignToCapacity (202 — poll to a terminal state), POST /v1/workspaces/{id}/applyTags / unapplyTags (workspace tags), item identity, semantic model refresh |
admin-remediate | /v1/admin/* writes — domains, bulk workspace assignment, domain roles, labels, tenant tag definitions, tenant settings |
dataowner-audit, admin-audit | none — read-only |
Before reporting a write done, confirm an explicit success (200/201, or a terminal LRO
success for a 202) and read the result back.
Write gates — must pass first
| Write | Mode | Gate |
|---|---|---|
| Any curation write | curate | The owner saw a numbered current → proposed preview of every suggestion and explicitly approved; "apply all" covers only what was shown. Approving an audit or picking a remediation never approves text the owner hasn't seen. |
| Table and column descriptions | curate | A write replaces the table's whole additional metadata: re-read, change only the approved descriptions, send the complete set in the same command, read again. The API has no concurrency check — never claim concurrent edits were preserved. A shortcut table is written on its source — name it and get explicit confirmation. |
| Delete a domain | admin | Check subdomains (parentDomainId) and assigned-workspace counts for the domain and every subdomain; if workspaces would be orphaned, STOP and get explicit confirmation naming them. The API has no cascade-block. See domain-crud.md. |
| Delete a tag definition | admin | Report how many items carry it first — deletion detaches it everywhere with no undo. |
| Bulk-assign workspaces to a domain | admin | Check each target's current domainId and warn before silently overriding an assignment. Dry-run the target list first. |
| Remove a principal from a domain role | admin | Confirm it will not leave the domain ownerless; name the principal being removed. |
| Bulk sensitivity-label change | admin | Dry-run: show the affected items and before/after label, get confirmation. No service principal / managed identity — the call will fail. |
| Write a tenant setting | admin | Read and show the current value, then the proposed value — tenant-wide blast radius. |
| Assign / unassign one workspace to a domain | dataowner | A move is a reassignment — confirm the current domainId and name the domain it leaves. Needs domain contributor and workspace Admin; say which is missing on failure. |
| Reassign item ownership (item identity, preview) | dataowner | Assigns to the caller only; needs Write on the item and its children. Confirm the intended identity. |
| Assign a workspace to a capacity | dataowner | Needs workspace Admin plus capacity Contributor/Admin. 202 is not success — poll to a terminal state. |
| Apply / remove a workspace tag (preview) | dataowner | Needs workspace Admin. Name the workspace and the tags, and confirm. Removing an applied tag is not deleting its definition. |
Don't promise a write that has no API. Endorsement, DLP policies, an owner changing a sensitivity label, and tenant-admin item deletion have no write route — say so and name who can act (no-write-api-escalation.md). A SQL Database's display name is fixed at creation: never send a rename for it, even when the owner asks for one — say it can't be renamed and offer the description and tags instead.
Shared essentials (all modes)
Prerequisites: auth & tokens · REST, pagination, LRO, rate limits · CLI auth recipes ·
az rest(always pass--resource) · OneLake viacurl(Storage-audience token) · OneLake shortcuts.Resolve workspace and item IDs with the one-call lookups in CRITICAL NOTES 1–2.
Keep tool calls few. Each call re-sends the whole conversation, so extra calls are slow and costly. Combine related reads in one script, and don't re-open a doc you've already read.
Read an item's definition in one command that waits for the long-running operation itself (a semantic model usually returns
202) — never poll it in separate calls. It waits as long as Fabric'sRetry-Afterasks (often 20–30 s), so give the command up to 3 minutes: if your shell tool has a wait or timeout setting, raise it rather than letting the command move to the background. Only for types with a definition: Warehouse, SQL Database, SQL analytics endpoint, ML model/experiment and Datamart have none — read their schema instead. PowerShell 7 (bash:fabric_lroin COMMON-CLI.md):$h = @{ Authorization = "Bearer $(az account get-access-token --resource https://api.fabric.microsoft.com --query accessToken -o tsv)"; 'x-ms-fabric-skill' = 'onelake-catalog-cli' } $st = @{ n = 0; end = (Get-Date).AddMinutes(3) } # Waits the full Retry-After (202 and 429); backs off 2-30 s only when the header is missing or invalid. function Wait-RetryAfter($r) { $ra = 0 if (-not [int]::TryParse("$(@($r.Headers['Retry-After'])[0])", [ref]$ra) -or $ra -lt 1) { $ra = [Math]::Min(30, [Math]::Pow(2, ++$st.n)) } if ((Get-Date).AddSeconds($ra) -gt $st.end) { throw "Definition read did not finish within 3 minutes." } Start-Sleep -Seconds $ra } while (($r = Invoke-WebRequest -Method Post -Uri "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/items/$ITEM_ID/getDefinition" -Headers $h -SkipHttpErrorCheck).StatusCode -eq 429) { Wait-RetryAfter $r } if ($r.StatusCode -ge 400) { throw "getDefinition returned $($r.StatusCode): $($r.Content)" } $def = if ($r.StatusCode -eq 202) { $op = [string]$r.Headers['Location']; $res = $r; $s = '' while ($s -notin 'Succeeded', 'Failed') { Wait-RetryAfter $res; $res = Invoke-WebRequest $op -Headers $h -SkipHttpErrorCheck if ($res.StatusCode -eq 200) { $s = ($res.Content | ConvertFrom-Json).status } elseif ($res.StatusCode -ne 429) { throw "Polling returned $($res.StatusCode): $($res.Content)" } } if ($s -ne 'Succeeded') { throw "Definition read failed: $($res.Content)" } while (($res = Invoke-WebRequest "$op/result" -Headers $h -SkipHttpErrorCheck).StatusCode -eq 429) { Wait-RetryAfter $res } if ($res.StatusCode -ge 400) { throw "Definition result returned $($res.StatusCode): $($res.Content)" } $res.Content | ConvertFrom-Json } else { $r.Content | ConvertFrom-Json } $dir = New-Item -ItemType Directory -Force -Path (Join-Path ([IO.Path]::GetTempPath()) "def-$ITEM_ID") foreach ($p in $def.definition.parts) { $t = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($p.payload)); $f = Join-Path $dir ($p.path -replace '[\\/:]', '_'); Set-Content -LiteralPath $f -Value $t "== $($p.path) ($($t.Length) chars)"; if ($t.Length -le 4000) { $t } else { $t.Substring(0, 4000); "[first 4000 of $($t.Length) chars; full text in $f]" } }A part cut at 4,000 characters is saved in full: read the rest (one call) if what's shown isn't enough.
Use the exact Fabric Admin, Core, Power BI, Graph or OneLake API surface the mode documents; a
401or403is never permission to bypass RBAC.
Rules
MUST
Load exactly one mode reference for the request and follow it end to end; come back to the index below when another procedure is needed. In curate, also read the suggestion guidance before drafting anything, and the table metadata reference before any table or column work.
(curate) Propose exactly what the owner asked for. A specific request gets only that: "add a description" → the item description; "suggest tags" → tags; "describe the table" → the table description only; "describe the columns" → column descriptions only; "describe the item's objects" or "its tables and columns" → both. A general request ("curate this item", "make it more discoverable", "improve its metadata") gets the item's description, name and tags; an item with a OneLake Tables folder also gets its table and column descriptions. If the owner names several items, cover each one, and report each with only the fields it has.
(curate) Check the scope before any call. Curate covers one item, an explicit list of items, or one named workspace at a time. For a tenant-wide request ("all my items", "every workspace"), say plainly that it isn't supported and offer one named workspace or an explicit list; for several named workspaces, ask which to start with. Don't list workspaces or items first.
(govern) State scope, exclusions, pagination completeness, and freshness caveats with every governance statistic.
PREFER
Least-privileged Core or Power BI APIs for data-owner actions instead of requiring tenant-admin rights.
Findings as evidence, consequence, recommended action, priority and effort — not an inventory dump.
Sequencing ownership and access-scope fixes before bulk assignment or labeling.
AVOID
Mutating a tenant from an audit mode, or reporting an asynchronous
202as completion.Inventing write APIs for endorsement, DLP policy, admin item deletion, or third-party item-identity assignment.
(curate) Volunteering anything about table or column descriptions for items without a OneLake Tables folder (semantic models, reports, notebooks, pipelines, dataflows, …). For these items, description, name and tags are the complete list — present them without qualifiers in the preview and whenever you say what the skill can do (e.g. while declining a request, or offering what else you could review next). Don't add a note that table or column descriptions are N/A, don't apply or aren't covered, and don't offer them: the owner didn't ask. Only if they ask, answer that they aren't supported for that item type, then stop and let the owner choose — don't load another skill or draft those descriptions yourself.
(curate) Saying "sub-items" — use the owner's words: "tables" and "columns", or "objects" when speaking generally.
References
Each reference is one hop from this index; after loading one, return here when another is needed.
Curate
Curate — workflow, permission per change, preview format, examples, errors
Suggestion guidance — drafting descriptions, names and tags from content
Tag taxonomy — tenant/domain tag scope and name → ID resolution
Table metadata — table and column descriptions (OneLake table API, preview)
Curation API reference — Update Item, Apply/Unapply Tags, List Tags
Govern — shared
Govern pillars — the three pillars, what "good" looks like, reporting conventions
Governance data sources — verified API field coverage and blind spots
Governance roles — permission tiers, domain/workspace roles, insight refresh lag
Catalog concepts — the entity model and API-backed versus conceptual terms
Govern — modes
Admin audit — tenant-wide read-only governance assessment
Admin audit scope — governable denominator (active workspaces of type Workspace), exclusions, and known blind spots
Admin audit assessment — end-to-end evaluative workflow, prioritization, and deliverable contract
Admin remediate — tenant-wide guarded writes through Admin APIs
Data-owner audit — caller-scoped read-only checks through Core APIs, including a workspace's domain assignment
Data-owner workspace health — empty and inactive workspaces within the caller's scope
Data-owner remediate — least-privileged Core and Power BI writes: moving one workspace to a domain, capacity, workspace tags, refresh, item identity
Govern — admin audit procedures: domain health · workspace health · capacity health · item inventory · item health · protect coverage · trust curation
Govern — admin remediation procedures: domain lifecycle · bulk workspace assignment (tenant admin) · domain roles · tag definitions · item sensitivity labels · domain default labels · trust remediation · no-write escalation
Examples
I'm curating my items for the OneLake catalog. Propose a better description for the semantic model Sales Model in the Finance workspace.Make the lakehouse LSEGDemo more discoverable — describe its tables and columns too.Audit our tenant's OneLake catalog governance posture and prioritize the findings.Which workspaces I administer are not assigned to a domain?Show a dry run for assigning these workspaces to the Finance domain, including current assignments.Find unlabeled items tenant-wide and explain which remediations require a tenant admin versus a data owner.Files
- ATTRIBUTION.mdAdded by AutoGineer883 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md21.5 KiB
- apm.yml345 B
- references/admin-audit-assessment.md10.9 KiB
- references/admin-audit-scope.md5.7 KiB
- references/admin-audit.md14.9 KiB
- references/admin-audit/health-capacity.md7.3 KiB
- references/admin-audit/health-domains.md11.5 KiB
- references/admin-audit/health-item.md13.7 KiB
- references/admin-audit/health-workspaces.md15.4 KiB
- references/admin-audit/item-inventory.md9.1 KiB
- references/admin-audit/protect-labels-dlp.md1.4 KiB
- references/admin-audit/trust-curation.md2.8 KiB
- references/admin-remediate.md17.1 KiB
- references/admin-remediate/domain-assign-workspaces.md7.3 KiB
- references/admin-remediate/domain-crud.md10.5 KiB
- references/admin-remediate/domain-default-label.md2.6 KiB
- references/admin-remediate/domain-roles.md4.5 KiB
- references/admin-remediate/item-sensitivity-label.md2.6 KiB
- references/admin-remediate/no-write-api-escalation.md13.4 KiB
- references/admin-remediate/tags.md1.9 KiB
- references/admin-remediate/trust-curate.md3.4 KiB
- references/catalog-concepts.md7.2 KiB
- references/curate.md19.7 KiB
- references/curate/api-reference.md7.8 KiB
- references/curate/metadata-suggestion-guidance.md10.6 KiB
- references/curate/table-metadata.md9.9 KiB
- references/curate/tag-taxonomy.md3.1 KiB
- references/dataowner-audit.md14.4 KiB
- references/dataowner-audit/health-workspaces.md14.1 KiB
- references/dataowner-remediate.md15.0 KiB
- references/govern-data-sources.md7.9 KiB
- references/govern-pillars.md13.3 KiB
- references/govern-roles.md9.9 KiB
references/curate.md
Curate mode — owner curation of catalog metadata
An item owner raises discoverability by reviewing suggested descriptions, display names and tags, plus table and column descriptions for items with a OneLake Tables folder (such as a Lakehouse); approved changes are written only on explicit confirmation.
SKILL.md holds the ID lookups, the one-command definition read, the write gates and terminal
writes, and indexes the curate references (curate/metadata-suggestion-guidance.md,
curate/tag-taxonomy.md, curate/table-metadata.md, curate/api-reference.md). Auth and
pagination: common/COMMON-CLI.md (always pass --resource to az rest; the OneLake table
API needs a Storage-audience token).
Contents
Scope
Permission per change
Rules
Inputs
Workflow
Handoff from a governance audit
Output format
Examples
Error handling
Scope
Bulk — one item, an explicit list (may span workspaces), or one named workspace: list its items (
GET /v1/workspaces/{ws}/items, followingcontinuationToken), keep those lacking good metadata (empty description, weak/placeholder name, no tags), and exclude Dataflows Gen2 staging artifacts (StagingLakehouseForDataflows*/StagingWarehouseForDataflows*and their SQL endpoints — system plumbing).Tables & columns (preview API) — only items with a OneLake Tables folder; a write replaces all of a table's additional metadata. Descriptions only: tags exist only on items.
Permission per change
| Actor | Required permission | Scope |
|---|---|---|
| Item owner / creator | Read and write on the item | Change the item's description and display name |
| Item owner / creator | Contributor or higher on the workspace | Apply or remove the item's tags |
| Item owner / creator | Write access on the item, or ReadWrite through a OneLake data access role | Curate its table and column descriptions |
| Reader | Read only | Cannot apply — explain what would change and suggest asking the owner for access |
MUST check the permission for each operation before proposing to apply it; offer only the changes the caller can make. Curation needs neither tenant admin nor workspace Admin.
Rules
MUST
Read
curate/metadata-suggestion-guidance.mdbefore drafting any suggestion, andcurate/table-metadata.mdbefore any table or column work.Read the current metadata first (
GET items/{id}) and preserve fields you are not changing.Base suggestions on real content (the definition read from SKILL.md, table/schema listing) — never invent facts about the item.
Show a current → proposed diff and get explicit confirmation before any write.
Resolve tag names to applicable tag IDs via
GET /tagsbeforeapplyTags(Apply Tags takes IDs, not names). Tenant tags apply tenant-wide; domain tags are eligible for new application only whenscope.domainIdmatches the workspace's current domain.Respect limits — description ≤ 256 characters; at most 10 tags per item;
applyTags≤ 25 requests/minute (throttle bulk).Always work from fresh state, and honor re-run requests — re-read the item's current metadata + content and the live tag definitions and workspace domain on every run. If the owner asks to try again, re-analyze from scratch — never treat a repeat as an automatic no-op.
Let the owner review every suggestion — item, table, and column. Number each one; the owner can accept, edit, or reject it, or exclude a whole item or table. Write only accepted suggestions; on partial failure, continue the rest and report per item.
PREFER
High-level, durable descriptions that state what the item contains and its purpose — accurate over the long run, not tied to the item's current shape.
Reusing existing applicable tenant or domain tags over proposing new ones an admin must create.
Updating only the fields that need it (skip the display name if it's already clear and matches the item's contents; if it's well-formed but mismatched, flag it rather than skip).
AVOID
Writing anything the owner did not approve.
Overwriting a non-empty description with a generic one — offer to merge/improve instead.
Trusting a non-empty description the content doesn't back — an empty item whose description claims contents/behavior it lacks is a mismatch to flag, not a "good" description to leave alone. Never fabricate a description for an empty item.
Volatile specifics in an item description (column names, row/table counts, refresh cadence, table grain) — those belong in a point-in-time summary, not durable owner metadata.
Copying data values into table or column descriptions — describe what a column means, never sample rows, example values, or statistics. Don't read table rows to draft descriptions.
Writing through a shortcut without saying so — a shortcut table's descriptions live on the source table; name the source and get explicit confirmation before changing it.
Proposing, editing, or mentioning table/column tags — Fabric tags exist only on items. Keep any stored
tagsvalues exactly as read.Putting sensitive or confidential content into metadata — a description or tag is broadly discoverable in catalog search, visible to people who may not have access to the item's data. Never copy raw values, secrets, personal data, or restricted names into it. Don't try to auto-classify what's sensitive — the owner knows, so surface the proposed text and let them redact or reject anything at the confirm step.
Proposing tags that do not exist or domain tags that are not applicable to the target workspace (flag them clearly and exclude them from the apply call).
Pasting auth tokens into commands — acquire them at run time.
Inputs
| Input | Source | Required |
|---|---|---|
| Workspace(s) (name or ID) | user / handoff | yes |
| Item(s) (name+type or ID) — explicit set | user / handoff | one of these |
| Named workspace (curate its weakly-described items) | user names a workspace | one of these |
| Fields to curate | user / handoff | no (default: all weak fields) |
| Tables / columns to describe | user | no (only for items with a OneLake Tables folder; default: tables and columns without a good description) |
| Owner-provided edits / exclusions | user | no (applied over suggestions) |
Workflow
Resolve scope — build the target item list with the one-call lookups in SKILL.md. A single item is a batch of size 1; an explicit list is that batch. For a named workspace, confirm the caller has write access on it, enumerate its items and filter as in Scope. Set aside items whose metadata already looks complete, but still validate them in step 4 — only metadata that accurately and durably reflects the item counts as well-curated and is reported as skipped (already curated), not re-proposed.
Per item, read baseline —
GET /v1/workspaces/{ws}/items/{id}; capture currenttype,displayName,description,tags,sensitivityLabel; also read the workspace's current domain assignment so domain-tag applicability can be evaluated.Per item, gather content signal — for types with a definition, read it with the one-command recipe in SKILL.md § Shared essentials (never poll in separate calls); a part cut at 4,000 characters is saved in full — read the rest (one call) if needed. Warehouse, SQL Database, SQL analytics endpoint, ML model/experiment and Datamart have no definition export: never call
getDefinitionfor them. For OneLake tabular items (Lakehouse, Warehouse, SQL Database, Mirrored Database, KQL) read the tables/schema — list-tables (GET .../lakehouses/{id}/tables),INFORMATION_SCHEMAvia SQL, or Kusto.show tables.Per item, draft suggestions, following
curate/metadata-suggestion-guidance.md— don't draft from memory.description— ≤ 256 chars; high-level & durable: what the item contains + its purpose. Validate any existing description against the content signal — if the item is empty or the content contradicts it (e.g. an empty pipeline whose description claims it ingests data), flag the mismatch. If the item is only partially configured (e.g. an Eventstream with a source but no destination), describe only what exists and note what's missing. An empty item with no description gets none — say so. For a contradicted/empty item, also offer to remove the misleading description (PATCH"description":"") and tags (unapplyTags) — owner confirms; keep only if it's a known placeholder.displayName— propose a rename if the current name is weak/placeholder (lh_tmp2,Untitled) or content-mismatched. For a mismatch, flag it and let owner intent decide rename-vs-keep — never rename silently. Skip rename for item types with an immutable name (e.g. SQLDatabase, which rejects it withSQLDatabaseDisplayNameCannotBeChanged) — say it can't be renamed; know this from the item type — never send a trial rename to find out.tags— pick from applicable definitions returned byGET /v1/tags(every page, followingcontinuationUri): all tenant-scoped tags plus domain-scoped tags whosescope.domainIdmatches the workspace's current domain; resolve to IDs percurate/tag-taxonomy.md. A tag found only in another domain is not applicable; a tag not found at all can't be applied. Preserve an already-applied out-of-domain tag left after a workspace move unless the owner explicitly approves removal.Tables & columns (only for items with a top-level OneLake Tables folder; for any other item this step doesn't exist) — per table, read its descriptions and its Delta comments (a separate field the skill never changes or suggests changing), and check whether it is a shortcut; propose descriptions where they are empty or don't match the schema, using any comment as a signal. Follow
curate/table-metadata.md.
Present the preview & confirm — the owner reviews every suggestion. Show current vs proposed for each suggestion and number them. Descriptions and display names can be accepted, edited, or rejected; each suggested tag can be accepted or rejected (picked from existing applicable tags — no free-text). The owner may also exclude any item or table. With many tables or columns, review one table at a time so no suggestion is buried. Wait for an explicit "apply". "Apply all" accepts every suggestion currently shown — never ones not yet shown.
Apply (only approved items/fields):
PATCH /v1/workspaces/{ws}/items/{id}with only the changed keys.PATCHis atomic — senddisplayNameanddescriptionin separate calls (a rejected rename fails the whole call) and report a rejected rename as not saved.POST /v1/workspaces/{ws}/items/{id}/applyTags(orunapplyTags) with the resolved tag ID array — throttle to ≤ 25 requests/min for larger batches.Per approved table: re-read its additional metadata, change only the accepted table and column descriptions, and
POSTthe complete set (curate/table-metadata.md).
Verify & report — re-
GETeach item and each written table; confirm applied values. Report each change as saved, skipped or not saved (with the reason). On partial failure, continue the rest — never abort the whole batch silently.
Handoff from a governance audit
When govern hands off gaps it found, treat them as candidates to recheck, not current truth:
Work only on the bounded target handed over (explicit items, or one named workspace) and only the fields the user chose — "fix missing descriptions" means descriptions only.
Re-read each item (step 2) — it may have been fixed or changed since the audit.
Approving the audit or the remediation never approves suggestion text: the owner still reviews every suggestion here (step 5).
Where the caller lacks the permission for a change, don't attempt it — name the owner or contact govern passed along.
Report back per item; the handoff is done only when step 7 has verified the write.
Output format
Always be informative and clear — for every curation, single item or bulk. Say plainly what state each item is in (already well-curated vs needs work), what you propose and why, and what will change. Never leave the owner guessing; never bury the items that need attention.
Answer first — e.g.
Read "wh_fact_sales" (Warehouse). Proposing 1 description, 1 rename, 3 tags.For a workspace, lead with a clear tally:Workspace 'Sales': 27 items — 8 already well-curated, 16 need attention, 3 staging artifacts skipped.Diff table —
# | item | object | field | current | proposedwhereobjectis the item itself, a table, ortable.column. (For a single item,itemmay be omitted.) No label column or bracket tags ([DATA],[INFERENCE],[GAP]) — owners don't know them.Confirmation prompt — "Apply these changes? (accept/edit/reject each numbered suggestion, exclude any item or table, or reply 'apply all' to accept everything shown)". No write until confirmed.
Post-apply report — per item and table, each change as Saved, Skipped or Not saved (with the reason); anything you can't do is one plain sentence: what, why, who can act.
Speak plain owner language, never API jargon. Describe every proposed action in words the owner understands — e.g. "add a description", "clear the description", "add the tag Sales", "remove the tag Sales", "rename the item to X", "keep the current name", "describe the column customer_id". Never surface raw REST calls, HTTP verbs, endpoints, or internal property names (
PATCH items/{id},applyTags/unapplyTags,getDefinition,additionalMetadata,displayName). Don't mention table or column comments either; they're only an internal signal. For an item without a OneLake Tables folder, go straight from the diff table to the confirmation prompt (see the semantic model example below).Be explicit about what's already good. For a single item, say clearly whether it's already well-curated or what specifically needs work (e.g. "description is solid; only the tags are missing"). For a workspace scan, state up front which items are already well-curated and name the ones needing work — e.g. "All 27 items are already well-described except 3, which need attention: X, Y, Z". A filled-in description, tag, or name does not by itself mean "good" — flag filled-but-inaccurate metadata as needing work.
Examples
Preview for a semantic model
Read "sales_model" (Semantic Model). Proposing 1 description; name and tags are fine.
| # | Field | Current | Proposed |
|---|-------------|--------------|---------------------------------------------------------------------------|
| 1 | Description | "Sales data" | "Order and revenue measures by region, used for monthly sales reporting." |
| 2 | Name | sales_model | (keep) |
| 3 | Tags | Sales | (keep) |
Apply these changes? (accept/edit/reject each numbered suggestion, or reply 'apply all')For a named workspace, list its items once, drop staging artifacts, then preview every
candidate. Request bodies for the item writes are in curate/api-reference.md; the table and
column chain (fresh read → change only accepted descriptions → write the complete set → read
again) is in curate/table-metadata.md § Example.
Error handling
When you can't do something, say so clearly — state plainly what isn't supported, why, and the closest thing that is supported, so the owner can proceed in one step. Never fail silently, half-do an unsupported request, or leave the owner guessing what to try next. When you name what the skill can do, name only what applies to this item.
| Scenario | Behavior |
|---|---|
| Caller lacks the permission for a change | Say clearly which changes they can't make and why: the description and name need read and write on the item, tags need Contributor or higher on the workspace, and table descriptions need write access on the item or OneLake ReadWrite. Don't attempt those writes; offer the changes they can make, and suggest asking the owner/admin for access. In a workspace scan, name the items skipped for missing permission. |
| More than one workspace named for a bulk scan | Say clearly you curate one workspace at a time; ask which to start with, then offer to do the others one by one after each finishes. |
| Whole-tenant / "all my items everywhere" request | Say clearly a tenant-wide scan isn't supported; suggest curating one named workspace or an explicit list of items instead, and offer to start with one. |
GET items/{id} fails | Say the item couldn't be read and why; do not proceed. |
| Description > 256 chars | Trim/rewrite to ≤ 256 before proposing; never send an over-limit value. |
Suggested tag not in /tags | Say "There's no <name> tag yet — ask a Fabric admin to create it"; skip it in applyTags. |
applyTags 429 (rate limit) | Honor Retry-After; batch ≤ 25 requests/min. |
| Bulk: one item fails mid-batch | Continue the remaining items; record the failure in the batch report; never abort silently. |
| Workspace scan surfaces Dataflows staging artifacts | Exclude them — system plumbing, never propose curation. |
| Sensitivity label / endorsement change requested | Say it can't be done here — there's no owner-facing write API (curate/api-reference.md); do not attempt. Offer what curation can do for that item (for a semantic model or report: "its description, name and tags", with no note about tables or columns). |
PATCH items rejects a displayName change (e.g. SQLDatabaseDisplayNameCannotBeChanged) | Report the rename as not saved; retry with description only (PATCH is atomic — never bundle the two). Curate description + tags instead. |
Table metadata read fails (404, unsupported item, preview not available) | Say that table's descriptions can't be read or changed; continue with item-level curation. Never write without a successful fresh read. |
| Owner asks to change a table or column comment | Explain curation covers descriptions, not comments, and offer to propose a description instead. |
| Owner asks for table or column descriptions on an item without a OneLake Tables folder | Say briefly that they aren't supported for that item type. For a semantic model, add that the model's own table and column descriptions are edited with the semantic-model-authoring skill, then stop and let the owner choose — don't switch to that skill or draft those descriptions unless they ask. |
| Table is a shortcut | Name the source table and its workspace, explain the change is made on the source, and write only after the owner explicitly confirms that table. If the write is refused, say plainly they lack permission on the source table and suggest asking its owner. |
| Table/column tags requested | Explain that tags exist only on items; offer table and column descriptions instead. |
| Governance audit or admin remediation requested (domains, capacity, labels, certification, tag definitions, workspace tags) | Leave curate mode: that's govern — pick the govern mode in SKILL.md. |
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills-for-fabric · skills/onelake-catalog-cli · commit f8fac11
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- microsoft/skills-for-fabric
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download onelake-catalog-cli.zip