Skip to content

Releases

v0.5.5 — loopback-only HTTP endpoint, MCP SDK 1.32, fileContext, clean package

Choose a tag to compare

@muloka muloka released this 07 Nov 21:38

Restart the server, then re-import the Desktop Bridge plugin. The HTTP guard and the SDK upgrade take effect when the server restarts. fileContext/resultAnalysis come from a change to figma-desktop-bridge/ui.html, and this fork never shows Figma's update banner, so re-import manifest.json by hand. If you launch with plain npx @muloka/figma-console-mcp, npx may keep running a cached older version. Run it once as npx @muloka/figma-console-mcp@latest.

This release covers 0.5.4 and 0.5.5. 0.5.4 had no release notes of its own; 0.5.5 is the same code, packaged correctly.

Security (0.5.4)

  • The HTTP endpoint only answers loopback clients. With MCP_HTTP_PORT set, every request must name a loopback Host on that port (localhost, 127.0.0.1 or [::1]) and carry either no Origin or a loopback one. Anything else gets a 403 before it reaches MCP, on /mcp and on the / status route. The endpoint already bound 127.0.0.1, but a web page could still reach it through DNS rebinding and call any tool. Non-browser MCP clients send no Origin and are unaffected.
  • MCP SDK 1.26 → 1.32.2. Fixes advisories that reach the HTTP endpoint, including a single oversized request exhausting server memory during validation. Still on zod 3. The tool list served to clients is unchanged: all 112 definitions are identical.
  • figma_scan_code_accessibility no longer runs scripts from the HTML it scans. <script> tags and inline handlers in the scanned HTML used to execute inside the server's Node process. Cherry-picked from upstream (fe3af0b6, the Local Mode part only), authorship preserved.

Added (0.5.4)

  • figma_execute results carry fileContext and resultAnalysis. fileContext is { fileName, fileKey } of the file the code actually ran in, so a caller using 0.5.1's fileKey can confirm the call landed where it asked. resultAnalysis flags empty and null results, as the tool's description has always promised. The plugin computed both, but its UI relay dropped them before they reached the server. Cherry-picked from upstream (63745813), authorship preserved.

Packaging (0.5.5)

  • The package now contains exactly the build it needs. dist/ is rebuilt from empty before every publish. Stale Cloud Mode compiler output (dist/cloudflare/, which nothing in the package uses) is gone, and both MCP App bundles (token browser, design-system dashboard) are included. They were missing from 0.5.1 and 0.5.2, so reading those app resources failed there.

Notes

  • Versions below 0.5.4 are deprecated on npm. They lack the HTTP guard and the accessibility-scan fix.
  • 0.5.3 was never released.
  • A missing fileContext means unverified, not failed. It arrives only once the plugin has been re-imported from 0.5.4 or later. Clients that rely on it should treat its absence as "targeting not confirmed".
  • npm audit still lists the SDK advisories against the copy nested under agents, which only Cloud Mode loads. Local mode never imports it.
  • Suite: 1467 tests across 55 suites. The HTTP guard is tested with real requests and was checked live: allowed clients complete the handshake and tool calls, while a rebinding Host or a cross-site Origin gets a 403.

npm: npx @muloka/figma-console-mcp@0.5.5

v0.5.2 — the HTTP port survives a re-created port file

Choose a tag to compare

@muloka muloka released this 07 Nov 19:49

No plugin re-import needed. Only the server changed. Restart the server on 0.5.2 to pick up the fix; if you launch with plain npx @muloka/figma-console-mcp, run it once as npx @muloka/figma-console-mcp@latest so npx doesn't reuse a cached copy.

Fixes

  • The HTTP port stays discoverable after the port file is re-created. A server started with MCP_HTTP_PORT publishes it as mcpHttpPort in its port-discovery file (<tmpdir>/figma-console-mcp-<port>.json). If that file was deleted, the 30s heartbeat re-created it without mcpHttpPort and with a new startedAt, so clients that find the server through the file reported its HTTP transport as disabled until a restart. The server now keeps the record it advertised and rewrites it whole: a re-created file keeps mcpHttpPort and the original startedAt, and a file that lost the field gets it back on the next beat. The file's fields are unchanged.
  • The test suite no longer touches real port files. tests/port-discovery.test.ts deleted the default port files (9223–9232) in the real tmpdir after each test, which removed the file of any server running on the same machine; the stale-instance cleanup tests also scanned real servers' files. Each jest run now gets a private TMPDIR, removed at the end.

Notes

  • Patch bump per this fork's versioning rule: fixes only; no tool or behavior change for callers.
  • Suite: 1449 tests across 52 suites; both fixes landed test-first. Checked end to end: a server whose port file was deleted re-created it about 24s later with mcpHttpPort and startedAt intact.

