Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "dataverse-skills",
"metadata": {
"description": "Official Dataverse plugin marketplace for Cursor",
"version": "1.15.0"
"version": "1.15.1"
},
"owner": {
"name": "Microsoft",
Expand All @@ -14,7 +14,7 @@
"name": "dataverse",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"source": "./.github/plugins/dataverse",
"version": "1.15.0",
"version": "1.15.1",
"homepage": "https://github.com/microsoft/Dataverse-skills"
}
]
Expand Down
4 changes: 2 additions & 2 deletions .github/plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "dataverse-skills",
"metadata": {
"description": "Official Dataverse plugin marketplace for agent-guided development",
"version": "1.15.0"
"version": "1.15.1"
},
"owner": {
"name": "Microsoft",
Expand All @@ -13,7 +13,7 @@
"name": "dataverse",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"source": "./.github/plugins/dataverse",
"version": "1.15.0",
"version": "1.15.1",
"homepage": "https://github.com/microsoft/Dataverse-skills"
}
]
Expand Down
2 changes: 1 addition & 1 deletion .github/plugins/dataverse/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dataverse",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"version": "1.15.0",
"version": "1.15.1",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
Expand Down
2 changes: 1 addition & 1 deletion .github/plugins/dataverse/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dataverse",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"version": "1.15.0",
"version": "1.15.1",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
Expand Down
2 changes: 1 addition & 1 deletion .github/plugins/dataverse/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "dataverse",
"displayName": "Microsoft Dataverse",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"version": "1.15.0",
"version": "1.15.1",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
Expand Down
2 changes: 1 addition & 1 deletion .github/plugins/dataverse/.github/plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dataverse",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"version": "1.15.0",
"version": "1.15.1",
"author": {
"name": "Microsoft",
"url": "https://www.microsoft.com"
Expand Down
4 changes: 2 additions & 2 deletions .github/plugins/dataverse/gemini-extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dataverse",
"version": "1.15.0",
"version": "1.15.1",
"description": "Microsoft Dataverse plugin for coding agents, covering record CRUD, bulk data operations, advanced queries, schema and metadata, administration, security, environment management, and solution lifecycle through MCP, CLI, and SDK workflows.",
"settings": [
{
Expand All @@ -20,7 +20,7 @@
"${DATAVERSE_URL}"
],
"env": {
"DATAVERSE_OPERATION_CONTEXT": "app=dataverse-skills/1.15.0;skill=mcp-direct;agent=gemini-cli"
"DATAVERSE_OPERATION_CONTEXT": "app=dataverse-skills/1.15.1;skill=mcp-direct;agent=gemini-cli"
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions .github/plugins/dataverse/skills/dv-connect/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
---
name: dv-connect
description: One-step setup and connection diagnostics for a Dataverse environment — installs tools, authenticates, registers MCP, writes `.env`, and verifies active profiles and linked ERP endpoints. Use when starting a new project, switching environments, fixing authentication, troubleshooting MCP, or checking existing Dataverse / Finance and Operations connectivity or linkage.
description: One-step Dataverse connection setup and diagnostics — verifies WhoAmI, reuses injected non-interactive credentials, installs tools, authenticates, registers MCP, and writes `.env`. Use when starting a project, checking an existing or CI connection, switching environments, fixing authentication, troubleshooting MCP, or verifying linked Finance and Operations endpoints.
---

# Skill: Connect

One-step, idempotent Dataverse connection. Each step checks if it's already done and skips.
> ## Critical workspace safety rules — read first
> 1. In CI, reuse injected auth and verify only. Never start browser or device-code login.
> 2. Never replace `.gitignore`; append missing entries and preserve every existing line.

> **Environment-First Rule** — All metadata and plugin registrations are created **in the environment** via API/scripts, then pulled into the repo. Never hand-write solution XML to create components.

Expand Down
12 changes: 10 additions & 2 deletions .github/plugins/dataverse/skills/dv-data/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import requests # WRONG for SDK-supported ops

Forms/views (`systemform`/`savedquery`) **are** ordinary records — create/modify them with `client.records.*` (see **dv-metadata**), and read N:N with `records.list(expand=...)`. For the genuine gaps below, prefer the managed `dataverse api` escape hatch over raw `urllib`:
- Global option sets — see **dv-metadata**
- N:N record association — CLI `dataverse data associate`, or `POST /api/data/v9.2/<entity>(<id>)/<nav-property>/$ref`
- Record association — CLI `dataverse data associate` / `disassociate` supports N:N and lookup navigation properties; `client.records.update()` is the scripted N:1 lookup path
- `$apply` aggregation — use `client.query.fetchxml()`; see **dv-query**
- Unbound actions (e.g., `PublishXml`, `InstallSampleData`) — `dataverse api request`/`invoke`
- DeleteMultiple, general OData batching
Expand All @@ -86,7 +86,7 @@ dataverse data upsert --table accounts --key "accountnumber='ACC-001'" --data '{
# Delete (--no-confirm skips the prompt)
dataverse data delete --table accounts --id <guid> --no-confirm --context "app=dataverse-skills/<ver>;skill=dv-data;agent=<agent>"

# Associate two records (N:N or lookup)
# Link an existing contact to its parent account using the IDs returned by create
dataverse data associate --table accounts --id <guid> --relationship contact_customer_accounts --related contacts --related-id <contact-guid> --context "app=dataverse-skills/<ver>;skill=dv-data;agent=<agent>"

# Disassociate (N:N — pass --related-id; clear a lookup — omit --related-id)
Expand Down Expand Up @@ -164,6 +164,14 @@ print(f"Created: {guid}")
| System polymorphic: `customerid` | `customerid_account@odata.bind` | ~~`customerid@odata.bind`~~ |
| System: `parentcustomerid` | `parentcustomerid_account@odata.bind` | ~~`_parentcustomerid_value@odata.bind`~~ |

For an account/contact N:1 link, update the contact side with the IDs returned by the create calls; do not handcraft a raw `$ref` request:

```python
client.records.update("contact", contact_id, {
"parentcustomerid_account@odata.bind": f"/accounts({account_id})",
})
```

### Find the Navigation Property Name

After creating a lookup via SDK: `result.lookup_schema_name` is the navigation property name.
Expand Down
21 changes: 1 addition & 20 deletions .github/plugins/dataverse/skills/dv-metadata/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ created = client.tables.add_columns(
print(created) # ['new_Description', 'new_Amount', 'new_Active']
```

Supported type strings: `"string"` / `"text"`, `"int"` / `"integer"`, `"decimal"` / `"money"`, `"float"` / `"double"`, `"datetime"` / `"date"`, `"bool"` / `"boolean"`, `"file"`, and `Enum` subclasses (for local option sets).
Supported type strings: `"string"` / `"text"`, `"int"` / `"integer"`, `"decimal"`, `"float"` / `"double"`, `"datetime"` / `"date"`, `"bool"` / `"boolean"`, `"file"`, and `Enum` subclasses (for local option sets). For true currency, SDK `"money"` is currently Decimal; use the managed path in [currency-columns.md](references/currency-columns.md).

**Choice (picklist) column via SDK:**

Expand All @@ -172,25 +172,6 @@ created = client.tables.add_columns(
)
```

**Web API approach (needed for column types the SDK doesn't support — e.g., currency with precision, memo with custom max length):**

```python
# Currency column
attribute = {
"@odata.type": "Microsoft.Dynamics.CRM.MoneyAttributeMetadata",
"SchemaName": "new_amount",
"DisplayName": {"@odata.type": "Microsoft.Dynamics.CRM.Label",
"LocalizedLabels": [{"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "Amount", "LanguageCode": 1033}]},
"RequiredLevel": {"Value": "None"},
"MinValue": 0,
"MaxValue": 1000000000,
"Precision": 2,
"PrecisionSource": 2
}
# POST to /api/data/v9.2/EntityDefinitions(LogicalName='new_projectbudget')/Attributes
```

---

## Lookup Columns and Relationships
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Currency columns

The Python SDK currently maps both `"decimal"` and `"money"` to `DecimalAttributeMetadata`. For a true Dataverse currency column, use the managed `dataverse api request` escape hatch with `MoneyAttributeMetadata`. Do not send metadata payloads with `requests` or `urllib`.

Create the payload file with Python:

```python
import json

attribute = {
"@odata.type": "Microsoft.Dynamics.CRM.MoneyAttributeMetadata",
"SchemaName": "new_amount",
"DisplayName": {
"@odata.type": "Microsoft.Dynamics.CRM.Label",
"LocalizedLabels": [{
"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "Amount",
"LanguageCode": 1033,
}],
},
"RequiredLevel": {"Value": "None"},
"MinValue": 0,
"MaxValue": 1000000000,
"Precision": 2,
"PrecisionSource": 2,
}

with open("money-column.json", "w", encoding="utf-8") as payload_file:
json.dump(attribute, payload_file)
```

Send it through the authenticated CLI and associate it with the solution:

```
dataverse api request --target dataverse --method POST --path "/api/data/v9.2/EntityDefinitions(LogicalName='new_projectbudget')/Attributes" --body-file money-column.json --header "MSCRM.SolutionUniqueName:MySolution" --context "app=dataverse-skills/<ver>;skill=dv-metadata;agent=<agent>"
```

After creation, read the column metadata and confirm `AttributeType` is `Money` before reporting success.
Loading