Skip to content

Auth Discussion - Support Azure Auth Server #685

Closed

Description

@2underscores

Had to make 4 adjustments to inspector to get the debug OAuth flow to work with an MCP server using Azure authorisation server (AS). Changes were:

  1. Inspector client not following Oauth standards/MCP spec - Not checking all common /.well-known AS metadata endpoints
  2. Inspector client not following MCP spec - Mandating DCR without static client ID fallback
  3. Azure AS not following OAuth spec - PKCE supported but not advertised in metadata
  4. Azure AS behaviour - Not a spec break, but it doesn't support resource param and fails if it is provided.

Main question

1 & 2 are issues in inspector and should be changed (PRs already raised). For 3 & 4 should MCP Inspector make some minor changes to support MCP servers using Azure as AS, or not?

Details on 4 Issues

1. AS Metadata Endpoints

Inspector only checks /.well-known/openid-configuration and not the other, common /.well-known/openid-configuration. This is somewhat OAuth standards (RFC8414 ~=acks openid should be supported) and against MCP spec discovery section. Closed my PR (#651) as upstream fix in core MCP auth library addressing this - modelcontextprotocol/typescript-sdk#652

2. No pre-registered Client alternative to DCR

MCP spec has DCR support as a "should", but MCP inspector implementation makes it a "must". Inspector already has concept of user provided client ID, it just wasn't used in debug flow. Easy fix, and more details in PR - #684. Issue already raised with #683

3. Azure AS not advertise PKCE

Azure AS supports PKCE, but it's metadata payload does not include a code_challenge_methods_supported field at all. RFC8414 is explicit - "If omitted, the authorization server does not support PKCE". This is on Azure, but unlikely to change. It's a known issue, and the metadata doc cannot be manually changed AFAIK.

Azure bypass for this (& # 4) is at these commits on my fork. Not PR-ing (yet) as discussion is about whether this client should flex the rules to support one of the largest AS providers.

4. Azure use scope param, not resource param

Nothing in OAuth mandates use of RFC 8707's resource params. Azure v2 endpoints do not accept resource params (They don't silently drop as this PR suspected all AS would, but rather throw error “AADSTS901002: The ‘resource’ request parameter is not supported.). MCP does mandate RFC 8707 - "MCP clients MUST implement Resource Indicators".

Azure v2 uses scopes instead. If anyone knows more about this would love some pointers, but AFAIK Azure v1 introduces resources, RFC 8707 is based of Azure's pattern, then Azure bailed on them in favour of scopes. What.

An example of how to remove resource is here (no Azure conditionals, just me confirming that removing them does fix the flow) - these commits on my fork.

Summary

Azure AS does not advertise RFC 8414's code_challenge_methods_supported in metadata properly, or support RFC 8707's resource params (which MCP spec mandates). This means, if RFC 8414 and MCP spec is strictly followed, Azure AD cannot be used as the AS for MCP servers. They are a large AS provider and these issues have been there a long time, so i suspect clients typically just support Azure's quirks with bypasses. Should MCP inspector add bypasses for these issues for compatibility with Azure, based on assumption that's what many other clients will do?

Activity

  1. changed the title [-]Discussion - Support Azure Auth Server[/-] [+]Auth Discussion - Support Azure Auth Server[/+] on Aug 6, 2025
  2. added
    bugSomething isn't working
    authIssues and PRs related to authorization
    and removed
    bugSomething isn't working
    on Aug 11, 2025
  3. cliffhall commented on Aug 11, 2025

    @cliffhall
    Member

    Should MCP inspector add bypasses for these issues for compatibility with Azure, based on assumption that's what many other clients will do?

    If I understand correctly, the actual bugs raised here are already being addressed, and the outstanding points are where Azure is out of spec.

    So... let the largest AS provider slide, rather than holding them to spec, encouraging others to also not implement to spec? Is that the suggestion?

  4. added
    spec complianceLabel for issues and PRs that are related to adding or fixing support for a specific spec feature.
    on Aug 11, 2025
  5. 2underscores commented on Aug 12, 2025

    @2underscores
    ContributorAuthor

    Sorry @cliffhall, I forgot to close this one. I realised it didn't belong in the inspector, but rather the underlying SDK . I have raised the issue for discussion (with an example implementation PR) over at modelcontextprotocol/typescript-sdk#862. If you wanted to move your comment there i can move my reply as well. All below can be disregarded in this context of the inspector, it shouldn't be supporting this if the SDK doesn't.

    But yes those two first bugs are being addressed, and yes to this is proposing to let Azure AS slide. For the reasons below, i think it is going to be a long time (and for resource param, maybe never) until AS is fully compliant with todays MCP spec, regardless of the SDK or MCP spec. I think with that (big) assumption, it becomes about how much, and what kinds, of leniency should the underlying SDK allow in the client. Without these changes, the SDK cannot be used with Azure acting as the AS. For a lot of enterprise UC, that means those clients just use different SDKs/forks rather than waiting for Azure to change. I think given the prevalence of Azure AS and the (imo) small size of the spec breaks, this is a case where the benefit in standardisation coming from increased SDK usage outweighs the encouragement of further spec breaks (but really no idea on that, that's one for people who know way more about this than me).

    I don't think Azure will fix these anytime soon because Issue # 3 is a OAuth RFC breach (i.e. AS metadata, not MCP issue) by Azure and has been there for many years. OAuth clients are already using this integration with PKCE, and i assume workarounds like these are already prevalent for this issue. # 4 is weird, it's an MCP spec breach because resource indicators are optional OAuth RFC that are mandatory part of MCP spec. Azure implements scope instead. You could either say they choose not to implement optional resource indicators (and breach MCP) or they implement it but mangle the resource param to scope param (OAuth RFC breach). Either way, the OAuth resource RFC was based on & standardised Azure's existing v1 API implementation of resource, but when Azure moved to v2 endpoints they changed to scope. As this move was an intentional one, i fear they may never add resource back in, regardless of MCP/OAuth spec.

  6. kamranayub commented on Oct 24, 2025

    @kamranayub

    Since this isn't yet supported in the SDK implementation, I'm using @2underscores's fork commits to workaround this. For convenience, I'm using patch-package to apply them automatically (as of 0.17.2):

    1. Add the following patch files to patches/ directory

    @modelcontextprotocol+inspector+0.17.2.patch

    diff --git a/node_modules/@modelcontextprotocol/inspector/client/dist/assets/index-Bl2jgoAl.js b/node_modules/@modelcontextprotocol/inspector/client/dist/assets/index-Bl2jgoAl.js
    index c245baf..900ed4d 100644
    --- a/node_modules/@modelcontextprotocol/inspector/client/dist/assets/index-Bl2jgoAl.js
    +++ b/node_modules/@modelcontextprotocol/inspector/client/dist/assets/index-Bl2jgoAl.js
    @@ -17082,7 +17082,7 @@ const oauthTransitions = {
           context.provider.saveServerMetadata(parsedMetadata);
           context.updateState({
             resourceMetadata,
    -        resource,
    +        resource: undefined, // TODO: This must be undefined for azure
             resourceMetadataError,
             authServerUrl,
             oauthMetadata: parsedMetadata,
    @@ -17118,6 +17118,13 @@ const oauthTransitions = {
         execute: async (context) => {
           const metadata = context.state.oauthMetadata;
           const clientInformation = context.state.oauthClientInfo;
    +
    +      // Azure supports PKCE, but it's not advertised in metadata
    +      if (metadata.issuer.includes("login.microsoftonline.com") && !metadata.code_challenge_methods_supported) {
    +        console.log("Detected Azure AD - adding PKCE support to metadata");
    +        metadata.code_challenge_methods_supported = ["S256"];
    +      }
    +
           const scope = await discoverScopes(
             context.serverUrl,
             context.state.resourceMetadata ?? void 0
    @@ -17130,7 +17137,7 @@ const oauthTransitions = {
               redirectUrl: context.provider.redirectUrl,
               scope,
               state: generateOAuthState(),
    -          resource: context.state.resource ?? void 0
    +          // resource: context.state.resource ?? void 0
             }
           );
           context.provider.saveCodeVerifier(codeVerifier);

    @modelcontextprotocol+inspector-client+0.17.2.patch

    diff --git a/node_modules/@modelcontextprotocol/inspector-client/dist/assets/index-Bl2jgoAl.js b/node_modules/@modelcontextprotocol/inspector-client/dist/assets/index-Bl2jgoAl.js
    index c245baf..900ed4d 100644
    --- a/node_modules/@modelcontextprotocol/inspector-client/dist/assets/index-Bl2jgoAl.js
    +++ b/node_modules/@modelcontextprotocol/inspector-client/dist/assets/index-Bl2jgoAl.js
    @@ -17082,7 +17082,7 @@ const oauthTransitions = {
           context.provider.saveServerMetadata(parsedMetadata);
           context.updateState({
             resourceMetadata,
    -        resource,
    +        resource: undefined, // TODO: This must be undefined for azure
             resourceMetadataError,
             authServerUrl,
             oauthMetadata: parsedMetadata,
    @@ -17118,6 +17118,13 @@ const oauthTransitions = {
         execute: async (context) => {
           const metadata = context.state.oauthMetadata;
           const clientInformation = context.state.oauthClientInfo;
    +
    +      // Azure supports PKCE, but it's not advertised in metadata
    +      if (metadata.issuer.includes("login.microsoftonline.com") && !metadata.code_challenge_methods_supported) {
    +        console.log("Detected Azure AD - adding PKCE support to metadata");
    +        metadata.code_challenge_methods_supported = ["S256"];
    +      }
    +
           const scope = await discoverScopes(
             context.serverUrl,
             context.state.resourceMetadata ?? void 0
    @@ -17130,7 +17137,7 @@ const oauthTransitions = {
               redirectUrl: context.provider.redirectUrl,
               scope,
               state: generateOAuthState(),
    -          resource: context.state.resource ?? void 0
    +          // resource: context.state.resource ?? void 0
             }
           );
           context.provider.saveCodeVerifier(codeVerifier);
    1. Run npm install patch-package --save-dev
    2. Run npx patch-package
    3. It will apply the patches
    4. Add "postinstall": "patch-package" script (as noted in patch-package README)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    authIssues and PRs related to authorizationspec complianceLabel for issues and PRs that are related to adding or fixing support for a specific spec feature.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions