PropelAuth Logo
Back to Blog

MCP Default Resource: Connecting OAuth 2.0-Only Clients

MCP Default Resource: Connecting OAuth 2.0-Only Clients

Some MCP clients don't send the resource parameter that the MCP authorization spec requires. Microsoft Copilot Studio is the big one right now: its MCP connector runs a standard OAuth 2.0 authorization code flow, and resource isn't part of it. A spec-compliant authorization server has to reject that request, so users trying to connect a Copilot Studio agent to your MCP server get an error instead of a login screen.

We've added a Default Resource setting to PropelAuth's MCP Authentication to fix this. Turn it on, and any authorize request that arrives without a resource parameter is treated as if it had asked for the resource you configure. Copilot Studio, and any other OAuth 2.0-only client, gets a valid, audience-bound access token. Nothing else about your OAuth 2.1 flow changes.

Image in article: MCP Default Resource: Connecting OAuth 2.0-Only Clients

How Default Resource Works

The feature is deliberately small:

  • Clients that do send resource are unaffected. Their value is used, same as before.
  • Clients that don't send it get a token bound to your default resource instead of an error.
  • Tokens are still audience-bound. You aren't issuing tokens that work anywhere. You're issuing tokens for one specific, known MCP server.
  • Everything else in the OAuth 2.1 flow stays the same. PKCE and scope consent all work exactly as they did.

It's off by default, and most setups should leave it that way. Which brings us to the important question.

When Should You Turn On Default Resource?

Turn it on if:

  • You have a single MCP server behind your PropelAuth environment, and
  • You need to support a client that doesn't send resource, like Copilot Studio today, or the generic OAuth 2.0 integrations you'll increasingly see as MCP spreads into low-code tools and enterprise platforms

Leave it off if:

  • All of your MCP clients already follow the MCP spec (the first-party clients you're most likely to see, like Claude, ChatGPT, and Cursor, already send resource), or
  • You run more than one MCP server behind the same PropelAuth environment

That second case is worth spelling out. If you have https://mcp.example.com and https://analytics-mcp.example.com, a client that doesn't say which one it wants is truly ambiguous. A default would silently pick one, and a user trying to connect to the other would get a token that doesn't work there. In that situation the failing request is the right outcome, because it's telling you the client needs to be fixed, not the server.

The rule of thumb: Default Resource is a compatibility shim for the "only one possible answer" case. It's not a way to opt out of resource indicators.

How to Enable Default Resource in PropelAuth

  1. Open the MCP section of the PropelAuth Dashboard.
  2. Scroll down to Default Resource and turn it on.
  3. Enter the canonical URL of your MCP server, exactly as your server expects to see it in the token's audience.
  4. Save.

If you haven't already, add the client's redirect URI under Allowed MCP Clients, just as you would for any other MCP client.

From there, a Copilot Studio agent (or any other OAuth 2.0-only client) can run a normal authorization code flow against your PropelAuth authorize and token endpoints and come back with a valid token. Your MCP server validates it through the Introspection API like every other token. Nothing changes on that side.

Full documentation is available here.

Background: OAuth 2.0 vs. OAuth 2.1 for MCP

If you've looked into this before, you've probably seen Copilot Studio described as "OAuth 2.0 only" and the MCP spec described as "OAuth 2.1," and concluded the two are simply incompatible. That framing hides what's actually going on.

OAuth 2.1 isn't a new protocol. It's OAuth 2.0 with the sharp edges filed off:

  • PKCE is required for every client (most OAuth 2.0 clients already do this)
  • The implicit grant and password grant are gone
  • Access tokens go in the Authorization header, never in a URL query string

Any client written in the last few years almost certainly does all of that already. The real gap is the set of additional specs that the MCP authorization spec layers on top of OAuth 2.1:

What MCP requiresSpecWhat it's for
Protected Resource MetadataRFC 9728Lets the client discover which authorization server protects your MCP server
Authorization Server MetadataRFC 8414Lets the client discover your authorize, token, and registration endpoints
Dynamic Client RegistrationRFC 7591Lets the client register itself without you creating credentials by hand
Resource IndicatorsRFC 8707Tells the authorization server which MCP server the token is for

A generic "OAuth 2.0 connector" like the one in Copilot Studio has none of these built in. You paste in an authorize URL, a token URL, and a client ID, and it runs a plain authorization code flow. That gets you surprisingly far. The one piece it can't get past is the last row.

What Is the OAuth resource Parameter, and Why Does MCP Require It?

RFC 8707 adds a resource parameter to the authorization and token requests. The client uses it to say "I'm requesting this token to use with https://mcp.example.com," and the authorization server binds the token's audience to that value.

The MCP spec makes this mandatory. Clients must send resource on both the authorize and token requests, and it must be the canonical URL of the MCP server.

The reason is a class of attack usually called the confused deputy or token passthrough problem. Without an audience, a token minted for MCP Server A is just a bearer token. If it ends up in the hands of MCP Server B, nothing stops B from using it against A. With resource, the token is stamped for A, and B has no business accepting it. As users connect AI agents to more and more services, that's exactly the kind of protection you want on by default.

So when a spec-compliant authorization server receives an authorize request with no resource, the correct behavior is to reject it, typically with an invalid_target error. Microsoft has confirmed on the Power Platform community forums that the Copilot Studio connector doesn't support OAuth 2.1 yet, with no public timeline, and the suggested workarounds were a translating proxy or an "OAuth 2.0 compatibility mode" on the server. A proxy is a whole new thing to build and secure, and compatibility mode usually means turning off the protections you wanted in the first place. Default Resource is the middle path: the authorization server fills in the one missing value, and the token still ends up bound to a specific audience.

The Bigger Picture: Meeting MCP Clients Where They Are

MCP is moving fast, and the spec is ahead of a lot of the ecosystem. The first wave of MCP clients was built alongside the authorization spec and follows it closely. The second wave looks different: enterprise platforms, low-code builders, and internal tools bolting MCP onto OAuth integrations they already had. Those clients will catch up eventually, but "wait for the vendor" isn't an answer your customers will accept in the meantime.

Our goal with PropelAuth's MCP Authentication is to give you the secure, spec-compliant path by default, plus a narrow, well-understood escape hatch for the cases where a client can't meet you there yet. Default Resource is that escape hatch. Turn it on when you need it, leave it off when you don't, and either way your users get to connect the tools they actually want to use.