microsoft / microsoft/Dataverse-MCP

OAuth Protected Resource Metadata advertises wrong `resource` value, breaking remote MCP clients (AADSTS9010010)

Open
#15 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
65
Forks
13
PR merge metrics
No merged PRs in 30d

Description

OAuth Protected Resource Metadata advertises wrong resource value, breaking remote MCP clients (AADSTS9010010)

Description

When connecting to the Dataverse MCP server remote endpoint (/api/mcp) using a remote MCP client (e.g., Claude.ai custom connector), the OAuth authorization flow fails with AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes.

This is caused by a mismatch between the resource field in the Protected Resource Metadata (RFC 9728) and the Azure AD resource where the Dynamics CRM scopes are registered.

Steps to Reproduce

  1. Enable the Dataverse MCP server for an environment per the [documentation](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/data-platform-mcp-other-clients#connect-using-the-remote-endpoint).
  2. Register a custom Entra app with mcp.tools and user_impersonation delegated permissions under Dynamics CRM.
  3. Add the app's client ID to the allowed MCP clients list in PPAC.
  4. Connect a remote MCP client (e.g., Claude.ai custom connector) to https://<org>.crm.dynamics.com/api/mcp.
  5. The client fetches /.well-known/oauth-protected-resource/api/mcp and reads the resource field.
  6. The client includes this resource value in the Azure AD authorization request per RFC 8707.
  7. Azure AD rejects the request with AADSTS9010010.

Root Cause

The Protected Resource Metadata endpoint returns:

{
  "resource_name": "Dataverse MCP Server",
  "resource": "https://<org>.crm.dynamics.com/api/mcp",
  "authorization_servers": [
    "https://login.microsoftonline.com/<tenant-id>/v2.0"
  ],
  "scopes_supported": [
    "openid",
    "profile",
    "offline_access",
    "https://<org>.crm.dynamics.com/user_impersonation"
  ]
}

The resource field is https://<org>.crm.dynamics.com/api/mcp (with the /api/mcp path), but the scopes are registered in Azure AD under https://<org>.crm.dynamics.com (without the path). When a compliant MCP client passes the resource value from the metadata into the authorization request, Azure AD sees a mismatch between the resource and the scopes and returns AADSTS9010010.

Expected Behavior

The resource field in the Protected Resource Metadata should be https://<org>.crm.dynamics.com to match the Azure AD resource registration where the Dynamics CRM scopes (user_impersonation, mcp.tools) are defined.

Alternatively, the scopes in Azure AD could be registered under the /api/mcp path — but changing the metadata is the simpler fix.

Error Details

Request Id:      b14e4c7b-edcf-46cb-94d7-ff224732a200
Correlation Id:  6160e6cf-932b-47de-b5da-b0a9024e00af
Timestamp:       2026-03-12T18:58:07Z
Message:         AADSTS9010010: The resource parameter provided in the request
                 doesn't match with the requested scopes.

Authorization URL constructed by the client (abridged):

https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize
  ?scope=openid+profile+offline_access+https://<org>.crm.dynamics.com/user_impersonation
  &resource=https://<org>.crm.dynamics.com/api/mcp

Impact

This blocks all remote MCP clients that follow RFC 9728 / RFC 8707 from connecting to the Dataverse MCP server via the remote endpoint documented [here](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/data-platform-mcp-other-clients#connect-using-the-remote-endpoint). The local proxy approach is unaffected since it handles authentication via MSAL.

Environment

  • Dataverse org URL: https://<org>.crm.dynamics.com
  • MCP endpoint: /api/mcp
  • MCP client: Claude.ai custom connector (also affects any RFC 9728-compliant client)
  • Entra app permissions: Dynamics CRM mcp.tools + user_impersonation (delegated), Microsoft Graph email, openid, profile, User.Read, offline_access — all granted admin consent

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the handler for /.well-known/oauth-protected-resource/api/mcp and inspect how it builds the resource and scopes_supported values. Compare the metadata with the documented Dataverse endpoint and RFC 9728/RFC 8707 behavior; done means remote clients receive the org URL without /api/mcp and the authorization flow no longer returns AADSTS9010010.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure
Domain
api, authentication, authorization
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.