Skip to main content
Glama
claude-design-mcp

claude-design-mcp

by e-brokenc0de

claude-design-mcp

An MCP server that drives Claude Design — Anthropic's design-system generator — from agentic coding CLIs (Claude Code, Cursor, etc.). It exposes semantic tools so you can create_design_system, generate, iterate, list_files, read_file, and export without touching a browser.

WARNING

Unofficial — not affiliated with or endorsed by Anthropic. Claude Design has no public API, so this drives a real Chrome and calls claude.ai's internal endpoints. Expect it to break when the site changes. Point it only at your own account, stay within Anthropic's terms, and use it at your own risk. Your logged-in session is sensitive — see SECURITY.md.

Status: working. ~30 tools implemented (see the table below). Most call Claude Design's internal OmeletteService Connect-RPC API as JSON (via in-page fetch); generate/iterate/get_status drive the chat UI (the Chat RPC payload is opaque).

Tools

Create & generate

Tool

Purpose

create_design_system({ name, brief, sources? })

Create a design system. Returns { projectId, url }.

create_design_project({ name, brief?, designSystemIds?, designComponents? })

Create a design PROJECT (screens/app), optionally binding design systems.

generate({ projectId })

Start generation from the stored brief. Returns once started (~5 min total).

get_status({ projectId })

Poll: generating | ready | error | draft.

iterate({ projectId, prompt })

Send a chat message. Non-blocking — returns once started; poll get_status.

send_message({ projectId, prompt, conversationId? })

Revise/prompt; optionally target a specific conversation.

Design-system bindings

Tool

Purpose

attach_design_system({ projectId, designSystemId })

Bind a (published) design system to a project.

detach_design_system({ projectId, designSystemId })

Unbind a design system.

list_attached_design_systems({ projectId })

List bound systems (with names).

refresh_design_system({ projectId, designSystemId? })

Pull the latest version of bound system(s).

Conversations

Tool

Purpose

list_conversations({ projectId })

List chats: { chatId, title, turns, active }.

new_conversation({ projectId })

Start a fresh conversation.

Files

Tool

Purpose

list_files({ projectId })

