Skip to content

About

Authenticate Figma MCP for ZCode (OAuth whitelist workaround)

Resources

Stars

10 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

zcode-figma-mcp

Authenticate the Figma MCP server for ZCode, despite ZCode not being on Figma's client whitelist.

The problem

ZCode connects to remote MCP servers over HTTP and runs the standard MCP OAuth flow (RFC 9700 / StreamableHTTPClientTransport). Figma's MCP server only allows a fixed list of client names, and "ZCode" isn't on it — so the out-of-the-box flow fails at client registration.

This script works around that by performing the OAuth flow under the client name Codex (which is whitelisted), capturing the resulting tokens, and injecting them into ZCode's encrypted credential store so ZCode can use them directly on subsequent connections.

What it does

  1. Registers a new OAuth client named Codex against the Figma MCP server.
  2. Opens a browser for you to authorize the request in Figma.
  3. Catches the localhost:3000/callback redirect and exchanges the authorization code for access + refresh tokens (PKCE).
  4. Encrypts the tokens with the same AES-256-GCM scheme ZCode uses for ~/.zcode/v2/credentials.json, and writes them under the Figma server's id.
  5. Backs up credentials.json first and verifies the round-trip after writing.

Prerequisites

  • Node.js ≥ 20

  • ZCode installed and run at least once, with the Figma MCP server declared in ~/.zcode/cli/config.json:

    {
      "mcp": {
        "servers": {
          "figma": { "url": "https://mcp.figma.com/mcp" }
        }
      }
    }

    ZCode must have attempted to connect to the server at least once so that a mcp:oauth:*:discovery_state entry exists in credentials.json — the script reads the server id from there.

Install

git clone <this repo> ~/projects/darkgenius/zcode-figma-mcp
cd ~/projects/darkgenius/zcode-figma-mcp
npm install

Usage

# Default flow — opens the browser, waits for you to authorize in Figma.
node figma-mcp-auth.mjs

# Verbose mode — prints decrypted values for debugging.
node figma-mcp-auth.mjs --verbose

# Custom MCP server URL (defaults to https://mcp.figma.com/mcp).
node figma-mcp-auth.mjs https://mcp.figma.com/mcp

After a successful run:

  1. Restart ZCode so it re-reads credentials.json.
  2. Verify in Settings → MCP that the figma server shows as connected and lists its tools (get_screenshot, get_design_context, use_figma, …).

Files written

Path Purpose
~/.zcode/v2/credentials.json The script adds/overwrites two keys here:
mcp:oauth:<server-id>:tokens
mcp:oauth:<server-id>:client_information
~/.zcode/v2/credentials.json.backup Copy of credentials.json from just before the write. Overwritten on every run.

No other files are touched.

How server-id is resolved

The <server-id> in the credential keys is not derived from the URL — ZCode assigns it during OAuth metadata discovery and stores it inside the encrypted discovery_state payload. The script:

  1. Scans all mcp:oauth:*:discovery_state keys in credentials.json.
  2. Decrypts each one and matches resourceMetadata.resource against the target MCP URL.
  3. Falls back to the single available entry if there's only one.

If ZCode has never attempted the flow, there's nothing to match, and the script will tell you to start ZCode once first.

How encryption works

ZCode wraps credential values as enc:v1:<iv>.<authTag>.<ciphertext>, where:

  • algorithm: aes-256-gcm
  • key: sha256(ZCODE_CREDENTIAL_SECRET || fallback)
  • fallback: zcode-credential-fallback:<platform>:<homedir>:<username>
  • iv: 12 random bytes, auth tag: 16 bytes, all base64url-encoded

Set the ZCODE_CREDENTIAL_SECRET environment variable to override the fallback (e.g. on a shared/CI machine).

Token expiry & re-auth

Access tokens expire (see the expiresAt / expires_in fields — roughly 90 days). When ZCode starts getting 401s from Figma, re-run the script and restart ZCode. The refresh token may extend the lifetime, but Figma eventually requires a fresh interactive authorization.

Troubleshooting

Safari can't connect to the server "localhost" after clicking Authorize. The local callback server must be reachable from your browser. The script binds to 0.0.0.0 (all interfaces) so both IPv4 (127.0.0.1) and IPv6 (::1) work — this is the classic macOS fix, since Safari resolves localhost to ::1. If you still hit this, make sure nothing else is squatting on port 3000:

lsof -i :3000

No mcp:oauth:*:discovery_state entries found. ZCode hasn't attempted the Figma OAuth flow yet. Open ZCode, ensure the server is configured, trigger a connection (it will fail at authorization — that's fine), then re-run this script.

Multiple MCP OAuth servers found … none matches. There are several remote OAuth MCP servers configured and none of their discovery payloads reference the Figma URL. Run with --verbose to inspect, or remove stale entries from credentials.json.

Verification failed / decrypt mismatch. The machine profile (platform, homedir, username) used for key derivation must match the one ZCode runs under. If you run ZCode under a different user, set ZCODE_CREDENTIAL_SECRET consistently for both.

About

Authenticate Figma MCP for ZCode (OAuth whitelist workaround)

Resources

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages