This guide provides step-by-step instructions for registering and installing the Dataverse MCP Server for use with Microsoft Copilot Studio.
The installation process consists of four main steps:
- Register the MCP Server App in Entra ID
- Deploy the server to Azure using
azd up - Register the MCP Server Connector App in Entra ID
- Create a Custom Connector in Power Platform
- Azure subscription with appropriate permissions
- Azure Developer CLI (
azd) installed (Install Guide) - Docker installed and running
- Microsoft Dataverse environment
- Power Platform environment with Copilot Studio access
- Permissions to create app registrations in Entra ID
The MCP Server App is the backend service that will run in Azure Container Apps and access Dataverse on behalf of users.
- Navigate to Azure Portal
- Go to Microsoft Entra ID > App registrations
- Click New registration
- Configure the registration:
- Name:
Dataverse MCP Server - Supported account types:
Accounts in this organizational directory only (Single tenant) - Redirect URI: Leave blank for now (will be configured after deployment)
- Name:
- Click Register
After registration, on the Overview page, copy and save:
- Application (client) ID
- Directory (tenant) ID
Note: This setup uses a User-Assigned Managed Identity for secure, secret-less authentication in Azure. After deploying the infrastructure, you will configure a Federated Credential to establish trust between your App Registration and the Managed Identity running in Azure.
The MCP Server needs permission to access Dataverse on behalf of users.
- In your app registration, go to API permissions
- Click Add a permission
- Select Dynamics CRM (or search for "Dynamics CRM")
- Choose Delegated permissions
- Select user_impersonation
- Click Add permissions
- If required by your organization, click Grant admin consent
The MCP Server must expose an API that the Connector App will call.
- In your app registration, go to Expose an API
- Click Add next to "Application ID URI"
- Accept the default value (
api://<client-id>) or customize it - Click Save
- Click Add a scope
- Configure the scope:
- Scope name:
mcp:tools - Who can consent:
Admins and users - Admin consent display name:
Access Dataverse MCP tools - Admin consent description:
Allows the application to access Dataverse MCP tools on behalf of the signed-in user - User consent display name:
Access Dataverse MCP tools - User consent description:
Allows the application to access Dataverse MCP tools on your behalf - State:
Enabled
- Scope name:
- Click Add scope
Note: The full scope will be in the format
api://<client-id>/mcp:tools(e.g.,api://b52b5b7a-e895-4600-b567-2c4cbe27d2e7/mcp:tools). You'll need this complete scope when configuring the custom connector.
Deploy the MCP Server to Azure Container Apps using Azure Developer CLI.
azd auth loginThis will open a browser window to authenticate with your Azure account.
azd upYou'll be prompted for the following information:
- Environment name: Choose a name (e.g.,
dataverse-mcp) - Azure subscription: Select your subscription
- Location: Select a region (e.g.,
eastus,westeurope)
Then provide the configuration values:
- Azure AD Tenant ID: From Step 1.2
- Azure AD Client ID: From Step 1.2 (MCP Server App)
- Dataverse URL: Your Dataverse environment URL (e.g.,
https://yourorg.crm.dynamics.com) - Dataverse API Version:
v9.2(or latest)
After deployment completes, note the Container App URL (e.g., https://your-app.azurecontainerapps.io).
This is the critical step to enable secret-less authentication. You will link your Dataverse MCP Server App Registration to the User-Assigned Managed Identity that was created during deployment.
Note: This setup uses two different Client IDs:
- App Registration Client ID (
AZURE_AD_CLIENT_ID): The Client ID of theDataverse MCP ServerApp Registration from Step 1.2- Managed Identity Client ID (
AZURE_CLIENT_ID): The Client ID of the User-Assigned Managed Identity created byazdThe Federated Credential establishes trust between these two identities, allowing the Managed Identity to obtain tokens on behalf of the App Registration.
-
Find the Managed Identity Client ID:
- In the Azure Portal, navigate to the resource group created by
azd(e.g.,rg-dataverse-mcp). - Find the User-Assigned Managed Identity. Its name will be similar to
uai-dataverse-mcp-<unique_string>. - Click on it, and from the Overview page, copy its Client ID.
- Save this value - you'll need it for verification later (this becomes the
AZURE_CLIENT_IDenvironment variable).
- In the Azure Portal, navigate to the resource group created by
-
Add the Federated Credential:
- Return to your
Dataverse MCP ServerApp Registration in Microsoft Entra ID. - Go to the Certificates & secrets blade and click the Federated credentials tab.
- Click Add credential.
- For the Federated credential scenario, select Managed Identity.
- Click Select a managed identity.
- Choose your Subscription and select the User-assigned managed identity that was created by
azd(its name will be similar touai-dataverse-mcp-...). - Click Select.
- The Issuer and Subject identifier fields will be populated automatically.
- Verify that the Subject identifier matches the Managed Identity Client ID you copied in step 1.
- Provide a Name for the credential (e.g.,
mcp-server-managed-identity). - Click Add.
- Return to your
This configuration tells Entra ID to trust tokens issued by the Managed Identity as if they are coming from your application.
Test the health endpoint to confirm deployment:
curl https://<your-app-url>.azurecontainerapps.io/healthExpected response:
{
"status": "healthy",
"timestamp": "2025-12-10T..."
}Note: You might need to restart your app service after configuring the federated credential for changes to take effect.
The Connector App is used by Power Platform to authenticate users and call the MCP Server on their behalf.
Note: For more instructions on creating connector and app registration with On-Behalf-Of (OBO) flow, visit the official Microsoft documentation:
- Navigate to Azure Portal
- Go to Microsoft Entra ID > App registrations
- Click New registration
- Configure the registration:
- Name:
Dataverse MCP Connector - Supported account types:
Accounts in this organizational directory only (Single tenant) - Redirect URI: Leave blank (will be configured after creating the connector)
- Name:
- Click Register
Copy and save:
- Application (client) ID (Connector App)
- Directory (tenant) ID
The Connector App needs permission to call the MCP Server API.
- Go to API permissions
- Click Add a permission
- Click APIs my organization uses tab
- Search for your MCP Server App (e.g., "Dataverse MCP Server")
- Click on your MCP Server App
- Select Delegated permissions
- Check the
mcp:toolsscope you created earlier - Click Add permissions
- Click Grant admin consent for [your organization] (required for OBO flow)
Important: Ensure you select Delegated permissions (not Application permissions) since OBO authentication requires acting on behalf of the signed-in user.
To enable OBO authentication, the Connector App must expose a scope and authorize the Azure API Connections service principal.
- In your Connector App registration, go to Expose an API
- Click Add next to "Application ID URI"
- Accept the default value (
api://<connector-client-id>) or customize it - Click Save
- Click Add a scope
- Configure the scope:
- Scope name:
access_as_user - Who can consent:
Admins and users - Admin consent display name:
Allow Azure API Connections to obtain tokens on behalf of users - Admin consent description:
Allows the Azure API Connections service to obtain tokens on behalf of the user - User consent display name:
Allow connector to act on your behalf - User consent description:
Allows the Azure API Connections service to obtain tokens and access resources on your behalf - State:
Enabled
- Scope name:
- Click Add scope
This step allows the Azure API Connections service to obtain tokens on behalf of users without requiring explicit sign-in each time.
-
In the Expose an API blade, scroll down to Authorized client applications
-
Click Add a client application
-
Enter the client ID:
fe053c5f-3692-4f14-aef2-ee34fc081caeThis is the Microsoft Azure API Connections service principal ID
-
Select the
access_as_userscope you just created -
Click Add application
Note: If you encounter errors when authorizing the service principal, it may not be provisioned in your tenant yet. Contact your tenant administrator to provision it. See Microsoft's documentation on provisioning Azure API Connections service principal for details.
Create a custom connector in Power Platform that uses the MCP Server.
- Go to Power Platform Maker Portal
- Select your environment
- Navigate to Custom connectors under Data > Custom connectors
- Click New custom connector
- Select Import from GitHub
- Configure the import:
- Connector Type: Select Custom
- Branch: Select dev
- Connector: Select MCP-Streamable-HTTP
- Click Continue
On the General tab:
- Host: Enter your Container App hostname (e.g.,
your-app.azurecontainerapps.io) - Base URL:
/mcp - Scheme:
HTTPS - Connector Name: E.g.
Dataverse MCP Connector
On the Security tab, you will configure OAuth 2.0 to use a Managed Identity, which avoids the need for a client secret.
- Authentication type: Select OAuth 2.0.
- Identity Provider: Select Azure Active Directory.
- Client ID: Your Connector App Client ID (from Step 3.2).
- Secret options: Select Use managed identity (the connector will generate its own managed identity).
- Authorization URL:
https://login.microsoftonline.com(default). - Tenant ID: Enter your tenant ID from Step 1.2, or use
commonfor multi-tenant scenarios. - Resource URL: Your MCP Server App Application ID URI (from Step 1.4, e.g.,
api://<server-app-client-id>). - Enable on-behalf-of login: Set to
true. - Scope: The full scope including the Application ID URI, e.g.,
api://<server-app-client-id>/mcp:tools. - Click Create connector.
- After the connector is saved, note the following values:
- Scroll down to the Managed identity section and copy the Issuer and Subject identifier values (under "Federated Identity Credentials").
- At the bottom of the Security tab, copy the Redirect URL (it will be something like
https://global.consent.azure-apim.net/redirect/mcp-2dstreamable-2dhttp-5f...).
Now that the connector has been created and generated a redirect URL, you need to add it to the Connector App Registration.
- Return to the Microsoft Entra ID portal.
- Go to App registrations and select your
Dataverse MCP Connectorapp. - Go to Authentication.
- Click Add a platform.
- Select Web.
- Enter the Redirect URL you copied from the Power Platform connector (e.g.,
https://global.consent.azure-apim.net/redirect/mcp-2dstreamable-2dhttp-5f...). - Click Configure.
Verification: After adding the redirect URI, you should see it listed under the "Web" platform in the Authentication blade.
Now, you will configure the Dataverse MCP Connector App Registration to trust the Managed Identity of the custom connector.
- Return to the Microsoft Entra ID portal.
- Go to App registrations and select your
Dataverse MCP Connectorapp. - Go to the Certificates & secrets blade and click the Federated credentials tab.
- Click Add credential.
- For Federated credential scenario, select Other issuer.
- Under Connect your account, configure the following:
- Issuer: Paste the Issuer value you copied from the custom connector (e.g.,
https://login.microsoftonline.com/{tenant-id}/v2.0). - Type: Select Explicit subject identifier (should be selected by default).
- Value: Paste the Subject identifier value you copied from the custom connector (this is a long path starting with
/eid1/c/pub/...).
- Issuer: Paste the Issuer value you copied from the custom connector (e.g.,
- Under Credential details:
- Name: Give it a descriptive name (e.g.,
power-platform-connector). - Description: Optionally add a description.
- Audience: This should be pre-filled as
api://AzureADTokenExchange(leave as is).
- Name: Give it a descriptive name (e.g.,
- Click Add.
- Return to your custom connector in the Power Platform Maker Portal.
- Review the Definition tab to see imported operations.
- Go to the Test tab.
- Click New connection.
- Sign in with a user account that has Dataverse access. The connection should now succeed without prompting for a secret.
- Test Share the Custom Connector
After configuring your custom connector, share it with appropriate users so they can use it in agent conversations.
- In the Power Platform Maker Portal, navigate to your custom connector
- Click Share (or navigate to Connections > Custom connectors)
- Share with the appropriate users based on their role:
- Can edit: Grant to makers who need to configure and manage the connector within agents
- Can view: Grant to end users who will sign in and use the connector during agent conversations
For detailed instructions, see Share a custom connector in your organization.
- Navigate to Copilot Studio
- Create or open a Copilot
- Go to Actions > Add an action
- Select Custom connector
- Choose your Dataverse MCP connector
- Select the operations you want to use
- Configure and test your Copilot with the MCP Server
Note: The first time a user interacts with an action that uses the connector, they'll be prompted to grant consent. After granting consent once, subsequent interactions will work transparently.
If you receive errors about the Azure API Connections service principal (fe053c5f-3692-4f14-aef2-ee34fc081cae) not being found:
- The service principal may not be provisioned in your tenant yet
- Contact your tenant administrator to provision it
- See Microsoft's documentation for provisioning instructions
If users are repeatedly prompted to grant consent:
- Verify the Azure API Connections service principal (
fe053c5f-3692-4f14-aef2-ee34fc081cae) is authorized in the Connector App's Expose an API > Authorized client applications section - Ensure the
access_as_userscope is selected for the authorized client - Check that admin consent has been granted for all API permissions
Ensure scopes are formatted correctly:
- MCP Server scope:
api://<server-app-client-id>/mcp:tools - Connector App scope:
api://<connector-app-client-id>/access_as_user - In the Power Platform connector configuration, use the full scope format including the
api://prefix
- Verify all Client IDs are correct:
AZURE_AD_CLIENT_IDshould be the App Registration Client ID (Dataverse MCP Server)AZURE_CLIENT_IDshould be the Managed Identity Client ID (auto-set by Container Apps)
- For the MCP Server App, ensure the Federated Credential is correctly configured:
- The subject identifier should match the Managed Identity Client ID (
AZURE_CLIENT_ID) - The issuer should be the Microsoft Entra ID token endpoint
- The subject identifier should match the Managed Identity Client ID (
- For the Connector App, ensure the Federated Credential is correctly configured with the issuer and subject from the Power Platform connector's security page.
- Ensure admin consent has been granted for API permissions.
- Check that redirect URIs are correctly configured.
- Restart the Container App after configuring federated credentials.
- Verify the Container App is running:
az containerapp show --name <app-name> --resource-group <rg-name> - Check the health endpoint
- Review Container App logs for errors
- Ensure the Connector App has permission to call the MCP Server API (
mcp:toolsscope) - Verify the MCP Server App has exposed the API correctly
- Check that the Resource URL matches the Application ID URI exactly
- Ensure the user has appropriate security roles in Dataverse
- Verify the MCP Server App has
user_impersonationpermission for Dynamics CRM - Check that users have granted consent to the applications
If azd up times out or fails during deployment, Azure may leave resources in a failed provisioning state. Subsequent deployments will fail because Azure cannot update resources that are in a failed state.
When to use this solution:
- First deployment attempt times out
- You see errors like "ResourceDeploymentFailure" or "reached terminal provisioning state 'Failed'"
- Deployment fails with "dataverse-mcp-fetch-image" errors
- Resources are stuck in "Failed" provisioning state
Quick cleanup and retry:
# Set your resource group name
$RESOURCE_GROUP = "your-resource-group-name"
# Clean up failed resources
Write-Host "Cleaning up failed resources..."
az containerapp delete --resource-group $RESOURCE_GROUP --name dataverse-mcp --yes 2>$null
az deployment group delete --resource-group $RESOURCE_GROUP --name dataverse-mcp-fetch-image 2>$null
az deployment group delete --resource-group $RESOURCE_GROUP --name dataverseMcp 2>$null
az deployment group delete --resource-group $RESOURCE_GROUP --name resources 2>$null
# Reset deployment flags
azd env set SERVICE_DATAVERSE_MCP_RESOURCE_EXISTS false
# If you have Owner permissions and role assignments are failing, skip them
# (see "Role Assignment Failures" below)
# azd env set SKIP_ROLE_ASSIGNMENTS true
# Retry deployment
Write-Host "`nRetrying deployment..."
azd upIf you need to start completely fresh:
# List all resources to verify before deleting
az resource list --resource-group $RESOURCE_GROUP --output table
# Delete all resources in the resource group
az resource list --resource-group $RESOURCE_GROUP --query "[].id" -o tsv | ForEach-Object {
az resource delete --ids $_ --verbose
}
# Then retry deployment
azd upEven with Owner permissions on the resource group, the automatic role assignment during deployment can fail due to Azure Policy restrictions, custom RBAC configurations, or timing issues.
Symptoms:
- Deployment fails with "AuthorizationFailed for roleAssignments" errors
- Error mentions "Microsoft.Authorization/roleAssignments/write" permission
- You have confirmed you have Owner role on the resource group
Solution: Skip role assignments during deployment and configure manually:
# Skip automatic role assignments
azd env set SKIP_ROLE_ASSIGNMENTS true
# Deploy
azd upAfter deployment succeeds, manually assign the required role:
$RESOURCE_GROUP = "your-resource-group-name"
# Get managed identity principal ID
$IDENTITY_PRINCIPAL_ID = az identity list `
--resource-group $RESOURCE_GROUP `
--query "[?contains(name, 'dataverse-mcp')].principalId" -o tsv
# Get ACR name
$ACR_NAME = az acr list `
--resource-group $RESOURCE_GROUP `
--query "[0].name" -o tsv
# Get subscription ID
$SUBSCRIPTION_ID = az account show --query id -o tsv
# Assign AcrPull role to the managed identity
az role assignment create `
--assignee $IDENTITY_PRINCIPAL_ID `
--role "AcrPull" `
--scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
Write-Host "✅ Role assignment completed successfully"
# Restart container app to pick up new permissions
$REVISION_NAME = az containerapp revision list `
--resource-group $RESOURCE_GROUP `
--name dataverse-mcp `
--query "[0].name" -o tsv
az containerapp revision restart `
--resource-group $RESOURCE_GROUP `
--name dataverse-mcp `
--revision $REVISION_NAME
Write-Host "✅ Container app restarted"Verify the role assignment:
# Check role assignments on the ACR
az role assignment list `
--scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME" `
--output tableFor more details on deploying with skip role assignments, see SKIP_ROLE_ASSIGNMENTS.md.
For issues and questions:
- Check the Support documentation
- File an issue in the GitHub repository
- Review Azure Container App logs for detailed error messages
- Secrets Management: Use Managed Identity and Federated Credentials for Azure resources and Power Platform connectors to avoid managing secrets.
- Consent: Ensure users understand what data access they're granting.
- Monitoring: Enable logging and monitoring for the Container App.
- Regular Updates: Keep app registration secrets (like the one for the Connector App) rotated according to your security policy.
- Least Privilege: Grant only necessary permissions to users and apps
After successful installation:
- Review the README for implementation details
- Configure logging levels if needed
- Monitor cache performance and adjust TTLs if required
- Set up alerts for the Container App
- Train users on available MCP tools and capabilities