>_ The Manifest

OAuth is usually where an otherwise clean MCP story gets messy. The server is ready. The tools are typed. The agent can call them. Then someone has to create an OAuth app, configure redirect URIs, copy a client ID, handle a client secret, paste scopes into the right place, and keep the configuration aligned across the identity provider, the Enterprise token store, and the plugin manifest.

That work is not hard because it is intellectually deep. It is hard because it is brittle. One wrong redirect URI, one missing scope, one stale secret, and the user sees a sign-in failure instead of an agent.

Dynamic client registration (DCR) removes the most error-prone part of that setup for MCP plugins. If your authorization server supports the right OAuth metadata and registration endpoints, Microsoft 365 can register the OAuth client dynamically once you wire in a DCR authentication configuration.

No pre-created client ID. No manually copied secret. No hand-created OAuth app just to bootstrap auth.

What DCR Does

Dynamic client registration lets a client register itself with an authorization server at setup time. Instead of you creating an OAuth client by hand, the platform follows the server’s metadata, uses a DCR auth configuration you register up front, calls the registration endpoint, receives client credentials, and uses that configuration reference when it needs tokens for the MCP server.

For MCP plugins in Microsoft 365 Copilot, DCR means:

  1. Your MCP server advertises the authorization server that protects it.
  2. The authorization server advertises a registration endpoint.
  3. You register a Dynamic client registration auth configuration in Developer Portal.
  4. Microsoft 365 uses that configuration to negotiate client credentials at runtime.
  5. Your MCP connector references that configuration by referenceId.

In the MCP connector configuration, DCR uses a dedicated authorization type:

{
  "remoteMcpServer": {
    "mcpServerUrl": "https://zava-helpdesk-mcp.azurewebsites.net/mcp",
    "authorization": {
      "type": "DynamicClientRegistration",
      "referenceId": "my-dcr-config"
    }
  }
}

With static OAuth, the reference points to an OAuth configuration backed by a client you created manually. With DCR, it points to a Dynamic client registration configuration that Microsoft 365 uses to negotiate client credentials with your authorization server.

📝 Note

DCR is supported for MCP plugins. It is not supported for API plugins. API plugins still use static OAuth registration, Entra SSO, API key, or anonymous auth depending on the scenario.

Static OAuth vs DCR

Static OAuth and DCR both end with Copilot obtaining bearer tokens for the signed-in user. The user experience is similar. The developer experience is not.

ConcernStatic OAuthDynamic client registration
Client creationYou create an OAuth app manuallyMicrosoft 365 registers the client through the DCR flow
Client ID and secretYou copy values into setupGenerated through registration
Redirect URI setupYou configure it manuallyRegistration handles client details
Developer PortalRegister an OAuth configRegister a Dynamic client registration config
Manifest referencePoints to an OAuth configPoints to a DCR config
Plugin supportMCP and API pluginsMCP plugins only

Static OAuth is still the right choice when your identity provider does not support DCR or your organization requires pre-approved OAuth clients. DCR is the right choice when your MCP server and authorization server are built for automated onboarding.

The Required Metadata

DCR only works if the protected resource and authorization server describe themselves correctly.

Your MCP server needs to expose OAuth 2.0 protected resource metadata at:

/.well-known/oauth-protected-resource

That metadata identifies the authorization server protecting the MCP server. Then the authorization server needs to expose its own metadata at:

/.well-known/oauth-authorization-server

That authorization-server metadata must include a registration_endpoint and support dynamic client registration.

The official Microsoft docs call out three important constraints:

  • The authorization server must support RFC 7591 dynamic client registration.
  • The MCP server must expose protected resource metadata as described by RFC 9728.
  • The authorization server metadata follows RFC 8414.

There is also a current platform constraint: DCR without a client secret is not supported yet. The authorization server must issue a client secret during registration. PKCE is enabled by default for DCR.

⚠️ Warning

Do not assume “supports OAuth” means “supports DCR.” Your provider needs a registration endpoint that issues client credentials dynamically. If that endpoint does not exist, use static OAuth instead.

What the Registration Flow Looks Like

The happy path is intentionally boring:

  1. Create the MCP connector for your server.
  2. Enter the MCP server URL.
  3. Register a Dynamic client registration auth configuration in Developer Portal.
  4. Set the MCP server authorization type to DynamicClientRegistration.
  5. Reference the DCR configuration ID in the connector.

If the MCP server and authorization server expose the required metadata, Microsoft 365 handles the rest. It fetches the registration details, registers the OAuth client dynamically, and uses the DCR configuration reference whenever it needs to obtain or refresh tokens.

That last part matters. Your source code does not need to carry a client secret. Your connector only carries a referenceId. The actual client bootstrap happens through the DCR flow.

A Zava Insurance Example

Zava Insurance has an internal helpdesk MCP server. The server exposes tools like:

  • createTicket
  • getTicketStatus
  • escalateTicket

