[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-microsoft-dv-overview":3,"mdc--ik3y9w-key":40,"related-repo-microsoft-dv-overview":3447,"related-org-microsoft-dv-overview":3483},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":35,"sourceUrl":38,"mdContent":39},"dv-overview","manage Dataverse and Power Platform environments","Foundational cross-cutting context for Dataverse \u002F Power Platform work — scope and the skill map, the tool-capability reference, the safety rules, and the safe change lifecycle. Use when the user mentions Dataverse, Dynamics 365, Power Platform, CRM, or ERP; load this first for orientation. Specialist skills self-route via their own frontmatter triggers.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"microsoft","Microsoft","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmicrosoft.png",[12,16,17,20],{"name":13,"slug":14,"type":15},"Operations","operations","tag",{"name":9,"slug":8,"type":15},{"name":18,"slug":19,"type":15},"Power Platform","power-platform",{"name":21,"slug":22,"type":15},"Dataverse","dataverse",184,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FDataverse-skills","2026-07-31T05:54:50.051254",null,48,[29,22,30,31,32,33,34,19],"agent-skills","dynamics-365","dynamics-crm","mcp","mcp-server","plugin",{"repoUrl":24,"stars":23,"forks":27,"topics":36,"description":37},[29,22,30,31,32,33,34,19],"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, deploying, and administering Dataverse environments.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FDataverse-skills\u002Ftree\u002FHEAD\u002F.github\u002Fplugins\u002Fdataverse\u002Fskills\u002Fdv-overview","---\nname: dv-overview\ndescription: Foundational cross-cutting context for Dataverse \u002F Power Platform work — scope and the skill map, the tool-capability reference, the safety rules, and the safe change lifecycle. Use when the user mentions Dataverse, Dynamics 365, Power Platform, CRM, or ERP; load this first for orientation. Specialist skills self-route via their own frontmatter triggers.\n---\n\n# Skill: Overview — What to Use and When\n\nLoad this skill first for any Dataverse work — it holds the cross-cutting context every task needs: scope, the tool-capability reference, the hard rules, and the change lifecycle. It does **not** route; the agent auto-selects specialist skills via their own WHEN\u002FDO NOT USE WHEN frontmatter triggers. Users describe what they want in plain English; the agent chains skills automatically and never asks the user to name a skill or command.\n\n---\n\n## What This Plugin Covers\n\nDataverse \u002F Power Platform work for **every persona** — builders and agent devs, data scientists, environment admins, and business users — delivered by specialist skills. The agent loads and routes to these automatically via their frontmatter triggers — you never invoke them by name.\n\n| Area | Skill |\n| --- | --- |\n| Connect, authenticate, configure MCP, verify the environment | `dv-connect` |\n| Schema — tables, columns, relationships, forms, views; inspect existing schema | `dv-metadata` |\n| Data writes — record CRUD, bulk create\u002Fupdate\u002Fupsert, CSV\u002FFK-ordered import, sample data | `dv-data` |\n| Data reads & analytics — OData queries, QueryBuilder, FetchXML (aggregation + N:N joins), DataFrames | `dv-query` |\n| Solution ALM — create, export, import, pack\u002Funpack, post-import validation | `dv-solution` |\n| Environment administration — bulk delete, retention\u002Farchival, org & OrgDB settings, recycle bin | `dv-admin` |\n| Security & access — roles, users, application users, business units, self-elevation (PAC CLI) | `dv-security` |\n\n**Model-driven apps:** the building blocks (tables, forms, views) are covered by `dv-metadata`; composing the app shell itself — site map and navigation — is **not yet** a first-class skill.\n\n**Out of scope:**\n\n- **Canvas apps** — a different technology; use `pac canvas` or the maker portal\n- **Power Automate flows** — use the maker portal or the Power Automate Management API\n- **Azure infrastructure** beyond what's needed for service-principal setup\n- **Business Central** or other Dynamics products\n\n---\n\n## Hard Rules — Read These First\n\nThe safety rules (init state, auth, environment confirmation, no bespoke MSAL) are non-negotiable. The tool-selection guidance (Rules 1, 2, 4) is capability-based — strong defaults, not rigid mandates.\n\n### 0. Check Init State Before Anything Else\n\nBefore writing ANY code or creating ANY files, check if the workspace is initialized:\n\n```bash\nls .env scripts\u002Fauth.py 2>\u002Fdev\u002Fnull\n```\n\n- If BOTH exist: workspace is initialized. Proceed to the relevant task.\n- If EITHER is missing: **Automatically run the connect flow** (see the `dv-connect` skill). Do NOT ask the user whether to initialize — just do it. Do not create your own `.env`, `requirements.txt`, `.env.example`, or auth scripts. The `dv-connect` skill handles all of this.\n\nDo NOT create `requirements.txt`, `.env.example`, or scaffold files manually. The connect flow produces the correct file structure. Skipping it is the #1 cause of broken setups.\n\n### 1. Python for scripting; the CLIs and MCP are first-class\n\nPython is the language for automation **logic** (transformation, control flow, retry, CSV). The toolchain (`scripts\u002Fauth.py`, the SDK, skill examples) is Python-based. But MCP tools, the Dataverse CLI (`dataverse`), the Python SDK, and the PAC CLI (`pac`) are all **first-class tool invocations** — use whichever fits. The Dataverse CLI has the same standing as `pac`, which is invoked freely across the solution and metadata skills.\n\n**NEVER:**\n- Write automation *logic* in JavaScript\u002FTypeScript\u002FNode.js (`npm`, `yarn`, `pnpm`, `package.json`, `node_modules\u002F`)\n- Use `@azure\u002Fmsal-node`, `@azure\u002Fidentity`, or any Node.js Azure SDK\n- Implement a bespoke MSAL \u002F device-code flow — auth is `scripts\u002Fauth.py`, `pac auth`, and the Dataverse CLI\n\n**ALWAYS:**\n- Use `pip install` and the Python SDK (`PowerPlatform-Dataverse-Client`) for data and schema logic\n- Use `scripts\u002Fauth.py` for tokens\u002Fcredentials; `azure-identity` (Python) for Azure credential flows\n- Treat the Dataverse CLI (`dataverse`) and `pac` as allowed first-party CLIs\n\nAbout to run `npm` or create a `package.json`? STOP — that is off-rails. Reaching for `pac` or the Dataverse CLI is not.\n\n### 2. Pick the surface that fits — capability awareness, not a fixed order\n\nNo mandated tool order. Each surface has a capability profile; pick what fits the job and the surface you are already in — soft defaults, not a required sequence. The full matrix is in **Tool Capabilities** below; the principles:\n\n- Prefer a managed surface (MCP, the Dataverse CLI, or the SDK) over hand-rolled raw OData — they carry auth, paging, retry, and geo routing that raw HTTP re-implements. When MCP can't handle it (bulk >25 records, large reads, advanced schema like forms\u002Fviews\u002FN:N relationships\u002Fglobal option sets\u002Falternate keys, multi-step workflows, analytics, or MCP isn't available), the **Python SDK** is the default.\n- **Raw Web API is the last-resort escape hatch** for surfaces with no managed path (unbound actions like `PublishXml`, global option sets, anything without a first-class SDK\u002FCLI command) — and even then prefer `dataverse api` (managed auth, exit codes) over hand-rolled `urllib`\u002F`get_token`. Forms\u002Fviews are **not** raw-only (SDK `records.create`\u002F`update` on `systemform`\u002F`savedquery`; only `PublishXml` needs `dataverse api`). Aggregation\u002FN:N joins aren't raw-only either: `client.query.fetchxml()` (aggregates + link-entity), or the CLI's `data associate` for N:N writes.\n- If an SDK method fails or a PAC command seems missing, check the relevant skill before hand-rolling raw HTTP.\n\n**Field casing:** `$select`\u002F`$filter` use lowercase logical names (`new_name`). `$expand` and `@odata.bind` use Navigation Property Names that are case-sensitive and must match `$metadata` (e.g., `new_AccountId`). Getting this wrong causes 400 errors. **SDK record payloads:** provide the correct SchemaName casing on `@odata.bind` keys (e.g., `new_AccountId@odata.bind`); the SDK does not auto-correct wrong casing. **Raw Web API calls** (forms, views, metadata): casing is entirely manual — a lowercase `new_accountid@odata.bind` will 400.\n\n**Publisher prefix:** Never hardcode a prefix (especially not `new`). Always query existing publishers in the environment and ask the user which to use. The prefix is permanent on every component created with it. See the solution skill's publisher discovery flow.\n\n### 3. Use Documented Auth Patterns\n\nThree entry points, one shared sign-in:\n- **`dataverse auth create`** (Dataverse CLI) writes a shared MSAL token cache under the DataverseCLI app registration. That single sign-in serves the CLI, the `@microsoft\u002Fdataverse` MCP proxy, **and** `scripts\u002Fauth.py` — which silently reuses the same cache via `msal-extensions` (the sanctioned MSAL API, not raw-file parsing), so Python scripts and the SDK don't prompt again.\n- **`scripts\u002Fauth.py`** is the auth entry point for all Python\u002FSDK code. Its order: service principal (`CLIENT_ID` + `CLIENT_SECRET` in `.env`) → shared Dataverse CLI cache → device-code fallback. Use `get_client(skill)` (SDK) or `get_plugin_headers(skill, get_token())` (raw Web API) — both stamp the skill attribution; bare `get_token()` does not.\n- **`pac auth create`** (PAC CLI) authenticates `pac` for `dv-solution` and `dv-admin`.\n\n**Telemetry attribution (keep it deterministic):** every request carries a closed-schema `app=dataverse-skills\u002F\u003Cver>;skill=\u003Cskill>;agent=\u003Cagent>` context so the server sees which skill routed each OData call. It is baked in — `get_client(skill)` and `get_plugin_headers(skill, ...)` stamp it on the SDK and raw-HTTP paths; the Dataverse CLI auto-stamps `DataverseCli\u002F\u003Cver>` + the command, and you add the skill with `--context \"app=dataverse-skills\u002F\u003Cver>;skill=\u003Cskill>;agent=\u003Cagent>\"` (the CLI wraps it in parentheses itself — do not pre-wrap). Never modify, omit, or free-form this context — it is a closed schema (allowlisted skill\u002Fagent, no PII).\n\n**NEVER:**\n- Read or parse raw token cache files (e.g., `tokencache_msalv3.dat`) — reuse the cache only through `scripts\u002Fauth.py` \u002F `msal-extensions`\n- Implement your own MSAL device-code flow\n- Hard-code tokens or credentials in scripts\n- Invent a new auth mechanism\n\nIf auth is expired or missing, re-run `dataverse auth create` (or `pac auth create` for `pac`), or check `.env` credentials. See the `dv-connect` skill.\n\n### 4. Be honest about gaps — don't hallucinate\n\nEach skill documents a tested sequence — follow it when it fits. The skills are the source of truth for the supported, non-deprecated API. If a call fails with `AttributeError`, the installed SDK version may not have it — check the skill's version note and use the documented alternative.\n\n**The honesty guard:** if you hit a gap the skills don't cover, say so and suggest a workaround. **Do not hallucinate an unsupported path** — do not invent a method, parameter, or endpoint that isn't documented. If unsure, say so.\n\n---\n\n## Tool Capabilities — Which Tool for Which Job\n\nUnderstanding the real limits of each tool prevents hallucinated paths. This is the one piece of context no individual skill owns.\n\n| Tool | Use for | Does NOT support |\n| --- | --- | --- |\n| **MCP Server** | Data CRUD (create\u002Fread\u002Fupdate\u002Fdelete records, batch up to 25 per call), table create\u002Fupdate\u002Fdelete + column add (incl. local choice\u002Fmultiselect + lookup\u002Fcustomer), schema + record inspection via `describe`, metadata search (`search`), data + file-content search (`search_data`, when Dataverse search is enabled), file upload\u002Fdownload | Forms, Views, **global** Option Sets, **N:N** relationships, alternate keys, Solutions (lookup + local choice\u002Fmultiselect columns **are** supported via `create_table`\u002F`update_table`). **Note:** table creation may timeout but still succeed — always `describe` (e.g. `describe('tables\u002F{name}')`) before retrying. Run queries sequentially (parallel calls timeout). Column names with spaces normalize to underscores (e.g., `\"Specialty Area\"` → `cr9ac_specialty_area`). **SQL (`read_query`):** supports `JOIN`, `GROUP BY` (COUNT\u002FSUM\u002FAVG\u002FMIN\u002FMAX), `TOP`, `WHERE`, `ORDER BY`; does NOT support `DISTINCT`, `HAVING`, subqueries, `OFFSET`, `UNION`, `CASE`\u002F`IF`, `CAST`\u002F`CONVERT`, CTE, or date functions. For those, use `client.query.sql()` (also allows `DISTINCT`, \u003C5K rows), `$apply`, or a builder->DataFrame with pandas — see `dv-query`. **Bulk:** MCP `create_record`\u002F`update_record`\u002F`delete_record` batch up to 25 records per call; for larger bulk use the SDK `CreateMultiple` — see `dv-data`. |\n| **Python SDK (`dv-data`)** | Scripted data writes, especially at volume. Record CRUD, upsert (alternate keys), bulk create\u002Fupdate\u002Fupsert (CreateMultiple\u002FUpdateMultiple\u002FUpsertMultiple), CSV import with lookup resolution, file column uploads (chunked >128MB) | global Option Sets, record association (`$ref`), `$apply` aggregation, table\u002Fcolumn\u002Frelationship creation (use `dv-metadata`), custom action invocation |\n| **Python SDK (`dv-query`)** | Bulk reads and analytics. Multi-page record iteration, OData queries (select\u002Ffilter\u002Fexpand\u002Forderby), QueryBuilder fluent API, GUID-free display (formatted values), `$expand` to resolve lookups, **aggregation and N:N joins via `client.query.fetchxml()`** (aggregate FetchXML + link-entity), pandas DataFrame handoff (`client.query.builder(...).execute().to_dataframe()`) for exports, Jupyter notebook snippets | OData `$apply` and N:N `$expand` on the **QueryBuilder** path — use `records.list(expand=...)` for N:N, or `fetchxml()` for aggregates (not raw `urllib`) |\n| **Dataverse CLI (`dataverse`)** | Headless data plane (no Python script needed): `data` CRUD (`query\u002Fget\u002Fcreate\u002Fupdate\u002Fupsert\u002Fdelete\u002Fcount`), `data associate`\u002F`disassociate` (N:N + lookups via `$ref`), `data upload` (file columns); `api request`\u002F`invoke` (managed Web API escape hatch); `api list`\u002F`describe` for Custom API discovery; shared `auth`\u002F`org` token cache | Metadata\u002Fschema creation (use SDK — `dv-metadata`), solution ALM (use PAC), forms\u002Fviews authoring |\n| **PAC CLI** | Solution export\u002Fimport\u002Fpack\u002Funpack, environment create\u002Flist\u002Fdelete\u002Freset, auth profile management, plugin updates (`pac plugin push` — first-time registration requires Web API), user\u002Frole assignment (`pac admin assign-user`), add solution components (`pac solution add-solution-component`) | Data CRUD, metadata creation (tables\u002Fcolumns\u002Fforms), listing solution components (no `list-components` — query `solutioncomponent` via SDK\u002FCLI) |\n| **Azure CLI** | App registrations, service principals, credential management | Dataverse-specific operations |\n| **GitHub CLI** | Repo management, GitHub secrets, Actions workflow status | Dataverse-specific operations |\n| **Raw Web API** (last resort) | Only when **no** managed surface exposes the operation — i.e. not doable via MCP, the Python SDK, the Dataverse CLI, or the `dataverse api` escape hatch. Genuine cases: unbound actions like `PublishXml`, global option sets, and similar edge cases (**not** forms\u002Fviews — those are SDK record CRUD on `systemform`\u002F`savedquery`). Even then, prefer `dataverse api` (managed auth + skill attribution) over hand-rolled `urllib`. | Functionally nothing (full OData\u002FMetadataService) — but raw `urllib` bypasses managed auth, paging, retry, and skill attribution, so treat it as the path of last resort |\n\n**Routing:** the table shows what each surface does; the *how to choose* principle (soft defaults, not a fixed order) is Hard Rule 2. MCP tools not in your list? Load `dv-connect`.\n\n**Volume guidance:** MCP for up to ~25 records per call or simple filters; the SDK's `CreateMultiple` for larger bulk writes (chunk large sets starting ~1,000 — see `dv-data`) and `dv-query` for bulk reads (streams pages, avoids MCP SQL limits); Web API for `$apply` aggregation.\n\n**SDK method cheat-sheet** (anti-hallucination, *not* a preference signal): SDK method names are the least discoverable surface — MCP tools appear in your tool list and the CLI self-documents via `dataverse --help`, but SDK calls surface nowhere, so agents invent them. This maps common ops to the exact call. Each op is equally reachable via MCP\u002FCLI per Hard Rule 2; see the noted skill for the full pattern.\n\n| Operation | SDK call | Skill |\n| --- | --- | --- |\n| Create \u002F update \u002F delete records | `client.records.create()` \u002F `.update()` \u002F `.delete()` (pass a list for bulk) | `dv-data` |\n| Upsert on an alternate key | `client.records.upsert()` | `dv-data` |\n| Query \u002F filter records | `client.records.list(...)` (flat) or `.list_pages(...)` (streaming) | `dv-query` |\n| One record by GUID | `client.records.retrieve(table, guid)` (`None` if missing) | `dv-query` |\n| Aggregation \u002F server-side joins | `client.query.fetchxml(xml)` (aggregates + link-entity) | `dv-query` |\n| Fluent query build (chainable) | `client.query.builder(Table).where(...).execute()` | `dv-query` |\n| Limited SQL read | `client.query.sql(\"SELECT ...\")` | `dv-query` |\n| Load into pandas | `client.query.builder(table).select(...).execute().to_dataframe()` | `dv-query` |\n| Upload to a file column | `client.files.upload(...)` | `dv-data` |\n| Create tables \u002F columns \u002F lookups \u002F N:N | `client.tables.create()` \u002F `.add_columns()` \u002F `.create_lookup_field()` \u002F `.create_many_to_many_relationship()` | `dv-metadata` |\n| Create an alternate key (enables upsert) | `client.tables.create_alternate_key(...)` | `dv-metadata` |\n| Inspect existing schema | `client.tables.list_columns(table)` \u002F `.list_table_relationships(table)` | `dv-metadata` |\n| Create publisher \u002F solution | `client.records.create(\"publisher\" \u002F \"solution\", {...})` | `dv-solution` |\n\n### MCP Availability Check\n\nIf the user's request involves MCP — either explicitly (\"connect via MCP\", \"use MCP\", \"query via MCP\") or implicitly (conversational data queries where MCP would be the natural tool) — check whether Dataverse MCP tools are available in your current tool list (e.g., `search`, `describe`, `read_query`, `create_record`).\n\n**If MCP tools are NOT available and the user explicitly asked for MCP** (e.g., \"use MCP to query\", \"why isn't MCP working\"):\n1. **Do NOT silently fall back** to the Python SDK or Web API\n2. Tell the user: \"Dataverse MCP tools aren't configured in this session yet.\"\n3. Load the `dv-connect` skill to set up the MCP server\n4. After MCP is configured, **stop here** — the session must be restarted for MCP tools to appear. Remind the user to resume the session without losing context (Claude Code: `claude --continue`; Cursor: reload the window with Ctrl+Shift+P → \"Developer: Reload Window\"; Copilot: reopen the Copilot panel). Do not proceed with SDK. Wait for the user to restart.\n\n**If MCP tools are NOT available and the user asked a data question without explicitly requesting MCP** (e.g., \"how many accounts with 'jeff'?\", \"show me open tickets\"):\n1. This is a SDK fallback case — use the Python SDK to answer the question. Do not block the user.\n2. After answering, offer: \"MCP would handle this conversationally — want me to set it up?\"\n\nThe distinction matters: explicit MCP request → block and set up MCP. Implicit\u002Fconversational question → answer with SDK, offer MCP setup.\n\n**If MCP tools ARE available**, prefer MCP for simple reads\u002Fqueries\u002Fsmall CRUD. Use the SDK only when a script is needed.\n\n---\n\n## The Change Lifecycle — Operate Safely\n\nFor any real change, walk these three steps in order: confirm **where**, confirm the **container**, then persist the **result**.\n\n### Step 1 — Confirm the Environment (MANDATORY)\n\nDataverse work often spans multiple environments (dev, test, staging, prod) and multiple sets of credentials. **Never assume** the active PAC auth profile, values in `.env`, or anything from memory or a previous session reflects the correct target for the current task.\n\n**Before the FIRST operation that touches a specific environment** — creating a table, deploying a plugin, pushing a solution, inserting data — you MUST:\n\n1. Show the user the environment URL you intend to use\n2. Ask them to confirm it is correct\n3. Run `pac org who` to verify the active connection matches\n\n> \"I'm about to make changes to `\u003CURL>`. Is this the correct target environment?\"\n\n**Do not proceed until the user explicitly confirms.** This is the single most important safety check in the plugin. Skipping it risks making irreversible changes to the wrong environment. Once confirmed for a session, you do not need to re-confirm for every subsequent operation in the same session against the same environment.\n\n### Step 2 — Confirm the Solution (before any metadata change)\n\nBefore creating tables, columns, or other metadata, ensure a solution exists to contain the work:\n\n1. Ask the user: \"What solution should these components go into?\"\n2. If a solution name is in `.env` (`SOLUTION_NAME`), confirm it with the user\n3. If no solution exists yet, **load the `dv-solution` skill** and follow its publisher discovery + solution creation flow. Use the SDK — **never raw Web API** — to create publisher and solution records:\n\n```python\n# Quick reference — full pattern with publisher discovery is in dv-solution\npublisher_id = client.records.create(\"publisher\", {\n    \"uniquename\": \"\u003Cname>\", \"friendlyname\": \"\u003Cdisplay>\",\n    \"customizationprefix\": \"\u003Cprefix>\", \"description\": \"\u003Cdesc>\",\n})\nsolution_id = client.records.create(\"solution\", {\n    \"uniquename\": \"\u003CName>\", \"friendlyname\": \"\u003CDisplay>\",\n    \"version\": \"1.0.0.0\",\n    \"publisherid@odata.bind\": f\"\u002Fpublishers({publisher_id})\",\n})\n```\n\n4. Pass `solution=\"\u003CUniqueName>\"` on all SDK calls, or include `\"MSCRM.SolutionName\": \"\u003CUniqueName>\"` header on raw Web API metadata calls.\n\nCreating metadata without a solution means it exists only in the default solution and cannot be cleanly exported or deployed. Always solution-first.\n\n### Step 3 — Pull to Repo (MANDATORY)\n\nAny time you make a metadata change (via MCP, Web API, or the maker portal), **you must** end the session by pulling:\n\n```bash\npac solution export --name \u003CSOLUTION_NAME> --path .\u002Fsolutions\u002F\u003CSOLUTION_NAME>.zip --managed false\npac solution unpack --zipfile .\u002Fsolutions\u002F\u003CSOLUTION_NAME>.zip --folder .\u002Fsolutions\u002F\u003CSOLUTION_NAME>\nrm .\u002Fsolutions\u002F\u003CSOLUTION_NAME>.zip\ngit add .\u002Fsolutions\u002F\u003CSOLUTION_NAME>\ngit commit -m \"feat: \u003Cdescription>\"\ngit push\n```\n\nThe repo is always the source of truth.\n\n---\n\n## Scripts\n\nThe plugin ships `scripts\u002Fauth.py` (Azure Identity token\u002Fcredential acquisition — used by all other scripts and the SDK). Any Web API call beyond a one-off query should be a Python script committed to `\u002Fscripts\u002F`, using `scripts\u002Fauth.py` for tokens. For writes see `dv-data`; queries and analytics see `dv-query`; post-import validation see `dv-solution`.\n\n---\n\n## Windows Scripting\n\nPlatform-specific shell rules (ASCII in `.py`, no multiline `python -c`, PAC PowerShell wrapper, unbuffered background output) live in [`references\u002Fwindows-scripting.md`](references\u002Fwindows-scripting.md). Read it when running on Windows.\n\n",{"data":41,"body":42},{"name":4,"description":6},{"type":43,"children":44},"root",[45,54,68,72,79,91,239,263,271,324,327,333,338,345,350,395,452,470,476,525,533,623,631,692,718,724,736,864,966,984,990,995,1135,1183,1190,1233,1272,1278,1291,1308,1311,1317,1322,2099,2122,2159,2183,2600,2606,2636,2646,2697,2707,2720,2725,2735,2738,2744,2769,2775,2794,2804,2830,2847,2857,2863,2868,2921,3018,3042,3047,3053,3065,3338,3343,3346,3352,3399,3402,3408,3441],{"type":46,"tag":47,"props":48,"children":50},"element","h1",{"id":49},"skill-overview-what-to-use-and-when",[51],{"type":52,"value":53},"text","Skill: Overview — What to Use and When",{"type":46,"tag":55,"props":56,"children":57},"p",{},[58,60,66],{"type":52,"value":59},"Load this skill first for any Dataverse work — it holds the cross-cutting context every task needs: scope, the tool-capability reference, the hard rules, and the change lifecycle. It does ",{"type":46,"tag":61,"props":62,"children":63},"strong",{},[64],{"type":52,"value":65},"not",{"type":52,"value":67}," route; the agent auto-selects specialist skills via their own WHEN\u002FDO NOT USE WHEN frontmatter triggers. Users describe what they want in plain English; the agent chains skills automatically and never asks the user to name a skill or command.",{"type":46,"tag":69,"props":70,"children":71},"hr",{},[],{"type":46,"tag":73,"props":74,"children":76},"h2",{"id":75},"what-this-plugin-covers",[77],{"type":52,"value":78},"What This Plugin Covers",{"type":46,"tag":55,"props":80,"children":81},{},[82,84,89],{"type":52,"value":83},"Dataverse \u002F Power Platform work for ",{"type":46,"tag":61,"props":85,"children":86},{},[87],{"type":52,"value":88},"every persona",{"type":52,"value":90}," — builders and agent devs, data scientists, environment admins, and business users — delivered by specialist skills. The agent loads and routes to these automatically via their frontmatter triggers — you never invoke them by name.",{"type":46,"tag":92,"props":93,"children":94},"table",{},[95,114],{"type":46,"tag":96,"props":97,"children":98},"thead",{},[99],{"type":46,"tag":100,"props":101,"children":102},"tr",{},[103,109],{"type":46,"tag":104,"props":105,"children":106},"th",{},[107],{"type":52,"value":108},"Area",{"type":46,"tag":104,"props":110,"children":111},{},[112],{"type":52,"value":113},"Skill",{"type":46,"tag":115,"props":116,"children":117},"tbody",{},[118,137,154,171,188,205,222],{"type":46,"tag":100,"props":119,"children":120},{},[121,127],{"type":46,"tag":122,"props":123,"children":124},"td",{},[125],{"type":52,"value":126},"Connect, authenticate, configure MCP, verify the environment",{"type":46,"tag":122,"props":128,"children":129},{},[130],{"type":46,"tag":131,"props":132,"children":134},"code",{"className":133},[],[135],{"type":52,"value":136},"dv-connect",{"type":46,"tag":100,"props":138,"children":139},{},[140,145],{"type":46,"tag":122,"props":141,"children":142},{},[143],{"type":52,"value":144},"Schema — tables, columns, relationships, forms, views; inspect existing schema",{"type":46,"tag":122,"props":146,"children":147},{},[148],{"type":46,"tag":131,"props":149,"children":151},{"className":150},[],[152],{"type":52,"value":153},"dv-metadata",{"type":46,"tag":100,"props":155,"children":156},{},[157,162],{"type":46,"tag":122,"props":158,"children":159},{},[160],{"type":52,"value":161},"Data writes — record CRUD, bulk create\u002Fupdate\u002Fupsert, CSV\u002FFK-ordered import, sample data",{"type":46,"tag":122,"props":163,"children":164},{},[165],{"type":46,"tag":131,"props":166,"children":168},{"className":167},[],[169],{"type":52,"value":170},"dv-data",{"type":46,"tag":100,"props":172,"children":173},{},[174,179],{"type":46,"tag":122,"props":175,"children":176},{},[177],{"type":52,"value":178},"Data reads & analytics — OData queries, QueryBuilder, FetchXML (aggregation + N:N joins), DataFrames",{"type":46,"tag":122,"props":180,"children":181},{},[182],{"type":46,"tag":131,"props":183,"children":185},{"className":184},[],[186],{"type":52,"value":187},"dv-query",{"type":46,"tag":100,"props":189,"children":190},{},[191,196],{"type":46,"tag":122,"props":192,"children":193},{},[194],{"type":52,"value":195},"Solution ALM — create, export, import, pack\u002Funpack, post-import validation",{"type":46,"tag":122,"props":197,"children":198},{},[199],{"type":46,"tag":131,"props":200,"children":202},{"className":201},[],[203],{"type":52,"value":204},"dv-solution",{"type":46,"tag":100,"props":206,"children":207},{},[208,213],{"type":46,"tag":122,"props":209,"children":210},{},[211],{"type":52,"value":212},"Environment administration — bulk delete, retention\u002Farchival, org & OrgDB settings, recycle bin",{"type":46,"tag":122,"props":214,"children":215},{},[216],{"type":46,"tag":131,"props":217,"children":219},{"className":218},[],[220],{"type":52,"value":221},"dv-admin",{"type":46,"tag":100,"props":223,"children":224},{},[225,230],{"type":46,"tag":122,"props":226,"children":227},{},[228],{"type":52,"value":229},"Security & access — roles, users, application users, business units, self-elevation (PAC CLI)",{"type":46,"tag":122,"props":231,"children":232},{},[233],{"type":46,"tag":131,"props":234,"children":236},{"className":235},[],[237],{"type":52,"value":238},"dv-security",{"type":46,"tag":55,"props":240,"children":241},{},[242,247,249,254,256,261],{"type":46,"tag":61,"props":243,"children":244},{},[245],{"type":52,"value":246},"Model-driven apps:",{"type":52,"value":248}," the building blocks (tables, forms, views) are covered by ",{"type":46,"tag":131,"props":250,"children":252},{"className":251},[],[253],{"type":52,"value":153},{"type":52,"value":255},"; composing the app shell itself — site map and navigation — is ",{"type":46,"tag":61,"props":257,"children":258},{},[259],{"type":52,"value":260},"not yet",{"type":52,"value":262}," a first-class skill.",{"type":46,"tag":55,"props":264,"children":265},{},[266],{"type":46,"tag":61,"props":267,"children":268},{},[269],{"type":52,"value":270},"Out of scope:",{"type":46,"tag":272,"props":273,"children":274},"ul",{},[275,294,304,314],{"type":46,"tag":276,"props":277,"children":278},"li",{},[279,284,286,292],{"type":46,"tag":61,"props":280,"children":281},{},[282],{"type":52,"value":283},"Canvas apps",{"type":52,"value":285}," — a different technology; use ",{"type":46,"tag":131,"props":287,"children":289},{"className":288},[],[290],{"type":52,"value":291},"pac canvas",{"type":52,"value":293}," or the maker portal",{"type":46,"tag":276,"props":295,"children":296},{},[297,302],{"type":46,"tag":61,"props":298,"children":299},{},[300],{"type":52,"value":301},"Power Automate flows",{"type":52,"value":303}," — use the maker portal or the Power Automate Management API",{"type":46,"tag":276,"props":305,"children":306},{},[307,312],{"type":46,"tag":61,"props":308,"children":309},{},[310],{"type":52,"value":311},"Azure infrastructure",{"type":52,"value":313}," beyond what's needed for service-principal setup",{"type":46,"tag":276,"props":315,"children":316},{},[317,322],{"type":46,"tag":61,"props":318,"children":319},{},[320],{"type":52,"value":321},"Business Central",{"type":52,"value":323}," or other Dynamics products",{"type":46,"tag":69,"props":325,"children":326},{},[],{"type":46,"tag":73,"props":328,"children":330},{"id":329},"hard-rules-read-these-first",[331],{"type":52,"value":332},"Hard Rules — Read These First",{"type":46,"tag":55,"props":334,"children":335},{},[336],{"type":52,"value":337},"The safety rules (init state, auth, environment confirmation, no bespoke MSAL) are non-negotiable. The tool-selection guidance (Rules 1, 2, 4) is capability-based — strong defaults, not rigid mandates.",{"type":46,"tag":339,"props":340,"children":342},"h3",{"id":341},"_0-check-init-state-before-anything-else",[343],{"type":52,"value":344},"0. Check Init State Before Anything Else",{"type":46,"tag":55,"props":346,"children":347},{},[348],{"type":52,"value":349},"Before writing ANY code or creating ANY files, check if the workspace is initialized:",{"type":46,"tag":351,"props":352,"children":357},"pre",{"className":353,"code":354,"language":355,"meta":356,"style":356},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ls .env scripts\u002Fauth.py 2>\u002Fdev\u002Fnull\n","bash","",[358],{"type":46,"tag":131,"props":359,"children":360},{"__ignoreMap":356},[361],{"type":46,"tag":362,"props":363,"children":366},"span",{"class":364,"line":365},"line",1,[367,373,379,384,390],{"type":46,"tag":362,"props":368,"children":370},{"style":369},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[371],{"type":52,"value":372},"ls",{"type":46,"tag":362,"props":374,"children":376},{"style":375},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[377],{"type":52,"value":378}," .env",{"type":46,"tag":362,"props":380,"children":381},{"style":375},[382],{"type":52,"value":383}," scripts\u002Fauth.py",{"type":46,"tag":362,"props":385,"children":387},{"style":386},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[388],{"type":52,"value":389}," 2>",{"type":46,"tag":362,"props":391,"children":392},{"style":375},[393],{"type":52,"value":394},"\u002Fdev\u002Fnull\n",{"type":46,"tag":272,"props":396,"children":397},{},[398,403],{"type":46,"tag":276,"props":399,"children":400},{},[401],{"type":52,"value":402},"If BOTH exist: workspace is initialized. Proceed to the relevant task.",{"type":46,"tag":276,"props":404,"children":405},{},[406,408,413,415,420,422,428,430,436,437,443,445,450],{"type":52,"value":407},"If EITHER is missing: ",{"type":46,"tag":61,"props":409,"children":410},{},[411],{"type":52,"value":412},"Automatically run the connect flow",{"type":52,"value":414}," (see the ",{"type":46,"tag":131,"props":416,"children":418},{"className":417},[],[419],{"type":52,"value":136},{"type":52,"value":421}," skill). Do NOT ask the user whether to initialize — just do it. Do not create your own ",{"type":46,"tag":131,"props":423,"children":425},{"className":424},[],[426],{"type":52,"value":427},".env",{"type":52,"value":429},", ",{"type":46,"tag":131,"props":431,"children":433},{"className":432},[],[434],{"type":52,"value":435},"requirements.txt",{"type":52,"value":429},{"type":46,"tag":131,"props":438,"children":440},{"className":439},[],[441],{"type":52,"value":442},".env.example",{"type":52,"value":444},", or auth scripts. The ",{"type":46,"tag":131,"props":446,"children":448},{"className":447},[],[449],{"type":52,"value":136},{"type":52,"value":451}," skill handles all of this.",{"type":46,"tag":55,"props":453,"children":454},{},[455,457,462,463,468],{"type":52,"value":456},"Do NOT create ",{"type":46,"tag":131,"props":458,"children":460},{"className":459},[],[461],{"type":52,"value":435},{"type":52,"value":429},{"type":46,"tag":131,"props":464,"children":466},{"className":465},[],[467],{"type":52,"value":442},{"type":52,"value":469},", or scaffold files manually. The connect flow produces the correct file structure. Skipping it is the #1 cause of broken setups.",{"type":46,"tag":339,"props":471,"children":473},{"id":472},"_1-python-for-scripting-the-clis-and-mcp-are-first-class",[474],{"type":52,"value":475},"1. Python for scripting; the CLIs and MCP are first-class",{"type":46,"tag":55,"props":477,"children":478},{},[479,481,486,488,494,496,501,503,509,511,516,518,523],{"type":52,"value":480},"Python is the language for automation ",{"type":46,"tag":61,"props":482,"children":483},{},[484],{"type":52,"value":485},"logic",{"type":52,"value":487}," (transformation, control flow, retry, CSV). The toolchain (",{"type":46,"tag":131,"props":489,"children":491},{"className":490},[],[492],{"type":52,"value":493},"scripts\u002Fauth.py",{"type":52,"value":495},", the SDK, skill examples) is Python-based. But MCP tools, the Dataverse CLI (",{"type":46,"tag":131,"props":497,"children":499},{"className":498},[],[500],{"type":52,"value":22},{"type":52,"value":502},"), the Python SDK, and the PAC CLI (",{"type":46,"tag":131,"props":504,"children":506},{"className":505},[],[507],{"type":52,"value":508},"pac",{"type":52,"value":510},") are all ",{"type":46,"tag":61,"props":512,"children":513},{},[514],{"type":52,"value":515},"first-class tool invocations",{"type":52,"value":517}," — use whichever fits. The Dataverse CLI has the same standing as ",{"type":46,"tag":131,"props":519,"children":521},{"className":520},[],[522],{"type":52,"value":508},{"type":52,"value":524},", which is invoked freely across the solution and metadata skills.",{"type":46,"tag":55,"props":526,"children":527},{},[528],{"type":46,"tag":61,"props":529,"children":530},{},[531],{"type":52,"value":532},"NEVER:",{"type":46,"tag":272,"props":534,"children":535},{},[536,584,604],{"type":46,"tag":276,"props":537,"children":538},{},[539,541,546,548,554,555,561,562,568,569,575,576,582],{"type":52,"value":540},"Write automation ",{"type":46,"tag":542,"props":543,"children":544},"em",{},[545],{"type":52,"value":485},{"type":52,"value":547}," in JavaScript\u002FTypeScript\u002FNode.js (",{"type":46,"tag":131,"props":549,"children":551},{"className":550},[],[552],{"type":52,"value":553},"npm",{"type":52,"value":429},{"type":46,"tag":131,"props":556,"children":558},{"className":557},[],[559],{"type":52,"value":560},"yarn",{"type":52,"value":429},{"type":46,"tag":131,"props":563,"children":565},{"className":564},[],[566],{"type":52,"value":567},"pnpm",{"type":52,"value":429},{"type":46,"tag":131,"props":570,"children":572},{"className":571},[],[573],{"type":52,"value":574},"package.json",{"type":52,"value":429},{"type":46,"tag":131,"props":577,"children":579},{"className":578},[],[580],{"type":52,"value":581},"node_modules\u002F",{"type":52,"value":583},")",{"type":46,"tag":276,"props":585,"children":586},{},[587,589,595,596,602],{"type":52,"value":588},"Use ",{"type":46,"tag":131,"props":590,"children":592},{"className":591},[],[593],{"type":52,"value":594},"@azure\u002Fmsal-node",{"type":52,"value":429},{"type":46,"tag":131,"props":597,"children":599},{"className":598},[],[600],{"type":52,"value":601},"@azure\u002Fidentity",{"type":52,"value":603},", or any Node.js Azure SDK",{"type":46,"tag":276,"props":605,"children":606},{},[607,609,614,615,621],{"type":52,"value":608},"Implement a bespoke MSAL \u002F device-code flow — auth is ",{"type":46,"tag":131,"props":610,"children":612},{"className":611},[],[613],{"type":52,"value":493},{"type":52,"value":429},{"type":46,"tag":131,"props":616,"children":618},{"className":617},[],[619],{"type":52,"value":620},"pac auth",{"type":52,"value":622},", and the Dataverse CLI",{"type":46,"tag":55,"props":624,"children":625},{},[626],{"type":46,"tag":61,"props":627,"children":628},{},[629],{"type":52,"value":630},"ALWAYS:",{"type":46,"tag":272,"props":632,"children":633},{},[634,654,673],{"type":46,"tag":276,"props":635,"children":636},{},[637,638,644,646,652],{"type":52,"value":588},{"type":46,"tag":131,"props":639,"children":641},{"className":640},[],[642],{"type":52,"value":643},"pip install",{"type":52,"value":645}," and the Python SDK (",{"type":46,"tag":131,"props":647,"children":649},{"className":648},[],[650],{"type":52,"value":651},"PowerPlatform-Dataverse-Client",{"type":52,"value":653},") for data and schema logic",{"type":46,"tag":276,"props":655,"children":656},{},[657,658,663,665,671],{"type":52,"value":588},{"type":46,"tag":131,"props":659,"children":661},{"className":660},[],[662],{"type":52,"value":493},{"type":52,"value":664}," for tokens\u002Fcredentials; ",{"type":46,"tag":131,"props":666,"children":668},{"className":667},[],[669],{"type":52,"value":670},"azure-identity",{"type":52,"value":672}," (Python) for Azure credential flows",{"type":46,"tag":276,"props":674,"children":675},{},[676,678,683,685,690],{"type":52,"value":677},"Treat the Dataverse CLI (",{"type":46,"tag":131,"props":679,"children":681},{"className":680},[],[682],{"type":52,"value":22},{"type":52,"value":684},") and ",{"type":46,"tag":131,"props":686,"children":688},{"className":687},[],[689],{"type":52,"value":508},{"type":52,"value":691}," as allowed first-party CLIs",{"type":46,"tag":55,"props":693,"children":694},{},[695,697,702,704,709,711,716],{"type":52,"value":696},"About to run ",{"type":46,"tag":131,"props":698,"children":700},{"className":699},[],[701],{"type":52,"value":553},{"type":52,"value":703}," or create a ",{"type":46,"tag":131,"props":705,"children":707},{"className":706},[],[708],{"type":52,"value":574},{"type":52,"value":710},"? STOP — that is off-rails. Reaching for ",{"type":46,"tag":131,"props":712,"children":714},{"className":713},[],[715],{"type":52,"value":508},{"type":52,"value":717}," or the Dataverse CLI is not.",{"type":46,"tag":339,"props":719,"children":721},{"id":720},"_2-pick-the-surface-that-fits-capability-awareness-not-a-fixed-order",[722],{"type":52,"value":723},"2. Pick the surface that fits — capability awareness, not a fixed order",{"type":46,"tag":55,"props":725,"children":726},{},[727,729,734],{"type":52,"value":728},"No mandated tool order. Each surface has a capability profile; pick what fits the job and the surface you are already in — soft defaults, not a required sequence. The full matrix is in ",{"type":46,"tag":61,"props":730,"children":731},{},[732],{"type":52,"value":733},"Tool Capabilities",{"type":52,"value":735}," below; the principles:",{"type":46,"tag":272,"props":737,"children":738},{},[739,751,859],{"type":46,"tag":276,"props":740,"children":741},{},[742,744,749],{"type":52,"value":743},"Prefer a managed surface (MCP, the Dataverse CLI, or the SDK) over hand-rolled raw OData — they carry auth, paging, retry, and geo routing that raw HTTP re-implements. When MCP can't handle it (bulk >25 records, large reads, advanced schema like forms\u002Fviews\u002FN:N relationships\u002Fglobal option sets\u002Falternate keys, multi-step workflows, analytics, or MCP isn't available), the ",{"type":46,"tag":61,"props":745,"children":746},{},[747],{"type":52,"value":748},"Python SDK",{"type":52,"value":750}," is the default.",{"type":46,"tag":276,"props":752,"children":753},{},[754,759,761,767,769,775,777,783,785,791,793,797,799,805,806,812,814,820,821,827,829,834,836,841,843,849,851,857],{"type":46,"tag":61,"props":755,"children":756},{},[757],{"type":52,"value":758},"Raw Web API is the last-resort escape hatch",{"type":52,"value":760}," for surfaces with no managed path (unbound actions like ",{"type":46,"tag":131,"props":762,"children":764},{"className":763},[],[765],{"type":52,"value":766},"PublishXml",{"type":52,"value":768},", global option sets, anything without a first-class SDK\u002FCLI command) — and even then prefer ",{"type":46,"tag":131,"props":770,"children":772},{"className":771},[],[773],{"type":52,"value":774},"dataverse api",{"type":52,"value":776}," (managed auth, exit codes) over hand-rolled ",{"type":46,"tag":131,"props":778,"children":780},{"className":779},[],[781],{"type":52,"value":782},"urllib",{"type":52,"value":784},"\u002F",{"type":46,"tag":131,"props":786,"children":788},{"className":787},[],[789],{"type":52,"value":790},"get_token",{"type":52,"value":792},". Forms\u002Fviews are ",{"type":46,"tag":61,"props":794,"children":795},{},[796],{"type":52,"value":65},{"type":52,"value":798}," raw-only (SDK ",{"type":46,"tag":131,"props":800,"children":802},{"className":801},[],[803],{"type":52,"value":804},"records.create",{"type":52,"value":784},{"type":46,"tag":131,"props":807,"children":809},{"className":808},[],[810],{"type":52,"value":811},"update",{"type":52,"value":813}," on ",{"type":46,"tag":131,"props":815,"children":817},{"className":816},[],[818],{"type":52,"value":819},"systemform",{"type":52,"value":784},{"type":46,"tag":131,"props":822,"children":824},{"className":823},[],[825],{"type":52,"value":826},"savedquery",{"type":52,"value":828},"; only ",{"type":46,"tag":131,"props":830,"children":832},{"className":831},[],[833],{"type":52,"value":766},{"type":52,"value":835}," needs ",{"type":46,"tag":131,"props":837,"children":839},{"className":838},[],[840],{"type":52,"value":774},{"type":52,"value":842},"). Aggregation\u002FN:N joins aren't raw-only either: ",{"type":46,"tag":131,"props":844,"children":846},{"className":845},[],[847],{"type":52,"value":848},"client.query.fetchxml()",{"type":52,"value":850}," (aggregates + link-entity), or the CLI's ",{"type":46,"tag":131,"props":852,"children":854},{"className":853},[],[855],{"type":52,"value":856},"data associate",{"type":52,"value":858}," for N:N writes.",{"type":46,"tag":276,"props":860,"children":861},{},[862],{"type":52,"value":863},"If an SDK method fails or a PAC command seems missing, check the relevant skill before hand-rolling raw HTTP.",{"type":46,"tag":55,"props":865,"children":866},{},[867,872,874,880,881,887,889,895,897,903,905,911,913,919,921,927,929,934,936,941,943,949,951,956,958,964],{"type":46,"tag":61,"props":868,"children":869},{},[870],{"type":52,"value":871},"Field casing:",{"type":52,"value":873}," ",{"type":46,"tag":131,"props":875,"children":877},{"className":876},[],[878],{"type":52,"value":879},"$select",{"type":52,"value":784},{"type":46,"tag":131,"props":882,"children":884},{"className":883},[],[885],{"type":52,"value":886},"$filter",{"type":52,"value":888}," use lowercase logical names (",{"type":46,"tag":131,"props":890,"children":892},{"className":891},[],[893],{"type":52,"value":894},"new_name",{"type":52,"value":896},"). ",{"type":46,"tag":131,"props":898,"children":900},{"className":899},[],[901],{"type":52,"value":902},"$expand",{"type":52,"value":904}," and ",{"type":46,"tag":131,"props":906,"children":908},{"className":907},[],[909],{"type":52,"value":910},"@odata.bind",{"type":52,"value":912}," use Navigation Property Names that are case-sensitive and must match ",{"type":46,"tag":131,"props":914,"children":916},{"className":915},[],[917],{"type":52,"value":918},"$metadata",{"type":52,"value":920}," (e.g., ",{"type":46,"tag":131,"props":922,"children":924},{"className":923},[],[925],{"type":52,"value":926},"new_AccountId",{"type":52,"value":928},"). Getting this wrong causes 400 errors. ",{"type":46,"tag":61,"props":930,"children":931},{},[932],{"type":52,"value":933},"SDK record payloads:",{"type":52,"value":935}," provide the correct SchemaName casing on ",{"type":46,"tag":131,"props":937,"children":939},{"className":938},[],[940],{"type":52,"value":910},{"type":52,"value":942}," keys (e.g., ",{"type":46,"tag":131,"props":944,"children":946},{"className":945},[],[947],{"type":52,"value":948},"new_AccountId@odata.bind",{"type":52,"value":950},"); the SDK does not auto-correct wrong casing. ",{"type":46,"tag":61,"props":952,"children":953},{},[954],{"type":52,"value":955},"Raw Web API calls",{"type":52,"value":957}," (forms, views, metadata): casing is entirely manual — a lowercase ",{"type":46,"tag":131,"props":959,"children":961},{"className":960},[],[962],{"type":52,"value":963},"new_accountid@odata.bind",{"type":52,"value":965}," will 400.",{"type":46,"tag":55,"props":967,"children":968},{},[969,974,976,982],{"type":46,"tag":61,"props":970,"children":971},{},[972],{"type":52,"value":973},"Publisher prefix:",{"type":52,"value":975}," Never hardcode a prefix (especially not ",{"type":46,"tag":131,"props":977,"children":979},{"className":978},[],[980],{"type":52,"value":981},"new",{"type":52,"value":983},"). Always query existing publishers in the environment and ask the user which to use. The prefix is permanent on every component created with it. See the solution skill's publisher discovery flow.",{"type":46,"tag":339,"props":985,"children":987},{"id":986},"_3-use-documented-auth-patterns",[988],{"type":52,"value":989},"3. Use Documented Auth Patterns",{"type":46,"tag":55,"props":991,"children":992},{},[993],{"type":52,"value":994},"Three entry points, one shared sign-in:",{"type":46,"tag":272,"props":996,"children":997},{},[998,1041,1101],{"type":46,"tag":276,"props":999,"children":1000},{},[1001,1010,1012,1018,1020,1025,1026,1031,1033,1039],{"type":46,"tag":61,"props":1002,"children":1003},{},[1004],{"type":46,"tag":131,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":52,"value":1009},"dataverse auth create",{"type":52,"value":1011}," (Dataverse CLI) writes a shared MSAL token cache under the DataverseCLI app registration. That single sign-in serves the CLI, the ",{"type":46,"tag":131,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":52,"value":1017},"@microsoft\u002Fdataverse",{"type":52,"value":1019}," MCP proxy, ",{"type":46,"tag":61,"props":1021,"children":1022},{},[1023],{"type":52,"value":1024},"and",{"type":52,"value":873},{"type":46,"tag":131,"props":1027,"children":1029},{"className":1028},[],[1030],{"type":52,"value":493},{"type":52,"value":1032}," — which silently reuses the same cache via ",{"type":46,"tag":131,"props":1034,"children":1036},{"className":1035},[],[1037],{"type":52,"value":1038},"msal-extensions",{"type":52,"value":1040}," (the sanctioned MSAL API, not raw-file parsing), so Python scripts and the SDK don't prompt again.",{"type":46,"tag":276,"props":1042,"children":1043},{},[1044,1052,1054,1060,1062,1068,1070,1075,1077,1083,1085,1091,1093,1099],{"type":46,"tag":61,"props":1045,"children":1046},{},[1047],{"type":46,"tag":131,"props":1048,"children":1050},{"className":1049},[],[1051],{"type":52,"value":493},{"type":52,"value":1053}," is the auth entry point for all Python\u002FSDK code. Its order: service principal (",{"type":46,"tag":131,"props":1055,"children":1057},{"className":1056},[],[1058],{"type":52,"value":1059},"CLIENT_ID",{"type":52,"value":1061}," + ",{"type":46,"tag":131,"props":1063,"children":1065},{"className":1064},[],[1066],{"type":52,"value":1067},"CLIENT_SECRET",{"type":52,"value":1069}," in ",{"type":46,"tag":131,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":52,"value":427},{"type":52,"value":1076},") → shared Dataverse CLI cache → device-code fallback. Use ",{"type":46,"tag":131,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":52,"value":1082},"get_client(skill)",{"type":52,"value":1084}," (SDK) or ",{"type":46,"tag":131,"props":1086,"children":1088},{"className":1087},[],[1089],{"type":52,"value":1090},"get_plugin_headers(skill, get_token())",{"type":52,"value":1092}," (raw Web API) — both stamp the skill attribution; bare ",{"type":46,"tag":131,"props":1094,"children":1096},{"className":1095},[],[1097],{"type":52,"value":1098},"get_token()",{"type":52,"value":1100}," does not.",{"type":46,"tag":276,"props":1102,"children":1103},{},[1104,1113,1115,1120,1122,1127,1128,1133],{"type":46,"tag":61,"props":1105,"children":1106},{},[1107],{"type":46,"tag":131,"props":1108,"children":1110},{"className":1109},[],[1111],{"type":52,"value":1112},"pac auth create",{"type":52,"value":1114}," (PAC CLI) authenticates ",{"type":46,"tag":131,"props":1116,"children":1118},{"className":1117},[],[1119],{"type":52,"value":508},{"type":52,"value":1121}," for ",{"type":46,"tag":131,"props":1123,"children":1125},{"className":1124},[],[1126],{"type":52,"value":204},{"type":52,"value":904},{"type":46,"tag":131,"props":1129,"children":1131},{"className":1130},[],[1132],{"type":52,"value":221},{"type":52,"value":1134},".",{"type":46,"tag":55,"props":1136,"children":1137},{},[1138,1143,1145,1151,1153,1158,1159,1165,1167,1173,1175,1181],{"type":46,"tag":61,"props":1139,"children":1140},{},[1141],{"type":52,"value":1142},"Telemetry attribution (keep it deterministic):",{"type":52,"value":1144}," every request carries a closed-schema ",{"type":46,"tag":131,"props":1146,"children":1148},{"className":1147},[],[1149],{"type":52,"value":1150},"app=dataverse-skills\u002F\u003Cver>;skill=\u003Cskill>;agent=\u003Cagent>",{"type":52,"value":1152}," context so the server sees which skill routed each OData call. It is baked in — ",{"type":46,"tag":131,"props":1154,"children":1156},{"className":1155},[],[1157],{"type":52,"value":1082},{"type":52,"value":904},{"type":46,"tag":131,"props":1160,"children":1162},{"className":1161},[],[1163],{"type":52,"value":1164},"get_plugin_headers(skill, ...)",{"type":52,"value":1166}," stamp it on the SDK and raw-HTTP paths; the Dataverse CLI auto-stamps ",{"type":46,"tag":131,"props":1168,"children":1170},{"className":1169},[],[1171],{"type":52,"value":1172},"DataverseCli\u002F\u003Cver>",{"type":52,"value":1174}," + the command, and you add the skill with ",{"type":46,"tag":131,"props":1176,"children":1178},{"className":1177},[],[1179],{"type":52,"value":1180},"--context \"app=dataverse-skills\u002F\u003Cver>;skill=\u003Cskill>;agent=\u003Cagent>\"",{"type":52,"value":1182}," (the CLI wraps it in parentheses itself — do not pre-wrap). Never modify, omit, or free-form this context — it is a closed schema (allowlisted skill\u002Fagent, no PII).",{"type":46,"tag":55,"props":1184,"children":1185},{},[1186],{"type":46,"tag":61,"props":1187,"children":1188},{},[1189],{"type":52,"value":532},{"type":46,"tag":272,"props":1191,"children":1192},{},[1193,1218,1223,1228],{"type":46,"tag":276,"props":1194,"children":1195},{},[1196,1198,1204,1206,1211,1213],{"type":52,"value":1197},"Read or parse raw token cache files (e.g., ",{"type":46,"tag":131,"props":1199,"children":1201},{"className":1200},[],[1202],{"type":52,"value":1203},"tokencache_msalv3.dat",{"type":52,"value":1205},") — reuse the cache only through ",{"type":46,"tag":131,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":52,"value":493},{"type":52,"value":1212}," \u002F ",{"type":46,"tag":131,"props":1214,"children":1216},{"className":1215},[],[1217],{"type":52,"value":1038},{"type":46,"tag":276,"props":1219,"children":1220},{},[1221],{"type":52,"value":1222},"Implement your own MSAL device-code flow",{"type":46,"tag":276,"props":1224,"children":1225},{},[1226],{"type":52,"value":1227},"Hard-code tokens or credentials in scripts",{"type":46,"tag":276,"props":1229,"children":1230},{},[1231],{"type":52,"value":1232},"Invent a new auth mechanism",{"type":46,"tag":55,"props":1234,"children":1235},{},[1236,1238,1243,1245,1250,1251,1256,1258,1263,1265,1270],{"type":52,"value":1237},"If auth is expired or missing, re-run ",{"type":46,"tag":131,"props":1239,"children":1241},{"className":1240},[],[1242],{"type":52,"value":1009},{"type":52,"value":1244}," (or ",{"type":46,"tag":131,"props":1246,"children":1248},{"className":1247},[],[1249],{"type":52,"value":1112},{"type":52,"value":1121},{"type":46,"tag":131,"props":1252,"children":1254},{"className":1253},[],[1255],{"type":52,"value":508},{"type":52,"value":1257},"), or check ",{"type":46,"tag":131,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":52,"value":427},{"type":52,"value":1264}," credentials. See the ",{"type":46,"tag":131,"props":1266,"children":1268},{"className":1267},[],[1269],{"type":52,"value":136},{"type":52,"value":1271}," skill.",{"type":46,"tag":339,"props":1273,"children":1275},{"id":1274},"_4-be-honest-about-gaps-dont-hallucinate",[1276],{"type":52,"value":1277},"4. Be honest about gaps — don't hallucinate",{"type":46,"tag":55,"props":1279,"children":1280},{},[1281,1283,1289],{"type":52,"value":1282},"Each skill documents a tested sequence — follow it when it fits. The skills are the source of truth for the supported, non-deprecated API. If a call fails with ",{"type":46,"tag":131,"props":1284,"children":1286},{"className":1285},[],[1287],{"type":52,"value":1288},"AttributeError",{"type":52,"value":1290},", the installed SDK version may not have it — check the skill's version note and use the documented alternative.",{"type":46,"tag":55,"props":1292,"children":1293},{},[1294,1299,1301,1306],{"type":46,"tag":61,"props":1295,"children":1296},{},[1297],{"type":52,"value":1298},"The honesty guard:",{"type":52,"value":1300}," if you hit a gap the skills don't cover, say so and suggest a workaround. ",{"type":46,"tag":61,"props":1302,"children":1303},{},[1304],{"type":52,"value":1305},"Do not hallucinate an unsupported path",{"type":52,"value":1307}," — do not invent a method, parameter, or endpoint that isn't documented. If unsure, say so.",{"type":46,"tag":69,"props":1309,"children":1310},{},[],{"type":46,"tag":73,"props":1312,"children":1314},{"id":1313},"tool-capabilities-which-tool-for-which-job",[1315],{"type":52,"value":1316},"Tool Capabilities — Which Tool for Which Job",{"type":46,"tag":55,"props":1318,"children":1319},{},[1320],{"type":52,"value":1321},"Understanding the real limits of each tool prevents hallucinated paths. This is the one piece of context no individual skill owns.",{"type":46,"tag":92,"props":1323,"children":1324},{},[1325,1346],{"type":46,"tag":96,"props":1326,"children":1327},{},[1328],{"type":46,"tag":100,"props":1329,"children":1330},{},[1331,1336,1341],{"type":46,"tag":104,"props":1332,"children":1333},{},[1334],{"type":52,"value":1335},"Tool",{"type":46,"tag":104,"props":1337,"children":1338},{},[1339],{"type":52,"value":1340},"Use for",{"type":46,"tag":104,"props":1342,"children":1343},{},[1344],{"type":52,"value":1345},"Does NOT support",{"type":46,"tag":115,"props":1347,"children":1348},{},[1349,1649,1698,1794,1915,1975,1996,2016],{"type":46,"tag":100,"props":1350,"children":1351},{},[1352,1360,1389],{"type":46,"tag":122,"props":1353,"children":1354},{},[1355],{"type":46,"tag":61,"props":1356,"children":1357},{},[1358],{"type":52,"value":1359},"MCP Server",{"type":46,"tag":122,"props":1361,"children":1362},{},[1363,1365,1371,1373,1379,1381,1387],{"type":52,"value":1364},"Data CRUD (create\u002Fread\u002Fupdate\u002Fdelete records, batch up to 25 per call), table create\u002Fupdate\u002Fdelete + column add (incl. local choice\u002Fmultiselect + lookup\u002Fcustomer), schema + record inspection via ",{"type":46,"tag":131,"props":1366,"children":1368},{"className":1367},[],[1369],{"type":52,"value":1370},"describe",{"type":52,"value":1372},", metadata search (",{"type":46,"tag":131,"props":1374,"children":1376},{"className":1375},[],[1377],{"type":52,"value":1378},"search",{"type":52,"value":1380},"), data + file-content search (",{"type":46,"tag":131,"props":1382,"children":1384},{"className":1383},[],[1385],{"type":52,"value":1386},"search_data",{"type":52,"value":1388},", when Dataverse search is enabled), file upload\u002Fdownload",{"type":46,"tag":122,"props":1390,"children":1391},{},[1392,1394,1399,1401,1406,1408,1413,1415,1421,1422,1428,1429,1434,1436,1441,1443,1449,1451,1457,1459,1465,1466,1479,1481,1487,1488,1494,1496,1502,1503,1509,1510,1516,1518,1524,1525,1531,1533,1539,1540,1546,1547,1553,1554,1560,1561,1567,1568,1574,1576,1582,1584,1589,1591,1597,1599,1604,1606,1611,1613,1619,1620,1626,1627,1633,1635,1641,1643,1648],{"type":52,"value":1393},"Forms, Views, ",{"type":46,"tag":61,"props":1395,"children":1396},{},[1397],{"type":52,"value":1398},"global",{"type":52,"value":1400}," Option Sets, ",{"type":46,"tag":61,"props":1402,"children":1403},{},[1404],{"type":52,"value":1405},"N:N",{"type":52,"value":1407}," relationships, alternate keys, Solutions (lookup + local choice\u002Fmultiselect columns ",{"type":46,"tag":61,"props":1409,"children":1410},{},[1411],{"type":52,"value":1412},"are",{"type":52,"value":1414}," supported via ",{"type":46,"tag":131,"props":1416,"children":1418},{"className":1417},[],[1419],{"type":52,"value":1420},"create_table",{"type":52,"value":784},{"type":46,"tag":131,"props":1423,"children":1425},{"className":1424},[],[1426],{"type":52,"value":1427},"update_table",{"type":52,"value":896},{"type":46,"tag":61,"props":1430,"children":1431},{},[1432],{"type":52,"value":1433},"Note:",{"type":52,"value":1435}," table creation may timeout but still succeed — always ",{"type":46,"tag":131,"props":1437,"children":1439},{"className":1438},[],[1440],{"type":52,"value":1370},{"type":52,"value":1442}," (e.g. ",{"type":46,"tag":131,"props":1444,"children":1446},{"className":1445},[],[1447],{"type":52,"value":1448},"describe('tables\u002F{name}')",{"type":52,"value":1450},") before retrying. Run queries sequentially (parallel calls timeout). Column names with spaces normalize to underscores (e.g., ",{"type":46,"tag":131,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":52,"value":1456},"\"Specialty Area\"",{"type":52,"value":1458}," → ",{"type":46,"tag":131,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":52,"value":1464},"cr9ac_specialty_area",{"type":52,"value":896},{"type":46,"tag":61,"props":1467,"children":1468},{},[1469,1471,1477],{"type":52,"value":1470},"SQL (",{"type":46,"tag":131,"props":1472,"children":1474},{"className":1473},[],[1475],{"type":52,"value":1476},"read_query",{"type":52,"value":1478},"):",{"type":52,"value":1480}," supports ",{"type":46,"tag":131,"props":1482,"children":1484},{"className":1483},[],[1485],{"type":52,"value":1486},"JOIN",{"type":52,"value":429},{"type":46,"tag":131,"props":1489,"children":1491},{"className":1490},[],[1492],{"type":52,"value":1493},"GROUP BY",{"type":52,"value":1495}," (COUNT\u002FSUM\u002FAVG\u002FMIN\u002FMAX), ",{"type":46,"tag":131,"props":1497,"children":1499},{"className":1498},[],[1500],{"type":52,"value":1501},"TOP",{"type":52,"value":429},{"type":46,"tag":131,"props":1504,"children":1506},{"className":1505},[],[1507],{"type":52,"value":1508},"WHERE",{"type":52,"value":429},{"type":46,"tag":131,"props":1511,"children":1513},{"className":1512},[],[1514],{"type":52,"value":1515},"ORDER BY",{"type":52,"value":1517},"; does NOT support ",{"type":46,"tag":131,"props":1519,"children":1521},{"className":1520},[],[1522],{"type":52,"value":1523},"DISTINCT",{"type":52,"value":429},{"type":46,"tag":131,"props":1526,"children":1528},{"className":1527},[],[1529],{"type":52,"value":1530},"HAVING",{"type":52,"value":1532},", subqueries, ",{"type":46,"tag":131,"props":1534,"children":1536},{"className":1535},[],[1537],{"type":52,"value":1538},"OFFSET",{"type":52,"value":429},{"type":46,"tag":131,"props":1541,"children":1543},{"className":1542},[],[1544],{"type":52,"value":1545},"UNION",{"type":52,"value":429},{"type":46,"tag":131,"props":1548,"children":1550},{"className":1549},[],[1551],{"type":52,"value":1552},"CASE",{"type":52,"value":784},{"type":46,"tag":131,"props":1555,"children":1557},{"className":1556},[],[1558],{"type":52,"value":1559},"IF",{"type":52,"value":429},{"type":46,"tag":131,"props":1562,"children":1564},{"className":1563},[],[1565],{"type":52,"value":1566},"CAST",{"type":52,"value":784},{"type":46,"tag":131,"props":1569,"children":1571},{"className":1570},[],[1572],{"type":52,"value":1573},"CONVERT",{"type":52,"value":1575},", CTE, or date functions. For those, use ",{"type":46,"tag":131,"props":1577,"children":1579},{"className":1578},[],[1580],{"type":52,"value":1581},"client.query.sql()",{"type":52,"value":1583}," (also allows ",{"type":46,"tag":131,"props":1585,"children":1587},{"className":1586},[],[1588],{"type":52,"value":1523},{"type":52,"value":1590},", \u003C5K rows), ",{"type":46,"tag":131,"props":1592,"children":1594},{"className":1593},[],[1595],{"type":52,"value":1596},"$apply",{"type":52,"value":1598},", or a builder->DataFrame with pandas — see ",{"type":46,"tag":131,"props":1600,"children":1602},{"className":1601},[],[1603],{"type":52,"value":187},{"type":52,"value":1605},". ",{"type":46,"tag":61,"props":1607,"children":1608},{},[1609],{"type":52,"value":1610},"Bulk:",{"type":52,"value":1612}," MCP ",{"type":46,"tag":131,"props":1614,"children":1616},{"className":1615},[],[1617],{"type":52,"value":1618},"create_record",{"type":52,"value":784},{"type":46,"tag":131,"props":1621,"children":1623},{"className":1622},[],[1624],{"type":52,"value":1625},"update_record",{"type":52,"value":784},{"type":46,"tag":131,"props":1628,"children":1630},{"className":1629},[],[1631],{"type":52,"value":1632},"delete_record",{"type":52,"value":1634}," batch up to 25 records per call; for larger bulk use the SDK ",{"type":46,"tag":131,"props":1636,"children":1638},{"className":1637},[],[1639],{"type":52,"value":1640},"CreateMultiple",{"type":52,"value":1642}," — see ",{"type":46,"tag":131,"props":1644,"children":1646},{"className":1645},[],[1647],{"type":52,"value":170},{"type":52,"value":1134},{"type":46,"tag":100,"props":1650,"children":1651},{},[1652,1666,1671],{"type":46,"tag":122,"props":1653,"children":1654},{},[1655],{"type":46,"tag":61,"props":1656,"children":1657},{},[1658,1660,1665],{"type":52,"value":1659},"Python SDK (",{"type":46,"tag":131,"props":1661,"children":1663},{"className":1662},[],[1664],{"type":52,"value":170},{"type":52,"value":583},{"type":46,"tag":122,"props":1667,"children":1668},{},[1669],{"type":52,"value":1670},"Scripted data writes, especially at volume. Record CRUD, upsert (alternate keys), bulk create\u002Fupdate\u002Fupsert (CreateMultiple\u002FUpdateMultiple\u002FUpsertMultiple), CSV import with lookup resolution, file column uploads (chunked >128MB)",{"type":46,"tag":122,"props":1672,"children":1673},{},[1674,1676,1682,1684,1689,1691,1696],{"type":52,"value":1675},"global Option Sets, record association (",{"type":46,"tag":131,"props":1677,"children":1679},{"className":1678},[],[1680],{"type":52,"value":1681},"$ref",{"type":52,"value":1683},"), ",{"type":46,"tag":131,"props":1685,"children":1687},{"className":1686},[],[1688],{"type":52,"value":1596},{"type":52,"value":1690}," aggregation, table\u002Fcolumn\u002Frelationship creation (use ",{"type":46,"tag":131,"props":1692,"children":1694},{"className":1693},[],[1695],{"type":52,"value":153},{"type":52,"value":1697},"), custom action invocation",{"type":46,"tag":100,"props":1699,"children":1700},{},[1701,1714,1746],{"type":46,"tag":122,"props":1702,"children":1703},{},[1704],{"type":46,"tag":61,"props":1705,"children":1706},{},[1707,1708,1713],{"type":52,"value":1659},{"type":46,"tag":131,"props":1709,"children":1711},{"className":1710},[],[1712],{"type":52,"value":187},{"type":52,"value":583},{"type":46,"tag":122,"props":1715,"children":1716},{},[1717,1719,1724,1726,1736,1738,1744],{"type":52,"value":1718},"Bulk reads and analytics. Multi-page record iteration, OData queries (select\u002Ffilter\u002Fexpand\u002Forderby), QueryBuilder fluent API, GUID-free display (formatted values), ",{"type":46,"tag":131,"props":1720,"children":1722},{"className":1721},[],[1723],{"type":52,"value":902},{"type":52,"value":1725}," to resolve lookups, ",{"type":46,"tag":61,"props":1727,"children":1728},{},[1729,1731],{"type":52,"value":1730},"aggregation and N:N joins via ",{"type":46,"tag":131,"props":1732,"children":1734},{"className":1733},[],[1735],{"type":52,"value":848},{"type":52,"value":1737}," (aggregate FetchXML + link-entity), pandas DataFrame handoff (",{"type":46,"tag":131,"props":1739,"children":1741},{"className":1740},[],[1742],{"type":52,"value":1743},"client.query.builder(...).execute().to_dataframe()",{"type":52,"value":1745},") for exports, Jupyter notebook snippets",{"type":46,"tag":122,"props":1747,"children":1748},{},[1749,1751,1756,1758,1763,1765,1770,1772,1778,1780,1786,1788,1793],{"type":52,"value":1750},"OData ",{"type":46,"tag":131,"props":1752,"children":1754},{"className":1753},[],[1755],{"type":52,"value":1596},{"type":52,"value":1757}," and N:N ",{"type":46,"tag":131,"props":1759,"children":1761},{"className":1760},[],[1762],{"type":52,"value":902},{"type":52,"value":1764}," on the ",{"type":46,"tag":61,"props":1766,"children":1767},{},[1768],{"type":52,"value":1769},"QueryBuilder",{"type":52,"value":1771}," path — use ",{"type":46,"tag":131,"props":1773,"children":1775},{"className":1774},[],[1776],{"type":52,"value":1777},"records.list(expand=...)",{"type":52,"value":1779}," for N:N, or ",{"type":46,"tag":131,"props":1781,"children":1783},{"className":1782},[],[1784],{"type":52,"value":1785},"fetchxml()",{"type":52,"value":1787}," for aggregates (not raw ",{"type":46,"tag":131,"props":1789,"children":1791},{"className":1790},[],[1792],{"type":52,"value":782},{"type":52,"value":583},{"type":46,"tag":100,"props":1795,"children":1796},{},[1797,1811,1903],{"type":46,"tag":122,"props":1798,"children":1799},{},[1800],{"type":46,"tag":61,"props":1801,"children":1802},{},[1803,1805,1810],{"type":52,"value":1804},"Dataverse CLI (",{"type":46,"tag":131,"props":1806,"children":1808},{"className":1807},[],[1809],{"type":52,"value":22},{"type":52,"value":583},{"type":46,"tag":122,"props":1812,"children":1813},{},[1814,1816,1822,1824,1830,1831,1836,1837,1843,1845,1850,1851,1857,1859,1865,1866,1872,1874,1880,1881,1886,1888,1894,1895,1901],{"type":52,"value":1815},"Headless data plane (no Python script needed): ",{"type":46,"tag":131,"props":1817,"children":1819},{"className":1818},[],[1820],{"type":52,"value":1821},"data",{"type":52,"value":1823}," CRUD (",{"type":46,"tag":131,"props":1825,"children":1827},{"className":1826},[],[1828],{"type":52,"value":1829},"query\u002Fget\u002Fcreate\u002Fupdate\u002Fupsert\u002Fdelete\u002Fcount",{"type":52,"value":1683},{"type":46,"tag":131,"props":1832,"children":1834},{"className":1833},[],[1835],{"type":52,"value":856},{"type":52,"value":784},{"type":46,"tag":131,"props":1838,"children":1840},{"className":1839},[],[1841],{"type":52,"value":1842},"disassociate",{"type":52,"value":1844}," (N:N + lookups via ",{"type":46,"tag":131,"props":1846,"children":1848},{"className":1847},[],[1849],{"type":52,"value":1681},{"type":52,"value":1683},{"type":46,"tag":131,"props":1852,"children":1854},{"className":1853},[],[1855],{"type":52,"value":1856},"data upload",{"type":52,"value":1858}," (file columns); ",{"type":46,"tag":131,"props":1860,"children":1862},{"className":1861},[],[1863],{"type":52,"value":1864},"api request",{"type":52,"value":784},{"type":46,"tag":131,"props":1867,"children":1869},{"className":1868},[],[1870],{"type":52,"value":1871},"invoke",{"type":52,"value":1873}," (managed Web API escape hatch); ",{"type":46,"tag":131,"props":1875,"children":1877},{"className":1876},[],[1878],{"type":52,"value":1879},"api list",{"type":52,"value":784},{"type":46,"tag":131,"props":1882,"children":1884},{"className":1883},[],[1885],{"type":52,"value":1370},{"type":52,"value":1887}," for Custom API discovery; shared ",{"type":46,"tag":131,"props":1889,"children":1891},{"className":1890},[],[1892],{"type":52,"value":1893},"auth",{"type":52,"value":784},{"type":46,"tag":131,"props":1896,"children":1898},{"className":1897},[],[1899],{"type":52,"value":1900},"org",{"type":52,"value":1902}," token cache",{"type":46,"tag":122,"props":1904,"children":1905},{},[1906,1908,1913],{"type":52,"value":1907},"Metadata\u002Fschema creation (use SDK — ",{"type":46,"tag":131,"props":1909,"children":1911},{"className":1910},[],[1912],{"type":52,"value":153},{"type":52,"value":1914},"), solution ALM (use PAC), forms\u002Fviews authoring",{"type":46,"tag":100,"props":1916,"children":1917},{},[1918,1926,1954],{"type":46,"tag":122,"props":1919,"children":1920},{},[1921],{"type":46,"tag":61,"props":1922,"children":1923},{},[1924],{"type":52,"value":1925},"PAC CLI",{"type":46,"tag":122,"props":1927,"children":1928},{},[1929,1931,1937,1939,1945,1947,1953],{"type":52,"value":1930},"Solution export\u002Fimport\u002Fpack\u002Funpack, environment create\u002Flist\u002Fdelete\u002Freset, auth profile management, plugin updates (",{"type":46,"tag":131,"props":1932,"children":1934},{"className":1933},[],[1935],{"type":52,"value":1936},"pac plugin push",{"type":52,"value":1938}," — first-time registration requires Web API), user\u002Frole assignment (",{"type":46,"tag":131,"props":1940,"children":1942},{"className":1941},[],[1943],{"type":52,"value":1944},"pac admin assign-user",{"type":52,"value":1946},"), add solution components (",{"type":46,"tag":131,"props":1948,"children":1950},{"className":1949},[],[1951],{"type":52,"value":1952},"pac solution add-solution-component",{"type":52,"value":583},{"type":46,"tag":122,"props":1955,"children":1956},{},[1957,1959,1965,1967,1973],{"type":52,"value":1958},"Data CRUD, metadata creation (tables\u002Fcolumns\u002Fforms), listing solution components (no ",{"type":46,"tag":131,"props":1960,"children":1962},{"className":1961},[],[1963],{"type":52,"value":1964},"list-components",{"type":52,"value":1966}," — query ",{"type":46,"tag":131,"props":1968,"children":1970},{"className":1969},[],[1971],{"type":52,"value":1972},"solutioncomponent",{"type":52,"value":1974}," via SDK\u002FCLI)",{"type":46,"tag":100,"props":1976,"children":1977},{},[1978,1986,1991],{"type":46,"tag":122,"props":1979,"children":1980},{},[1981],{"type":46,"tag":61,"props":1982,"children":1983},{},[1984],{"type":52,"value":1985},"Azure CLI",{"type":46,"tag":122,"props":1987,"children":1988},{},[1989],{"type":52,"value":1990},"App registrations, service principals, credential management",{"type":46,"tag":122,"props":1992,"children":1993},{},[1994],{"type":52,"value":1995},"Dataverse-specific operations",{"type":46,"tag":100,"props":1997,"children":1998},{},[1999,2007,2012],{"type":46,"tag":122,"props":2000,"children":2001},{},[2002],{"type":46,"tag":61,"props":2003,"children":2004},{},[2005],{"type":52,"value":2006},"GitHub CLI",{"type":46,"tag":122,"props":2008,"children":2009},{},[2010],{"type":52,"value":2011},"Repo management, GitHub secrets, Actions workflow status",{"type":46,"tag":122,"props":2013,"children":2014},{},[2015],{"type":52,"value":1995},{"type":46,"tag":100,"props":2017,"children":2018},{},[2019,2029,2087],{"type":46,"tag":122,"props":2020,"children":2021},{},[2022,2027],{"type":46,"tag":61,"props":2023,"children":2024},{},[2025],{"type":52,"value":2026},"Raw Web API",{"type":52,"value":2028}," (last resort)",{"type":46,"tag":122,"props":2030,"children":2031},{},[2032,2034,2039,2041,2046,2048,2053,2055,2059,2061,2066,2067,2072,2074,2079,2081,2086],{"type":52,"value":2033},"Only when ",{"type":46,"tag":61,"props":2035,"children":2036},{},[2037],{"type":52,"value":2038},"no",{"type":52,"value":2040}," managed surface exposes the operation — i.e. not doable via MCP, the Python SDK, the Dataverse CLI, or the ",{"type":46,"tag":131,"props":2042,"children":2044},{"className":2043},[],[2045],{"type":52,"value":774},{"type":52,"value":2047}," escape hatch. Genuine cases: unbound actions like ",{"type":46,"tag":131,"props":2049,"children":2051},{"className":2050},[],[2052],{"type":52,"value":766},{"type":52,"value":2054},", global option sets, and similar edge cases (",{"type":46,"tag":61,"props":2056,"children":2057},{},[2058],{"type":52,"value":65},{"type":52,"value":2060}," forms\u002Fviews — those are SDK record CRUD on ",{"type":46,"tag":131,"props":2062,"children":2064},{"className":2063},[],[2065],{"type":52,"value":819},{"type":52,"value":784},{"type":46,"tag":131,"props":2068,"children":2070},{"className":2069},[],[2071],{"type":52,"value":826},{"type":52,"value":2073},"). Even then, prefer ",{"type":46,"tag":131,"props":2075,"children":2077},{"className":2076},[],[2078],{"type":52,"value":774},{"type":52,"value":2080}," (managed auth + skill attribution) over hand-rolled ",{"type":46,"tag":131,"props":2082,"children":2084},{"className":2083},[],[2085],{"type":52,"value":782},{"type":52,"value":1134},{"type":46,"tag":122,"props":2088,"children":2089},{},[2090,2092,2097],{"type":52,"value":2091},"Functionally nothing (full OData\u002FMetadataService) — but raw ",{"type":46,"tag":131,"props":2093,"children":2095},{"className":2094},[],[2096],{"type":52,"value":782},{"type":52,"value":2098}," bypasses managed auth, paging, retry, and skill attribution, so treat it as the path of last resort",{"type":46,"tag":55,"props":2100,"children":2101},{},[2102,2107,2109,2114,2116,2121],{"type":46,"tag":61,"props":2103,"children":2104},{},[2105],{"type":52,"value":2106},"Routing:",{"type":52,"value":2108}," the table shows what each surface does; the ",{"type":46,"tag":542,"props":2110,"children":2111},{},[2112],{"type":52,"value":2113},"how to choose",{"type":52,"value":2115}," principle (soft defaults, not a fixed order) is Hard Rule 2. MCP tools not in your list? Load ",{"type":46,"tag":131,"props":2117,"children":2119},{"className":2118},[],[2120],{"type":52,"value":136},{"type":52,"value":1134},{"type":46,"tag":55,"props":2123,"children":2124},{},[2125,2130,2132,2137,2139,2144,2145,2150,2152,2157],{"type":46,"tag":61,"props":2126,"children":2127},{},[2128],{"type":52,"value":2129},"Volume guidance:",{"type":52,"value":2131}," MCP for up to ~25 records per call or simple filters; the SDK's ",{"type":46,"tag":131,"props":2133,"children":2135},{"className":2134},[],[2136],{"type":52,"value":1640},{"type":52,"value":2138}," for larger bulk writes (chunk large sets starting ~1,000 — see ",{"type":46,"tag":131,"props":2140,"children":2142},{"className":2141},[],[2143],{"type":52,"value":170},{"type":52,"value":684},{"type":46,"tag":131,"props":2146,"children":2148},{"className":2147},[],[2149],{"type":52,"value":187},{"type":52,"value":2151}," for bulk reads (streams pages, avoids MCP SQL limits); Web API for ",{"type":46,"tag":131,"props":2153,"children":2155},{"className":2154},[],[2156],{"type":52,"value":1596},{"type":52,"value":2158}," aggregation.",{"type":46,"tag":55,"props":2160,"children":2161},{},[2162,2167,2169,2173,2175,2181],{"type":46,"tag":61,"props":2163,"children":2164},{},[2165],{"type":52,"value":2166},"SDK method cheat-sheet",{"type":52,"value":2168}," (anti-hallucination, ",{"type":46,"tag":542,"props":2170,"children":2171},{},[2172],{"type":52,"value":65},{"type":52,"value":2174}," a preference signal): SDK method names are the least discoverable surface — MCP tools appear in your tool list and the CLI self-documents via ",{"type":46,"tag":131,"props":2176,"children":2178},{"className":2177},[],[2179],{"type":52,"value":2180},"dataverse --help",{"type":52,"value":2182},", but SDK calls surface nowhere, so agents invent them. This maps common ops to the exact call. Each op is equally reachable via MCP\u002FCLI per Hard Rule 2; see the noted skill for the full pattern.",{"type":46,"tag":92,"props":2184,"children":2185},{},[2186,2206],{"type":46,"tag":96,"props":2187,"children":2188},{},[2189],{"type":46,"tag":100,"props":2190,"children":2191},{},[2192,2197,2202],{"type":46,"tag":104,"props":2193,"children":2194},{},[2195],{"type":52,"value":2196},"Operation",{"type":46,"tag":104,"props":2198,"children":2199},{},[2200],{"type":52,"value":2201},"SDK call",{"type":46,"tag":104,"props":2203,"children":2204},{},[2205],{"type":52,"value":113},{"type":46,"tag":115,"props":2207,"children":2208},{},[2209,2250,2275,2310,2345,2372,2397,2422,2447,2472,2518,2543,2575],{"type":46,"tag":100,"props":2210,"children":2211},{},[2212,2217,2242],{"type":46,"tag":122,"props":2213,"children":2214},{},[2215],{"type":52,"value":2216},"Create \u002F update \u002F delete records",{"type":46,"tag":122,"props":2218,"children":2219},{},[2220,2226,2227,2233,2234,2240],{"type":46,"tag":131,"props":2221,"children":2223},{"className":2222},[],[2224],{"type":52,"value":2225},"client.records.create()",{"type":52,"value":1212},{"type":46,"tag":131,"props":2228,"children":2230},{"className":2229},[],[2231],{"type":52,"value":2232},".update()",{"type":52,"value":1212},{"type":46,"tag":131,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":52,"value":2239},".delete()",{"type":52,"value":2241}," (pass a list for bulk)",{"type":46,"tag":122,"props":2243,"children":2244},{},[2245],{"type":46,"tag":131,"props":2246,"children":2248},{"className":2247},[],[2249],{"type":52,"value":170},{"type":46,"tag":100,"props":2251,"children":2252},{},[2253,2258,2267],{"type":46,"tag":122,"props":2254,"children":2255},{},[2256],{"type":52,"value":2257},"Upsert on an alternate key",{"type":46,"tag":122,"props":2259,"children":2260},{},[2261],{"type":46,"tag":131,"props":2262,"children":2264},{"className":2263},[],[2265],{"type":52,"value":2266},"client.records.upsert()",{"type":46,"tag":122,"props":2268,"children":2269},{},[2270],{"type":46,"tag":131,"props":2271,"children":2273},{"className":2272},[],[2274],{"type":52,"value":170},{"type":46,"tag":100,"props":2276,"children":2277},{},[2278,2283,2302],{"type":46,"tag":122,"props":2279,"children":2280},{},[2281],{"type":52,"value":2282},"Query \u002F filter records",{"type":46,"tag":122,"props":2284,"children":2285},{},[2286,2292,2294,2300],{"type":46,"tag":131,"props":2287,"children":2289},{"className":2288},[],[2290],{"type":52,"value":2291},"client.records.list(...)",{"type":52,"value":2293}," (flat) or ",{"type":46,"tag":131,"props":2295,"children":2297},{"className":2296},[],[2298],{"type":52,"value":2299},".list_pages(...)",{"type":52,"value":2301}," (streaming)",{"type":46,"tag":122,"props":2303,"children":2304},{},[2305],{"type":46,"tag":131,"props":2306,"children":2308},{"className":2307},[],[2309],{"type":52,"value":187},{"type":46,"tag":100,"props":2311,"children":2312},{},[2313,2318,2337],{"type":46,"tag":122,"props":2314,"children":2315},{},[2316],{"type":52,"value":2317},"One record by GUID",{"type":46,"tag":122,"props":2319,"children":2320},{},[2321,2327,2329,2335],{"type":46,"tag":131,"props":2322,"children":2324},{"className":2323},[],[2325],{"type":52,"value":2326},"client.records.retrieve(table, guid)",{"type":52,"value":2328}," (",{"type":46,"tag":131,"props":2330,"children":2332},{"className":2331},[],[2333],{"type":52,"value":2334},"None",{"type":52,"value":2336}," if missing)",{"type":46,"tag":122,"props":2338,"children":2339},{},[2340],{"type":46,"tag":131,"props":2341,"children":2343},{"className":2342},[],[2344],{"type":52,"value":187},{"type":46,"tag":100,"props":2346,"children":2347},{},[2348,2353,2364],{"type":46,"tag":122,"props":2349,"children":2350},{},[2351],{"type":52,"value":2352},"Aggregation \u002F server-side joins",{"type":46,"tag":122,"props":2354,"children":2355},{},[2356,2362],{"type":46,"tag":131,"props":2357,"children":2359},{"className":2358},[],[2360],{"type":52,"value":2361},"client.query.fetchxml(xml)",{"type":52,"value":2363}," (aggregates + link-entity)",{"type":46,"tag":122,"props":2365,"children":2366},{},[2367],{"type":46,"tag":131,"props":2368,"children":2370},{"className":2369},[],[2371],{"type":52,"value":187},{"type":46,"tag":100,"props":2373,"children":2374},{},[2375,2380,2389],{"type":46,"tag":122,"props":2376,"children":2377},{},[2378],{"type":52,"value":2379},"Fluent query build (chainable)",{"type":46,"tag":122,"props":2381,"children":2382},{},[2383],{"type":46,"tag":131,"props":2384,"children":2386},{"className":2385},[],[2387],{"type":52,"value":2388},"client.query.builder(Table).where(...).execute()",{"type":46,"tag":122,"props":2390,"children":2391},{},[2392],{"type":46,"tag":131,"props":2393,"children":2395},{"className":2394},[],[2396],{"type":52,"value":187},{"type":46,"tag":100,"props":2398,"children":2399},{},[2400,2405,2414],{"type":46,"tag":122,"props":2401,"children":2402},{},[2403],{"type":52,"value":2404},"Limited SQL read",{"type":46,"tag":122,"props":2406,"children":2407},{},[2408],{"type":46,"tag":131,"props":2409,"children":2411},{"className":2410},[],[2412],{"type":52,"value":2413},"client.query.sql(\"SELECT ...\")",{"type":46,"tag":122,"props":2415,"children":2416},{},[2417],{"type":46,"tag":131,"props":2418,"children":2420},{"className":2419},[],[2421],{"type":52,"value":187},{"type":46,"tag":100,"props":2423,"children":2424},{},[2425,2430,2439],{"type":46,"tag":122,"props":2426,"children":2427},{},[2428],{"type":52,"value":2429},"Load into pandas",{"type":46,"tag":122,"props":2431,"children":2432},{},[2433],{"type":46,"tag":131,"props":2434,"children":2436},{"className":2435},[],[2437],{"type":52,"value":2438},"client.query.builder(table).select(...).execute().to_dataframe()",{"type":46,"tag":122,"props":2440,"children":2441},{},[2442],{"type":46,"tag":131,"props":2443,"children":2445},{"className":2444},[],[2446],{"type":52,"value":187},{"type":46,"tag":100,"props":2448,"children":2449},{},[2450,2455,2464],{"type":46,"tag":122,"props":2451,"children":2452},{},[2453],{"type":52,"value":2454},"Upload to a file column",{"type":46,"tag":122,"props":2456,"children":2457},{},[2458],{"type":46,"tag":131,"props":2459,"children":2461},{"className":2460},[],[2462],{"type":52,"value":2463},"client.files.upload(...)",{"type":46,"tag":122,"props":2465,"children":2466},{},[2467],{"type":46,"tag":131,"props":2468,"children":2470},{"className":2469},[],[2471],{"type":52,"value":170},{"type":46,"tag":100,"props":2473,"children":2474},{},[2475,2480,2510],{"type":46,"tag":122,"props":2476,"children":2477},{},[2478],{"type":52,"value":2479},"Create tables \u002F columns \u002F lookups \u002F N:N",{"type":46,"tag":122,"props":2481,"children":2482},{},[2483,2489,2490,2496,2497,2503,2504],{"type":46,"tag":131,"props":2484,"children":2486},{"className":2485},[],[2487],{"type":52,"value":2488},"client.tables.create()",{"type":52,"value":1212},{"type":46,"tag":131,"props":2491,"children":2493},{"className":2492},[],[2494],{"type":52,"value":2495},".add_columns()",{"type":52,"value":1212},{"type":46,"tag":131,"props":2498,"children":2500},{"className":2499},[],[2501],{"type":52,"value":2502},".create_lookup_field()",{"type":52,"value":1212},{"type":46,"tag":131,"props":2505,"children":2507},{"className":2506},[],[2508],{"type":52,"value":2509},".create_many_to_many_relationship()",{"type":46,"tag":122,"props":2511,"children":2512},{},[2513],{"type":46,"tag":131,"props":2514,"children":2516},{"className":2515},[],[2517],{"type":52,"value":153},{"type":46,"tag":100,"props":2519,"children":2520},{},[2521,2526,2535],{"type":46,"tag":122,"props":2522,"children":2523},{},[2524],{"type":52,"value":2525},"Create an alternate key (enables upsert)",{"type":46,"tag":122,"props":2527,"children":2528},{},[2529],{"type":46,"tag":131,"props":2530,"children":2532},{"className":2531},[],[2533],{"type":52,"value":2534},"client.tables.create_alternate_key(...)",{"type":46,"tag":122,"props":2536,"children":2537},{},[2538],{"type":46,"tag":131,"props":2539,"children":2541},{"className":2540},[],[2542],{"type":52,"value":153},{"type":46,"tag":100,"props":2544,"children":2545},{},[2546,2551,2567],{"type":46,"tag":122,"props":2547,"children":2548},{},[2549],{"type":52,"value":2550},"Inspect existing schema",{"type":46,"tag":122,"props":2552,"children":2553},{},[2554,2560,2561],{"type":46,"tag":131,"props":2555,"children":2557},{"className":2556},[],[2558],{"type":52,"value":2559},"client.tables.list_columns(table)",{"type":52,"value":1212},{"type":46,"tag":131,"props":2562,"children":2564},{"className":2563},[],[2565],{"type":52,"value":2566},".list_table_relationships(table)",{"type":46,"tag":122,"props":2568,"children":2569},{},[2570],{"type":46,"tag":131,"props":2571,"children":2573},{"className":2572},[],[2574],{"type":52,"value":153},{"type":46,"tag":100,"props":2576,"children":2577},{},[2578,2583,2592],{"type":46,"tag":122,"props":2579,"children":2580},{},[2581],{"type":52,"value":2582},"Create publisher \u002F solution",{"type":46,"tag":122,"props":2584,"children":2585},{},[2586],{"type":46,"tag":131,"props":2587,"children":2589},{"className":2588},[],[2590],{"type":52,"value":2591},"client.records.create(\"publisher\" \u002F \"solution\", {...})",{"type":46,"tag":122,"props":2593,"children":2594},{},[2595],{"type":46,"tag":131,"props":2596,"children":2598},{"className":2597},[],[2599],{"type":52,"value":204},{"type":46,"tag":339,"props":2601,"children":2603},{"id":2602},"mcp-availability-check",[2604],{"type":52,"value":2605},"MCP Availability Check",{"type":46,"tag":55,"props":2607,"children":2608},{},[2609,2611,2616,2617,2622,2623,2628,2629,2634],{"type":52,"value":2610},"If the user's request involves MCP — either explicitly (\"connect via MCP\", \"use MCP\", \"query via MCP\") or implicitly (conversational data queries where MCP would be the natural tool) — check whether Dataverse MCP tools are available in your current tool list (e.g., ",{"type":46,"tag":131,"props":2612,"children":2614},{"className":2613},[],[2615],{"type":52,"value":1378},{"type":52,"value":429},{"type":46,"tag":131,"props":2618,"children":2620},{"className":2619},[],[2621],{"type":52,"value":1370},{"type":52,"value":429},{"type":46,"tag":131,"props":2624,"children":2626},{"className":2625},[],[2627],{"type":52,"value":1476},{"type":52,"value":429},{"type":46,"tag":131,"props":2630,"children":2632},{"className":2631},[],[2633],{"type":52,"value":1618},{"type":52,"value":2635},").",{"type":46,"tag":55,"props":2637,"children":2638},{},[2639,2644],{"type":46,"tag":61,"props":2640,"children":2641},{},[2642],{"type":52,"value":2643},"If MCP tools are NOT available and the user explicitly asked for MCP",{"type":52,"value":2645}," (e.g., \"use MCP to query\", \"why isn't MCP working\"):",{"type":46,"tag":2647,"props":2648,"children":2649},"ol",{},[2650,2660,2665,2677],{"type":46,"tag":276,"props":2651,"children":2652},{},[2653,2658],{"type":46,"tag":61,"props":2654,"children":2655},{},[2656],{"type":52,"value":2657},"Do NOT silently fall back",{"type":52,"value":2659}," to the Python SDK or Web API",{"type":46,"tag":276,"props":2661,"children":2662},{},[2663],{"type":52,"value":2664},"Tell the user: \"Dataverse MCP tools aren't configured in this session yet.\"",{"type":46,"tag":276,"props":2666,"children":2667},{},[2668,2670,2675],{"type":52,"value":2669},"Load the ",{"type":46,"tag":131,"props":2671,"children":2673},{"className":2672},[],[2674],{"type":52,"value":136},{"type":52,"value":2676}," skill to set up the MCP server",{"type":46,"tag":276,"props":2678,"children":2679},{},[2680,2682,2687,2689,2695],{"type":52,"value":2681},"After MCP is configured, ",{"type":46,"tag":61,"props":2683,"children":2684},{},[2685],{"type":52,"value":2686},"stop here",{"type":52,"value":2688}," — the session must be restarted for MCP tools to appear. Remind the user to resume the session without losing context (Claude Code: ",{"type":46,"tag":131,"props":2690,"children":2692},{"className":2691},[],[2693],{"type":52,"value":2694},"claude --continue",{"type":52,"value":2696},"; Cursor: reload the window with Ctrl+Shift+P → \"Developer: Reload Window\"; Copilot: reopen the Copilot panel). Do not proceed with SDK. Wait for the user to restart.",{"type":46,"tag":55,"props":2698,"children":2699},{},[2700,2705],{"type":46,"tag":61,"props":2701,"children":2702},{},[2703],{"type":52,"value":2704},"If MCP tools are NOT available and the user asked a data question without explicitly requesting MCP",{"type":52,"value":2706}," (e.g., \"how many accounts with 'jeff'?\", \"show me open tickets\"):",{"type":46,"tag":2647,"props":2708,"children":2709},{},[2710,2715],{"type":46,"tag":276,"props":2711,"children":2712},{},[2713],{"type":52,"value":2714},"This is a SDK fallback case — use the Python SDK to answer the question. Do not block the user.",{"type":46,"tag":276,"props":2716,"children":2717},{},[2718],{"type":52,"value":2719},"After answering, offer: \"MCP would handle this conversationally — want me to set it up?\"",{"type":46,"tag":55,"props":2721,"children":2722},{},[2723],{"type":52,"value":2724},"The distinction matters: explicit MCP request → block and set up MCP. Implicit\u002Fconversational question → answer with SDK, offer MCP setup.",{"type":46,"tag":55,"props":2726,"children":2727},{},[2728,2733],{"type":46,"tag":61,"props":2729,"children":2730},{},[2731],{"type":52,"value":2732},"If MCP tools ARE available",{"type":52,"value":2734},", prefer MCP for simple reads\u002Fqueries\u002Fsmall CRUD. Use the SDK only when a script is needed.",{"type":46,"tag":69,"props":2736,"children":2737},{},[],{"type":46,"tag":73,"props":2739,"children":2741},{"id":2740},"the-change-lifecycle-operate-safely",[2742],{"type":52,"value":2743},"The Change Lifecycle — Operate Safely",{"type":46,"tag":55,"props":2745,"children":2746},{},[2747,2749,2754,2756,2761,2763,2768],{"type":52,"value":2748},"For any real change, walk these three steps in order: confirm ",{"type":46,"tag":61,"props":2750,"children":2751},{},[2752],{"type":52,"value":2753},"where",{"type":52,"value":2755},", confirm the ",{"type":46,"tag":61,"props":2757,"children":2758},{},[2759],{"type":52,"value":2760},"container",{"type":52,"value":2762},", then persist the ",{"type":46,"tag":61,"props":2764,"children":2765},{},[2766],{"type":52,"value":2767},"result",{"type":52,"value":1134},{"type":46,"tag":339,"props":2770,"children":2772},{"id":2771},"step-1-confirm-the-environment-mandatory",[2773],{"type":52,"value":2774},"Step 1 — Confirm the Environment (MANDATORY)",{"type":46,"tag":55,"props":2776,"children":2777},{},[2778,2780,2785,2787,2792],{"type":52,"value":2779},"Dataverse work often spans multiple environments (dev, test, staging, prod) and multiple sets of credentials. ",{"type":46,"tag":61,"props":2781,"children":2782},{},[2783],{"type":52,"value":2784},"Never assume",{"type":52,"value":2786}," the active PAC auth profile, values in ",{"type":46,"tag":131,"props":2788,"children":2790},{"className":2789},[],[2791],{"type":52,"value":427},{"type":52,"value":2793},", or anything from memory or a previous session reflects the correct target for the current task.",{"type":46,"tag":55,"props":2795,"children":2796},{},[2797,2802],{"type":46,"tag":61,"props":2798,"children":2799},{},[2800],{"type":52,"value":2801},"Before the FIRST operation that touches a specific environment",{"type":52,"value":2803}," — creating a table, deploying a plugin, pushing a solution, inserting data — you MUST:",{"type":46,"tag":2647,"props":2805,"children":2806},{},[2807,2812,2817],{"type":46,"tag":276,"props":2808,"children":2809},{},[2810],{"type":52,"value":2811},"Show the user the environment URL you intend to use",{"type":46,"tag":276,"props":2813,"children":2814},{},[2815],{"type":52,"value":2816},"Ask them to confirm it is correct",{"type":46,"tag":276,"props":2818,"children":2819},{},[2820,2822,2828],{"type":52,"value":2821},"Run ",{"type":46,"tag":131,"props":2823,"children":2825},{"className":2824},[],[2826],{"type":52,"value":2827},"pac org who",{"type":52,"value":2829}," to verify the active connection matches",{"type":46,"tag":2831,"props":2832,"children":2833},"blockquote",{},[2834],{"type":46,"tag":55,"props":2835,"children":2836},{},[2837,2839,2845],{"type":52,"value":2838},"\"I'm about to make changes to ",{"type":46,"tag":131,"props":2840,"children":2842},{"className":2841},[],[2843],{"type":52,"value":2844},"\u003CURL>",{"type":52,"value":2846},". Is this the correct target environment?\"",{"type":46,"tag":55,"props":2848,"children":2849},{},[2850,2855],{"type":46,"tag":61,"props":2851,"children":2852},{},[2853],{"type":52,"value":2854},"Do not proceed until the user explicitly confirms.",{"type":52,"value":2856}," This is the single most important safety check in the plugin. Skipping it risks making irreversible changes to the wrong environment. Once confirmed for a session, you do not need to re-confirm for every subsequent operation in the same session against the same environment.",{"type":46,"tag":339,"props":2858,"children":2860},{"id":2859},"step-2-confirm-the-solution-before-any-metadata-change",[2861],{"type":52,"value":2862},"Step 2 — Confirm the Solution (before any metadata change)",{"type":46,"tag":55,"props":2864,"children":2865},{},[2866],{"type":52,"value":2867},"Before creating tables, columns, or other metadata, ensure a solution exists to contain the work:",{"type":46,"tag":2647,"props":2869,"children":2870},{},[2871,2876,2895],{"type":46,"tag":276,"props":2872,"children":2873},{},[2874],{"type":52,"value":2875},"Ask the user: \"What solution should these components go into?\"",{"type":46,"tag":276,"props":2877,"children":2878},{},[2879,2881,2886,2887,2893],{"type":52,"value":2880},"If a solution name is in ",{"type":46,"tag":131,"props":2882,"children":2884},{"className":2883},[],[2885],{"type":52,"value":427},{"type":52,"value":2328},{"type":46,"tag":131,"props":2888,"children":2890},{"className":2889},[],[2891],{"type":52,"value":2892},"SOLUTION_NAME",{"type":52,"value":2894},"), confirm it with the user",{"type":46,"tag":276,"props":2896,"children":2897},{},[2898,2900,2912,2914,2919],{"type":52,"value":2899},"If no solution exists yet, ",{"type":46,"tag":61,"props":2901,"children":2902},{},[2903,2905,2910],{"type":52,"value":2904},"load the ",{"type":46,"tag":131,"props":2906,"children":2908},{"className":2907},[],[2909],{"type":52,"value":204},{"type":52,"value":2911}," skill",{"type":52,"value":2913}," and follow its publisher discovery + solution creation flow. Use the SDK — ",{"type":46,"tag":61,"props":2915,"children":2916},{},[2917],{"type":52,"value":2918},"never raw Web API",{"type":52,"value":2920}," — to create publisher and solution records:",{"type":46,"tag":351,"props":2922,"children":2926},{"className":2923,"code":2924,"language":2925,"meta":356,"style":356},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Quick reference — full pattern with publisher discovery is in dv-solution\npublisher_id = client.records.create(\"publisher\", {\n    \"uniquename\": \"\u003Cname>\", \"friendlyname\": \"\u003Cdisplay>\",\n    \"customizationprefix\": \"\u003Cprefix>\", \"description\": \"\u003Cdesc>\",\n})\nsolution_id = client.records.create(\"solution\", {\n    \"uniquename\": \"\u003CName>\", \"friendlyname\": \"\u003CDisplay>\",\n    \"version\": \"1.0.0.0\",\n    \"publisherid@odata.bind\": f\"\u002Fpublishers({publisher_id})\",\n})\n","python",[2927],{"type":46,"tag":131,"props":2928,"children":2929},{"__ignoreMap":356},[2930,2938,2947,2956,2965,2974,2983,2992,3001,3010],{"type":46,"tag":362,"props":2931,"children":2932},{"class":364,"line":365},[2933],{"type":46,"tag":362,"props":2934,"children":2935},{},[2936],{"type":52,"value":2937},"# Quick reference — full pattern with publisher discovery is in dv-solution\n",{"type":46,"tag":362,"props":2939,"children":2941},{"class":364,"line":2940},2,[2942],{"type":46,"tag":362,"props":2943,"children":2944},{},[2945],{"type":52,"value":2946},"publisher_id = client.records.create(\"publisher\", {\n",{"type":46,"tag":362,"props":2948,"children":2950},{"class":364,"line":2949},3,[2951],{"type":46,"tag":362,"props":2952,"children":2953},{},[2954],{"type":52,"value":2955},"    \"uniquename\": \"\u003Cname>\", \"friendlyname\": \"\u003Cdisplay>\",\n",{"type":46,"tag":362,"props":2957,"children":2959},{"class":364,"line":2958},4,[2960],{"type":46,"tag":362,"props":2961,"children":2962},{},[2963],{"type":52,"value":2964},"    \"customizationprefix\": \"\u003Cprefix>\", \"description\": \"\u003Cdesc>\",\n",{"type":46,"tag":362,"props":2966,"children":2968},{"class":364,"line":2967},5,[2969],{"type":46,"tag":362,"props":2970,"children":2971},{},[2972],{"type":52,"value":2973},"})\n",{"type":46,"tag":362,"props":2975,"children":2977},{"class":364,"line":2976},6,[2978],{"type":46,"tag":362,"props":2979,"children":2980},{},[2981],{"type":52,"value":2982},"solution_id = client.records.create(\"solution\", {\n",{"type":46,"tag":362,"props":2984,"children":2986},{"class":364,"line":2985},7,[2987],{"type":46,"tag":362,"props":2988,"children":2989},{},[2990],{"type":52,"value":2991},"    \"uniquename\": \"\u003CName>\", \"friendlyname\": \"\u003CDisplay>\",\n",{"type":46,"tag":362,"props":2993,"children":2995},{"class":364,"line":2994},8,[2996],{"type":46,"tag":362,"props":2997,"children":2998},{},[2999],{"type":52,"value":3000},"    \"version\": \"1.0.0.0\",\n",{"type":46,"tag":362,"props":3002,"children":3004},{"class":364,"line":3003},9,[3005],{"type":46,"tag":362,"props":3006,"children":3007},{},[3008],{"type":52,"value":3009},"    \"publisherid@odata.bind\": f\"\u002Fpublishers({publisher_id})\",\n",{"type":46,"tag":362,"props":3011,"children":3013},{"class":364,"line":3012},10,[3014],{"type":46,"tag":362,"props":3015,"children":3016},{},[3017],{"type":52,"value":2973},{"type":46,"tag":2647,"props":3019,"children":3020},{"start":2958},[3021],{"type":46,"tag":276,"props":3022,"children":3023},{},[3024,3026,3032,3034,3040],{"type":52,"value":3025},"Pass ",{"type":46,"tag":131,"props":3027,"children":3029},{"className":3028},[],[3030],{"type":52,"value":3031},"solution=\"\u003CUniqueName>\"",{"type":52,"value":3033}," on all SDK calls, or include ",{"type":46,"tag":131,"props":3035,"children":3037},{"className":3036},[],[3038],{"type":52,"value":3039},"\"MSCRM.SolutionName\": \"\u003CUniqueName>\"",{"type":52,"value":3041}," header on raw Web API metadata calls.",{"type":46,"tag":55,"props":3043,"children":3044},{},[3045],{"type":52,"value":3046},"Creating metadata without a solution means it exists only in the default solution and cannot be cleanly exported or deployed. Always solution-first.",{"type":46,"tag":339,"props":3048,"children":3050},{"id":3049},"step-3-pull-to-repo-mandatory",[3051],{"type":52,"value":3052},"Step 3 — Pull to Repo (MANDATORY)",{"type":46,"tag":55,"props":3054,"children":3055},{},[3056,3058,3063],{"type":52,"value":3057},"Any time you make a metadata change (via MCP, Web API, or the maker portal), ",{"type":46,"tag":61,"props":3059,"children":3060},{},[3061],{"type":52,"value":3062},"you must",{"type":52,"value":3064}," end the session by pulling:",{"type":46,"tag":351,"props":3066,"children":3068},{"className":353,"code":3067,"language":355,"meta":356,"style":356},"pac solution export --name \u003CSOLUTION_NAME> --path .\u002Fsolutions\u002F\u003CSOLUTION_NAME>.zip --managed false\npac solution unpack --zipfile .\u002Fsolutions\u002F\u003CSOLUTION_NAME>.zip --folder .\u002Fsolutions\u002F\u003CSOLUTION_NAME>\nrm .\u002Fsolutions\u002F\u003CSOLUTION_NAME>.zip\ngit add .\u002Fsolutions\u002F\u003CSOLUTION_NAME>\ngit commit -m \"feat: \u003Cdescription>\"\ngit push\n",[3069],{"type":46,"tag":131,"props":3070,"children":3071},{"__ignoreMap":356},[3072,3157,3228,3261,3294,3326],{"type":46,"tag":362,"props":3073,"children":3074},{"class":364,"line":365},[3075,3079,3084,3089,3094,3099,3104,3110,3115,3120,3125,3130,3134,3138,3142,3147,3152],{"type":46,"tag":362,"props":3076,"children":3077},{"style":369},[3078],{"type":52,"value":508},{"type":46,"tag":362,"props":3080,"children":3081},{"style":375},[3082],{"type":52,"value":3083}," solution",{"type":46,"tag":362,"props":3085,"children":3086},{"style":375},[3087],{"type":52,"value":3088}," export",{"type":46,"tag":362,"props":3090,"children":3091},{"style":375},[3092],{"type":52,"value":3093}," --name",{"type":46,"tag":362,"props":3095,"children":3096},{"style":386},[3097],{"type":52,"value":3098}," \u003C",{"type":46,"tag":362,"props":3100,"children":3101},{"style":375},[3102],{"type":52,"value":3103},"SOLUTION_NAM",{"type":46,"tag":362,"props":3105,"children":3107},{"style":3106},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[3108],{"type":52,"value":3109},"E",{"type":46,"tag":362,"props":3111,"children":3112},{"style":386},[3113],{"type":52,"value":3114},">",{"type":46,"tag":362,"props":3116,"children":3117},{"style":375},[3118],{"type":52,"value":3119}," --path",{"type":46,"tag":362,"props":3121,"children":3122},{"style":375},[3123],{"type":52,"value":3124}," .\u002Fsolutions\u002F",{"type":46,"tag":362,"props":3126,"children":3127},{"style":386},[3128],{"type":52,"value":3129},"\u003C",{"type":46,"tag":362,"props":3131,"children":3132},{"style":375},[3133],{"type":52,"value":3103},{"type":46,"tag":362,"props":3135,"children":3136},{"style":3106},[3137],{"type":52,"value":3109},{"type":46,"tag":362,"props":3139,"children":3140},{"style":386},[3141],{"type":52,"value":3114},{"type":46,"tag":362,"props":3143,"children":3144},{"style":375},[3145],{"type":52,"value":3146},".zip",{"type":46,"tag":362,"props":3148,"children":3149},{"style":375},[3150],{"type":52,"value":3151}," --managed",{"type":46,"tag":362,"props":3153,"children":3154},{"style":386},[3155],{"type":52,"value":3156}," false\n",{"type":46,"tag":362,"props":3158,"children":3159},{"class":364,"line":2940},[3160,3164,3168,3173,3178,3182,3186,3190,3194,3198,3202,3207,3211,3215,3219,3223],{"type":46,"tag":362,"props":3161,"children":3162},{"style":369},[3163],{"type":52,"value":508},{"type":46,"tag":362,"props":3165,"children":3166},{"style":375},[3167],{"type":52,"value":3083},{"type":46,"tag":362,"props":3169,"children":3170},{"style":375},[3171],{"type":52,"value":3172}," unpack",{"type":46,"tag":362,"props":3174,"children":3175},{"style":375},[3176],{"type":52,"value":3177}," --zipfile",{"type":46,"tag":362,"props":3179,"children":3180},{"style":375},[3181],{"type":52,"value":3124},{"type":46,"tag":362,"props":3183,"children":3184},{"style":386},[3185],{"type":52,"value":3129},{"type":46,"tag":362,"props":3187,"children":3188},{"style":375},[3189],{"type":52,"value":3103},{"type":46,"tag":362,"props":3191,"children":3192},{"style":3106},[3193],{"type":52,"value":3109},{"type":46,"tag":362,"props":3195,"children":3196},{"style":386},[3197],{"type":52,"value":3114},{"type":46,"tag":362,"props":3199,"children":3200},{"style":375},[3201],{"type":52,"value":3146},{"type":46,"tag":362,"props":3203,"children":3204},{"style":375},[3205],{"type":52,"value":3206}," --folder",{"type":46,"tag":362,"props":3208,"children":3209},{"style":375},[3210],{"type":52,"value":3124},{"type":46,"tag":362,"props":3212,"children":3213},{"style":386},[3214],{"type":52,"value":3129},{"type":46,"tag":362,"props":3216,"children":3217},{"style":375},[3218],{"type":52,"value":3103},{"type":46,"tag":362,"props":3220,"children":3221},{"style":3106},[3222],{"type":52,"value":3109},{"type":46,"tag":362,"props":3224,"children":3225},{"style":386},[3226],{"type":52,"value":3227},">\n",{"type":46,"tag":362,"props":3229,"children":3230},{"class":364,"line":2949},[3231,3236,3240,3244,3248,3252,3256],{"type":46,"tag":362,"props":3232,"children":3233},{"style":369},[3234],{"type":52,"value":3235},"rm",{"type":46,"tag":362,"props":3237,"children":3238},{"style":375},[3239],{"type":52,"value":3124},{"type":46,"tag":362,"props":3241,"children":3242},{"style":386},[3243],{"type":52,"value":3129},{"type":46,"tag":362,"props":3245,"children":3246},{"style":375},[3247],{"type":52,"value":3103},{"type":46,"tag":362,"props":3249,"children":3250},{"style":3106},[3251],{"type":52,"value":3109},{"type":46,"tag":362,"props":3253,"children":3254},{"style":386},[3255],{"type":52,"value":3114},{"type":46,"tag":362,"props":3257,"children":3258},{"style":375},[3259],{"type":52,"value":3260},".zip\n",{"type":46,"tag":362,"props":3262,"children":3263},{"class":364,"line":2958},[3264,3269,3274,3278,3282,3286,3290],{"type":46,"tag":362,"props":3265,"children":3266},{"style":369},[3267],{"type":52,"value":3268},"git",{"type":46,"tag":362,"props":3270,"children":3271},{"style":375},[3272],{"type":52,"value":3273}," add",{"type":46,"tag":362,"props":3275,"children":3276},{"style":375},[3277],{"type":52,"value":3124},{"type":46,"tag":362,"props":3279,"children":3280},{"style":386},[3281],{"type":52,"value":3129},{"type":46,"tag":362,"props":3283,"children":3284},{"style":375},[3285],{"type":52,"value":3103},{"type":46,"tag":362,"props":3287,"children":3288},{"style":3106},[3289],{"type":52,"value":3109},{"type":46,"tag":362,"props":3291,"children":3292},{"style":386},[3293],{"type":52,"value":3227},{"type":46,"tag":362,"props":3295,"children":3296},{"class":364,"line":2967},[3297,3301,3306,3311,3316,3321],{"type":46,"tag":362,"props":3298,"children":3299},{"style":369},[3300],{"type":52,"value":3268},{"type":46,"tag":362,"props":3302,"children":3303},{"style":375},[3304],{"type":52,"value":3305}," commit",{"type":46,"tag":362,"props":3307,"children":3308},{"style":375},[3309],{"type":52,"value":3310}," -m",{"type":46,"tag":362,"props":3312,"children":3313},{"style":386},[3314],{"type":52,"value":3315}," \"",{"type":46,"tag":362,"props":3317,"children":3318},{"style":375},[3319],{"type":52,"value":3320},"feat: \u003Cdescription>",{"type":46,"tag":362,"props":3322,"children":3323},{"style":386},[3324],{"type":52,"value":3325},"\"\n",{"type":46,"tag":362,"props":3327,"children":3328},{"class":364,"line":2976},[3329,3333],{"type":46,"tag":362,"props":3330,"children":3331},{"style":369},[3332],{"type":52,"value":3268},{"type":46,"tag":362,"props":3334,"children":3335},{"style":375},[3336],{"type":52,"value":3337}," push\n",{"type":46,"tag":55,"props":3339,"children":3340},{},[3341],{"type":52,"value":3342},"The repo is always the source of truth.",{"type":46,"tag":69,"props":3344,"children":3345},{},[],{"type":46,"tag":73,"props":3347,"children":3349},{"id":3348},"scripts",[3350],{"type":52,"value":3351},"Scripts",{"type":46,"tag":55,"props":3353,"children":3354},{},[3355,3357,3362,3364,3370,3372,3377,3379,3384,3386,3391,3393,3398],{"type":52,"value":3356},"The plugin ships ",{"type":46,"tag":131,"props":3358,"children":3360},{"className":3359},[],[3361],{"type":52,"value":493},{"type":52,"value":3363}," (Azure Identity token\u002Fcredential acquisition — used by all other scripts and the SDK). Any Web API call beyond a one-off query should be a Python script committed to ",{"type":46,"tag":131,"props":3365,"children":3367},{"className":3366},[],[3368],{"type":52,"value":3369},"\u002Fscripts\u002F",{"type":52,"value":3371},", using ",{"type":46,"tag":131,"props":3373,"children":3375},{"className":3374},[],[3376],{"type":52,"value":493},{"type":52,"value":3378}," for tokens. For writes see ",{"type":46,"tag":131,"props":3380,"children":3382},{"className":3381},[],[3383],{"type":52,"value":170},{"type":52,"value":3385},"; queries and analytics see ",{"type":46,"tag":131,"props":3387,"children":3389},{"className":3388},[],[3390],{"type":52,"value":187},{"type":52,"value":3392},"; post-import validation see ",{"type":46,"tag":131,"props":3394,"children":3396},{"className":3395},[],[3397],{"type":52,"value":204},{"type":52,"value":1134},{"type":46,"tag":69,"props":3400,"children":3401},{},[],{"type":46,"tag":73,"props":3403,"children":3405},{"id":3404},"windows-scripting",[3406],{"type":52,"value":3407},"Windows Scripting",{"type":46,"tag":55,"props":3409,"children":3410},{},[3411,3413,3419,3421,3427,3429,3439],{"type":52,"value":3412},"Platform-specific shell rules (ASCII in ",{"type":46,"tag":131,"props":3414,"children":3416},{"className":3415},[],[3417],{"type":52,"value":3418},".py",{"type":52,"value":3420},", no multiline ",{"type":46,"tag":131,"props":3422,"children":3424},{"className":3423},[],[3425],{"type":52,"value":3426},"python -c",{"type":52,"value":3428},", PAC PowerShell wrapper, unbuffered background output) live in ",{"type":46,"tag":3430,"props":3431,"children":3433},"a",{"href":3432},"references\u002Fwindows-scripting.md",[3434],{"type":46,"tag":131,"props":3435,"children":3437},{"className":3436},[],[3438],{"type":52,"value":3432},{"type":52,"value":3440},". Read it when running on Windows.",{"type":46,"tag":3442,"props":3443,"children":3444},"style",{},[3445],{"type":52,"value":3446},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3448,"total":2949},[3449,3462,3469],{"slug":136,"name":136,"fn":3450,"description":3451,"org":3452,"tags":3453,"stars":23,"repoUrl":24,"updatedAt":3461},"connect to Dataverse environments","One-step setup for a Dataverse environment — installs tools, authenticates, registers the MCP server, and writes `.env`. Use when starting a new project, switching environments, fixing authentication, or troubleshooting an MCP connection that won't come up.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3454,3457,3458,3460],{"name":3455,"slug":3456,"type":15},"Configuration","configuration",{"name":21,"slug":22,"type":15},{"name":3459,"slug":32,"type":15},"MCP",{"name":9,"slug":8,"type":15},"2026-07-31T05:54:51.062501",{"slug":4,"name":4,"fn":5,"description":6,"org":3463,"tags":3464,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3465,3466,3467,3468],{"name":21,"slug":22,"type":15},{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":18,"slug":19,"type":15},{"slug":238,"name":238,"fn":3470,"description":3471,"org":3472,"tags":3473,"stars":23,"repoUrl":24,"updatedAt":3482},"manage security and access in Dataverse","Security-role assignment, user access, application users, business units, and admin self-elevation in Dataverse environments. Use when the user wants to give someone access, grant a role, become an admin, or add a service principal.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3474,3477,3478,3479],{"name":3475,"slug":3476,"type":15},"Access Control","access-control",{"name":21,"slug":22,"type":15},{"name":9,"slug":8,"type":15},{"name":3480,"slug":3481,"type":15},"Security","security","2026-07-24T05:41:15.889984",{"items":3484,"total":3674},[3485,3507,3528,3549,3562,3578,3589,3602,3617,3630,3649,3662],{"slug":3486,"name":3486,"fn":3487,"description":3488,"org":3489,"tags":3490,"stars":3504,"repoUrl":3505,"updatedAt":3506},"rushstack-best-practices","manage Rush monorepos with best practices","Provides best practices and guidance for working with Rush monorepos. Use when the user is working in a Rush-based repository, asks about Rush commands (install, update, build, rebuild), needs help with project selection, dependency management, build caching, subspace configuration, or troubleshooting Rush-specific issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3491,3494,3497,3498,3501],{"name":3492,"slug":3493,"type":15},"Engineering","engineering",{"name":3495,"slug":3496,"type":15},"Local Development","local-development",{"name":9,"slug":8,"type":15},{"name":3499,"slug":3500,"type":15},"Project Management","project-management",{"name":3502,"slug":3503,"type":15},"Rush","rush",6484,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frushstack","2026-04-06T18:34:44.965032",{"slug":3508,"name":3508,"fn":3509,"description":3510,"org":3511,"tags":3512,"stars":3525,"repoUrl":3526,"updatedAt":3527},"azure-ai-agents-persistent-dotnet","build AI agents with Azure .NET SDK","Azure AI Agents Persistent SDK for .NET. Low-level SDK for creating and managing AI agents with threads, messages, runs, and tools. Use for agent CRUD, conversation threads, streaming responses, function calling, file search, and code interpreter. Triggers: \"PersistentAgentsClient\", \"persistent agents\", \"agent threads\", \"agent runs\", \"streaming agents\", \"function calling agents .NET\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3513,3516,3519,3522],{"name":3514,"slug":3515,"type":15},".NET","net",{"name":3517,"slug":3518,"type":15},"Agents","agents",{"name":3520,"slug":3521,"type":15},"Azure","azure",{"name":3523,"slug":3524,"type":15},"LLM","llm",2804,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills","2026-07-03T16:32:10.297433",{"slug":3529,"name":3529,"fn":3530,"description":3531,"org":3532,"tags":3533,"stars":3525,"repoUrl":3526,"updatedAt":3548},"azure-ai-anomalydetector-java","build anomaly detection applications with Java","Build anomaly detection applications with Azure AI Anomaly Detector SDK for Java. Use when implementing univariate\u002Fmultivariate anomaly detection, time-series analysis, or AI-powered monitoring.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3534,3537,3538,3541,3544,3545],{"name":3535,"slug":3536,"type":15},"Analytics","analytics",{"name":3520,"slug":3521,"type":15},{"name":3539,"slug":3540,"type":15},"Data Analysis","data-analysis",{"name":3542,"slug":3543,"type":15},"Java","java",{"name":9,"slug":8,"type":15},{"name":3546,"slug":3547,"type":15},"Monitoring","monitoring","2026-05-13T06:14:16.261754",{"slug":3550,"name":3550,"fn":3551,"description":3552,"org":3553,"tags":3554,"stars":3525,"repoUrl":3526,"updatedAt":3561},"azure-ai-contentsafety-java","build content moderation applications with Azure AI","Build content moderation applications with Azure AI Content Safety SDK for Java. Use when implementing text\u002Fimage analysis, blocklist management, or harm detection for hate, violence, sexual content, and self-harm.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3555,3558,3559,3560],{"name":3556,"slug":3557,"type":15},"AI Infrastructure","ai-infrastructure",{"name":3520,"slug":3521,"type":15},{"name":3542,"slug":3543,"type":15},{"name":3480,"slug":3481,"type":15},"2026-07-07T06:53:31.293235",{"slug":3563,"name":3563,"fn":3564,"description":3565,"org":3566,"tags":3567,"stars":3525,"repoUrl":3526,"updatedAt":3577},"azure-ai-contentsafety-py","detect harmful content with Azure AI Content Safety","Azure AI Content Safety SDK for Python. Use for detecting harmful content in text and images with multi-severity classification.\nTriggers: \"azure-ai-contentsafety\", \"ContentSafetyClient\", \"content moderation\", \"harmful content\", \"text analysis\", \"image analysis\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3568,3569,3572,3573,3574,3576],{"name":3520,"slug":3521,"type":15},{"name":3570,"slug":3571,"type":15},"Compliance","compliance",{"name":3523,"slug":3524,"type":15},{"name":9,"slug":8,"type":15},{"name":3575,"slug":2925,"type":15},"Python",{"name":3480,"slug":3481,"type":15},"2026-07-18T05:14:23.017504",{"slug":3579,"name":3579,"fn":3580,"description":3581,"org":3582,"tags":3583,"stars":3525,"repoUrl":3526,"updatedAt":3588},"azure-ai-language-conversations-py","implement conversational language understanding with Python","Implement Conversational Language Understanding (CLU) using the azure-ai-language-conversations Python SDK. Use when working with ConversationAnalysisClient to analyze conversation intent and entities, building NLP features, or integrating language understanding into applications.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3584,3585,3586,3587],{"name":3535,"slug":3536,"type":15},{"name":3520,"slug":3521,"type":15},{"name":3523,"slug":3524,"type":15},{"name":3575,"slug":2925,"type":15},"2026-07-31T05:54:29.068751",{"slug":3590,"name":3590,"fn":3591,"description":3592,"org":3593,"tags":3594,"stars":3525,"repoUrl":3526,"updatedAt":3601},"azure-ai-translation-text-py","translate text using Azure AI services","Azure AI Text Translation SDK for real-time text translation, transliteration, language detection, and dictionary lookup. Use for translating text content in applications.\nTriggers: \"text translation\", \"translator\", \"translate text\", \"transliterate\", \"TextTranslationClient\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3595,3598,3599,3600],{"name":3596,"slug":3597,"type":15},"API Development","api-development",{"name":3520,"slug":3521,"type":15},{"name":9,"slug":8,"type":15},{"name":3575,"slug":2925,"type":15},"2026-07-18T05:14:16.988376",{"slug":3603,"name":3603,"fn":3604,"description":3605,"org":3606,"tags":3607,"stars":3525,"repoUrl":3526,"updatedAt":3616},"azure-ai-vision-imageanalysis-py","analyze images with Azure AI Vision","Azure AI Vision Image Analysis SDK for captions, tags, objects, OCR, people detection, and smart cropping. Use for computer vision and image understanding tasks.\nTriggers: \"image analysis\", \"computer vision\", \"OCR\", \"object detection\", \"ImageAnalysisClient\", \"image caption\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3608,3609,3612,3615],{"name":3520,"slug":3521,"type":15},{"name":3610,"slug":3611,"type":15},"Computer Vision","computer-vision",{"name":3613,"slug":3614,"type":15},"Images","images",{"name":3575,"slug":2925,"type":15},"2026-07-18T05:14:18.007737",{"slug":3618,"name":3618,"fn":3619,"description":3620,"org":3621,"tags":3622,"stars":3525,"repoUrl":3526,"updatedAt":3629},"azure-appconfiguration-java","manage configuration with Azure App Configuration","Azure App Configuration SDK for Java. Centralized application configuration management with key-value settings, feature flags, and snapshots.\nTriggers: \"ConfigurationClient java\", \"app configuration java\", \"feature flag java\", \"configuration setting java\", \"azure config java\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3623,3624,3625,3628],{"name":3520,"slug":3521,"type":15},{"name":3455,"slug":3456,"type":15},{"name":3626,"slug":3627,"type":15},"Feature Flags","feature-flags",{"name":3542,"slug":3543,"type":15},"2026-07-03T16:32:01.278468",{"slug":3631,"name":3631,"fn":3632,"description":3633,"org":3634,"tags":3635,"stars":3525,"repoUrl":3526,"updatedAt":3648},"azure-cosmos-rust","build applications with Azure Cosmos DB","Azure Cosmos DB library for Rust (NoSQL API). Document CRUD, containers, and globally distributed data.\nTriggers: \"cosmos db rust\", \"CosmosClient rust\", \"document crud rust\", \"NoSQL rust\", \"partition key rust\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3636,3639,3642,3645],{"name":3637,"slug":3638,"type":15},"Cosmos DB","cosmos-db",{"name":3640,"slug":3641,"type":15},"Database","database",{"name":3643,"slug":3644,"type":15},"NoSQL","nosql",{"name":3646,"slug":3647,"type":15},"Rust","rust","2026-07-31T05:54:27.021432",{"slug":3650,"name":3650,"fn":3632,"description":3651,"org":3652,"tags":3653,"stars":3525,"repoUrl":3526,"updatedAt":3661},"azure-cosmos-ts","Azure Cosmos DB JavaScript\u002FTypeScript SDK (@azure\u002Fcosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: \"Cosmos DB\", \"@azure\u002Fcosmos\", \"CosmosClient\", \"document CRUD\", \"NoSQL queries\", \"bulk operations\", \"partition key\", \"container.items\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3654,3655,3656,3657,3658],{"name":3637,"slug":3638,"type":15},{"name":3640,"slug":3641,"type":15},{"name":9,"slug":8,"type":15},{"name":3643,"slug":3644,"type":15},{"name":3659,"slug":3660,"type":15},"TypeScript","typescript","2026-07-03T16:31:19.368382",{"slug":3663,"name":3663,"fn":3664,"description":3665,"org":3666,"tags":3667,"stars":3525,"repoUrl":3526,"updatedAt":3673},"azure-data-tables-java","build table storage applications with Java","Build table storage applications with Azure Tables SDK for Java. Use when working with Azure Table Storage or Cosmos DB Table API for NoSQL key-value data, schemaless storage, or structured data at scale.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3668,3669,3670,3671,3672],{"name":3520,"slug":3521,"type":15},{"name":3637,"slug":3638,"type":15},{"name":3640,"slug":3641,"type":15},{"name":3542,"slug":3543,"type":15},{"name":3643,"slug":3644,"type":15},"2026-05-13T06:14:17.582229",267]