microsoft / microsoft/azure-devops-mcp

[REMOTE] Org-scoped protected-resource-metadata advertises a `resource` that doesn't match its own `scopes_supported`, forcing AADSTS9010010 (server-side)

Open
#1,601 1 comment 0 reactions 2 assignees View on GitHub

@aaudzei is already working on this.

Since Sep 14, 2026.

Dominant language
TypeScript
Stars
2k
Forks
649
Avg merge
3d 7h
Merged PRs (30d)
23

Description

Summary

The org-scoped protected-resource-metadata (PRM) document returned by the remote MCP endpoint is internally inconsistent: it advertises a resource value that does not match its own scopes_supported. A spec-compliant MCP client that follows RFC 9728 (read resource from the PRM) and uses it as the RFC 8707 resource indicator is therefore forced to send a resource/scope pair that Entra ID's v2.0 endpoint rejects with AADSTS9010010.

This is the same user-facing symptom as #1293 and #1348, but I believe the root cause is server-side, not a client bug. Those threads attribute the failure to the client sending a resource parameter at all. But the client is faithfully using what the server advertises — and the server advertises an inconsistent document only for the org-scoped URL. The bare URL works with the exact same client and code path; the only variable is which PRM the server returns.

Evidence

https://mcp.dev.azure.com/works:

GET https://mcp.dev.azure.com/.well-known/oauth-protected-resource
{
  "resource": "https://mcp.dev.azure.com",
  "authorization_servers": ["https://login.microsoftonline.com/organizations/v2.0"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["https://mcp.dev.azure.com/.default"]
}

Here resource (https://mcp.dev.azure.com) and the scope's app-ID-URI host (https://mcp.dev.azure.com/.default) are consistent, so the resulting token request is accepted.

https://mcp.dev.azure.com/<org>fails with AADSTS9010010:

GET https://mcp.dev.azure.com/.well-known/oauth-protected-resource/<org>
{
  "resource": "https://mcp.dev.azure.com/<org>",
  "authorization_servers": ["https://login.microsoftonline.com/<tenant-guid>/v2.0"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["https://mcp.dev.azure.com/.default"]
}

Here resource is https://mcp.dev.azure.com/<org> but scopes_supported is still https://mcp.dev.azure.com/.default. The resource indicator and the scope now point at different identifiers, so Entra rejects the token request:

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

The error text is literally describing the inconsistency in the metadata document.

Why this is server-side, not a client bug
  • Same client, same version, same OAuth code path in both cases.
  • The only difference is the PRM the server returns.
  • When the PRM is self-consistent (bare URL), auth succeeds.
  • When the PRM is inconsistent (org URL), auth fails.

If the org-scoped PRM advertised a resource/scope pair that agreed with each other, the client would send a valid request and succeed — as it already does for the bare URL. The fix does not require the client to stop honoring the metadata.

Proposed fix

The org-scoped PRM should advertise "resource": "https://mcp.dev.azure.com" — the app-ID-URI of the single enterprise application that backs the .default scope — even when the request URL carries an org path. The org context can be conveyed by the request path/routing without changing the OAuth audience. That makes resource and scopes_supported consistent, exactly as the working bare-URL document already is.

Note that the inverse — advertising a per-org scope such as https://mcp.dev.azure.com/<org>/.default — is not a viable fix. Entra resolves a /.default scope against a registered application identifier URI, and the backing enterprise app is registered only with https://mcp.dev.azure.com; there is no org-suffixed identifier URI in the tenant (nor could there realistically be one per org). The token audience must be that single registered app regardless of which org the request targets, so the resource value is the piece that has to change.

Environment
  • Remote (HTTP) Azure DevOps MCP server at https://mcp.dev.azure.com
  • Entra ID (Azure AD) v2.0 auth
  • Org-scoped URL form https://mcp.dev.azure.com/<org> fails; bare https://mcp.dev.azure.com/ succeeds
Related
  • #1293 (closed) — same error, org-scoped URL
  • #1348 (open) — same error, org-scoped URL, still reproduces
  • #1284 — referenced from #1293

Contributor guide

Open the contributing guide

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.