The old static OAuth setup looked like this:

  1. Register an OAuth app for the helpdesk MCP server.
  2. Add https://teams.microsoft.com/api/platform/v1.0/oAuthRedirect as the redirect URI.
  3. Generate a client secret.
  4. Register the OAuth configuration and wire its reference into the connector.
  5. Configure scopes.
  6. Validate and publish the app package.

That works, but it makes every new environment a small ceremony. Dev, test, staging, production, partner demo: each one needs the right app registration and secret handling.

With DCR, the helpdesk authorization server exposes the metadata and registration endpoint. The developer creates the connector, enters the MCP server URL, registers a DCR config in Developer Portal, and references that config from the connector. Microsoft 365 then registers the OAuth client dynamically when it needs to authenticate to the MCP server.

The user experience stays the same:

HR Onboarding Buddy

Create a ticket for my broken badge at Building 25.

I need you to sign in to Helpdesk before I can create the ticket.

After sign-in, Copilot uses the auth config to obtain and refresh tokens on behalf of the user, then calls the MCP server with the right bearer token. The difference is not what the employee sees. The difference is how much auth plumbing the developer avoided.

What DCR Does Not Solve

DCR automates client registration. It does not remove the need for auth design.

You still need to decide:

  • which scopes the MCP server requires,
  • how users consent,
  • how tokens are validated,
  • how refresh and expiry work,
  • which tenants or organizations can use the integration,
  • and what the server does when the user lacks permission.

You also need to build the authorization server correctly. If the registration endpoint is too permissive, you have created a security problem. If it is too strict or returns incomplete metadata, onboarding fails.

Think of DCR as a safer bootstrap, not as a substitute for identity architecture.

DCR, Static OAuth, and Entra SSO

For MCP plugins, you now have three strong auth choices:

Auth modelUse it when
Entra SSOYour MCP server is protected by Microsoft Entra ID and you want low-friction same-tenant sign-in.
Static OAuthYour OAuth provider does not support DCR, or your org requires manually approved OAuth clients.
Dynamic client registrationYour MCP server’s authorization server supports DCR and you want automated client onboarding.

My default recommendation:

  • Use Entra SSO for first-party or same-tenant enterprise services.
  • Use DCR for MCP servers that need OAuth and are designed for multi-environment or multi-tenant onboarding.
  • Use static OAuth when the provider requires manual app registration, like many third-party services still do.

All three approaches still end in bearer tokens for the signed-in user, but the configuration shape is not identical. Static OAuth and Entra SSO use an OAuth config reference, while DCR uses a dedicated DynamicClientRegistration reference for the MCP connector.

How DCR Pairs with Dynamic Tool Discovery

DCR becomes even more interesting when paired with dynamic tool discovery. Dynamic discovery lets the agent resolve the server’s current tools at runtime. DCR lets the agent register the OAuth client without manual setup.

Together, they make the MCP plugin feel much more like a live service integration:

{
  "remoteMcpServer": {
    "mcpServerUrl": "https://zava-helpdesk-mcp.azurewebsites.net/mcp",
    "authorization": {
      "type": "DynamicClientRegistration",
      "referenceId": "my-dcr-config"
    }
  }
}

The server owns the tool surface. The authorization server owns client registration. The agent package points at both through durable references.

That is the shape MCP has been aiming for: portable tools, runtime discovery, and authentication that does not require every developer to become a part-time portal operator.

Common Gotchas

Your provider supports OAuth, but not DCR. DCR needs a dynamic registration endpoint. If the provider does not expose one, Microsoft 365 cannot invent it.

The authorization server does not issue a client secret. Current Copilot support requires DCR with a client secret. Secretless DCR is not supported yet.

Metadata endpoints are missing or incomplete. Microsoft 365 needs the MCP protected resource metadata and authorization server metadata to find the registration endpoint and configure the auth flow.

You created the wrong auth registration. DCR needs a Dynamic client registration config in Developer Portal, not a standard OAuth config.

You are building an API plugin. DCR is MCP-only. API plugins should use the auth options supported for OpenAPI-based plugins.

The Value You Just Unlocked

DCR removes the most fragile setup step from OAuth-backed MCP plugins:

  • No manual OAuth app bootstrap: The client is registered dynamically.
  • No copied client secret in project setup: Credentials are created through the registration flow instead of manual app bootstrap.
  • Cleaner multi-environment onboarding: Each environment can register the right client from metadata.
  • Purpose-built runtime auth model: The connector points to a dedicated DCR configuration instead of a manually created OAuth app.
  • Better fit for MCP as a platform: A portable server can describe its tools and its auth requirements without forcing a hand-built OAuth client per environment.

OAuth is still OAuth. You still need the right scopes, consent, token validation, and governance. But with DCR, the first mile of connecting an MCP server to a declarative agent finally feels like the rest of the protocol: discoverable, automatable, and built for scale.

Resources

Have questions or want to share what you're building? Connect with me on LinkedIn or check out more on The Manifest.