Skip to content
Design
Skill

/seed-verify-figma-mcp-transports

Figma MCP 도구 변경 뒤 REST와 WebSocket 결과를 실제로 비교해 transport parity를 검증할 때 사용한다.

BOOST
From plugin
seed-design
1.2k11 skills4 agents6 commands3 MCP
Install
$ npx -y skills add daangn/seed-design --skill seed-verify-figma-mcp-transports --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/seed-verify-figma-mcp-transports

Context preview

The summary Claude sees to decide when to auto-load this skill.

Figma MCP 도구 변경 뒤 REST와 WebSocket 결과를 실제로 비교해 transport parity를 검증할 때 사용한다.

SKILL.md

seed-verify-figma-mcp-transports.SKILL.md
name: seed-verify-figma-mcp-transports
description: Figma MCP 도구 변경 뒤 REST와 WebSocket 결과를 실제로 비교해 transport parity를 검증할 때 사용한다.

Verify Figma MCP Transports

A Figma MCP tool answers the same question over two paths: **REST** (personal access token) and **WebSocket** (the Figma plugin). Fixing one and not the other still typechecks, so the drift is silent. Run both and compare mechanically.

두 경로의 구현 차이가 판단에 필요할 때만 `packages/mcp/AGENTS.md`를 읽는다.

> [!IMPORTANT] > Run this skill **on the main thread**. Phase 3 is a hard stop that waits on a person, and a subagent has nobody to ask — it will pass itself.

Prerequisites

  • `FIGMA_PERSONAL_ACCESS_TOKEN` is set. If not, stop at Phase 0 and ask for it.
  • The Figma desktop app is installed.
  • The tool under test is registered in `PROBES` in the probe script. If it isn't, register it first — see the header comment in that file.

Phase 0: Decide what to inspect

Both transports need a target, so this comes before any probing — REST in Phase 1 already needs it.

**검증 기준은 변경 diff에서 스스로 도출한다.** 사용자가 이미 조건을 만족하는 layer URL을 제공했으면 그대로 사용한다. 그렇지 않으면 특정 node가 아니라 필요한 layer 형태를 설명해 URL을 요청한다. "A frame containing a layer with two or more annotations, and a text layer with none"은 답할 수 있지만, "Give me a layer URL"은 검증 설계를 사용자에게 넘긴다.

Start from this checklist and cut what your change doesn't touch:

| Cover | Why | |---|---| | The queried node itself carrying a value | Catches a traversal that skips its own root | | A descendant carrying a value | The recursive collection path | | A leaf (no `children`) | Whether a non-container node throws | | A page (`CANVAS` / `PAGE`) | The plugin-only `loadAsync` path, plus the type-vocabulary difference | | A node inside a component instance | IDs composed as `I<a>;<b>;<c>` |

The last two apply to every tool. The rest apply only when the tool walks a tree.

Ask with **AskUserQuestion**, and ask for a **layer URL** — `parseFigmaUrl` takes the file key and node id straight out of it, so nobody has to read ids off a canvas.

If the same file gets reused across runs, put its key in `SEED_MCP_PROBE_FILE_KEY` and pass only `--node-id` afterwards.

Phase 1: REST alone (no person needed)

REST needs nothing but the token, so **finish it without asking anyone.**

bun packages/mcp/scripts/probe-transports.ts \
  --probe <tool> \
  --transport rest \
  --file-key <key> \
  --node-id <id>
  • The script calls the same helper the tool handler calls. Never reach past it to the REST API directly — that tests Figma, not the tool.
  • If this fails, do not move on to WebSocket prep. Calling a person in to help debug a broken REST path spends their time on your bug.

Phase 2: Prepare WebSocket (up to the human boundary)

Build everything that does not need a person, so the person is interrupted exactly once.

1. Build the plugin. Editing the source without rebuilding leaves Figma reading the old `dist`.

   bun --filter figma-mcp build

2. Start the relay in the background (`Bash` with `run_in_background: true`).

   bun packages/mcp/bin/index.mjs socket

Wait for `WebSocket server running on port 3055`. If the port is already held, ask whether to reuse that process — never kill something you did not start.

Phase 3: Hand off (hard stop)

Only a person can drive the Figma desktop app. There is no way around this step.

**Before asking, confirm all of these.** If any is false, go back to Phase 2 — the person gets called once.

  • [ ] `tools/figma-mcp/dist` was just rebuilt
  • [ ] The relay is listening on 3055
  • [ ] Phase 1 passed

Then ask with **AskUserQuestion**. Do not write the question into chat and continue — that is not a stop.

Spell out what to do and why each step matters; without the reason people skip the reload. Refer to the file by the key Phase 1 actually used. If they open a different file the two transports answer about different documents, and that difference gets reported as a code bug.

WebSocket side is ready. Two things in Figma:

1. Quit the plugin and run it again — dist was just rebuilt, and a running
   instance keeps answering with the old code.
2. Open the file from Phase 1 (<key>) and hit Connect in the plugin.
   Port 3055, channel is fixed to local-default, so there is nothing to type.

Offer three options:

| Option | Next | |---|---| | `Ready` | Phase 4 | | `Show me how to reload the plugin` | Explain, then ask again | | `Stop` | Clean up the relay, report Phase 1 only |

Phase 4: Probe and compare

1. **Do not take "ready" at face value.** Check the relay log for `New client connected` first. If it is missing, ask again rather than probing into a void — an unconnected run yields a 30-second timeout that reads like a plugin bug.

2. Run both and diff:

   bun packages/mcp/scripts/probe-transports.ts \
     --probe <tool> \
     --transport both \
     --file-key <key> \
     --node-id <id>

3. **The exit code decides whether anything differs — not whether it is a bug.** Do not read the output and conclude it "looks the same"; 0 means the transports agree on every compared field. A 1 prints the disagreement, which you then classify with the table below before calling it a bug.

4. Run every node you chose in Phase 0. One passing node is not a pass.

Phase 5: Report and clean up

  • Report pass/fail per node, and for any failure which field differed and how.
  • Record which file and nodes you used. Without that nobody can reproduce the result.
  • **Terminate only a relay you started in Phase 2.** If you reused one that was already running, leave it.

Four ways the transports diverge

Comparing is not "the whole payload matches". Sort each field into one of four classes.

| Class | Handling | |---|---| | **Must match** | The default. A difference is a bug. | | **Transport-only** | Only one side can produce it. Add it to the probe's `ignore`. | | **Different vocabulary** | Both name the same thing differe

Read more
Ships withseed-design

SEED는 당근 제품을 위한 통합된 디자인 언어입니다. 하나의 토큰 소스에서 React, iOS, Android, Lynx까지 여러 플랫폼에 일관된 디자인을 전달하고, Figma와 연동됩니다.

Get the whole plugin

Other skills on seed-design.

seed-change
Skill

seed-change

SEED 변경의 영향·검증·기준 브랜치를 판단하거나, 공개 패키지 changeset을 작성하거나, 명시적으로 요청받은 rebase·commit·push·PR 제출을 할…