Figma MCP + AI: design tokens from variables to production JSON

How Figma MCP and AI keep design tokens in sync across code, internal tools, and brand assets—one JSON source of truth for every platform.

design tokensFigma MCPdesign systemsAI-assisted designdesign engineeringJSON

Design tokens break down in predictable ways. A designer renames a variable in Figma to fix a naming inconsistency. An engineer references the old CSS custom property because the documentation was never updated. An internal dashboard ships with the wrong surface color because it was built before the last token audit. Three months later, the product looks like three different companies made it.

The problem is not that tokens are a bad idea. The problem is that tokens live in two places—Figma and code—and without an explicit workflow to keep them synchronized, they drift. The solution I use at Peridio and Avocado OS is a JSON-first token system that connects Figma variables to code through Figma MCP, AI-assisted auditing, and Style Dictionary transforms. The result: one source of truth that feeds external products, internal tools, marketing assets, and brand documentation without manual transcription.

For the token architecture itself—how primitives, semantics, and context layers are structured—see Peridio & Avocado OS: semantic tokens and AI-native design systems. This post is the workflow layer underneath that architecture: how you build it, connect it, and keep it honest over time.

Why Figma variables need to mirror the JSON graph exactly

Before connecting anything, Figma variables need to be organized in a way that makes synchronization possible. That means collections that map to JSON layers, not groupings that made visual sense in a past file.

The structure I use:

  • Primitives — raw values; one collection, all modes (light, dark, high-contrast). No component references at this layer.
  • Semantic — named roles: surface.canvas.default, text.primary, intent.warning.bg. This collection references primitives by variable alias—never by raw value.
  • Context / Brand — overrides per brand (Peridio vs. Avocado OS) or per product (console vs. marketing site). This collection references semantics, again by alias.

The naming convention matters: semantic/surface/canvas/default in Figma should map directly to semantic.surface.canvas.default in JSON. Slashes in Figma variable names become dots in JSON keys. If these don’t match, any script that syncs the two needs a translation table—and translation tables accumulate bugs.

Variable types by layer:

  • Primitives: COLOR, FLOAT, STRING (for font families)
  • Semantics: COLOR only—semantic spacing and radius consume primitive floats through component properties, not variable aliases, to keep the graph readable
  • Context: COLOR only—override values only where the brand or product actually diverges

Setting this up correctly upfront is slower than dumping all variables into one collection. Every tool downstream—Figma MCP, Style Dictionary, AI agents—works from the same named graph. When the graph is consistent, machines can operate on it reliably.

How Figma MCP connects AI to your variable library

Figma MCP (Model Context Protocol) exposes the Figma API as a structured interface that AI tools—Claude, Cursor, custom agents—can call directly in a conversation. Instead of a designer manually copying variable values into a spreadsheet to share with an engineer, the AI reads them from Figma in real time, reasons about them, and either proposes changes or writes them back.

A typical audit session starts with: “Read all semantic color tokens and check whether each text/background pair meets WCAG AA for normal-size body copy.” The MCP client calls the Figma API, retrieves the variables, resolves aliases to raw hex values, runs the contrast check, and returns a list of failing pairs with suggested primitive adjustments. The designer reviews and approves; the approved changes can be written back to Figma via MCP in the same session.

This is different from plugins that run inside Figma. MCP runs in the AI conversation context—you can chain it with other tools (linting the JSON file, checking against code, generating a migration note) without context-switching between apps.

Common MCP operations for token work:

  • Read variable state — pull all variables and their current values before starting any token refactor to create a baseline snapshot
  • Detect alias chains — identify variables that reference other variables more than two layers deep; deep chains are fragile and should be flagged for simplification
  • Check naming consistency — compare Figma variable names against the JSON key structure; surface mismatches that would cause sync errors
  • Write bulk updates — after approving a proposed ramp change, write updated primitives to Figma without manual entry

The key constraint: MCP operations on Figma are most reliable on named, well-organized variable libraries. A chaotic file with orphaned styles and inconsistent naming produces unreliable reads. The organizational discipline in the previous section is what makes MCP trustworthy.

Building and maintaining the JSON source of truth

The JSON file is the canonical record of every token decision. Figma is where designers iterate; JSON is where the decisions land. The flow is:

Figma variables → JSON (canonical) → Style Dictionary → CSS / Tailwind / iOS / Android

Running a sync script—or asking an AI agent via MCP to produce a diff—yields a JSON file that matches the current Figma variable state. Here is the minimal shape for the semantic layer, extending the full schema in the architecture post:

{
  "semantic": {
    "surface": {
      "canvas": {
        "default": { "value": "{primitive.color.neutral.0}", "type": "color" },
        "muted":   { "value": "{primitive.color.neutral.50}", "type": "color" }
      }
    },
    "text": {
      "primary":   { "value": "{primitive.color.neutral.950}", "type": "color" },
      "secondary": { "value": "{primitive.color.neutral.600}", "type": "color" },
      "link":      { "value": "{primitive.color.brand.600}",  "type": "color" }
    }
  }
}

Each value is an alias reference, not a raw hex—so when a primitive changes, all semantics that reference it update through Style Dictionary without a manual find-and-replace.

Governance rules for the JSON file:

  • The file lives in the same repository as the component library, reviewed through the same PR process as code
  • Changelog entries are required for any semantic rename or primitive ramp change
  • Old alias names are deprecated in deprecated.json for one minor version before removal—never deleted silently

How Style Dictionary transforms reach every platform

