Skip to content

Latest commit

Β 

History

30 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

DesignContext

A local-first context compiler that sits between AI coding agents and the Figma MCP.
It indexes a Figma design and answers agent queries with the minimum sufficient context β€” never the raw design dump.

npm version Node.js >= 22.5 TypeScript License MIT Status MVP

πŸ“– Full documentation


Why

Dumping an entire Figma file into an AI agent wastes tokens and produces worse results. DesignContext indexes a user-selected scope, persists a normalized semantic representation locally, and serves agents exactly what they need.

Primary metric: β‰₯ 70% token reduction vs. raw design context.

Design source: only Figma is supported today (via the Figma MCP). Support for other design tools is not implemented yet.

Features

  • Metadata-first indexing β€” discover the design structure cheaply, fetch full context on demand.
  • Minimum sufficient context β€” progressive levels (0 summary β†’ 4 raw) with a token budget.
  • Incremental scan β€” content + structural hashing; re-index only what changed.
  • Diff β€” design_get_changes reports exactly what changed since the previous version.
  • Local & private β€” SQLite + content-addressable cache under ~/.designcontext/; no telemetry.
  • Multi-file β€” track several Figma files in one project, each under its own alias, all queryable through one shared graph/cache and one MCP server.
  • MCP server β€” design_get_project, design_list_files, design_get_screen, design_get_structure, design_get_component, design_get_tokens, design_get_changes, design_find, design_inspect.

How it works

Figma MCP ──(stdio)──▢ FigmaMcpAdapter ──▢ Design IR ──▢ Design Graph ──▢ SQLite cache
                                                              β”‚
                                                              β–Ό
AI agent ◀──(MCP over stdio)── design-context server ◀── Context Engine
  1. designcontext scan connects to the Figma MCP and indexes the requested scope.
  2. The result is normalized into a local Design IR, hashed, and cached.
  3. Agents query the local index through the design-context MCP server.

Requirements

  • Node.js β‰₯ 22.5 (uses the built-in node:sqlite)
  • A Figma connection β€” one of:
    • an already-configured Figma MCP (auto-detected from .mcp.json / ~/.claude.json), or
    • a hosted Figma MCP URL, or
    • a Figma Personal Access Token (fallback)
  • Network access on the first scan (if npx needs to fetch figma-developer-mcp)

Install

npm install -g designcontext

Confirm it worked:

designcontext --version

Quick start

cd your-project
designcontext init

This creates a .designcontext/ folder with the project's configuration.

Connect to Figma

Paste a Figma URL (Share β†’ Copy link) β€” connect parses the file key (and node id, if the link points at a specific frame) straight out of it:

designcontext connect --file "https://www.figma.com/design/aBc123XyZ/Checkout-Flow?node-id=155-1282"

connect prefers an existing Figma MCP β€” it auto-detects one already configured in your agent (from .mcp.json or ~/.claude.json) and reuses it, so in most cases no token is needed. Since you didn't pass --alias, it makes one fresh call to fetch the Figma file's real name ("Checkout Flow") and slugifies it into the default alias (checkout-flow); pass --alias to choose your own instead:

designcontext connect --file "https://www.figma.com/design/aBc123XyZ/Checkout-Flow" --alias checkout

If you don't have a Figma MCP configured, or want to point somewhere specific:

designcontext connect --file <url> --url https://host/mcp     # a hosted Figma MCP
designcontext connect --file <url> --token <key>              # fallback: spawn figma-developer-mcp with a token

Figma credentials are stored in the OS secure vault (Keychain on macOS, Credential Manager on Windows) β€” never in project files.

If no --file is given, or no connection method can be resolved at all (no existing Figma MCP, no --url, no --token), connect fails loudly instead of silently succeeding with an empty config:

No Figma file given. Paste a Figma URL: designcontext connect --file <url> [--token <token>]

Connecting more than one file

A project can track multiple Figma files. Run connect again with a different URL β€” it appends the new file (under its own alias) instead of replacing the one you already connected:

designcontext connect --file "https://www.figma.com/design/qRs456TuV/Cancelamento" --alias cancelamento

Both files now share the same local graph/cache and the same MCP server; every other command that touches a specific file takes --file <alias> to pick between them.

No Figma token? Let the agent fetch the data instead

If you don't want to generate a Figma Personal Access Token (e.g. a restricted/View-seat account), and your AI agent already has its own Figma MCP connector, register the file with --import-only β€” no connection, no token:

designcontext connect --file "https://www.figma.com/design/aBc123XyZ/Checkout-Flow" --import-only

Then ask your agent to fetch that file's data with its own Figma MCP tool and hand it to DesignContext via the design_import MCP tool β€” it reuses the exact same scan/cache pipeline as a normal designcontext scan, just fed by data the agent already had access to instead of a connection DesignContext holds itself. See Agent integration below for design_import's parameters.

Index a screen

designcontext scan                    # 1 file configured: scans it. >1 file: scans ALL of them, one report line each
designcontext scan --file checkout    # scan only the "checkout" file
designcontext scan --node 123:456     # index a specific frame/component (requires --file once >1 file is connected)
designcontext status                  # see what got indexed, aggregate + per-file breakdown

The first scan of a file is a full scan; after that, scan only re-indexes what changed.

status also reports a running, never-reset total of how much the local cache has actually saved: tokensSaved (full-content vs. optimized-summary token counts, and the reduction percentage, across every design_get_* call served) and figmaCallsSaved (cache hit rate during incremental scans β€” a hit means that node's data came from the local cache instead of a Figma API call).

Register with your AI agent

designcontext setup

Registers the DesignContext MCP server with your agent's config in one step. Supports Claude Desktop, Claude Code, Gemini CLI, OpenAI Codex, and opencode β€” pick one interactively, or skip the prompt with --agent claude-code,gemini-cli. See Agent integration to configure it by hand instead.

If designcontext wasn't installed globally (e.g. npm install without -g, or a restricted environment where global installs aren't allowed), setup detects that and writes npx -y designcontext mcp into the agent config instead of a bare designcontext command β€” so the agent can still start it without you fixing your PATH first.

CLI

Command Description
designcontext init [name] Create .designcontext/ project config.
designcontext connect --file <url> [--alias <name>] [--token <token>] [--url <url>] [--import-only] Connect a Figma file β€” --file accepts a pasted Figma URL or a bare file key. Auto-reuses an existing Figma MCP; auto-fetches the file's name as the default alias when --alias is omitted. Run again with a different --file to connect an additional file to the same project. Throws a clear error instead of silently succeeding when no file or connection method is given, unless --import-only is passed β€” which registers the file with no connection of its own, for use with design_import (see Agent integration).
designcontext scan [--file <alias>] Index one file's scope, or every configured file (sequentially, one report line each) when --file is omitted. Accepts --node <id> (requires --file once the project tracks more than one file) and --incremental.
designcontext status Show aggregate + per-file screens/components/tokens/cache breakdown. No --file flag β€” always reports on every connected file.
designcontext diff [screen] --file <alias> Show only what changed since the last scan for one file. --file is required once the project tracks more than one file (errors listing the known aliases otherwise).
designcontext inspect --node <id> [--level 0-4] --file <alias> Print a node's context at a level. --file is required once the project tracks more than one file.
designcontext clear-cache [--file <alias>] Clear the local cache. --file is optional β€” omit it to clear everything.
designcontext setup Register the MCP server with an agent (--agent <ids> to skip the prompt).

Agent integration

DesignContext runs as an MCP server over stdio. designcontext setup does this for you (see above); to configure it by hand, add this to your agent's MCP config:

{
  "mcpServers": {
    "design-context": {
      "command": "designcontext",
      "args": ["mcp"]
    }
  }
}

This gives the agent tools to query the design directly: design_get_project, design_list_files, design_get_screen, design_get_structure, design_get_component, design_get_tokens, design_get_changes, design_find, design_inspect.

