Telemetry
microsoft/power-platform-skills
A skill your agent uses when the user wants to enable, disable, turn on or off, opt out of, opt in to, or check the status of power-automate telemetry / usage data.
Dataverse schema authoring and inspection — tables, columns, relationships, forms, and views.
$ npx skills add microsoft/Dataverse-skills --skill dv-metadata -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install microsoft/Dataverse-skills dv-metadata --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/microsoft/Dataverse-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/plugins/dataverse/skills/dv-metadata .claude/skills/dv-metadata && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "dv-metadata" agent skill from https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadata into .claude/skills/dv-metadata/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dv-metadata", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadataType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add microsoft/Dataverse-skills --skill dv-metadata -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install microsoft/Dataverse-skills dv-metadata --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/Dataverse-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.github/plugins/dataverse/skills/dv-metadata .agents/skills/dv-metadata && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "dv-metadata" agent skill from https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadata into .agents/skills/dv-metadata/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dv-metadata", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add microsoft/Dataverse-skills --skill dv-metadata -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install microsoft/Dataverse-skills dv-metadata --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/Dataverse-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.github/plugins/dataverse/skills/dv-metadata .cursor/skills/dv-metadata && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "dv-metadata" agent skill from https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadata into .cursor/skills/dv-metadata/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dv-metadata", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/microsoft/Dataverse-skills.git --path .github/plugins/dataverse/skills/dv-metadata--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add microsoft/Dataverse-skills --skill dv-metadata -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install microsoft/Dataverse-skills dv-metadata --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/Dataverse-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.github/plugins/dataverse/skills/dv-metadata .gemini/skills/dv-metadata && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "dv-metadata" agent skill from https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadata into .gemini/skills/dv-metadata/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dv-metadata", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install microsoft/Dataverse-skills dv-metadataInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add microsoft/Dataverse-skills --skill dv-metadata -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/microsoft/Dataverse-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/.github/plugins/dataverse/skills/dv-metadata .github/skills/dv-metadata && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "dv-metadata" agent skill from https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadata into .github/skills/dv-metadata/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dv-metadata", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add microsoft/Dataverse-skills --skill dv-metadata -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install microsoft/Dataverse-skills dv-metadata --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/microsoft/Dataverse-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.github/plugins/dataverse/skills/dv-metadata .opencode/skills/dv-metadata && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "dv-metadata" agent skill from https://github.com/microsoft/Dataverse-skills/tree/main/.github/plugins/dataverse/skills/dv-metadata into .opencode/skills/dv-metadata/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dv-metadata", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
dv-metadataDataverse schema authoring and inspection — tables, columns, relationships, forms, and views.
Dv Metadata is an agent skill from microsoft/Dataverse-skills, published by the product's own GitHub organization. Dataverse schema authoring and inspection — tables, columns, relationships, forms, and views. Use when the user wants to define, evolve, or inspect the data model — add a column, create a table, set up a lookup, customize a form, build a view, or list existing columns and relationships.
Its SKILL.md is about 5.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/alternate-keys.md`, `references/forms-and-views.md` and `references/metadata-propagation.md`).
It sits in AI & LLM Engineering. It works with Power Automate and Model Context Protocol. The repository describes itself as: Microsoft Dataverse skills for AI coding agents. Wraps the Dataverse MCP server, Dataverse CLI, Python SDK, and PAC CLI behind specialist skills for building, querying… The licence is MIT.
2 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 3be592f. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pythonFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Dv Metadata loads about 5.4k tokens when it runs, and up to ~9.3k if it reads all its reference files. Until then it costs about 75 tokens; SKILL.md has 1,650 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
ents go into?" If `SOLUTION_NAME` is in `.env`, confirm it. If no solution exists yet, **you MUST ask the user** for theAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from microsoft/Dataverse-skills at commit 3be592f, republished under its MIT licence (© microsoft). 1,650 words, ~5,404 tokens.
.claude/skills/dv-metadata/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Before the first metadata change in a session:
SOLUTION_NAME is in .env, confirm it. If no solution exists yet, you MUST ask the user for the solution name and publisher prefix before creating anything. The publisher prefix is permanent — it cannot be changed after components are created with it.STOP and ask the user:
"What solution name and publisher prefix should I use? The prefix (e.g.,
contoso,lit,soc) is permanent on every table and column."
Then query existing publishers and show them — the user may want to reuse one:
# Publisher discovery + solution creation — use SDK (never raw Web API).
# See dv-solution for the full publisher discovery flow.
publishers = client.records.list("publisher",
filter="customizationprefix ne 'none' and uniquename ne 'MicrosoftCorporation'",
select=["publisherid", "uniquename", "friendlyname", "customizationprefix"], top=10)
# MANDATORY: Show existing publishers to user and ask which to use or create newAfter user confirms, create using SDK:
publisher_id = client.records.create("publisher", {
"uniquename": "<name>", "friendlyname": "<display>",
"customizationprefix": "<prefix>", # from user input, NOT hardcoded
"description": "<desc>",
})
solution_id = client.records.create("solution", {
"uniquename": "<SolutionName>", "friendlyname": "<Display Name>",
"version": "1.0.0.0",
"publisherid@odata.bind": f"/publishers({publisher_id})",
})Never create tables or columns outside a solution.
solution="<UniqueName>" in every SDK call, or include "MSCRM.SolutionName": "<UniqueName>" on every raw Web API call.| Need | Use instead |
|---|---|
| Create, update, or delete data records | dv-data |
| Query or read records | dv-query |
| Export or deploy solutions | dv-solution |
| ERP schema | dv-query; ERP routing |
Do not write solution XML by hand to create new tables, columns, forms, or views.
The environment validates metadata far more reliably than an agent editing XML. The correct workflow is:
pac commands where available)pac solution export + pac solution unpackThe exported XML is generated by Dataverse itself and is always valid. Hand-written XML is fragile — a single incorrect attribute or missing element causes an import failure with an opaque error.
The only time you write files directly is when editing something that already exists in the repo (e.g., tweaking an existing view's columns or modifying a form layout you've already pulled).
CLI schema inspection: dataverse data describe --table account --include all --json (uses LogicalName). API discovery: dataverse api list --target dataverse.
If creating multiple tables for a data import, also see these sections later in this skill:
Prefer the SDK for table creation — use raw Web API only when you need full control over OwnershipType, HasActivities, or other advanced properties the SDK doesn't expose.
SDK approach (use this by default):
import os, sys
sys.path.insert(0, os.path.join(os.getcwd(), "scripts"))
from auth import get_client
# get_client sets a plugin attribution context on the User-Agent header.
# Do not modify the context value — it is a closed schema for server-side
# telemetry (app/skill/agent). Never include secrets or PII.
client = get_client("dv-metadata")
info = client.tables.create(
"new_ProjectBudget",
{"new_Amount": "decimal", "new_Description": "string"},
solution="MySolution",
primary_column="new_Name",
display_name="Project Budget", # human-readable name; plural auto-appends "s"
)
print(f"Created: {info['table_schema_name']}")Web API fallback (ONLY when you need OwnershipType, HasActivities, or other properties the SDK doesn't expose):
# Helper for Label boilerplate
def label(text):
return {"@odata.type": "Microsoft.Dynamics.CRM.Label",
"LocalizedLabels": [{"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": text, "LanguageCode": 1033}]}
entity = {
"@odata.type": "Microsoft.Dynamics.CRM.EntityMetadata",
"SchemaName": "new_ProjectBudget",
"DisplayName": label("Project Budget"),
"DisplayCollectionName": label("Project Budgets"),
"Description": label(""),
"OwnershipType": "UserOwned",
"HasActivities": False, "HasNotes": False, "IsActivity": False,
"PrimaryNameAttribute": "new_name",
"Attributes": [{
"@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata",
"SchemaName": "new_name",
"DisplayName": label("Name"),
"RequiredLevel": {"Value": "ApplicationRequired"},
"MaxLength": 100, "IsPrimaryName": True,
}]
}
# POST to /api/data/v9.2/EntityDefinitions with MSCRM.SolutionUniqueName header*Id Suffix CollisionsNever name a regular column with an Id suffix (e.g., prefix_CountryId). Dataverse auto-generates a navigation property with the Id suffix when you create a lookup — if a regular column with that name exists, lookup creation fails with a schema name collision.
prefix_DepartmentId (int) — collides with auto-generated lookupprefix_SrcDepartmentId or prefix_DepartmentSourceIdSDK approach (preferred):
created = client.tables.add_columns(
"new_ProjectBudget",
{"new_Description": "string", "new_Amount": "decimal", "new_Active": "bool"},
)
print(created) # ['new_Description', 'new_Amount', 'new_Active']Supported type strings: "string" / "text", "int" / "integer", "decimal" / "money", "float" / "double", "datetime" / "date", "bool" / "boolean", "file", and Enum subclasses (for local option sets).
Choice (picklist) column via SDK:
from enum import IntEnum
class BudgetStatus(IntEnum):
DRAFT = 100000000
APPROVED = 100000001
REJECTED = 100000002
created = client.tables.add_columns(
"new_ProjectBudget",
{"new_Status": BudgetStatus},
)Web API approach (needed for column types the SDK doesn't support — e.g., currency with precision, memo with custom max length):
# Currency column
attribute = {
"@odata.type": "Microsoft.Dynamics.CRM.MoneyAttributeMetadata",
"SchemaName": "new_amount",
"DisplayName": {"@odata.type": "Microsoft.Dynamics.CRM.Label",
"LocalizedLabels": [{"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "Amount", "LanguageCode": 1033}]},
"RequiredLevel": {"Value": "None"},
"MinValue": 0,
"MaxValue": 1000000000,
"Precision": 2,
"PrecisionSource": 2
}
# POST to /api/data/v9.2/EntityDefinitions(LogicalName='new_projectbudget')/AttributesSDK approach — simple lookup (preferred):
result = client.tables.create_lookup_field(
referencing_table="new_projectbudget",
lookup_field_name="new_AccountId",
referenced_table="account",
display_name="Account",
solution="MySolution",
)
print(f"Created lookup: {result.lookup_schema_name}")SDK approach — full control over 1:N relationship:
from PowerPlatform.Dataverse.models.relationship import (
LookupAttributeMetadata,
OneToManyRelationshipMetadata,
CascadeConfiguration,
)
from PowerPlatform.Dataverse.models.labels import Label, LocalizedLabel
from PowerPlatform.Dataverse.common.constants import CASCADE_BEHAVIOR_REMOVE_LINK
lookup = LookupAttributeMetadata(
schema_name="new_AccountId",
display_name=Label(localized_labels=[LocalizedLabel(label="Account", language_code=1033)]),
)
relationship = OneToManyRelationshipMetadata(
schema_name="account_new_projectbudget",
referenced_entity="account",
referencing_entity="new_projectbudget",
referenced_attribute="accountid",
cascade_configuration=CascadeConfiguration(delete=CASCADE_BEHAVIOR_REMOVE_LINK),
)
result = client.tables.create_one_to_many_relationship(lookup, relationship, solution="MySolution")
print(f"Created: {result.relationship_schema_name}")SDK approach — many-to-many relationship:
from PowerPlatform.Dataverse.models.relationship import ManyToManyRelationshipMetadata
relationship = ManyToManyRelationshipMetadata(
schema_name="new_ticket_knowledgebase",
entity1_logical_name="new_ticket",
entity2_logical_name="new_knowledgebase",
)
result = client.tables.create_many_to_many_relationship(relationship, solution="MySolution")
print(f"Created: {result.relationship_schema_name}")Web API approach (fallback when SDK patterns don't suffice):
relationship = {
"@odata.type": "Microsoft.Dynamics.CRM.OneToManyRelationshipMetadata",
"SchemaName": "account_new_projectbudget",
"ReferencedEntity": "account",
"ReferencingEntity": "new_projectbudget",
"Lookup": {
"@odata.type": "Microsoft.Dynamics.CRM.LookupAttributeMetadata",
"SchemaName": "new_AccountId",
"DisplayName": {"@odata.type": "Microsoft.Dynamics.CRM.Label",
"LocalizedLabels": [{"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "Account", "LanguageCode": 1033}]},
"RequiredLevel": {"Value": "None"}
}
}
# POST to /api/data/v9.2/RelationshipDefinitionsAfter creating a lookup — the @odata.bind navigation property:
When you create records that set this lookup, you need the navigation property name for @odata.bind. The navigation property name is case-sensitive and must match the entity's $metadata (usually the SchemaName of the lookup field, e.g., new_AccountId):
| Navigation Property Name | @odata.bind key | Entity set |
|---|---|---|
new_AccountId | new_AccountId@odata.bind | /accounts(<guid>) |
new_ParentTicketId | new_ParentTicketId@odata.bind | /new_tickets(<guid>) |
Common mistake: Using the logical name (lowercase) like new_accountid@odata.bind returns a 400 error. Navigation property names are case-sensitive and must match the entity's $metadata.
After creating a table via API, add it to your solution so it gets pulled on export:
pac solution add-solution-component \
--solutionUniqueName <SOLUTION_NAME> \
--component <SchemaName> \
--componentType 1 \
--environment <url>Component type 1 = Entity (Table). See dv-solution for the full type code list.
Or via Web API:
# POST to /api/data/v9.2/AddSolutionComponent
body = {
"ComponentId": "<entity-metadata-id>",
"ComponentType": 1, # 1 = Entity
"SolutionUniqueName": "<SOLUTION_NAME>",
"AddRequiredComponents": True
}systemform (forms) and savedquery (views) are ordinary entities — create/read/modify them with the SDK's record CRUD (no urllib). Only publishing (PublishXml, an unbound action) needs dataverse api request.
Quick reference:
client.records.create("systemform", {...formxml..., "type": 2}) (2=Main, 7=Quick Create, 6=Quick View, 11=Card).records.list("systemform", filter=...) for a template → mutate formxml → records.update("systemform", id, {...}) → publish.dataverse api request POST PublishXml — required for changes to take effect.client.records.create("savedquery", {...fetchxml..., ...layoutxml...}) (0=standard, 1=advanced find, 2=associated, 4=quick find).Full code, the template recipe, the classid table, and publish: references/forms-and-views.md.
Key invariants:
id attributes in form XML must be unique GUIDs (str(uuid.uuid4()).upper()).python -c for GUID generation on Windows — write a .py file.Create business rules in the Power Apps maker portal. They are too complex to write reliably as JSON/XAML. After creation, export+unpack the solution and commit the result.
All custom schema names must use your solution's publisher prefix (e.g., new_, contoso_). Find yours:
pac solution list --environment <url>Or check solutions/<SOLUTION_NAME>/Other/Solution.xml after the first pull — look for <CustomizationPrefix>.
id attributes must be valid GUIDs in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Do not use strings like "general".labelid is also a GUID — not a human-readable string.<ViewId> — must be the GUID of an existing SavedQuery. Create the view first.classid values — see the classid table above.Tip: Create forms in the maker portal and pull via pac solution export — use the pulled XML as a template for programmatic creation.
After creating columns (via Web API or MCP), always report the actual logical names to the user. Column names may be normalized or prefixed in ways the user doesn't expect. Summarize in a table:
| Display Name | Logical Name | Type |
|---|---|---|
| cr9ac_email | String | |
| Tier | cr9ac_tier | Picklist |
| Customer | cr9ac_customerid | Lookup |
This prevents downstream failures when the user tries to insert data using incorrect column names.
| Error Code | Meaning | Recovery |
|---|---|---|
0x80040216 | Transient metadata cache error. Column or table metadata not yet propagated. | Wait 3-5 seconds and retry. Usually succeeds on second attempt. |
0x80048d19 | Invalid property in payload. A field name doesn't match any column on the table. | Check logical column names — use EntityDefinitions(LogicalName='...')/Attributes to verify. |
0x80040237 | Schema name already exists. | Verify the column/table exists before creating a new one — it may have been created by a previous timed-out call. |
0x8004431a | Publisher prefix mismatch. | Ensure all schema names use the solution's publisher prefix. |
0x80060891 | Metadata cache not ready after table creation. | Call GET EntityDefinitions(LogicalName='...') first to force cache refresh, then retry. |
Always translate error codes to plain English before presenting them to the user.
After creating tables / columns / alternate keys, Dataverse runs internal metadata operations (index build, cache propagation) for 3–30 seconds. Submitting another metadata operation while these run causes lock-contention errors.
Mitigation — phased creation, not interleaved. Create ALL tables → wait 15–30s → create ALL alternate keys → wait 15–30s → create ALL lookups. Do NOT interleave operations on the same table.
Symptoms (any of these means propagation isn't done):
0x80040216@odata.bind fails with "Invalid property"update_table (MCP) fails with "EntityId not found in MetadataCache"For the retry_metadata helper that catches transient lock errors and the full phased-creation sequence, see references/metadata-propagation.md.
Before changing a model, inspect what already exists. These read-only calls return raw metadata dictionaries (PascalCase property names) and are safe to run anytime.
Assumes
clientfrom the auth setup shown earlier in this skill (from auth import get_client).
# Columns on a table (optionally filtered / projected)
columns = client.tables.list_columns("account", select=["LogicalName", "AttributeType", "SchemaName"])
for col in columns:
print(f"{col['LogicalName']} ({col.get('AttributeType')})")
# All relationships for one table (1:N, N:1, and N:N combined)
rels = client.tables.list_table_relationships("account")
for rel in rels:
print(f"{rel['SchemaName']} -> {rel.get('@odata.type')}")
# All relationships in the environment (optionally filtered)
all_rels = client.tables.list_relationships(select=["SchemaName", "ReferencedEntity", "ReferencingEntity"])For SQL-queryable column discovery (virtual/computed columns excluded), dv-query also has
client.query.sql_columns(table).
After every metadata session, perform the pull-to-repo sequence — see dv-overview "After Any Change: Pull to Repo" for the full export/unpack/commit commands.
If you used the MSCRM.SolutionName header during creation, verify components were added before exporting:
sol = client.records.list("solution",
filter="uniquename eq '<SOLUTION_NAME>'", select=["solutionid"], top=1).first()
if sol is not None:
components = client.records.list("solutioncomponent",
filter=f"_solutionid_value eq {sol['solutionid']}",
select=["componenttype", "objectid"])
print(f"{len(components)} components in the solution")When creating tables programmatically (e.g., a schema setup script that may be re-run), use a check-first pattern — query client.tables.get() before creating. This is explicit, avoids masking unrelated errors, and lets you branch logic based on whether the table was created or reused:
def ensure_table(client, schema_name, columns, solution, primary_column="prefix_Name", display_name=None):
existing = client.tables.get(schema_name)
if existing:
print(f"Reusing: {schema_name}")
return existing
info = client.tables.create(schema_name, columns, solution=solution,
primary_column=primary_column, display_name=display_name)
print(f"Created: {info['table_schema_name']}")
return infoUpsertMultiple requires an alternate key on the column(s) Dataverse should use to identify existing records. Always create alternate keys on source-system ID columns (prefix_Src*Id) at schema-setup time so every import is idempotent.
Quick reference:
client.tables.create_alternate_key(table, key_name, [columns], display_name=...). Composite keys: pass multiple columns.client.tables.get_alternate_keys(table) to skip keys that already exist — see references/alternate-keys.md for the ensure_alternate_key helper.client.tables.get_alternate_keys(table) until status == "Active" before using.For SDK code samples (single + composite + idempotent + status-check), the agent decision rules for which column to pick (DB source vs Excel/CSV), and the failure-handling notes, see references/alternate-keys.md.
startswith() is NOT supported as a filter on EntityDefinitions. This query will return a 400 error:
GET /api/data/v9.2/EntityDefinitions?$filter=startswith(LogicalName,'new_') # BROKENTo retrieve metadata for multiple custom tables, query each table individually:
GET /api/data/v9.2/EntityDefinitions(LogicalName='new_projectbudget')?$select=LogicalName,EntitySetNameOr query all and filter client-side:
GET /api/data/v9.2/EntityDefinitions?$select=LogicalName,EntitySetNameWhen using MCP create_table or update_table:
describe('tables/{name}') before retrying or a follow-up update_table (if the table exists, skip creation).update_table after creation.© microsoft, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (references) in .github/plugins/dataverse/skills/dv-metadata of microsoft/Dataverse-skills.
Open the folder on GitHubat commit 3be592f
Dv Metadata next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Dv Metadata this skillmicrosoft/Dataverse-skills | 241 | — | ~5.4k | Automated safety check: Notes | MIT | |
| Telemetrymicrosoft/power-platform-skills | 967 | — | ~635 | Automated safety check: Notes | MIT | |
| Microsoft Docsmicrosoft/ai-agents-for-beginners | 77k | 3 repos | ~1.2k | Automated safety check: Pass | MIT | |
| Microsoft Docsmicrosoft/ai-agents-for-beginners | 77k | — | ~1.5k | Automated safety check: Pass | MIT | |
| Microsoft Docsmicrosoft/ai-agents-for-beginners | 77k | — | ~1.6k | Automated safety check: Pass | MIT | |
| Microsoft Docsmicrosoft/ai-agents-for-beginners | 77k | — | ~1.3k | Automated safety check: Pass | MIT |
microsoft/power-platform-skills
A skill your agent uses when the user wants to enable, disable, turn on or off, opt out of, opt in to, or check the status of power-automate telemetry / usage data.
microsoft/ai-agents-for-beginners
Query official Microsoft documentation to find concepts, tutorials, and code examples across Azure, .NET, Agent Framework, Aspire, VS Code, GitHub, and more.
microsoft/ai-agents-for-beginners
Kysy virallista Microsoftin dokumentaatiota löytääksesi käsitteitä, opetusohjelmia ja koodiesimerkkejä Azureen, .NET:iin, Agent Frameworkiin, Aspireen, VS Codeen, GitHubiin ja muihin liittyen.
microsoft/ai-agents-for-beginners
Interroger la documentation officielle de Microsoft pour trouver des concepts, des tutoriels et des exemples de code couvrant Azure, .NET, Agent Framework, Aspire, VS Code, GitHub, et plus encore.
microsoft/ai-agents-for-beginners
שאילתה בתיעוד הרשמי של Microsoft למציאת מושגים, מדריכים ודוגמאות קוד ב-Azure, .NET, Agent Framework, Aspire, VS Code, GitHub ועוד.
microsoft/ai-agents-for-beginners
आधिकारिक Microsoft दस्तावेज़ों में क्वेरी करें ताकि Azure, .NET, Agent Framework, Aspire, VS Code, GitHub, और अन्य के बारे में अवधारणाएँ, ट्यूटोरियल और कोड उदाहरण मिल सकें। डिफ़ॉल्ट रूप से Microsoft…
microsoft/Dataverse-skills
One-step setup and connection diagnostics for a Dataverse environment — installs tools, authenticates, registers MCP, writes .env, and verifies active profiles and linked ERP endpoints.
microsoft/Dataverse-skills
Environment-level Dataverse administration — bulk delete, retention/archival, organization settings, OrgDB settings, recycle bin, audit, and the 37 allowlisted PPAC toggles.
microsoft/Dataverse-skills
Record-level CRUD and bulk operations — create, update, delete, upsert, CSV import, multi-table foreign-key loads, AI-generated sample data.
microsoft/Dataverse-skills
Bulk reads, multi-page iteration, and analytics over Dataverse data.
microsoft/Dataverse-skills
X++ code development lifecycle for Finance and Operations — scaffold models, author classes, custom services/APIs, and data entities, install matching SDKs, compile deployable packages, deploy…
microsoft/Dataverse-skills
Foundational cross-cutting context for Dataverse / Power Platform work — scope and the skill map, the tool-capability reference, the safety rules, and the safe change lifecycle.
Works with
Categories
Dataverse schema authoring and inspection — tables, columns, relationships, forms, and views. Dv Metadata is an agent skill from microsoft/Dataverse-skills, published by the product's own GitHub organization. Dataverse schema authoring and inspection — tables, columns, relationships, forms, and views.
Dv Metadata fits situations like: the user wants to define; inspect the data model — add a column; set up a lookup; customize a form.
Run `npx skills add microsoft/Dataverse-skills --skill dv-metadata -a claude-code`. Or copy the skill folder (.github/plugins/dataverse/skills/dv-metadata in microsoft/Dataverse-skills) into .claude/skills/dv-metadata in your project. Claude Code loads it when a task matches its description.
Run `npx skills add microsoft/Dataverse-skills --skill dv-metadata -a codex`. Or copy the skill folder (.github/plugins/dataverse/skills/dv-metadata in microsoft/Dataverse-skills) into .agents/skills/dv-metadata in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add microsoft/Dataverse-skills --skill dv-metadata -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dv-metadata, .gemini/skills/dv-metadata, .github/skills/dv-metadata and .opencode/skills/dv-metadata in your project.
Going by SKILL.md and its folder, Dv Metadata needs the command-line tools its instructions call (python). Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Dv Metadata is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.4k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.9k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Dv Metadata: Telemetry (microsoft/power-platform-skills, 967 stars), Microsoft Docs (microsoft/ai-agents-for-beginners, 77k stars), Microsoft Docs (microsoft/ai-agents-for-beginners, 77k stars) and Microsoft Docs (microsoft/ai-agents-for-beginners, 77k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
microsoft (a GitHub organization, an official publisher) maintains it in microsoft/Dataverse-skills, which has 241 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on October 5, 2026.
Source: microsoft/Dataverse-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.