Install
$ agentstack add skill-satriotsubasa-powerplatform-core-data-operations ✓ 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Data Operations
This skill owns Dataverse row create, read, update, upsert, and delete, plus query design and execution. It is the data branch of the powerplatform-core orchestrator — start there to discover repo context and confirm the target environment and solution. Keep data work separate from schema work: a solution import is not the way to sync environment-specific config data, and creating/changing tables or columns belongs in the dataverse-schema skill.
Default safety posture: create, read, update, and upsert are in scope when the user asks for them. Read is non-mutating and needs no preflight. Delete is supported but is the highest-risk write: only delete when the user explicitly asks, and only after the live-mutation preflight and explicit approval.
When to use this
- Create a single row, or create-or-update by primary key or alternate key.
- Read a row back by primary key or alternate key (verification, debugging, or "what's the current value").
- List or query rows with a FetchXML/spec query, with bounded paging and a count of how many rows match.
- Update only the columns that changed on a known record.
- Delete a row by primary key or alternate key (explicit request + preflight).
- Seed or sync reference/configuration data into an environment.
- Design a query and get the OData path, FetchXML, and Power Automate "List rows" parameters for a structured spec.
For table/column/lookup/form/view/ribbon/icon changes, use the dataverse-schema skill instead.
Helpers
The Python helpers live in the plugin's scripts/ directory at the plugin root, not inside this skill folder. Resolve the plugin root and invoke a helper like this (use $CODEX_PLUGIN_ROOT, also exposed as $PLUGIN_ROOT, when running under Codex; if installed standalone, the scripts/ folder sits beside this bundle):
- Claude Code:
python "$CLAUDE_PLUGIN_ROOT/scripts/upsert_data.py" --table contoso_account --data ./row.json --key ./key.json --auth-dialog --verify - Codex:
python "$CODEX_PLUGIN_ROOT/scripts/upsert_data.py" --table contoso_account --data ./row.json --key ./key.json --auth-dialog --verify
design_dataverse_query.py— offline query designer. Takes--spec(a JSON object or path describingtableLogicalName,entitySetName,select,filters,orderBy,top,expand) plus optional--repo-root/--output. Emits a Web API OData path, FetchXML, Power Automate "List rows" parameters, and warnings about missing filters, row limits, select lists, or entity-set names. No live call.upsert_data.py— live row write. Key flags:--table(logical name, required),--data(JSON object or path, required),--mode {create,update,upsert}(defaultupsert),--id(primary-key GUID for update/upsert),--key(JSON object or path with alternate-key values),--verify(retrieve the changed columns after the write), plus the shared auth flags (--environment-url/--target-url,--username,--tenant-id,--auth-dialog,--auto-validate,--auth-flow {auto,devicecode,interactive,clientsecret,certificate},--app-id,--certificate-path,--force-prompt,--verbose) and--repo-root(resolves project-profile deployment defaults, including typed row-write coercion).--dry-runreads the current row and prints a per-column diff of the would-be write (changed/added/unchanged) without mutating anything; it needs--idor--keyfor update/upsert (create mode reports every column as new).read_data.py— live, read-only row read (no preflight).--mode retrievereads one row by--idor--key(optional--columns/--all-columns);--mode listruns a query from--fetchxmlor--spec(built with the offline designer) with--max-rows(default 100),--page-size, and--exact-total. The response reportsreturnedCount,moreRecords, andtotalRecordCount(Dataverse caps that count at 5000;totalRecordCountLimitExceededflags when the true total is higher). Shares the same auth flags asupsert_data.py.delete_data.py— live row delete by--idor--key(--tablerequired). Mutating and irreversible: run the live-mutation preflight and get explicit approval first; prefer--auth-dialogto confirm the target. Shares the same auth flags.
If the repo already has a proven seed-data or data-sync mechanism, or server-side SDK code, prefer that repo-owned path over reconstructing one. The Web API is the simpler direct/scriptable path when no SDK code exists.
Unattended (service-principal) auth. For CI/CD, scheduled agents, or headless verification, read_data.py/upsert_data.py/delete_data.py accept --auth-flow clientsecret (with --app-id and --tenant-id, client secret read from the DATAVERSE_CLIENT_SECRET environment variable) or --auth-flow certificate (--app-id, --tenant-id, --certificate-path, password from DATAVERSE_CERTIFICATE_PASSWORD). Secrets come from environment variables only — never pass a secret or certificate password as a CLI argument. Service-principal mode skips the auth dialog and PAC-profile defaulting, so pass --environment-url explicitly. The application user must exist in the target environment (see the platform-administration skill for pac admin create-service-principal).
Dataverse MCP interop. If Microsoft's Dataverse MCP is connected, prefer it for quick interactive "what does this data look like" lookups (search/describe/read_query). Use these helpers whenever the read must be paged (read_data.py --mode list returns returnedCount/moreRecords/totalRecordCount), keyed and verified, or followed by a write — and route every live mutation through the helpers so it passes the preflight gate, never through the MCP. When an MCP read_query result is truncated by its row cap or its SQL subset rejects a query, fall back to design_dataverse_query.py + read_data.py. See the orchestrator skill for the full routing rules.
Workflow
- Confirm targeting before writing. Resolve the target environment, the table logical name (and entity set name when querying), whether the operation is create-only, update-only, or create-or-update, the matching key (record ID, alternate key, or agreed lookup), the exact columns to set, and duplicate-handling expectations. If ambiguous, ask only for the missing high-risk parts.
- Choose the mode deliberately. Use
createto let Dataverse assign the key;updateto send only changed columns by primary or alternate key;upsertfor create-or-update when the row might already exist. For Web API update-only behavior,If-Match: *prevents a silent upsert. - Key choice for rerunnable work. For integration/migration/rerunnable writes, prefer alternate keys over user-editable business fields, and prefer immutable keys. When the source identifier comes from another system, do not rely on a bare reused ID unless it is globally unique in the tenant — prefer a source-system-qualified key (
source_system + source_id). - Resolve lookups and choices safely. Bind lookups using supported references, not display-name guessing; use logical names and valid choice values; reuse early-bound classes, enums, or constants when the repo already has them; prefer reference tables or global choices over repeated free text for controlled value sets.
- Plan before bulk/config apply. For config-data sync, imports, migrations, or bulk corrections, run a dry-run/diff/plan phase first that names rows to be created, updated, skipped, invalid, and any target-only rows present in Dataverse but missing from the source extract (that last category drives whether deactivation, deletion, or an explicit no-op policy is needed). Do not apply config data to TST/TEST until that plan exists.
- Apply and verify. Validate the smallest possible payload, use
--verifywhen confirming the write matters, and capture whether the action created or updated the row. - Preserve provenance. When syncing from another source, keep enough provenance to identify origin, retain source-system-qualified keys when multiple upstreams may reuse an external ID, and avoid casually overwriting provenance columns used for reconciliation or audit.
Key safety and decision rules
- Run the live-mutation preflight defined in the
powerplatform-coreorchestrator before any live row write or delete. Reads (read_data.py) are non-mutating and skip the preflight. Stop if any required field is missing. - Prefer the auth dialog (
--auth-dialog) so the user confirms the target URL and selects the working solution; warn when the requested target does not match the active PAC profile. TreatDEVas the working environment andTESTas validation. Do not touch production. - Capability boundary:
upsert_data.pyperforms live row writes and optional post-write verification, plus a keyed--dry-runthat diffs a single would-be update/upsert against the current row (no mutation);read_data.pyreads (retrieve/list) and is non-mutating;delete_data.pydeletes a single row. There is no bulk dry-run/plan mode across many rows, andread_data.pylist returns at most--max-rowsrows per call (default 100) with amoreRecordsflag rather than streaming an entire table. For multi-row plan/apply (config sync, migrations), keep that planning phase in the workflow or repo-specific tooling layer; do not imply the shared helpers already batch it. - Do not delete business data unless the user explicitly asked for deletion and separately approved it. Prefer safe create, keyed update, or upsert over any delete path.
- Separate solution customization from configuration rows. A solution import is not the default way to sync environment-specific config data.
- If no write executed because a required key or environment value was missing, say so explicitly. When a write is performed, report the table targeted, whether it created/updated/upserted, the key or alternate key used, which columns changed, and what safety checks were applied.
Query design notes
- Prefer the simplest query that matches the requirement: use logical names (not display names), select only needed columns, set row limits and pagination intentionally, and guard against nulls and empty arrays.
- Use OData (
$select, then$filteronly for necessary predicates,$expandsparingly) for straightforward server-side filtering. Dataverse Web API does not support every OData option; if the query needs complex joins, aggregates, or view definitions, prefer FetchXML. - If the entity set name is unknown, provide it explicitly in the helper input rather than guessing a pluralized logical name.
- For Power Automate expressions, prefer clear guards (
coalesce,if,empty) over nested fragile expressions. Validateinfilters against the specific connector action, falling back to FetchXML if rejected.
References
Read the shared references at the plugin's references/ directory for depth:
references/data-operations.md— create/update/upsert paths, keying and provenance, dry-run/apply planning, and validation/reporting.references/queries-and-xml.md— OData and FetchXML guidance, viewFetchXml/LayoutXml, and direct solution XML rules.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: satriotsubasa
- Source: satriotsubasa/PowerPlatform-Core
- License: Apache-2.0
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.