Skip to main content
Glama
Rachit0-glitch

figma-custom-mcp

README.md
# figma-custom-mcp

A small MCP + Figma plugin that patches three specific, confirmed capability gaps in
[Plumb](https://github.com/tathagat22/plumb-mcp) — it does **not** modify, fork, or replace Plumb, and is
designed to be paired in Figma alongside it.

The gaps, and the full source-level evidence for them, are documented in
[`PLUMB_GAP_ANALYSIS.md`](./PLUMB_GAP_ANALYSIS.md) (a from-source audit of Plumb v0.13.2). This project
implements the P0 and P1 items from that audit:

**P0 — foundation**
- **P0-1 — Absolute / overlapping positioning.** Plumb's DSL compiler forces every container into
  auto-layout and never sets Figma's `layoutPositioning="ABSOLUTE"`, so overlapping compositions (badge over
  image, text over photo, etc.) are structurally impossible to build. This project's compiler defaults to
  free (x/y) positioning and supports `absolute: true` children inside auto-layout regions.
- **P0-2 — Local/custom image import.** Plumb's `image.src` is always compiled into a web-search query
  against six fixed stock-photo providers; a user's own file can never enter a Plumb-built design. This
  project reads `file:`/`data:` URIs directly, with typed errors and zero placeholder substitution.
- **P0-3 — Strict schema validation.** Plumb's Zod schemas silently strip unknown/misspelled fields. Every
  schema here is `.strict()`.

**P1 — advanced construction primitives** (all absent from Plumb entirely)
- **Boolean operations** (union/subtract/intersect/exclude) — real `BOOLEAN_OPERATION` nodes, either authored
  fresh in a `figma_design` tree or combined from existing nodes via `figma_boolean`.
- **True grouping** — real `GROUP` nodes via `figma_group`, with `figma_ungroup` reconstructing Figma's
  missing native ungroup.
- **Components, component sets, and variants** — real `COMPONENT`/`COMPONENT_SET` structures with genuine
  `variantProperties`, via a `"component"` node type + `figma_create_component_set`.
- **Constraints** — real `node.constraints`, both for newly-authored and existing nodes.
- **Paint styles** — real, idempotent-by-name `PaintStyle` creation and application.

**P2 — component/instance/variable/style/text-range depth, plus structural tooling** (see
`docs/P2-AUDIT.md` for the full 20-group audit this phase worked from)
- **Component properties & instance overrides** — real definitions on `COMPONENT`/`COMPONENT_SET`, real
  instance property values/per-sublayer overrides/main-component swaps, plus `figma_create_instance` to
  actually produce an instance to operate on.
- **Variables** — real collections/modes/variables/values and all 4 distinct binding paths (node-scalar,
  paint color, effect field, layout-grid field), each through its own real Figma helper API.
- **Text/effect/grid styles** and **per-range text styling** — mixed/rich text (bold word inside a
  paragraph, etc.) was a real, previously-undocumented gap in this project's own P0/P1 work.
- **Direct layoutGrids, auto-layout sizing (fill/hug/fixed), sections, multi-subpath vectors, persisted
  export settings, wrap alignment/z-index reversal, native `locked`/`expanded` metadata, 2 more gradient
  types (angular/diamond), `maskType`, cross-parent node moves with transform correction.**
- **`figma_batch`** (validated, fail-fast, honestly-non-transactional orchestration) and **`figma_diff`**
  (structural comparison against a real Figma read-back) — plus a selective `include` read-back filter.
- **`operationKey`-based idempotency** for `figma_group`/`figma_create_component_set`, in a plugin-data
  namespace kept structurally separate from `figma_design`'s own sync-mode reconciliation key (a real bug
  found and fixed during live testing — see `docs/P2-IMPLEMENTATION.md`).

**P3 — the design quality loop: inspect → measure → compare → correct → verify → iterate** (see
`docs/P3-ARCHITECTURE.md`)
- **Richer inspection** — page-space `absoluteBoundingBox`, hierarchy (`parentId`/`index`), full
  typography (font family/style/size/case/decoration/line-height/letter-spacing), and `visible` (real
  gap: patchable since P0, never read back until P3) added to `figma_node`.
- **`figma_measure`** (new) — deterministic gap/overlap/containment/center-delta/alignment, computed
  from real page-space geometry. Reports numbers only; never judges whether a result is "correct."
- **`figma_diff` (extended) / `figma_verify` (new)** — explicit, overridable numeric tolerance and a
  deterministic 4-level severity (CRITICAL/MAJOR/MINOR/INFO) added to comparison; `figma_verify` is a
  lighter flat-expectations mode for when a full compiled `DesignDoc` isn't on hand.
- **`figma_patch_node` (extended)** — fill, stroke, radius, effects, blendMode, locked, auto-layout
  properties, and whole-node text, all reusing the tree-DSL's own real schemas — each field genuinely
  optional and untouched-if-omitted, so a narrow correction never disturbs anything it didn't mention.
- The LLM stays the design intelligence throughout — P3 provides mechanical inspection/measurement/
  comparison/correction primitives, never a hidden autonomous "make it better" planner.