List files (tokens/*.css, components/*, SKILL.md, …).

read_file({ projectId, path })

Read a single file (utf8).

export({ projectId, destDir })

Dump all files to destDir, byte-faithful.

mint_handoff({ projectId, includeChats?, instructions?, destDir? })

Primary handoff. Official capability URL + ready Claude Code command; with destDir, downloads + extracts the bundle and returns projectDir (feed to scaffold:ui).

export_handoff({ projectId, destDir })

Deprecated — local bundle (project/ + chats/ + README). Prefer mint_handoff.

search_files({ projectId, pattern })

Grep files → { path, line, context }.

write_file / edit_file / delete_file

Direct file edits without chat.

Publish, listing & management

Tool

Purpose

publish({ projectId }) / set_default({ projectId })

Publish / set default design system.

list_design_systems() / list_projects()

List design systems / all projects.

rename_project / delete_project / duplicate_project / remix_project / set_favorite

Project housekeeping.

get_usage()

Account usage/quota (5-hour & 7-day).

create_claude_code_session({ projectId, instructions? })

Open the project as a Claude Code session → { sessionUrl }.

Related MCP server: claudecode-mcp

Setup

Prerequisites: Node ≥ 20, pnpm, and a desktop Google Chrome installed. A claude.ai account with Claude Design access.

claude.ai is behind Cloudflare, which blocks Playwright's bundled Chromium (automation fingerprint) with an endless "Just a moment…" loop. The server sidesteps this by attaching to a real Chrome over the Chrome DevTools Protocol (CDP) — a normally-launched Chrome passes Cloudflare cleanly.

git clone https://github.com/e-brokenc0de/claude-design-mcp.git
cd claude-design-mcp

pnpm install
pnpm exec playwright install chromium   # only the Node bindings are needed

# Start the real Chrome (dedicated debug profile in .auth/cdp-chrome) and log
# into claude.ai once. The window stays open; the session persists.
pnpm run chrome:cdp

pnpm run build

Dev-only: pnpm run recon:capture tees Claude Design's network/RPC traffic into ./recon/ so you can re-map the internal API in src/selectors.ts if the site changes. Not needed for normal use. Captures can contain cookies — they're gitignored; never commit them.

The MCP server attaches to the same Chrome (port 9222 by default). If Chrome isn't running, the server auto-launches it; if it's not logged in, tools return NOT_AUTHED — run pnpm run chrome:cdp and log in.

CLI

Every tool is also a terminal command via claude-design. The CLI is a thin MCP client — it spawns the same server and forwards your arguments, so the commands, schemas, and output are exactly the server's (add a tool to the server and it shows up here automatically). Good for automation/CI, quick debugging, and one-off ops without an agent in the loop.

claude-design --help                  # list every command (discovered from the server)
claude-design <command> --help        # flags for one command
claude-design list-projects --json    # data tools print JSON → pipe to jq
claude-design create-design-system --name "Acme" --brief "Calm, editorial, dark-first"
claude-design get-status --project-id <id>
  • Command names accept kebab- or snake_case (create-design-system == create_design_system).

  • Flags mirror each tool's arguments in kebab-case (projectId → --project-id); array args repeat (--design-system-ids a --design-system-ids b); booleans are presence flags.

  • --json guarantees machine-readable stdout. Exit codes: 0 ok, 1 error, 2 NOT_AUTHED.

  • Same prerequisites as the server: a logged-in Chrome (claude-design chrome), and generation is async — kick off generate/iterate, then claude-design watch --project <id>.

The dev scripts are folded in as subcommands too: claude-design chrome (auth), claude-design scaffold (export → packages/ui), claude-design watch (block until a generation settles). They're equivalent to the matching pnpm run scripts.

Run it without installing globally via npx claude-design …, or node dist/cli.js … from a clone.

Scaffold a packages/ui from an export

Turn a Claude Design export (the project/ folder of a handoff bundle, or a plain export dir) into a maintainable token + UI package: DTCG tokens → Style Dictionary → Tailwind v4 @theme, plus a component skeleton. Components are scaffolded (not auto-converted) with the raw export kept under _design-source/ for Claude Code to port.

pnpm run scaffold:ui -- --src <exportDir> --out <repo>/packages --name ui --ds-name "My DS"

Produces packages/tokens (DTCG JSON source of truth + build/theme.css + tokens.ts, rebuildable with style-dictionary build) and packages/ui (styles/, primitives/, components/, index.ts, CLAUDE.md), plus a root PROMPT.md with porting steps. Primitives land in :root; semantic tokens become Tailwind utilities via @theme inline, with var() references preserved so a one-token re-theme still cascades.

Registering with Claude Code / Cursor

Copy .mcp.json into your project, or add an entry to your existing MCP config:

{
  "mcpServers": {
    "claude-design": {
      "command": "node",
      "args": ["/absolute/path/to/claude-design-mcp/dist/server.js"]
    }
  }
}

Architecture

  • src/server.ts — MCP stdio server; thin tool dispatcher.

  • src/backend.ts — DesignBackend interface (the contract every backend implements).

  • src/browser.ts — CDP acquisition: spawn/reuse real Chrome with a debug port, attach over CDP, find the design tab.

  • src/backends/cdp.ts — CDP-attached backend; reattaches per call so generations survive across tool calls.

  • src/selectors.ts — ⚠️ THE ONLY PLACE selectors and endpoint patterns live. UI shifts? Edit this one file.

  • src/registry.ts — Persists projectId → { url, name } across stdio invocations.

  • src/config.ts / src/errors.ts — env-driven config + structured loud errors.

Once recon captures Claude Design's internal API, tool bodies wire to in-page fetch (preferred) or DOM interaction, both centralized via src/selectors.ts.

Secrets

./.auth/ (the Chrome debug profile, holding your logged-in session) and any captures in ./recon/ are gitignored. Never commit them. See SECURITY.md for the full list and reporting policy.

Contributing

Issues and PRs welcome. See CONTRIBUTING.md for dev setup and the one rule that matters: when claude.ai changes, fix src/selectors.ts first.

License

MIT © Brokenc0de. Unofficial; not affiliated with Anthropic.

Available Tools

32 tools
attach_design_systemC

Bind a design system to a project so it reuses that system's tokens/components.

Inputs: projectId (required), designSystemId (required).

create_claude_code_sessionB

Open the project as a Claude Code session. Returns { sessionUrl }. May be gated per account.

Inputs: projectId (required), instructions.

create_design_projectA

Create a new design PROJECT (screens/app/prototype), optionally attaching design systems. Returns { projectId, url }. Call generate to start from the brief, or send_message to drive it.

Inputs: name (required), brief, designSystemIds, designComponents.

create_design_systemA

Create a new Claude Design project. Returns { projectId, url }. Does NOT start generation — call generate next.

Inputs: name (required), brief (required), sources.

delete_fileC

Delete a file from the project.

Inputs: projectId (required), path (required).

delete_projectC

Delete a project permanently.

Inputs: projectId (required).

detach_design_systemC

Unbind a design system from a project.

Inputs: projectId (required), designSystemId (required).

duplicate_projectC

Duplicate a project. Returns the new { projectId, url }.

Inputs: projectId (required).

edit_fileC

Replace an exact string in a project file (single occurrence edit).

Inputs: projectId (required), path (required), oldString (required), newString (required).

exportC

Write all generated files into destDir, preserving structure.

Inputs: projectId (required), destDir (required).

export_handoffA

DEPRECATED — prefer mint_handoff. Builds a LOCAL handoff bundle (project/ files + chats/ transcripts + README) by reading every file over CDP. Use only for offline bundles or to commit transcripts into a repo.

Inputs: projectId (required), destDir (required).

generateA

Start generation for an existing project. Returns immediately once generation has STARTED — generation takes ~5 minutes, poll get_status.

Inputs: projectId (required).

get_statusB

Poll generation status. Returns { status: 'generating'|'ready'|'error'|'draft', detail?: string }.

Inputs: projectId (required).

get_usageB

Get account usage/quota status (5-hour and 7-day windows).

Inputs: no named parameters.

iterateA

Send a chat message to iterate on the design. Non-blocking: returns once the run has STARTED (~seconds). Poll get_status until 'ready', or run pnpm run watch:status in the background for an auto wake-up.

Inputs: projectId (required), prompt (required).

list_attached_design_systemsA

List the design systems currently bound to a project (with names).

Inputs: projectId (required).

list_conversationsA

List a project's conversations (chats): { chatId, title, turns, active }.

Inputs: projectId (required).

list_design_systemsB

List all known design system projects.

Inputs: no named parameters.

list_filesB

List files generated for the project (tokens, components, screens, SKILL.md, etc.).

Inputs: projectId (required).

list_projectsA

List ALL projects (both design systems and design projects) with their kind.

Inputs: no named parameters.

mint_handoffA

PRIMARY handoff to Claude Code. Mints the official capability URL to the server-built bundle and returns a ready-to-run command (Fetch … / Implement: …). The URL is fetchable without auth and expires shortly. Pass destDir to also download + extract the bundle locally (returns projectDir, ready for pnpm run scaffold:ui).

Inputs: projectId (required), includeChats, instructions, destDir.

new_conversationA

Start a fresh conversation in the project (then use send_message).

Inputs: projectId (required).

publishB

Publish the design system (make it shareable / consumable as a Skill).

Inputs: projectId (required).

read_fileB

Read a single generated file by its path within the project.

Inputs: projectId (required), path (required).

refresh_design_systemA

Pull the latest version of bound design system(s) into the project.

Inputs: projectId (required), designSystemId.

remix_projectC

Remix a project into a new one (optionally including chats).

Inputs: projectId (required), includeChats.

rename_projectC

Rename a project.

Inputs: projectId (required), name (required).

search_filesC

Grep the project's files for a pattern. Returns { path, line, context } matches.

Inputs: projectId (required), pattern (required).

send_messageA

Send a prompt / revision to the project chat. Non-blocking: returns once the run has STARTED. Optionally target a specific conversation by conversationId. Poll get_status (or pnpm run watch:status) for completion.

Inputs: projectId (required), prompt (required), conversationId.

set_defaultC

Set this design system as the default one used by Claude Design.

Inputs: projectId (required).

set_favoriteA

Mark/unmark a project as favorite.

Inputs: projectId (required), favorite (required).

write_fileA

Create or overwrite a file in the project with the given UTF-8 content.

Inputs: projectId (required), path (required), content (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 32 tools

    Disambiguation4/5

    Most tools have distinct purposes, but 'iterate' and 'send_message' both send chat messages to iterate on design, causing potential confusion. Also, 'export_handoff' is deprecated but remains, creating overlap with 'mint_handoff'. Overall, the set is mostly clear.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern in snake_case (e.g., attach_design_system, list_projects, rename_project). No mixing of styles or irregular names.

    Tool Count2/5

    32 tools is excessive for a typical MCP server, even for a complex domain. The set includes deprecated tools and several overlapping functions (e.g., generate/iterate, export_handoff/mint_handoff) that could be consolidated.

    Completeness4/5

    The tool set covers the full lifecycle of design project management: creation, generation, iteration, file management, export, and handoff. Minor gaps exist (e.g., no direct tool to update design system properties), but core workflows are well-supported.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Local MCP server that wraps the headless Claude Code CLI as MCP tools, providing stateless access to Claude's coding capabilities through prompt-based interactions. It enables users to execute Claude Code commands with various prompt formats and structured outputs directly from MCP clients.
      3
      MIT
    • A
      license
      C
      quality
      D
      maintenance
      A comprehensive MCP server that enables Claude to read, create, edit, and generate code from Figma designs. Supports design tokens, code generation to multiple frameworks, and accessibility checks.
      100
      4
      MIT
    • F
      license
      Not graded
      quality
      B
      maintenance
      An MCP server that bridges Claude Code to Figma, enabling AI-driven design creation, modification, and export via semantic tools and WebSocket communication.
      -