npm: npx @muloka/figma-console-mcp@0.5.2

v0.5.1 — per-call file targeting

Choose a tag to compare

@muloka muloka released this 07 Nov 19:01

No plugin re-import needed. Only the server changed; figma-desktop-bridge/ is untouched, so updating the npm package is enough. If you launch with plain npx @muloka/figma-console-mcp, npx may keep running a cached 0.5.0. Run it once as npx @muloka/figma-console-mcp@latest.

Added

  • Per-call file targeting. figma_execute, figma_setup_design_tokens, figma_batch_create_variables, figma_batch_update_variables, figma_delete_variable, figma_rename_variable and figma_rename_node take an optional fileKey. With it, the call runs only in that file's Desktop Bridge plugin, whichever file is active, and even when another client has pinned the target with figma_navigate({ lock: true }). Several clients sharing one server can each work in their own file without the active file moving under them. Leave fileKey out and nothing changes.
  • A refusal instead of a wrong-file write. If the named file's plugin isn't connected, the call is refused and nothing is sent: File <key> is not connected to the Desktop Bridge, so nothing was sent. Connected files: "<name>" (<key>), …. It never falls back to the active file. Calls without a fileKey keep the old error text.
  • Local mode only. The cloud relay pairs with a single file, so it refuses a fileKey rather than run the call in the paired file.

figma_get_variables already read a specific file through fileUrl; that's unchanged. Details: Targeting a file.

Notes

  • Patch bump per this fork's versioning rule: one optional argument added, and existing calls behave exactly as before.
  • Check the server version before relying on fileKey. A 0.5.0 server silently drops the unknown argument and runs the call in the active file. Clients that depend on targeting should require serverInfo.version ≥ 0.5.1.
  • Suite: 1447 tests across 52 suites, including real-socket tests with two connected files and concurrent calls to both. Also checked live against two open Figma files.

npm: npx @muloka/figma-console-mcp@0.5.1

v0.5.0 — no more orphans, real timeouts, plan-aware mode limits

Choose a tag to compare

@muloka muloka released this 25 Aug 19:37

⚠️ Plugin re-import required for the plugin-side fixes. code.js and ui.html both changed (orphan cleanup, dispatch budgets), but PLUGIN_VERSION correctly stays on the vendored 1.35.0 lineage — so no update banner will prompt you. Re-import figma-desktop-bridge/manifest.json manually. Server-side fixes arrive with the npm update alone.