See [`docs/P0-CAPABILITY-MATRIX.md`](./docs/P0-CAPABILITY-MATRIX.md),
[`docs/P1-CAPABILITY-MATRIX.md`](./docs/P1-CAPABILITY-MATRIX.md), and
[`docs/P2-CAPABILITY-MATRIX.md`](./docs/P2-CAPABILITY-MATRIX.md) for the full audit-item-by-item
traceability, and [`docs/`](./docs) for the rest of the documentation set.

## Status

**P0 COMPLETE, P1 COMPLETE, P2 COMPLETE, P3 COMPLETE** — see [`P0-FINAL-REPORT.md`](./P0-FINAL-REPORT.md),
[`P1-FINAL-REPORT.md`](./P1-FINAL-REPORT.md), [`docs/P2-FINAL-REPORT.md`](./docs/P2-FINAL-REPORT.md), and
[`docs/P3-FINAL-REPORT.md`](./docs/P3-FINAL-REPORT.md) for the full acceptance-criteria checklists and
real live-Figma test results. `tests/p1-live-screenshot.png`, `tests/p2-live-screenshot.png`, and
`tests/p3-live-screenshot.png` are real, live compositions this project built (and, for P3, deliberately
broke and then corrected) and screenshotted against the actual paired Figma plugin — not flattened
images, not mocks. P2's live test exercises all 20 audited capability groups plus a sync-mode idempotency
rerun; P3's live test (`tests/p3-live.mjs`) runs the full inspect → measure → diff/verify → correct →
verify → idempotency-rerun → failure-recovery loop end to end. Both surfaced real runtime bugs along the
way — each found, fixed, and re-verified live, documented in `docs/P2-IMPLEMENTATION.md` and
`docs/P3-IMPLEMENTATION.md` rather than glossed over.

## Quickstart

```bash
npm install
npm run build
npm test
```

Then see [`docs/QUICKSTART.md`](./docs/QUICKSTART.md) to pair the Figma plugin and run the live end-to-end
test.

## Documentation

- [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md)
- [`docs/P0-CAPABILITY-MATRIX.md`](./docs/P0-CAPABILITY-MATRIX.md) / [`docs/P1-CAPABILITY-MATRIX.md`](./docs/P1-CAPABILITY-MATRIX.md) / [`docs/P2-CAPABILITY-MATRIX.md`](./docs/P2-CAPABILITY-MATRIX.md)
- [`docs/P0-TOOLS.md`](./docs/P0-TOOLS.md) (all 26 tools, P0 + P1 + P2 + P3) / [`docs/P3-TOOLS.md`](./docs/P3-TOOLS.md) (P3's when-to-use guidance)
- [`docs/P0-DESIGN-SCHEMA.md`](./docs/P0-DESIGN-SCHEMA.md) (includes P1 additions)
- [`docs/P0-TEST-PLAN.md`](./docs/P0-TEST-PLAN.md) / [`docs/P1-TEST-REPORT.md`](./docs/P1-TEST-REPORT.md) / [`docs/P2-TEST-REPORT.md`](./docs/P2-TEST-REPORT.md) / [`docs/P3-TEST-PLAN.md`](./docs/P3-TEST-PLAN.md)
- [`docs/P0-IMPLEMENTATION.md`](./docs/P0-IMPLEMENTATION.md) / [`docs/P1-IMPLEMENTATION.md`](./docs/P1-IMPLEMENTATION.md) / [`docs/P2-IMPLEMENTATION.md`](./docs/P2-IMPLEMENTATION.md) / [`docs/P3-IMPLEMENTATION.md`](./docs/P3-IMPLEMENTATION.md)
- [`docs/P0-LIMITATIONS.md`](./docs/P0-LIMITATIONS.md)
- [`docs/P2-AUDIT.md`](./docs/P2-AUDIT.md) (the 20-group audit P2 was built from) / [`docs/P2-FINAL-REPORT.md`](./docs/P2-FINAL-REPORT.md)
- [`docs/P3-ARCHITECTURE.md`](./docs/P3-ARCHITECTURE.md) / [`docs/P3-FINAL-REPORT.md`](./docs/P3-FINAL-REPORT.md)
- [`docs/QUICKSTART.md`](./docs/QUICKSTART.md)

## License

MIT

TDQS

A3.5/5.0

Scored across 7 tools

Disambiguation4/5

Each tool targets a distinct action (delete, reorder, export, status, design/create, read, patch). The only potential overlap is between figma_design and figma_patch_node, but design is for initial creation/sync while patch is for targeted updates, so the boundary is clear.

Naming Consistency4/5

All tools use the prefix 'figma_' followed by a descriptive verb_noun pattern (e.g. figma_delete_node, figma_reorder_node). The only minor inconsistency is the verb choice: 'screenshot' is less typical than 'export', and 'status' is a noun rather than an action, but overall the pattern is clear and predictable.

Tool Count5/5

7 tools is well-scoped for a Figma design tool MCP server. Each tool covers a core operation (CRUD, reorder, export, status) without being too many to navigate or too few to be useful.

Completeness4/5

The server covers essential operations: create (via figma_design), read (figma_node), update (figma_patch_node, figma_reorder_node), delete (figma_delete_node), and export (figma_screenshot). A minor gap is the lack of a dedicated tool for listing node children or searching nodes, but the read tool with nodeId omission provides a reasonable workaround.

Maintenance

ActivitySlowing
ResponsivenessNo issues