[BUG] Custom MCP connector OAuth fails with Azure DevOps Remote MCP Server (AADSTS9010010 resource/scope mismatch)

Resolved 💬 4 comments Opened May 4, 2026 by mhkolk Closed May 8, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Describe the bug

When adding a custom MCP connector in claude.ai pointing to Microsoft's hosted Azure DevOps MCP
server (https://mcp.dev.azure.com/{org}), authentication always fails with AADSTS9010010.
The OAuth request claude.ai constructs includes both a resource parameter and a scope
parameter that Azure AD considers inconsistent, and there is no way to fix this from the user side.

Steps to reproduce

  1. Create an Azure Entra ID App Registration with:
  • Redirect URIs: https://claude.ai/api/mcp/auth_callback and https://claude.com/api/mcp/auth_callback
  • accessTokenAcceptedVersion: 2 in manifest
  • API permission for the Azure DevOps MCP service principal

(2a72489c-aab2-4b65-b93a-a91edccf33b8, Ado.Mcp.Tools scope) with admin consent granted

  1. In claude.ai → Settings → Connectors → Add custom connector, enter:
  • MCP Server URL: https://mcp.dev.azure.com/{org}
  • Client ID and Secret from the app registration above
  1. Click Connect

Expected behavior

OAuth completes and the connector authenticates successfully, giving access to Azure DevOps MCP
tools in the claude.ai web interface.

Actual behavior

Azure AD returns:
AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes.

Root cause (diagnosed)

Inspecting the OAuth request via browser DevTools shows claude.ai constructs the authorization
URL with both resource and scope parameters:

scope=2a72489c-aab2-4b65-b93a-a91edccf33b8/.default+offline_access
resource=https://mcp.dev.azure.com/{org}

The resource parameter is a v1 OAuth concept. When sent to Azure AD's v2 endpoint
(/oauth2/v2.0/authorize) alongside scope, Azure AD requires them to be consistent —
the app referenced in scope must have its Application ID URI match the resource URL.
Since 2a72489c-... is Microsoft's first-party MCP service app, the user has no ability
to modify its identifier URIs, so this mismatch cannot be resolved from the user side.

The resource parameter appears to originate from the MCP server URL being passed through.
Removing it, or not sending it alongside scope on the v2 endpoint, would resolve the issue.

Environment

  • claude.ai web (custom connector UI)
  • Azure DevOps Remote MCP Server: https://mcp.dev.azure.com/{org} (Microsoft-hosted, preview)
  • Azure AD tenant with single-tenant app registration
  • OAuth 2.0 with PKCE (v2 endpoint)

Workaround

None available via the claude.ai web connector. The local @azure-devops/mcp package works
via the Claude Code VSCode extension using a PAT.

What Should Happen?

When constructing the OAuth authorization URL for a custom MCP connector using Azure AD's v2
endpoint (/oauth2/v2.0/authorize), claude.ai should not include the resource parameter.

The resource parameter is a legacy OAuth v1 concept replaced by scope in v2. Azure AD's v2
endpoint supports resource only in narrow scenarios, and rejects any request where resource
and scope reference different identifiers — which is unavoidable here because:

  • scope is derived from the app ID discovered via the MCP server's OAuth metadata

(2a72489c-aab2-4b65-b93a-a91edccf33b8/.default)

  • resource is the MCP server URL (https://mcp.dev.azure.com/{org})

These will never match unless the user can modify the Application ID URI of Microsoft's
first-party app, which they cannot.

Suggested fix: strip the resource parameter from the authorization URL when targeting
the v2 endpoint. The scope parameter alone is sufficient for Azure AD v2 OAuth flows and
is what Microsoft's own documentation recommends.

Alternatively, if resource is required by the MCP spec (e.g. RFC 8707 Resource Indicators),
derive scope from the resource URL directly (https://mcp.dev.azure.com/{org}/.default)
rather than from the app GUID in the MCP server's OAuth metadata, so the two parameters
remain consistent.

Error Messages/Logs

Steps to Reproduce

  1. Create an Azure Entra ID App Registration with:
  • Redirect URIs: https://claude.ai/api/mcp/auth_callback and https://claude.com/api/mcp/auth_callback
  • accessTokenAcceptedVersion: 2 in manifest
  • API permission for the Azure DevOps MCP service principal

(2a72489c-aab2-4b65-b93a-a91edccf33b8, Ado.Mcp.Tools scope) with admin consent granted

  1. In claude.ai → Settings → Connectors → Add custom connector, enter:
  • MCP Server URL: https://mcp.dev.azure.com/{org}
  • Client ID and Secret from the app registration above
  1. Click Connect

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

v2.1.126

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