Skip to content

Authentication

Ryan James edited this page Aug 17, 2026 · 1 revision

DATAVERSE_AUTH_TYPE selects the credential. Default interactive. Any other value than interactive or azure_cli fails at startup with Unsupported DATAVERSE_AUTH_TYPE: '<value>'. Supported values: interactive, azure_cli.

No client ID, tenant ID or secret is configured anywhere — the server uses the Azure Identity default developer client registration and signs in as you.

interactive azure_cli
Requires A browser on the machine running the server Azure CLI installed and az login already done
First sign-in Browser opens on the first tool call, not at startup None — reuses the existing CLI session
MFA / Conditional Access Full browser context, so MFA and CA claims flow normally Handled by az login
Survives restart Yes, via the persisted MSAL cache (below) Yes, for as long as the CLI session is valid
Multiple accounts on one host Yes, via DATAVERSE_TOKEN_CACHE_PROFILE No — one CLI session per user
Best for Everyday desktop use Headless hosts, CI, or where a CLI session already exists

Pick interactive unless the host cannot open a browser. It is a local, single-user, stdio process, so the browser and its 127.0.0.1 loopback listener reach you. If you run the server on a remote host, interactive will open a browser you never see — use azure_cli there.

On Windows, azure_cli also probes C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin and its (x86) equivalent and prepends them to PATH when az is not already on it — MCP clients often launch the server without a login shell.

First sign-in

  1. The client starts the server. Nothing happens yet: the credential is constructed, no token is requested.
  2. The agent calls its first tool. The server requests a token for https://yourorg.crm.dynamics.com/.default.
  3. interactive opens the browser; you sign in and complete MFA. azure_cli shells out to az.
  4. The token is cached and the tool call proceeds.

Credential acquisition is capped by DATAVERSE_AUTH_TIMEOUT_SECONDS (default 30). A browser sign-in with MFA regularly takes longer than 30 seconds — raise it to 120 if the first call fails with Credential acquisition timed out after 30s. and retrying works.

What is cached, and where

Two layers:

In-process access tokens. One per scope (<environment-url>/.default, plus https://service.powerapps.com/.default for dataverse_list_environments), refreshed 5 minutes before expiry. Lost when the server stops.

On-disk MSAL cacheinteractive only, controlled by the variables below. Encrypted by the OS secret store (Windows DPAPI, macOS Keychain, Linux libsecret) and named dataverse-mcp.cache, or dataverse-mcp.<profile>.cache when a profile is set. Alongside it the server writes an AuthenticationRecord sidecar — dataverse-mcp.authrecord.json (or dataverse-mcp.<profile>.authrecord.json) in %LOCALAPPDATA%\dataverse-mcp on Windows, $XDG_CONFIG_HOME/dataverse-mcp (else ~/.config/dataverse-mcp) elsewhere, mode 0600 on POSIX. The sidecar holds no secret — home account id, tenant, authority, username — and it is what lets MSAL pick the right account silently on restart. If it is missing or unreadable the server logs a warning and falls back to a fresh prompt.

Variable Default Effect
DATAVERSE_TOKEN_CACHE_PERSIST true false reverts to an in-memory-only cache — a browser prompt on every restart. No effect on azure_cli.
DATAVERSE_TOKEN_CACHE_PROFILE (empty) Suffixes the cache name and sidecar filename so concurrent servers signed in to different tenants/accounts do not overwrite each other. [A-Za-z0-9_-] only — any other character fails at startup rather than being sanitised, because sanitising could silently collapse two profiles into one shared cache.
DATAVERSE_TOKEN_CACHE_ALLOW_UNENCRYPTED false Permits writing the cache without OS-level encryption.

The unencrypted flag is a real trade-off

With the default false, a host that has no OS secret store — typically headless Linux without libsecret / GNOME Keyring — fails at the first token acquisition, not at startup. Three ways out, in order of preference:

  1. Install libsecret / gnome-keyring in the image and keep the cache encrypted.
  2. Set DATAVERSE_TOKEN_CACHE_PERSIST=false and accept a prompt per restart.
  3. Set DATAVERSE_TOKEN_CACHE_ALLOW_UNENCRYPTED=true.

Option 3 writes a long-lived refresh token in cleartext. Anyone who can read that file can act as you against every environment you can reach, without MFA. Only do it on a trusted, access-controlled host. The server logs a warning at startup whenever the flag is active.

Multiple tenants and environments

dataverse_url is a per-call argument, so one server instance already reaches every environment your single sign-in can reach — no extra configuration for multi-environment work.

You only need a second server entry when you must be signed in as a different account or tenant. Give each entry a distinct DATAVERSE_TOKEN_CACHE_PROFILE; without it both share the default cache filenames and each restart re-pins whichever account signed in last. See the side-by-side example in Client-Setup.

Dataverse permissions the account needs

The server does nothing to elevate you — every call runs as the signed-in user and Dataverse enforces its own privileges.

To do this The account needs
Anything against an environment An enabled Dataverse user record in that environment (an Entra account alone is not enough)
Read records, metadata, solutions A security role with read privileges on the tables and components involved (Basic User is often not enough for schema reads)
Create/update/delete records The matching write/delete privileges — plus DATAVERSE_ALLOW_WRITE / DATAVERSE_ALLOW_DELETE on the server (Safety-and-Permissions)
Schema, solution, plug-in and app changes System Customizer or System Administrator
dataverse_list_environments Environment or tenant admin — it calls the Power Platform admin API (scopes/admin/environments), so it lists only environments you can administer

dataverse_list_environments is a convenience for discovering URLs. If you already know the environment URL you never need it, and lacking admin rights blocks nothing else.

Start with First-Stepsdataverse_whoami is the fastest way to confirm all of the above at once.

Clone this wiki locally