Style Dictionary is the transform layer that converts JSON aliases into platform-specific outputs. One configuration maps the JSON structure to multiple build targets:

// style-dictionary.config.js (simplified)
module.exports = {
  source: ["tokens/**/*.json"],
  platforms: {
    css: {
      transformGroup: "css",
      buildPath: "build/css/",
      files: [{ destination: "tokens.css", format: "css/variables" }]
    },
    tailwind: {
      transformGroup: "js",
      buildPath: "build/js/",
      files: [{ destination: "tailwind-tokens.js", format: "javascript/es6" }]
    },
    ios: {
      transformGroup: "ios-swift",
      buildPath: "build/ios/",
      files: [{ destination: "StyleTokens.swift", format: "ios-swift/class.swift" }]
    }
  }
};

Running style-dictionary build produces CSS custom properties for the web component library, a Tailwind config extension for the marketing site, and Swift constants for native iOS work—all from the same JSON. When a token value changes, one PR updates the JSON, CI runs Style Dictionary, and all platform outputs regenerate in the same commit.

This is what “reusable across the board” means in practice. The JSON does not need to be manually translated for each surface. The transform is automated; human judgment is reserved for token design decisions, not copy-paste maintenance.

Reaching every surface: internal tools, external products, brand assets

A semantic token system scales across surfaces precisely because semantics describe purpose, not appearance. When surface.canvas.default and text.primary are consumed by a Figma component library, a React component library, and a static marketing site, they can share identical visual output or diverge intentionally through context overrides—without forking the component source.

Internal tools are often the first surface to drift. Because they are never customer-facing, they skip design review and accumulate hardcoded colors and one-off styles. The solution is friction reduction: when the shared component library pulls from the same token layer and is easy to import, using the design system becomes the path of least resistance. Internal tools built on the shared library inherit every token update automatically.

External products (the customer-facing UI at Peridio, the Avocado OS console) consume tokens through the component library. Brand context overrides let Peridio and Avocado OS use distinct accent colors and photography treatment while sharing every surface, intent, and spacing token. The two products look related, not identical—which is correct for a platform company where both share infrastructure but serve different narratives.

Marketing sites use the Tailwind token extension. The clamp()-based fluid spacing tokens land in tailwind.config.js under spacing; brand primaries land under colors. Marketing engineers build with Tailwind utility classes wired to the same semantic values the product team uses. When the brand ramp shifts, the marketing site and product UI update from the same source without a coordination meeting.

Brand documentation and presentation assets are where token systems most often stop short. Slides, one-pagers, and executive reports are built in Google Slides or Keynote, which have no API to the token system. The bridge I use: a brand kit JSON that is a flattened subset of semantic tokens—hex values resolved, no aliases—that feeds a custom slide template and AI-assisted content generation scripts. When brand colors update, the brand kit JSON regenerates from Style Dictionary, and a Cursor/Claude workflow updates the template’s color swatches. Not fully automatic, but it reduces brand drift in documents from a constant problem to quarterly maintenance.

Using AI to detect and prevent token drift

The most valuable AI integration is not generating new tokens—it is catching drift between Figma and the JSON file. Token drift is quiet: a designer adjusts a variable in Figma during a late-sprint fix, the JSON is not updated, and CI does not catch it because CI only tests the JSON, not Figma.

A regular audit workflow:

  1. Figma MCP read — pull current variable state from Figma
  2. JSON diff — compare against the file in the repo
  3. Discrepancy report — AI produces a list of variables that differ, with “Figma has X, JSON has Y” for each
  4. Review and resolve — designer decides which is correct; AI writes approved updates back to Figma or opens a PR for the JSON

Running this before every sprint review catches drift before it compounds. On a large system, this would take a human an afternoon per month. As an AI-assisted workflow, it runs in under ten minutes and produces a diff the whole team can read.

The broader principle: AI tools work reliably on token systems when the inputs are structured. A flat list of hex values is unstructured—a model cannot reason about intent or catch semantic drift in it. Layered JSON with stable semantic names is structured; models can diff, audit, propose, and explain changes the way a careful engineer would.

How do you know when the token system is working?

The token system is working when:

  • A designer can change a brand ramp value in one PR and see it propagate correctly to the product UI, the marketing site, and the design system documentation with no manual follow-up
  • An engineer building a new internal tool can import the component library and produce an on-brand screen without referencing the design file
  • A new product surface can be added by defining a context override block in JSON without forking any component code
  • An AI agent auditing the token file can produce a sensible, accurate diff—because the structure is consistent enough to reason about

All four are achievable with the setup described here. None are achievable with an ad hoc approach where tokens are “kind of documented somewhere” and components hardcode color values.

Key Takeaways

  • Figma variable collections should mirror the JSON layer structure (primitives → semantics → context); any mismatch creates a translation problem that accrues bugs over time.
  • Figma MCP connects AI directly to variable state, enabling automated audits, bulk updates, and drift detection without manual exports.
  • JSON is the canonical record; Figma is the iteration environment. Style Dictionary transforms JSON into CSS, Tailwind, iOS, and other targets automatically.
  • Every surface—product UI, internal tools, marketing site, brand documents—reaches the token system through the appropriate transform output, not through copy-pasted hex values.
  • AI-assisted drift detection is the most practical ongoing use: comparing Figma variables against the JSON file on a regular cadence and producing a reviewable diff before it compounds.

The architecture behind this workflow is in Peridio & Avocado OS: semantic tokens and AI-native design systems. For how this token system connects to deployment and release branches, see branching strategies for design-engineering collaboration.