Once a project tracks more than one Figma file, every tool except design_get_project accepts an optional file input (an alias or raw file id) to pick which file to query, and it becomes required as soon as more than one file is connected. design_list_files takes no input and returns each connected file's alias, file id, screen count, and component count β€” call it first when the agent isn't sure which alias to pass. design_find is the one exception: when file is omitted it searches across all connected files, and each match's file field reports which file (by alias) it came from.

If a file has no indexed data yet, tools return an actionable message instead of a bare "not found" β€” telling the agent exactly whether the file needs a Figma connection (with the connect --token command to run) or just a scan, so the agent can walk the user through fixing it without them digging through docs.

design_import β€” index data the agent already fetched itself

When a file was registered with connect --file <url> --import-only, the MCP server also exposes design_import: {file, scopeNodeId, rawData} β†’ {discovered, indexed, changed, cached, warning?}. The agent calls its own Figma MCP tool (e.g. get_figma_data) for scopeNodeId, then passes that tool's exact raw text output as rawData β€” DesignContext parses it and runs it through the same indexing pipeline a normal scan uses. If rawData doesn't parse into any nodes (the agent's Figma MCP returns a different format than figma-developer-mcp's), the response carries a warning instead of silently indexing nothing, so the agent can fall back to suggesting a token.

Project structure

npm workspaces monorepo, one package per architecture boundary:

packages/
β”œβ”€β”€ shared/           hashing, token estimation, paths, logging
β”œβ”€β”€ core/             domain types, core interfaces, indexer, metrics
β”œβ”€β”€ figma-adapter/    FigmaAdapter + FigmaMcpAdapter (client of the Figma MCP)
β”œβ”€β”€ cache/            SQLite + content-addressable cache, project config, invalidation
β”œβ”€β”€ design-graph/     node store + name-based search
β”œβ”€β”€ design-ir/        Figma raw β†’ Design IR normalization, context levels
β”œβ”€β”€ diff-engine/      content/structural diff
β”œβ”€β”€ context-engine/   Context Optimizer, component/token/changes assembly
β”œβ”€β”€ mcp-server/       MCP server (design_get_* / design_find / design_inspect)
└── cli/              Commander CLI (init, connect, scan, status, diff, inspect, clear-cache, setup, mcp)

Full end-user documentation: erickson-ivanowski.github.io/DesignContext (also available in this repo at docs/index.html, in Portuguese, English, and Spanish).

Development

npm install
npm run typecheck   # tsc --noEmit
npm run lint        # eslint
npm test            # vitest (unit + integration + contract)
npm run build       # esbuild bundle -> dist/cli.mjs

Testing

  • tests/unit/ β€” hashing, token estimation, IR normalization, diff
  • tests/integration/ β€” index β†’ get_screen (US1), incremental change detection (US2), cache reuse across sessions (US5), Figma MCP over stdio
  • tests/contract/ β€” MCP tool input/output schemas

Tests are hermetic: a MockFigmaAdapter and a mock Figma MCP server spawned over stdio (tests/fixtures/mock-figma-server.mjs) replace the live Figma MCP, and an in-memory cache replaces SQLite.

Storage & security

  • Metadata/indexes in SQLite (~/.designcontext/database.sqlite); blobs content-addressable by SHA-256.
  • ~/.designcontext/ is global, not versioned, and treated as sensitive (gitignored).
  • Credentials go to the OS keychain via keytar when available β€” never into versioned files.
  • Structured logs redact secrets/tokens.

Implementation notes

  • SQLite driver: the plan called for drizzle-orm + better-sqlite3. Since better-sqlite3 is a native module that can't compile without a C++ toolchain, the storage layer uses Node's built-in node:sqlite. The schema and CacheStore contract are unchanged.
  • Figma connection: a client of the Figma MCP via @modelcontextprotocol/sdk. Three modes, in order of preference: (1) reuse an existing Figma MCP (auto-detected from .mcp.json / ~/.claude.json), (2) a hosted Figma MCP over streamable HTTP (--url), or (3) spawn figma-developer-mcp over stdio with a stored token. StdioClientTransport and StreamableHTTPClientTransport are both supported.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages