Desktop app DCR uses client_name "Claude Desktop (…)" which Figma's MCP register endpoint rejects with 403 — CLI works because it sends "Claude Code"

Open 💬 0 comments Opened Jul 6, 2026 by jonathanglasmeyer

Summary

The Figma remote MCP server (https://mcp.figma.com/mcp) allowlists OAuth Dynamic Client Registration by exact client_name. Figma's POST /v1/oauth/mcp/register returns 200 only for a known set of client names (Claude Code, Codex, …) and 403 Forbidden for everything else.

The Claude Desktop app (Managed MCP UI / Cowork connectors) registers with:

client_name: `Claude Desktop (${app.getVersion()})`   // e.g. "Claude Desktop (1.18286.0)"

which Figma rejects → the connection dies at initialize with the user-facing error:

HTTP 403 … Invalid OAuth error response: Unexpected token 'F', "Forbidden" is not valid JSON. Raw body: Forbidden
FAILED REQUEST HTTP https://mcp.figma.com/mcp → initialize

The Claude Code CLI connects fine to the same endpoint — because it registers as client_name: "Claude Code", which is on Figma's allowlist.

Reproduction (deterministic, no auth needed)

REG=https://api.figma.com/v1/oauth/mcp/register
body(){ echo "{\"client_name\":\"$1\",\"redirect_uris\":[\"http://127.0.0.1:33418/callback\"],\"grant_types\":[\"authorization_code\",\"refresh_token\"],\"response_types\":[\"code\"],\"token_endpoint_auth_method\":\"none\",\"scope\":\"mcp:connect\"}"; }
for n in "Claude Desktop (1.18286.0)" "Claude Desktop" "Claude Code" "Codex" "Cursor"; do
  printf '%-30s -> %s\n' "$n" "$(curl -s -o /dev/null -w '%{http_code}' -X POST $REG -H 'content-type: application/json' --data "$(body "$n")")"
done

Output:

Claude Desktop (1.18286.0)   -> 403
Claude Desktop               -> 403
Claude Code                  -> 200
Codex                        -> 200
Cursor                       -> 403

The client_name is the only variable — same redirect_uri, grant_types, scope, and token_endpoint_auth_method throughout. (client_id/client_secret returned by the 200 responses omitted here.)

Root cause

The clientMetadata getter in the desktop app's MCP OAuth provider hardcodes client_name: "Claude Desktop (<version>)". Figma's register endpoint is not a generic RFC 7591 DCR endpoint — it is name-allowlisted, and the desktop app's name isn't on the list.

This is distinct from the parser hypothesis in #59463: the WWW-Authenticate 401 is parsed fine (the OAuth flow starts and produces a valid authorization URL); the failure is one step later, at POST /register. The "Forbidden" is not valid JSON message is the desktop client choking on Figma's plaintext 403 body from the register call.

Impact

Figma MCP is completely unusable from the Claude Desktop app (Managed MCP + Cowork connector), while working from the Claude Code CLI against the identical endpoint. This blocks managed/enterprise rollout of the Figma connector to desktop users, who have no /mcp manual-auth fallback (cf. #59854).

Suggested fixes

  1. Send client_name: "Claude Code" (or another Figma-allowlisted name) from the desktop DCR path, for parity with the CLI that already works today. Simplest fix.
  2. Coordinate with Figma to allowlist the desktop client_name.
  3. Broader: honor a pre-configured clientId/clientSecret and skip DCR (dup of #26675) — the desktop "Bring your own client" UI already exposes both fields; wiring it to bypass DCR would sidestep this whole class of allowlist/DCR-less-server bugs.

Related

  • #59463 — same symptom (Figma "Failed to connect"), but root-caused to the WWW-Authenticate parser; this report shows the actual failure is the client_name allowlist at /register.
  • #59854 — Cowork DCR failure (GitHub connector), no manual-auth fallback in Cowork.
  • #26675 — support pre-configured OAuth client credentials without DCR.

Environment

  • Claude Desktop 1.18286.0, macOS 15 (Darwin 25.5.0)
  • Figma remote MCP https://mcp.figma.com/mcp, scope mcp:connect

View original on GitHub ↗