Mercury Gotchas
Cross-cutting lessons from building real Figma designs via Mercury. These are not specific to any one tool — they apply whenever you're stringing calls together. Read the rule, the reason, the fix.
1. Verify visually, not by tool results
Rule: A batch that returns ok does not mean the screen looks right.
Why: Mercury's tools return structural success (the node exists, the fill applied). They do not render. You can get a "successful" screen where the hero number is off-frame, the auto-layout collapsed, or two elements overlap.
Fix: At least once per design phase, call mcp__mercury__export_node on
the parent frame (PNG, 2x scale) and look at the image before continuing.
Treat the export as a required checkpoint, not a nice-to-have.
2. Auto-layout sizing modes are the #1 bug source
Rule: Know the difference between primaryAxisSizingMode,
counterAxisSizingMode, and layoutSizingHorizontal / layoutSizingVertical.
Why: Figma has two parallel systems. Sizing mode values (FIXED, AUTO)
describe the frame itself. Layout sizing values (FIXED, FILL, HUG)
describe how a child behaves inside its parent. They're easy to confuse.
Concrete traps:
primaryAxisSizingMode: "FIXED"on create without an explicitwidth/heightdefaults the length to 100px. Your "full-width" hero ends up 100px wide. Always pass explicit dimensions when using FIXED.layoutSizingHorizontal: "FILL"often cannot be set at creation time. Set it via a follow-upmcp__mercury__patchafter the node exists.- A child with
layoutSizingHorizontal: "FILL"inside a parent withprimaryAxisSizingMode: "AUTO"produces nothing — FILL needs a defined parent length to fill.
3. Batch size cap: ~40 ops
Rule: Keep mcp__mercury__batch calls at or under 40 sub-operations.
Hard ceiling around 55–60.
Why: The WebSocket bridge to the Figma plugin has timeout behavior around 60 ops. You'll see partial success with no clear error.
Fix: Chunk larger work into multiple batches. You lose single-undo atomicity across chunks, but Cmd+Z still works per chunk. For truly atomic multi-phase builds, export between chunks and verify — don't rely on one gigantic batch.
4. Use ${idx}.id to chain ops in one batch
Rule: batch takes { ops: [{ tool, params }, ...] }. When a later op
needs an id produced by an earlier op, reference it as ${idx}.id inside
any string param, where idx is the zero-based op index.
Why: Without this, you'd need a round-trip per dependent op — 65 calls
instead of 12 for a typical screen build. Mercury resolves ${idx}.field
placeholders server-side before executing.
Example:
batch {
ops: [
{ tool: "create", params: { kind: "frame", name: "Card", width: 343, height: 120 } },
{ tool: "patch", params: { id: "${0}.id", autoLayout: { direction: "VERTICAL", itemSpacing: 8 } } }
]
}
5. Text styles overwrite everything — apply first, tune second
Rule: If you're applying a text style (mcp__mercury__style op:"apply")
AND setting per-node overrides (mcp__mercury__set_text_style), apply the
style first, THEN set overrides.
Why: Applying a style resets the node's text properties to the style's values. If you set font size first and then apply the style, your size is gone.
6. Off-canvas scaffolding appears in exports — use a separate page
Rule: If you're building helper frames, reference components, or intermediate scaffolding, put them on a separate Figma page, not off to the side of the working screen.
Why: Setting x: -2000 hides scaffolding from view but
mcp__mercury__export_node on the containing frame will still render the
full node tree. Off-canvas ≠ off-page.
Fix: mcp__mercury__page op:"create" name:"Components" or "Scratch",
then op:"set-current" when you want to build there. Switch back to the
working page for the real design.
7. Corner radius differs by node type
Rule: cornerRadius is set differently on rectangle vs. frame vs.
ellipse.
Why: Figma's API exposes corner radius inline on rectangles (with an
optional rectangleCornerRadii for per-corner), but frames require it as a
patch field. Ellipses accept it but it has no visual effect unless the
ellipse is actually a rounded shape (which is rare — you want a rectangle
with matching corners).
Fix: Use mcp__mercury__patch with the appropriate field name. If in
doubt, inspect the node via mcp__mercury__query op:"subtree" depth:1 after
creation and check which corner fields are populated.
8. icon create returns a frame component, not a paint surface
Rule: mcp__mercury__icon op:"create" produces a component/frame. It is
not a fill, not a vector, not something you can directly recolor by setting
paints on it like a rectangle.
Why: Mercury bundles ~1943 Lucide icons as component-like frames so they can be instanced and recolored via component overrides.
Fix: If you need a raw vector, use mcp__mercury__create kind:"vector"
with an SVG path string. If you need an icon, use icon create, instantiate
it, and style via instance overrides (mcp__mercury__component op:"bind" or
mcp__mercury__patch on the instance's fills).
9. Atomic undo: one tool call = one Cmd+Z
Rule: Every single Mercury tool invocation wraps figma.commitUndo().
One tool call = one undo step in Figma.
Why: Lets designers recover cleanly from an agent mistake. A 40-op
batch is still one Cmd+Z.
Fix: Communicate this to the designer explicitly when reporting. "I applied 12 changes in one batch — Cmd+Z once will revert the whole thing." Don't say "press Cmd+Z 12 times".
10. Absolute positioning escapes auto-layout
Rule: To pin a child to a specific corner of an auto-layout parent (e.g.,
a FAB pinned to bottom-right, a badge on a tab icon), set
layoutPositioning: "ABSOLUTE" on the child.
Why: Otherwise auto-layout packs the child into the flex flow and the fixed coordinates you set are overridden.
Fix: On create, pass layoutPositioning: "ABSOLUTE". On existing nodes,
patch it. Then x and y become meaningful relative to the parent.
Quick checklist before declaring a design "done"
- Exported the top-level frame(s) as PNG and visually reviewed.
- No hidden collapsed auto-layout frames (width/height = 100 or 0).
- Batches stayed under 40 ops each.
- Scaffolding is on a different page, not just off-canvas.
- Text styles applied before per-node tweaks.
- Atomic undo story communicated to the designer.