Fixes

  • Mode-limit failures roll back instead of orphaning (#7, #8). figma_setup_design_tokens and figma_create_variable_collection remove the just-created collection when addMode hits your plan's ceiling, and the setup tool returns the file's real limit: {error, planModeLimit, requested, rolledBack: true} — parsed from Figma's own Limited to N modes only error. The schema's stale 4-mode cap (Figma's pre-raise Professional limit) is now a 40 sanity bound; current plans allow 10/20/unlimited and the runtime governs.
  • Batch-create rows report partial effects honestly (#10). A failure row whose createVariable succeeded before the throw now carries created: true, id, valueSet: false — in figma_batch_create_variables and the setup create pass — so callers can clean up or complete instead of retrying into duplicates.
  • No more orphaned nodes on failure (#11, reduced cut). figma_create_connector validates endpoints before creating (a stale nodeId can no longer strand an endpoint-less connector — previously guaranteed); create-child, add-text-to-slide, and create-table remove their partially-created node on error, suffixing (partially-created node was removed); batch stickies report the id of any sticky a failed row left behind. figma_create_child also gains POLYGON/STAR/VECTOR.
  • Long-running commands get their real timeouts (#9). The server's per-command budget rides in each WS frame and the plugin dispatcher honors it (+5s margin, 310s cap) instead of cutting everything off at a fixed 30s: variable refresh and component scans get 300s, lint/audit 120s, large component sets their scaled budget — on both local and cloud transports. Absent/invalid field falls back to the old 30s, so mixed server/plugin versions behave exactly as before.
  • Plugin-loader guard. A comment pattern (…import at end of line above another comment) tripped Figma's import-expression scanner and bricked plugin load with possible import expression rejected around line 1. Fixed, and Figma's exact scanner regex (extracted from their bundle) now runs in the test suite so the class can't recur.

Notes

  • Minor bump per this fork's versioning rule: failure-path envelopes changed (rollback errors, partial-effect row fields) and plugin files changed.
  • Suite: 1414 tests across 52 suites; every fix landed test-first with the failing case verified before the change.

npm: npx @muloka/figma-console-mcp@0.5.0

v0.4.0 — honest errors, stable servers, truthful update banner

Choose a tag to compare

@muloka muloka released this 25 Aug 16:47

Fixes

  • Honest error reporting in the eight single-op variable/collection/mode write tools (#6). The Desktop Bridge resolves plugin failures as {success:false, error} objects; these tools never checked, so failures surfaced as false successes (figma_create_variable, figma_update_variable, figma_create_variable_collection, figma_rename_mode) or as a masking TypeError (figma_delete_variable, figma_delete_variable_collection, figma_rename_variable, figma_add_mode — e.g. a mode-limit failure reported "Cannot read properties of undefined (reading 'name')" instead of Figma's in addMode: Limited to 10 modes only). Every handler now guards the result envelope and propagates the plugin's error text verbatim; figma_update_variable also notes when the value had applied before a failed description step. 11 new regression tests.
  • Orphan reaper no longer kills healthy MCP servers — cherry-pick of upstream v1.38.2 (fbb1cb80, original authorship preserved). Fixes the "Server disconnected across every MCP client" failure: IPv6-blind health probe, non-atomic port-file writes, and corrupt-file cleanup racing healthy servers.
  • An older server no longer nags a newer plugin to re-import — cherry-pick of upstream v1.39.1 (e5e2df87). The update banner now compares versions directionally (compareSemver), so stale server processes left over from before an upgrade stop showing an un-clearable re-import banner.

Features

  • Plugin + server build versions surfaced in the Desktop Bridge UI and diagnostics.

Notes

  • Minor bump per this fork's versioning rule: the error-reporting guards change observable tool behavior (plugin failures now report as errors instead of successes).
  • Plugin re-import is optional for this release: PLUGIN_VERSION stays at the vendored 1.35.0 lineage, so no update banner will appear — but the version-surfacing improvements in the Desktop Bridge UI only arrive if you manually re-import the plugin from the updated package.
  • This fork is now frozen at the upstream v1.36.0 base with selective cherry-picks — see the README's "Relationship to upstream" section. Bugs go to this repo's tracker, not upstream.

npm: npx @muloka/figma-console-mcp@0.4.0

v0.3.0

Choose a tag to compare

@muloka muloka released this 20 Jul 23:09

Synced to upstream v1.36.0.

Added

Target lock for multi-file parallel work. figma_navigate accepts lock: true, pinning the active file so new connections, reconnects, and your own selection or page changes in other files can't move the target.

Use it when an agent works in one file while you work in another — without it, commands can silently route to whichever file most recently reported activity. Switching to another file or passing lock: false releases the pin, and it releases automatically if the pinned file disconnects.

figma_get_status and figma_navigate now report targetLocked.

Notes

No plugin re-import required. figma-desktop-bridge/ is unchanged from v1.35.0 — upstream's own v1.36.0 ships the same plugin files, so PLUGIN_VERSION stays at 1.35.0.

Requires Node >= 22 (unchanged since v0.2.0).

v0.2.0

Choose a tag to compare

@muloka muloka released this 20 Jul 22:33

First release with CI. Fork of southleft/figma-console-mcp, tracking upstream v1.35.0.

Breaking

  • engines.node raised to >=22. Node 18 reached EOL 2025-04 and Node 20 left maintenance 2026-04, so the previous >=18 certified runtimes nobody should be on. Published as 0.2.0 rather than 0.1.3 so npm's ^0.1.x ranges correctly withhold it.

Fixed

  • figma_get_variables now honors page/pageSize under format='full' (upstream #98). They were accepted, silently ignored, and omitted from the response, so callers had no way to detect paging had not happened. On a 689-variable file format='full' auto-summarizes into nothing usable and paging could not rescue it — the exact case the parameter documents. Both the cached and Desktop Bridge paths were affected.
  • Desktop Bridge no longer drops pagination metadata. It computed paginationInfo and never returned it, so cache-miss requests received silently truncated data with no hasNextPage signal.
  • page/pageSize are now documented accurately: hard limit 100, a soft ~25K-token ceiling above which a page is auto-summarized rather than returned, and out-of-range pages clamp to the last page instead of erroring — so paging loops must be driven off hasNextPage.

Added

  • Setup guidance in the MCP handshake. A connected agent hitting a disconnected bridge is now told to read pluginPath from figma_get_status, and that Figma's import dialog hides the plugin's dot-directory on macOS (press Cmd+Shift+G and paste the path). That last fact appears in no other surface — see upstream #100 and #101.
  • GitHub Actions CI — Node 22/24 test matrix plus a per-file typecheck ratchet that baselines known upstream type errors and fails on new ones.

No plugin re-import required — figma-desktop-bridge/ is unchanged from upstream v1.35.0.