Repository navigation
Closed
Labels
enhancementRequest for a new feature that's not currently supportedRequest for a new feature that's not currently supported
Description
Support Azure for Enterprise Adoption
- With MCP SDK, Azure AD cannot be used as the Authorisation Server (AS) as Azure:
- Does not advertise PKCE in AS metadata
- Uses
scopeparam instead of RFC 8707'sresourceparam
- MCP SDK should support Azure as an AS, as Azure is extremely commonly used, particularly in enterprise.
PKCE Not Advertised
- MCP spec mandates implementation of RFC 8414 - OAuth 2.0 Authorization Server Metadata, and Azure supports the metadata endpoint
- The
code_challenge_methods_supportedfield lists the PKCE methods supported by the AS. According to RFC8414 "If omitted, the authorization server does not support PKCE." - Azure AS omits
code_challenge_methods_supported, but does support PKCE with methodS256 - This one is on Azure and It's a known issue for years. To support Azure, a bypass is needed that ignores the field omission and assumes PKCE is supported, specifically for Azure.
- Bug already raised - Azure OIDC discovery metadata missing code_challenge_methods_supported breaks S256 PKCE validation #832
- According to RFC 8414, this is actually an Azure bug
scope instead of resource
- RFC 8707 - Resource Indicators for OAuth 2.0 is an optional extension to OAuth, that MCP has as mandatory.
- It introduces the
resourceparam that indicates which protected resource the client is requesting access to.- This is included in
/authorizeand/tokenendpoints, and in the JWT'saudclaim.
- This is included in
- Azure v2 endpoints do not implement RFC 8707. They implement a very similar
scopeparameter in place of theresourceparamscopeis a superset, and includes both the "resource" access is being requested to, and the actions ("scopes") to perform on it.
- Azure AS will fail if
resourceis provided (i.e. It does not ignore/silently drop it) - To support Azure, conditional logic is needed to provide
scopein place ofresourcewith the required minor change to value.
Other Related Azure Issues
- Azure AS metadata endpoint is at
/.well-known/openid-configurationrather than/.well-known/oauth-authorization-serverintroduced in RFC 8414- This is somewhat common and mentioned in the RFC
- This SDK added proper support for this with feat: support oidc discovery in client sdk #652
- Azure doesn't support RFC 7591 - OAuth 2.0 Dynamic Client Registration (DCR), however this is only recommended (i.e. not mandated) by spec and this SDK supports static client ID.
This commit has one implementation of the compatibility changes needed to support Azure as AS.
Reacted by Kamran Ayub
Metadata
Metadata
Assignees
Labels
enhancementRequest for a new feature that's not currently supportedRequest for a new feature that's not currently supported
Activity
[-]Workarounds to Support Microsoft Azure as Auth Server[/-][+]Workarounds Required to Support Microsoft Azure as Auth Server[/+]pcarleton commentedon Aug 12, 2025
One solution in the SDK's is to make auth more pluggable, so it's easy to override the behaviors needed to handle these quirks without the SDK having to consider every single one. there's this PR in progress to work on that: #485
that means if a developer has a client they want to work with an AS that is doing something unusual, they can easily swap out the auth impl to make it easier.
the downside of that approach, which becomes clear with inspector, is that if you have a client that's expected to be generic and connect to everything, you need the "every oddball AS special case" implementation.
I'd prefer we not litter the SDK with a bunch of vendor specific carve-outs, and also don't want to litter Inspector with it. one compromise would be to have an "advanced" flow in inspector where you can more easily directly manipulate all the params/headers.
on the particular issue regarding resource vs. scope, there's a conversation about scope here: modelcontextprotocol/modelcontextprotocol#835 i think we should probably just solve this one that way.
going to close this one for now
2underscores commentedon Aug 12, 2025
Yeah very understandable, it's pretty icky code. We'll continue maintaining our fork with this for now, but hoping for something in the future to standardise this.
Generic client fits our use case sadly, and IMO is what a lot of MCP clients will do (like the LSP analogy for editors and languages, MCP enables that interoperability and clients will connect to a variety of MCP servers).
For future reference on our use case (i think it's representative of a lot of enterprise MCP usage) - some of our MCPs use Azure as both the AS and IdP for authentication, and some use a vendor's AS, with IdP federation to our Azure (where the vendors AS is spec compliant, this SDK works for us).
IMO Azure (and maybe 0-3 others) are large enough, that where spec break is minor, carve outs for them specifically may improve standardisation by making a single SDK (this one) more broadly adopted rather than forcing forks if the big AS don't change. For reasons here, I don't think Azure is going to change anytime soon on these ones.
Thanks very much for reviewing and redirecting to the WIP links!
kamranayub commentedon Oct 24, 2025
I'm going to chime in with a +1 to @2underscores use case. I'm actually building a course focused on enterprise use cases, and using Entra ID for passwordless identities. It's slick -- except for this wrinkle with Inspector. Throughout the entire course, I can teach people how it all works using the Inspector as a client... except when it comes to this. So I'll probably call out this as an issue and use Jeremy's fork for now. I don't know how the team wants to handle this formally, but I think it makes sense that Inspector should work with a major auth provider like Entra IMHO (or maybe just offer a way to install an auth plugin to make it work, which it sounds like you're thinking about).
I mentioned this in another comment (modelcontextprotocol/csharp-sdk#730 (comment)), but there does seem to be a workaround that is compatible with MCP Inspector. It requires a lot of heavy lifting in Azure API Management: https://den.dev/blog/remote-mcp-server/#prerequisites
kamranayub commentedon Oct 26, 2025
Just a note to add to this: Claude's beta Remote MCP support ALSO has these compatibility issues 😞 Obviously we can't work around it manually or patch it, so I opened a support ticket on it, but I fear this is going to be a wider problem with any MCP client + Entra ID (vanilla). The only workaround I see (but haven't tested) is to basically front it with APIM and custom logic. FWIW, I think the Entra team should be the ones to fix this all on their end, it shouldn't be up to MCP clients/hosts/vendors to workaround but that's probably pie-in-the-sky thinking. VS Code has workarounds for all this and so everything "just works" there.
kamranayub commentedon Dec 19, 2025
Revisiting this after a couple months now, and after the latest spec drop.
AFAIK, the "state of the state" on Azure as an AS is:
scope(SEP-835: Update authorization spec with default scopes definition modelcontextprotocol#835)As far as the SDK goes, that means that static client registration should work without any workarounds.
As far as the Inspector goes, I haven't tested 0.18.0 yet, but I am not positive the same changes have been reflected there. I still see
resourcebeing included and I don't see the same S256 handling as the SDK. I have to do some further testing but if that's the case, IMHO the Inspector should be updated to reflect the spec updates.kamranayub commentedon Dec 19, 2025
Alright, today I took a look more at how this is working with MCP Inspector 0.18.0 and C# SDK.
SEP-835: Scope in WWW-Authenticate
First, the C# SDK hasn't yet implemented the
scopeparameter support for WWW-Authenticate (modelcontextprotocol/csharp-sdk#907).However, I have a custom patched
McpAuthenticationHandlerthat adds support for it:Despite this, the MCP inspector still appends
resourceeven thoughscopeis explicitly provided in the WWW-Authenticate.SEP-835
When implementing authorization flows, MCP clients SHOULD follow the principle of least privilege by requesting only the scopes necessary for their intended operations. During the initial authorization handshake, MCP clients SHOULD follow this priority order for scope selection:
Since
resourceis required for PRM, the Inspector should likely be updated to not passresourceifscopeis provided:https://github.com/modelcontextprotocol/inspector/blame/1977e2a597cd95bb8df6efef8bedee60876a289b/client/src/lib/oauth-state-machine.ts#L136C21-L136C56
PKCE Handling
This is now handled correctly, I don't receive an error in the flow anymore.
Client Registration (CIMD)
As far as DCR is concerned, Entra ID won't/doesn't support that, but it also doesn't seem to support the new CIMD either, so static pre-registration is the only option still there out-of-the-box.