Install
$ agentstack add skill-ryanmakesandbreaksstuff-custom-codex-claude-plugins-and-skills-dataverse-web-api ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Dataverse Web API — Metadata & Schema
CRITICAL RULES
- Always pass
MSCRM.SolutionUniqueNameheader when creating any component. Without it, components land in the Default Solution with the environment's random default publisher prefix (e.g.,cr8a3_mytable). The schema name is permanently baked with that random prefix. The component cannot be packaged into a deployable solution without being manually re-added — and it cannot be renamed.
- Column (Attribute) creation MUST include correct
@odata.type. Omitting or using the wrong type causes a 400 error with no helpful message. Example:"@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata". Seeresources/columns-attributes.mdfor all valid types.
- Every
POST /EntityDefinitionsMUST include aStringAttributeMetadatawithIsPrimaryName: true. TheAttributesarray inline in the table creation body must contain exactly one primary name attribute. Omitting it causes a 400.
- Metadata
PUTrequires the FULL definition — partial updates silently zero unspecified properties. The API returns 204 (success) when you send a partial payload, but every property you omit is cleared to its default. AlwaysGETthe current definition first, modify the specific properties, thenPUTthe complete object. AddMSCRM.MergeLabels: trueheader onPUTto preserve labels in other languages.
- Add
Consistency: Strongheader when reading metadata immediately after writing. Without it,GET EntityDefinitionsmay return a stale cached response, causing you to wrongly conclude a write failed or overwrite just-written values.
FormXmlandLayoutXmlmust stay in sync withFetchXml. Every column in a view'slayoutxmlMUST appear in itsfetchxml. Mismatches cause silent runtime errors at view render time — the API accepts the write, the error only appears to users when loading the view.
- Publishing is required after updating existing definitions — not after creating new ones. New tables and columns auto-publish. Updating existing forms, views, sitemaps, or ribbons requires explicit
PublishXml. Use scoped publish:logicalname.PublishAllXmlcauses visible latency spikes for all users — avoid in production.
- Windows: Always use PowerShell
.ps1for OData API calls. Bash interprets$filter,$select,$expand,$orderbyas shell variables and silently strips them. Write.ps1files, run withpowershell -ExecutionPolicy Bypass -File.
DateTimeBehavioris effectively permanent once records exist. The three behaviors (UserLocal,DateOnly,TimeZoneIndependent) can be set at column creation. Changing after data exists causes timezone-shifted corruption across all historical records. This is a design decision to make before the first record is created.
- Customer lookup columns require the
CreateCustomerRelationshipsaction. You cannotPOSTa Customer-type column directly to/Attributes. Use theCreateCustomerRelationshipsaction to create both the Account and Contact lookups atomically.
- Never use
pac auth token. This command does not exist. Get tokens via:az account get-access-token --resource "https://[org].crm.dynamics.com/" --tenant "[tenant-id]" --query accessToken -o tsv.
NEVER
- NEVER create metadata components without
MSCRM.SolutionUniqueName— random-prefix schema name baked in permanently; component is undeployable via solution export. - NEVER send a partial
PUTfor metadata updates — silently zeros all unspecified properties; API returns 204 success. Always GET → modify → PUT the full object. - NEVER uninstall a managed solution in production without a full data backup — uninstalling a managed solution destroys ALL records in ALL custom tables defined by that solution. This is irreversible.
- NEVER reuse a solution
uniquenameafter deletion — names are tombstoned per environment; reimporting causes conflicts. - NEVER set
RequiredLeveltoSystemRequiredunless permanent — this is a one-way door. It cannot be reverted via the API once set. - NEVER use
AttributeTypeto identify column types — it reportsImageandMultiSelectPicklistcolumns asVirtual. Always useAttributeTypeNamefor accurate type identification. - NEVER create placeholder columns — use formula columns, plugins, or code-based updates instead. Placeholder columns never get cleaned up and permanently pollute the schema.
- NEVER use Bash for OData query strings —
$filter,$select,$expandare silently stripped by shell variable expansion.
Pre-Design Checklist (Permanent Decisions)
Before creating any table, resolve these — they cannot be changed after the fact:
OwnershipType:UserOwned(per-record security, team ownership) vsOrganizationOwned(no per-record security)? This drives the entire security model.SchemaName/ prefix: Must use publisher prefix. Permanent. Rename = entirely new table with new logical name.TableType:Standard(SQL, full features) vsElastic(Cosmos DB, for IoT/high-volume/TTL use cases)? Permanent. Different capability sets — elastic tables cannot use standard activity feeds, relationships, or audit logging.- Column
@odata.type: Integer vs Decimal vs Float vs Currency? Type cannot change after creation — changing requires delete + re-create (data loss). DateTimeBehavior:UserLocal,DateOnly, orTimeZoneIndependent? Effectively permanent once records exist.- Custom API
UniqueName,IsFunction,BindingType,AllowedCustomProcessingStepType: All permanently immutable at creation. Changing any requires delete + re-create of the Custom API and all its request parameters and response properties.
Workflow: Building Schema from Scratch
Step 1 — Publisher + Solution
Read resources/solutions-alm.md → MANDATORY before any ALM work.
POST /publishers { "uniquename": "contoso", "customizationprefix": "cnt", "customizationoptionvalueprefix": 10000 }
POST /solutions { "uniquename": "ContosoHRModule", "publisherid@odata.bind": "/publishers({id})" }
Step 2 — Tables
Include MSCRM.SolutionUniqueName header. Primary Name attribute MUST be inline in Attributes array. Read resources/tables-entities.md → MANDATORY for all table properties and ownership types.
Step 3 — Columns
POST /EntityDefinitions(LogicalName='{table}')/Attributes with correct @odata.type. Read resources/columns-attributes.md → MANDATORY for all column types. For rich text, file, image, auto-number, multi-select, or currency: ALSO load resources/advanced-column-types.md.
Step 4 — Relationships
Read resources/relationships.md for 1:N, N:N, cascade config, and eligibility checks.
Step 5 — Views (FetchXML + LayoutXML)
Read resources/views-queries.md → Rule 6 (fetchxml ↔ layoutxml sync) is the critical failure mode.
Step 6 — Forms (FormXml)
Read resources/forms-ui.md for FormXml schema and programmatic form construction.
Step 7 — App Module + Sitemap
Read resources/app-modules.md for app composition, AddAppComponents, and ValidateApp.
Step 8 — Publish
POST /PublishXml { "ParameterXml": "cnt_table" }
Read resources/publishing-ops.md — always use entity-scoped publish. PublishAllXml in production causes latency spikes.
Loading Resources
Permanent design decisions before creating any table: → MANDATORY: Load resources/dataverse-design-rules.md FIRST. Check this before designing any new table.
Creating or modifying tables (ownership, behavioral properties, elastic vs standard): → MANDATORY: Load resources/tables-entities.md + resources/solutions-alm.md.
Adding any column type: → MANDATORY: Load resources/columns-attributes.md. For rich text, file, image, auto-number, multi-select, or currency columns: ALSO load resources/advanced-column-types.md. Do NOT load relationships.md or forms-ui.md for column-only tasks.
Creating or configuring views (FetchXML + LayoutXML): → MANDATORY: Load resources/views-queries.md. Rule 6 is the critical constraint. Do NOT load forms-ui.md for view-only tasks.
Creating or editing forms (FormXml): → MANDATORY: Load resources/forms-ui.md. Do NOT load views-queries.md for form-only tasks.
1:N or N:N relationships, cascade configuration, eligibility checks: → MANDATORY: Load resources/relationships.md.
Security roles, column security profiles, app-level security, sharing, BPF security: → MANDATORY: Load resources/security-model.md.
Custom API creation (binding type, IsFunction, request parameters, response properties): → MANDATORY: Load resources/custom-apis.md. Note all five permanent-at-creation fields before designing.
App modules, sitemaps, AddAppComponents, ValidateApp: → MANDATORY: Load resources/app-modules.md.
Publishing workflows, Custom APIs, business rules, workflows: → Load resources/publishing-ops.md.
Environment variables, formula columns, business rules, grid controls, parallelization strategy, testing/monitoring: → Load the matching file: resources/environment-variables.md, resources/formula-columns.md, resources/business-rules.md, resources/grid-controls.md, resources/parallelization.md, resources/testing-monitoring.md.
Do NOT load all resource files simultaneously — load only what the current task requires.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: RyanMakesAndBreaksStuff
- Source: RyanMakesAndBreaksStuff/Custom-Codex-Claude-Plugins-and-Skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.