import { Callout } from '@/components/ui/callout';
If you have been wiring Claude Code to MCP servers lately, you may have hit one of these:
sdk auth failed: incompatible auth server: does not support dynamic client registration
Or the terser version:
authorization failed
The first time I saw it, I assumed I had misconfigured something. After a few rounds of digging, I realized the error is almost always about a mismatch between Claude Code's evolving authentication flow and what the MCP server on the other end actually supports. Here is how I now think about this error, and the steps that reliably resolve it.
What the Error Is Really Saying
Claude Code now uses OAuth 2.1 with Dynamic Client Registration (RFC 7591) when it talks to MCP servers. Dynamic Client Registration lets the MCP client (Claude Code) introduce itself to the server at runtime — no pre-shared client ID, no manual setup. The trade-off is obvious: the MCP server has to actually implement that registration endpoint.
Read the error message again with this in mind:
incompatible auth server: does not support dynamic client registration
That is Claude Code telling you "the server you are pointing me at does not implement runtime registration." Either the server is on an older spec, or it deliberately uses pre-shared credentials.
The Three Common Triggers
After dealing with this across several projects, the failures cluster into three categories.
Trigger 1: Custom or Open-Source MCP Server Does Not Support Dynamic Registration
This is the most common case for in-house or community MCP servers. If /.well-known/oauth-authorization-server does not include a registration_endpoint field — or returns 404 when Claude Code tries to POST to it — Claude Code will refuse to continue.
Trigger 2: SaaS Connector Uses a Custom OAuth Flow
Some SaaS providers ship MCP connectors built around pre-issued client IDs. Slack and Notion's official connectors, for example, are designed to be installed through Cowork rather than wired up by hand in Claude Code. In those cases the error is not a bug; it is a sign you are using the wrong client surface.
Trigger 3: TLS Interception Breaks the Certificate Chain
Inside corporate networks, products like ZScaler or Netskope intercept TLS traffic. If NODE_EXTRA_CA_CERTS is not set, Claude Code cannot validate the auth server's certificate, and the failure surfaces as an authorization error. The console usually has more detail, so always check it before assuming OAuth is the problem.
A Diagnostic Flow You Can Run Top-Down
When the error fires, work through these in order.
Step 1: Run /doctor
Inside a Claude Code session, type /doctor. It surfaces the authentication, network, and MCP connection state in one place. Quite often it pinpoints the issue immediately.
Step 2: Inspect the Well-Known Metadata
curl https://your-mcp-server.example.com/.well-known/oauth-authorization-server | jq .If registration_endpoint is missing from the response, you have hit Trigger 1.
Step 3: Probe the Registration Endpoint Directly
curl -X POST https://your-mcp-server.example.com/oauth/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "Claude Code Test",
"redirect_uris": ["http://localhost:54321/callback"]
}'A 2xx response means dynamic registration works. Anything else means the endpoint is broken or absent.
Step 4: Add Dynamic Registration to Your MCP Server
If the server is yours, the latest @modelcontextprotocol/sdk for TypeScript has native support. Enable it like this:
import { McpServer } from "@modelcontextprotocol/sdk/server";
const server = new McpServer({
name: "my-mcp-server",
version: "1.0.0",
oauth: {
enabled: true,
dynamicRegistration: true,
registrationEndpoint: "/oauth/register",
authorizationEndpoint: "/oauth/authorize",
tokenEndpoint: "/oauth/token",
},
});Make sure registration_endpoint is also exposed in the well-known document. Once both pieces are in place, Claude Code's complaint disappears.
Step 5: When You Cannot Patch the Server
If the server is a SaaS that you do not control, your realistic options are:
- Use the official connector through Cowork instead of Claude Code
- Use Claude in Chrome to interact with the service through the web UI rather than MCP
- Wrap the API yourself and call it directly from Claude API code
Not every SaaS is a clean fit for Claude Code's MCP flow yet. Check each provider's current docs to see which client surface they support.
Corporate Network Pitfalls
Inside corporate environments, set the CA bundle explicitly:
export NODE_EXTRA_CA_CERTS=/path/to/your/corporate-ca-bundle.pemYour IT team can supply the bundle path. Restart Claude Code after setting it, and TLS handshakes start succeeding.
Designing for Fewer Errors, Not Just Better Recovery
For the services I run myself, I treat "users never see this error" as the design goal:
- Test both
/.well-known/oauth-authorization-serverand the registration endpoint before any deployment - Validate Claude Code upgrades in a staging environment before pushing to production
- Keep an operational runbook that includes a
/doctoroutput template, so on-call rotations move fast when the error does appear
Recovery procedures matter, but engineering away the conditions that cause the error matters more.
Next Step
The next time you see this error, start with /doctor and the well-known metadata. Those two steps cover ninety percent of the cases. The remaining ten percent are usually waiting on a SaaS to ship support, and switching client surfaces is the quickest unblock.