⏳ This skill is pending AI review.
Scores will appear once the review pipeline completes.
openclaw-dynamics-365
Create and update CRM records in Microsoft Dynamics 365 — Opportunities, Leads, Contacts, Accounts, and Tasks via Dataverse Web API with Azure AD OAuth 2.0.
Choose how to use this skill
You do not need every option. Choose the path your AI client supports. The stable page stays the same; versioned files are immutable.
1. Native installer
This listing has no registered native installer command. Use the complete package or source fallback below, depending on what your client supports.
Do not guess an installer command or replace an existing version without reviewing the diff.
2. Complete package recommended
Download the ZIP when available. It includes SKILL.md plus the references, security notes and version metadata.
No complete ProSkills package is published for this listing yet.3. Prompt-only
Copy the prompt above when the agent can read the stable page or when you want to adopt the workflow without installing a skill.
Need only the instruction file?
Download SKILL.md only if your client requires a single file. The complete ZIP is safer for a full installation because it preserves the references and release context.
No path installs or executes anything by itself. Your agent still needs access to the project files. Before updating, compare the installed version and review the diff.
// RATINGS
Not yet listed on ClawHub or SkillsMP
// README
openclaw-dynamics-365
OpenClaw skill for Microsoft Dynamics 365 CRM — voice-to-CRM via Dataverse Web API.
Create and update CRM records in Microsoft Dynamics 365 by voice — Opportunities, Leads, Contacts, Accounts, and Tasks — using the Dataverse Web API with Azure AD OAuth 2.0.
Supported entities
| Entity | Operations |
|---|---|
| Opportunity | Create, Update (upsert by name) |
| Lead | Create, Update (upsert by name or email) |
| Contact | Create, Update (upsert by name or email) |
| Account | Create, Update (upsert by name) |
| Task | Create |
Installation
# Via ClawHub CLI
clawhub install openclaw-dynamics-365
# Or as an npm package
npm install openclaw-dynamics-365
Azure AD setup
This skill requires an Azure App Registration. See the Azure Portal Setup Guide below.
Environment variables
| Variable | Required | Description |
|---|---|---|
DYNAMICS365_CLIENT_ID | ✅ | Azure AD Application (client) ID |
DYNAMICS365_CLIENT_SECRET | ✅ | Azure AD client secret value |
DYNAMICS365_TENANT_ID | ✅ | Azure AD Tenant ID (common for multi-tenant) |
DYNAMICS365_INSTANCE_URL | ✅ | Your D365 instance URL, e.g. https://contoso.crm.dynamics.com |
Quick start
import {
Dynamics365Client,
getAuthorizationUrl,
exchangeCodeForTokens,
isTokenExpired,
refreshAccessToken,
} from "openclaw-dynamics-365";
const config = {
clientId: process.env.DYNAMICS365_CLIENT_ID,
clientSecret: process.env.DYNAMICS365_CLIENT_SECRET,
tenantId: process.env.DYNAMICS365_TENANT_ID ?? "common",
instanceUrl: process.env.DYNAMICS365_INSTANCE_URL,
};
// 1. Start OAuth flow — redirect user to this URL
const authUrl = getAuthorizationUrl(config, "https://yourapp.com/callback", "csrf-state");
// 2. In the OAuth callback handler
const tokens = await exchangeCodeForTokens(config, code, "https://yourapp.com/callback");
// 3. Use the client
const client = new Dynamics365Client(tokens.instanceUrl, tokens.accessToken);
// Create or update an Opportunity
const result = await client.upsertOpportunity({
name: "Deal TechNova Q2",
estimatedvalue: 75000,
stepname: "Propose",
actualclosedate: "2026-06-30",
});
console.log(result.created ? "Created:" : "Updated:", result.id);
console.log(Dynamics365Client.recordUrl(tokens.instanceUrl, "opportunity", result.id));
API reference
Dynamics365Client
const client = new Dynamics365Client(instanceUrl: string, accessToken: string);
| Method | Returns | Description |
|---|---|---|
upsertOpportunity(payload) | Promise<UpsertResult> | Create or update an Opportunity |
upsertLead(payload) | Promise<UpsertResult> | Create or update a Lead |
upsertContact(payload) | Promise<UpsertResult> | Create or update a Contact |
upsertAccount(payload) | Promise<UpsertResult> | Create or update an Account |
createTask(payload) | Promise<string> | Create a Task — returns activityid |
searchOpportunity(name) | Promise<string | null> | Find Opportunity by name |
searchLead(query) | Promise<string | null> | Find Lead by name or email |
searchContact(query) | Promise<string | null> | Find Contact by name or email |
searchAccount(name) | Promise<string | null> | Find Account by name |
Static helpers:
// Deep link to a record in the Dynamics 365 UI
Dynamics365Client.recordUrl(instanceUrl, "opportunity", id);
// OData binding reference for lookup fields
Dynamics365Client.bindRef("accounts", accountId); // → "/accounts(abc-123)"
OAuth helpers
getAuthorizationUrl(config, redirectUri, state): string
exchangeCodeForTokens(config, code, redirectUri): Promise<OAuthTokens>
refreshAccessToken(config, refreshToken): Promise<OAuthTokens>
isTokenExpired(tokens): boolean
Azure Portal setup
Follow these steps to create the App Registration needed for OAuth 2.0.
1. Create App Registration
- Go to portal.azure.com → Microsoft Entra ID → App registrations → New registration
- Fill in:
- Name:
openclaw-dynamics-365(or any descriptive name) - Supported account types:
Accounts in any organizational directory (Any Azure AD directory - Multitenant) - Redirect URI: Web →
https://yourapp.com/auth/dynamics365/callback
- Name:
- Click Register
2. Note your credentials
After registration, copy:
- Application (client) ID →
DYNAMICS365_CLIENT_ID - Directory (tenant) ID →
DYNAMICS365_TENANT_ID(usecommonfor multi-tenant)
3. Create a client secret
- Go to Certificates & secrets → New client secret
- Set an expiry (24 months recommended)
- Copy the Value immediately →
DYNAMICS365_CLIENT_SECRET
4. Add API permissions
- Go to API permissions → Add a permission
- Select the APIs my organization uses tab
- Search for
Dataverseand select it from the results - Select Delegated permissions →
user_impersonation - Click Add permissions
- Click Grant admin consent (requires Global Admin or Application Admin role)
5. Get your instance URL
Your Dynamics 365 instance URL is shown in the D365 browser address bar:
https://{org}.crm.dynamics.com → set as DYNAMICS365_INSTANCE_URL
Linking records (OData bindings)
To link a Contact to an Account, or a Task to an Opportunity, use Dynamics365Client.bindRef():
// Link contact to account
await client.upsertContact({
fullname: "João Silva",
emailaddress1: "joao@techno.com",
"parentcustomerid_account@odata.bind": Dynamics365Client.bindRef("accounts", accountId),
});
// Link task to opportunity
await client.createTask({
subject: "Follow-up call",
prioritycode: 2,
"regardingobjectid_opportunity_task@odata.bind": Dynamics365Client.bindRef("opportunities", oppId),
});
Contributing
Contributions are welcome. Please open an issue or pull request on GitHub.
License
MIT © Diego Vieira
// HOW IT'S BUILT
KEY FILES