A VS Code extension for TypeScript development against Dynamics 365 / Dataverse. Browse entities and attributes, generate typed interfaces and const enums for option sets, and get IntelliSense-driven schema generation — all without leaving the editor.
Table of Contents
Features
Entity Explorer
A sidebar panel (D365 icon in the Activity Bar) that connects to your Dataverse environment and lets you explore its metadata.
- Lists all entities, sortable and filterable by solution
- Expand any entity to see its attributes, types, and whether each field is the primary ID or primary name
- Right-click an entity to generate a TypeScript interface
- Right-click a Picklist, State, or Status field to generate a standalone
const enum
TypeScript Interface Generation
Right-click an entity in the explorer (or run D365: Generate TypeScript Interface from the command palette) to generate a typed interface for it.
You'll be prompted to select which fields to include. The output is opened directly in the editor as a new TypeScript file.
- Fields are typed appropriately (
string, number, boolean)
- Lookup / Customer / Owner fields use the actual Web API key (
_logicalname_value) with an optional companion annotation field for the display name
- DateTime fields are typed
string with an ISO 8601 note
- Picklist / State / Status fields automatically have their option values fetched and a matching
const enum generated alongside the interface
Example output:
export const enum LeadStatusCode {
New = 1,
Contacted = 2,
Qualified = 3,
}
// Lead (lead)
export interface Lead {
leadid: string;
/** Primary Name */
fullname: string;
statuscode: LeadStatusCode;
_ownerid_value: string | null;
'_ownerid_value@OData.Community.Display.V1.FormattedValue'?: string;
}
Enum Generation
Right-click any Picklist, State, or Status attribute in the explorer and choose Make Enum. The extension fetches the option set values from Dataverse and opens a const enum ready to copy into your project.
export const enum LeadStatusCode {
New = 1,
Contacted = 2,
Qualified = 3,
}
IntelliSense Integration
Generate interfaces directly in your TypeScript files without touching the sidebar.
Option 1 — type d365
Start typing d365 anywhere in a .ts or .js file and two items appear in the autocomplete dropdown:
- D365: Generate interface… — prompts for an entity, then inserts all fields
- D365: Generate interface (select fields…) — prompts for an entity, then lets you pick which fields to include
Option 2 — trigger comment
Write a trigger comment with the entity name already known, then use the lightbulb (Ctrl+.):
// @d365 lead
The same two options appear. Accepting either replaces the comment with the generated code in-place.
Both paths fetch option set values automatically and produce const enums alongside the interface.
Connection Management
- Connect — prompts for environment URL and authentication method, then validates connectivity via WhoAmI
- Disconnect — clears the stored session
- Auto-restore — the extension activates in the background when VS Code opens and silently restores the last connection; the sidebar shows a spinner while this is in progress and a reconnect prompt if it fails
- Per-workspace — each workspace maintains its own connection independently; opening multiple workspaces simultaneously connects each to its own environment
Authentication options:
| Mode |
Description |
| User account |
Interactive sign-in via Microsoft account (MSAL device flow) |
| Client credentials |
App-only, using an Azure AD client ID and secret |
Client secrets are stored in VS Code's secret storage (OS keychain), never in plain text.
Status Bar
A status bar item on the left shows the current connection at a glance — $(plug) D365: yourorg when connected, $(debug-disconnect) D365: Not Connected otherwise, or a spinner while a saved connection is being restored. Click it to open a menu with:
- Disconnect (when connected)
- Switch Account… — re-prompts the Microsoft account picker for the current environment, for user-auth connections
- Connect to Environment… / Connect to Different Environment…
- Recent Environments — the last five environments you've connected to, for one-click reconnect without re-entering the URL, tenant, or auth mode
Connecting or switching accounts always shows the Microsoft account picker, even if only one account is signed in — this prevents silently reusing the wrong account when you have more than one D365 tenant. Routine background token refreshes (e.g. while browsing entities) don't force the account picker; if your Microsoft session has expired, VS Code may still prompt you to sign in again.
Browse Entity Fields
The Browse Entity Fields title bar button (or D365: Browse Entity Fields from the palette) opens a searchable quick-pick showing all attributes for any entity — useful for quickly looking up a field name or type without generating any code.
Web Resources
Publish local files straight to your connected environment as Dataverse web resources — no manual upload through the maker portal.
Setup
- Open the D365 Explorer sidebar and click the
... (more actions) button in its title bar.
- Choose Configure Web Resources….
- Pick (or type) the workspace folder that holds your web resource files — the folder icon opens a native browse dialog.
- Optionally set a name prefix (e.g.
new_). A trailing / is added automatically if you leave it off, so the resulting Dataverse name looks like new_/scripts/main.js.
Local file names map to Dataverse web resource names automatically: <prefix>/<path relative to the configured folder>. Supported extensions: .js, .html/.htm, .css, .xml, .png, .jpg/.jpeg, .gif, .svg, .ico, .xap, .resx.
Publishing
Once connected, publish via any of:
- Right-click a file or folder in Explorer → Publish Web Resource (folders publish every supported file underneath them)
- The cloud-upload icon in the editor title bar, for the file you're currently editing
- D365: Publish Web Resources… from the command palette, or the
... menu in the D365 Explorer sidebar — opens a multi-select list of every file under your configured folder
If a matching web resource doesn't exist yet, you'll be prompted to create it (display name, type, and optionally a solution to add it to). Existing web resources just have their content updated. Either way, the extension publishes the change immediately afterward, so it goes live without a separate manual publish step.
Comparing with the server
Right-click a text-based web resource file (.js, .html/.htm, .css, .xml, .resx, .svg) in Explorer, or use the diff icon in the editor title bar, and choose Compare with Dynamics 365 to open a side-by-side diff of your local file against the content currently published in the environment. Useful for checking what's actually changed before publishing, or spotting drift if someone edited the web resource directly in D365.
Ribbon Editor
A Ribbon Workbench-style viewer/editor for an entity's command bar, opened straight from the sidebar — no separate tool needed.
Opening it
- Right-click an entity in the explorer → Edit Ribbon → choose a location (Main Form, Home Grid, or Sub-Grid)
- Or run D365: Edit Ribbon… from the command palette, which prompts for the entity and location instead
Each entity/location combination opens in its own editor tab, since they're materially different ribbons (different tabs, groups, and buttons).
What you can do
- Browse the effective ribbon (tabs → groups → buttons/split-buttons/flyouts) rendered to look like the real thing, icons included
- Select any tab, group, or control to inspect and edit its label, tooltip, command, and enable/display rules
- Add new tabs, groups, and controls, or mark existing ones for deletion
- Export RibbonDiffXml — generates a diff fragment from your edits, opened as a new unsaved document ready to import via a solution
Edits stay in-memory in the editor; publishing the diff back to Dataverse (e.g. via a solution import) is a manual step for now.
Title Bar Actions
The sidebar title bar shows context-sensitive actions:
| Icon |
Command |
Shown when |
$(plug) |
Connect |
Disconnected |
$(debug-disconnect) |
Disconnect |
Connected |
$(refresh) |
Refresh Entities |
Connected |
$(list-flat) |
Browse Entity Fields |
Connected |
The ... overflow menu also has Configure Web Resources… (always) and Publish Web Resources… (when connected).
Extension Settings
All settings are resource-scoped (workspace-folder scoped) and can be set in .vscode/settings.json to pre-fill connection prompts for that workspace folder.
| Setting |
Description |
Default |
d365.environmentUrl |
Dataverse environment URL, e.g. https://yourorg.crm11.dynamics.com |
— |
d365.tenantId |
Azure AD tenant ID. Leave blank to auto-discover from the environment URL |
— |
d365.clientId |
Azure AD application (client) ID |
— |
d365.authMode |
user or clientCredentials. Leave blank to be prompted each time |
— |
d365.webResources.rootFolder |
Workspace-relative folder that maps to Dataverse web resources |
webresources |
d365.webResources.namePrefix |
Prefix prepended to a file's relative path to form its web resource name (trailing / added automatically) |
— |
Claude / AI Integration (MCP Server)
The extension ships an MCP (Model Context Protocol) server so Claude can query your live Dataverse schema while helping you write TypeScript scripts. When the server is running, Claude can look up entity shapes, field types, and option set values in real time — no copy-pasting schema details into the chat.
| Tool |
Description |
list_entities |
List all entities, optionally filtered to a solution |
get_entity_attributes |
Get all fields for an entity with their types |
get_option_values |
Get the numeric values and labels for a Picklist, State, or Status field |
generate_interface |
Generate a TypeScript interface (with auto-enums for option set fields) |
generate_enum |
Generate a const enum for a single option set field |
Setup
No credentials needed — the MCP server uses your existing VS Code session. Configuration is opt-in per workspace.
- Connect in the D365 sidebar — authenticate as normal.
- Run
D365: Configure MCP Server for this Workspace from the Command Palette. This writes (or merges into) .mcp.json in the workspace root, pointing Claude Code at the bundled server. A notification confirms when this happens.
- Restart Claude Code so it picks up the new
.mcp.json.
- Run
/mcp in Claude Code to confirm the d365 server is listed as connected.
That's it. The extension starts a local token-vending bridge (~/.d365-mcp-bridge) whenever you're connected; the MCP server reads from it so Claude always has a fresh token without storing any credentials.
If the d365 server shows as disconnected in /mcp, make sure the D365 sidebar is connected in VS Code first.
Example usage
Once connected, Claude can answer questions like:
"Generate a TypeScript interface for the lead entity, only including the name, status, owner, and created date fields."
Claude will call get_entity_attributes and generate_interface against your live environment and return ready-to-use code.
Requirements
- VS Code 1.85 or later
- Node.js 18+ (required for the bundled MCP server when launched via
node)
- A Dataverse / Dynamics 365 environment
- For user auth: an Azure AD application registered with Dataverse API permissions, or use the default Dataverse client ID
- For client credentials: an Azure AD app registration with a client secret and appropriate Dataverse permissions