The one Microsoft documents openly
Where the Finance and Operations MCP server names a single supported client, Dataverse takes the opposite approach. Microsoft publishes a page called "Use the Dataverse MCP server with other clients" and works through examples for non-Microsoft agents explicitly.
The mechanism is a local proxy. You run a small stdio server on your own machine; it handles the Entra sign-in and forwards MCP traffic to /api/mcp on your environment:
{
"mcpServers": {
"dataverse": {
"command": "npx",
"args": ["-y", "@microsoft/dataverse", "mcp",
"https://<org>.crm.dynamics.com"]
}
}
}Architecturally this is a useful contrast with the ERP server. Same protocol, two different deployment shapes — one a remote HTTP endpoint you authenticate against directly, the other a local process that authenticates on your behalf. Worth knowing when you are drawing the architecture, because they fail in different ways.
Three gates, not one
Access breaks into three independent layers, and confusing them costs time:
Your security role
A Dataverse role on the environment. Delegated auth means you see exactly what you would see in the Power Apps client — no more.
Environment feature
The MCP feature must be enabled for the environment, and the client app added to its allow-list. Environment admin can do this. This one blocks you silently.
Tenant consent
The Dataverse CLI first-party app needs admin consent, once, for the whole tenant. This one blocks you loudly.
We hit the third first. Environment admin was not enough — the client app the proxy authenticates as is a Microsoft first-party application, and enabling it for a tenant is a Global Administrator action.
A colleague using Dataverse MCP from Copilot Studio does not mean you can use it from another client. Copilot Studio authenticates through its own first-party app, already consented tenant-wide. Same server, same data, different door — and each door needs opening separately.
Then, with consent granted and sign-in working, we hit the second gate — and this is the one worth writing down, because it does not announce itself.
The failure that looks like a working server
Everything reported healthy. auth who returned the right identity, tenant and organisation. A direct CLI query returned real customer rows in about a second. The MCP client reported the server as connected.
And every tool call failed, with this:
MCP error -32603: An error occurred.That is the entire message. No status code, no endpoint, no hint about which of the three gates was shut. The connection is genuinely open — it is the MCP session handshake underneath that is being refused, and the client has no vocabulary for the distinction.
Turning on trace-level logging on the proxy gave the real answer in one line:
MCP initialize failed for https://<org>.crm.dynamics.com/api/mcp: 403 ForbiddenToken valid, endpoint refusing. Silent acquisition of the access token succeeded — the same token that had just worked for a data query. The environment was rejecting the MCP session specifically, which points at the feature toggle and the client allow-list, not at authentication. An environment administrator cleared it, and the same configuration worked unchanged.
The lesson generalises past Dataverse. When a layered access model fails, the error surfaces at the outermost layer and describes none of them. -32603 is a generic internal error; the 403 underneath it is the actual fact. If a server connects but every call fails, escalate logging before you touch configuration — the configuration is usually fine.
How to ask for the consent
Escalations go faster when the ask is specific and the reassurance is accurate. What worked:
App: Dataverse CLI (Microsoft first-party) — 0c412cc3-0dd6-449b-987f-05b053db9457
What it does: enables Microsoft's official Dataverse CLI and MCP tooling for the tenant. It uses delegated permissions only — each user who signs in gets exactly their own existing Dataverse security roles and row-level permissions.
What it does not do: grant the application standing or app-only access to data. It elevates nobody.
That last paragraph is what gets a fast yes. An administrator's real concern is not the tooling, it is whether they are creating a service identity with a permanent view of everything. They are not, and being precise about that is the difference between thirty seconds and a change request.
The consent itself is a URL, a review screen, and a button. After accepting, the browser may land on a blank or error-looking page — normal, the grant is recorded server-side.
Then it just works
npx -y @microsoft/dataverse auth create --environment https://<org>.crm.dynamics.com
npx -y @microsoft/dataverse auth whoBrowser sign-in as yourself, and auth who confirms the identity, tenant, organisation and environment. First query returned accounts in about a second.
The capability set is broad — table and metadata discovery, SQL-style querying, full CRUD, file columns. For a demonstration, stay on the read side.
Two things worth knowing
Preview labelling. The server reached general availability in December 2025, but the npm CLI still self-describes as Preview, and the Copilot Studio tool reference is still marked preview. Do not let "GA" and "preview" get conflated in a customer conversation — cite the specific surface you mean.
It is billed. Usage from non-Copilot-Studio clients costs 0.1 Copilot Credits per tool call. Trivial for a demo, worth modelling before anyone designs a chatty production agent against it.
What we actually found in the data
An unglamorous but useful discovery, and a good argument for verifying before you build a slide.
The environment turned out to be a dual-write mirror of the Finance and Operations customer master — the account numbers matched F&O exactly. Zero opportunities, zero leads, account rating and classification unset on every record. There was no CRM lifecycle in it at all.
Reading the account table's own metadata put the matter beyond argument. Alongside the standard CRM columns sits a block of msdyn_ fields — msdyn_company, msdyn_vendor, msdyn_customergroupid, msdyn_paymentterm, msdyn_salestaxgroup. Those are Finance and Operations concepts, sitting on a Dataverse table. The integration is not something you infer from matching account numbers; it is declared in the schema.
Any demonstration built around pipeline stages or lead conversion would have collapsed live. What the environment is good for is the cross-system story: find the customer in Dataverse, pull their open orders from F&O, and note that nothing was built to connect the two. We checked that it holds — US-001, Contoso Retail San Diego resolves in Dataverse, and the same account carries 47 open sales orders in F&O.
Query the environment before you design the demo. The data has an opinion about what story you can tell.
Sources
- Microsoft Learn — Use the Dataverse MCP server with other clients:
https://learn.microsoft.com/en-us/power-apps/maker/data-platform/data-platform-mcp-other-clients - Microsoft Learn — Dataverse MCP server release plan:
https://learn.microsoft.com/en-us/power-platform/release-plan/2025wave1/data-platform/dataverse-mcp-server - Microsoft Learn — Dataverse MCP in Copilot Studio:
https://learn.microsoft.com/en-us/microsoft-copilot-studio/mcp-dataverse
Ask a question or leave feedback
This is a review interaction. The WordPress version will store, thread and moderate comments.