claude_design built-in MCP server always 404s: /v1/design/mcp uses login-OAT, not the designOauth token from /design login (v2.1.181)
Bug: built-in claude_design MCP server always fails with 404 — /v1/design/mcp is authenticated with the login-OAT (no user:design:* scopes) instead of the designOauth token created by /design login
Environment
- Claude Code: 2.1.181 (native install, linux-x64, commit
2b2bfc5e2472) - Node: v24.3.0
- Account: Claude Max (subscription OAuth login)
- Feature gate:
tengu_omelette_whisk = true→claude_designauto-registered (scope "dynamic"); envCLAUDE_CODE_ENABLE_DESIGN_MCPunset
Summary
The built-in first-party MCP server claude_design (https://api.anthropic.com/v1/design/mcp) never connects. /doctor reports:
claude_design: failed — Streamable HTTP error: Error POSTing to endpoint: 404 page not found
Running /design login succeeds and stores a valid, design-scoped token, but the connector still 404s on every relaunch. The login token the transport actually sends is the wrong one.
Steps to reproduce
- Claude Max account with the design feature enabled (so
claude_designis auto-injected as a dynamic first-party server). - Launch
claude→/doctor→ "1 MCP server not connected:claude_design… 404 page not found". - Run
/design login, authorize in browser, complete the paste-code flow. It reports success;~/.claude/.credentials.jsongains adesignOauthblock with scopesuser:design:read,user:design:write. - Relaunch
claude→/doctorstill showsclaude_designfailed with the same 404.
Root cause
/v1/design/is onFIRST_PARTY_MCP_PATH_PREFIXES, so the HTTP transport uses "login-OAT auto-attach" — it attaches the mainclaudeAiOauthaccess token.- The main login token does not carry
user:design:*scopes, and the main login flow does not request them (design scopes are a separate scope set). /design loginstores the design-scoped token in a separate top-leveldesignOauthcredential block, which the transport never reads for this server.- Net: the POST to
/v1/design/mcpgoes out with a token that lacks design scopes (effectively unauthenticated for this endpoint) → 404.
Evidence
1. Post-login MCP debug log (~/.cache/claude-cli-nodejs/<project>/mcp-logs-claude-design/*.jsonl), recorded after a successful /design login:
HTTP transport options: {"url":"https://api.anthropic.com/v1/design/mcp",
"headers":{"User-Agent":"claude-code/2.1.181 (sdk-cli)","Accept-Encoding":"identity"},
"hasAuthProvider":false,"timeoutMs":60000}
Testing basic HTTP connectivity to https://api.anthropic.com/v1/design/mcp
HTTP Connection failed after 192ms: Streamable HTTP error: Error POSTing to endpoint: 404 page not found (code: 404)
Note "hasAuthProvider":false — no auth provider was wired to the server.
2. Direct request with the designOauth access token (the one /design login created) → HTTP 200:
POST https://api.anthropic.com/v1/design/mcp (Authorization: Bearer <designOauth.accessToken>)
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18",
"capabilities":{"prompts":{},"tools":{"listChanged":true}},
"serverInfo":{"name":"Claude Design","version":"0.1.0"}}}
3. Direct request with the main claudeAiOauth access token (what the CLI auto-attaches) → HTTP 404 "page not found".
4. Main login token scopes (after /design login, unchanged): user:file_upload, user:inference, user:mcp_servers, user:profile, user:sessions:claude_code — no user:design:*.designOauth scopes: user:design:read, user:design:write.
5. The CLI binary ships a guard string acknowledging this exact inconsistency:
"A built-in first-party MCP server URL is not on the first-party allowlist
(FIRST_PARTY_MCP_PATH_PREFIXES / isFirstPartyAnthropicHost) — login-OAT
auto-attach and bare-name rendering would not fire. Update firstPartyBuiltins.ts
or authState.ts so they agree."
Expected behavior
For /v1/design/ first-party URLs the transport should attach the designOauth token (the credential with user:design:* scopes produced by /design login) — OR /design login should mint/refresh the login-OAT to include user:design:* so the existing login-OAT auto-attach succeeds. Today the two halves disagree, so the connector can never authenticate.
Impact
Persistent "1 setup issue: MCP" on every launch for Claude Max users who have the design feature flag on. /design login appears to succeed but never clears the failure, and there is no user-side configuration that makes the built-in connector authenticate.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Adding a data point from an older build where the feature flag appears to be OFF, which may help bound the regression:
claude_design/ design instruction is injected into the session, but neither/design loginnor/design-loginexist as slash commands in this build — i.e. the instruction ships ahead of the command/feature for this account.claude mcp add --transport http claude_design https://api.anthropic.com/v1/design/mcp) yields "Failed to connect" rather than a 404. So on this account the request never even reaches the authenticated-404 path described here — consistent with the main token lackinguser:design:*scopes and nodesignOauthblock existing (since/design loginisn't available to create one).Net: same root cause (no
user:design:*scopes wired into the transport), but it manifests as "Failed to connect" when the design feature flag //design logincommand isn't present, vs. the 404 seen on 2.1.181. Suggest the fix also cover the case where the injected instruction is gated separately from the command + connector provisioning, so users don't get told to run a command that doesn't exist.Filed #69965 before finding this; closing it as a duplicate in favor of this thread.
Confirming this is still present in 2.1.197 (native install, macOS, after
claude update), and adding two data points:1. Not limited to Max/Linux. I'm on a Team/Enterprise org account (
/loginmanaged key) with Claude Design enabled org-wide — claude.ai/design works normally in the browser with the same account. The MCP still fails, consistent with the root cause here (org entitlement is irrelevant when the transport sends the unscoped login-OAT).2. The failed auth renders a misleading fallback page. I added the server manually per the Help Center docs:
claude mcp listshows! Needs authentication. Attempting auth (claude mcp login claude-design, or/mcp→ authenticate) opens a browser page that renders the retired gdrive template instead of a Design consent screen:Same generic fallback described in #59953 / #60807 — a downstream symptom of the endpoint rejecting the unscoped token, but it sends users chasing Google Drive config for a Design bug, so worth fixing alongside the token routing.