Atlas / MCP servers / tathagat22 / Plumb

PlumbCAUTION

mcp/tathagat22/plumb

Local Figma MCP server with no REST rate limits, no metered tool-call quotas, and a verification loop. Drop-in alternative to Figma's Dev Mode MCP and Framelink for Claude Code, Cursor, Windsurf — works on every plan including Free.

Verdict
CAUTION
Grade
C
Trust score
77 /100
Exposed tools
28 26r · 2w · 0d
Transport
stdio
License
MIT
Stars
88
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

⭐ If Plumb saves you tokens — or designs you a page — star it on GitHub so others can find it.

Plumb is an AI-native design engineering platform, shipped as a single MCP server. Point it at a Figma file or a live website and it normalises either one into the same semantic design graph — deduped tokens, flexbox-resolved layout, conservative role labels (nav / hero / card ...) — that your coding agent can build from and a verification loop can grade. Point it at a one-line prompt instead and it becomes an AI design director: it researches best-in-class references, extracts a brand, and generates a full, on-brand Figma file on your canvas, then critiques its own render until it clears the bar.

Design → code (Figma or the live web, verified, not vibes) • prompt → design (research → brand → generate → critique) • one semantic design graph underneath both. MCP-native — works with Claude Code, Cursor, Windsurf, or any agent that speaks Model Context Protocol.

📖 Full docs: ****

Read from source at commit 805f5f08f253OBSERVED · 2026-10-07
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add plumb-mcp --env FIGMA_TOKEN=${FIGMA_TOKEN} --env UNSPLASH_ACCESS_KEY=${UNSPLASH_ACCESS_KEY} --env PEXELS_API_KEY=${PEXELS_API_KEY} --env PIXABAY_API_KEY=${PIXABAY_API_KEY} -- npx -y [email protected]
03

Exposed tools (28)

26 read · 2 write · 0 destructive.

ToolRiskDescription
plumb_assetsread
plumb_auditread
plumb_brandread
plumb_componentsread
plumb_describeread
plumb_designread
plumb_diffread
plumb_emit_reactread
plumb_fig_noderead
plumb_fig_outlineread
plumb_fitread
plumb_import_webwrite
plumb_noderead
plumb_outlineread
plumb_queryread
plumb_reviewread
plumb_scan_referencesread
plumb_screenshotread
plumb_searchread
plumb_selectionread
plumb_sourceread
plumb_statusread
plumb_studioread
plumb_studio_kitread
plumb_studio_pageread
plumb_studio_startwrite
plumb_tokensread
plumb_verifyread
04

Trust audit

CAUTIONgrade C · trust 77/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (4 observation(s))
Network
declared (4 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (25)

MEDIUMInventory / provenance · inv.binary · CWE-1104
figma-plugin/emit/shared.ts
shared.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInventory / provenance · inv.binary · CWE-1104
src/emit/plan/text.ts
text.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
bench/run.ts:183
console.log(`  estTokens=${compression.estTokens}, token dedup ratio=${compression.dedupRatio.toFixed(3)}`);
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
scripts/prove.ts:121
console.log(`✓ PASS: fixture PDS is under the ${TARGET}-token target and structurally complete.`);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
Dockerfile:116
CMD node -e "fetch('http://127.0.0.1:'+(process.env.PLUMB_BRIDGE_PORT||31337)+'/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
src/tools/verify.ts:29
"QA-strict on appearance — colour (ΔE2000), icon/asset fidelity, box-shadow, " +
LOWInventory / provenance · inv.hidden_file · CWE-1104
.checkov.yaml
.checkov.yaml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
deploy/helm/plumb/.helmignore
.helmignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/cache.ts:19
const hash = createHash("sha1").update(key).digest("hex").slice(0, 20);
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/tools/source.ts:69
const hash = createHash("sha1").update(r.bytes!).digest("hex").slice(0, 10);
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
bench/fixtures/role.fixtures.ts:25
import type { CirEdge, CirNode, SemanticGraph } from "../../src/semantic/graph";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
playground/src/App.tsx:5
import type { PdsDocument } from "../../src/pds";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
playground/src/figma.ts:11
import { fetchNodeViaRest } from "../../src/figma/rest";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
playground/src/figma.ts:12
import { resolveFigmaTarget } from "../../src/figma/url";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
playground/src/figma.ts:13
import { normalizeToBudget } from "../../src/normalize/budget";
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:333
docker compose up bridge    # bridge + Plumb Studio on http://127.0.0.1:31337
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
deploy/README.md:15
open http://127.0.0.1:31337/
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
deploy/helm/plumb/templates/NOTES.txt:12
then open http://127.0.0.1:{{ .Values.bridge.port }}/
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
deploy/terraform/examples/minimal/README.md:7
open http://127.0.0.1:31337/
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
docs/public/play/assets/index-xlL-kyPz.js:90
})();<\/script>`;function fm(e){return e.includes("</body>")?e.replace("</body>",`${Ws}</body>`):e+Ws}function dm(e,t,n=8e3){return new Promise((r,l)=>{let i=!1;const o=()=>{i||(i=!0,clearTimeout(s),w
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
playground/src/App.tsx:27
return JSON.parse(decodeURIComponent(escape(atob(h.slice(4)))));
LOWObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
src/verify/color.test.ts:98
it("carries a numeric ΔE distance so the caller can rank findings", () => {
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@modelcontextprotocol/sdk, openfig-core, ws, zod, @figma/plugin-typings, @types/node, @types/ws, @vitest/coverage-v8
Why it matters. 16 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
playground/package.json
react, react-dom, @types/react, @types/react-dom, @vitejs/plugin-react, typescript, vite
Why it matters. 7 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
studio/package.json
react, react-dom, @types/react, @types/react-dom, @vitejs/plugin-react, typescript, vite
Why it matters. 7 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 805f5f08f253full audit observations/trust-audit/mcp-server/tathagat22__plumb.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-07805f5f08f253CAUTIONC77first audit
06

Questions

What is the Plumb MCP server?

Local Figma MCP server with no REST rate limits, no metered tool-call quotas, and a verification loop. Drop-in alternative to Figma's Dev Mode MCP and Framelink for Claude Code, Cursor, Windsurf — works on every plan including Free.

What tools does Plumb expose?

28 in total: 26 read-only, 2 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Plumb safe to connect to an agent?

With care. The audit graded it C (77/100) and found 25 things worth knowing before you trust this server, listed below with the exact line each was found on.

What credentials does Plumb need?

It reads ANTHROPIC_API_KEY, FIGMA_ACCESS_TOKEN, FIGMA_TOKEN, PEXELS_API_KEY, PIXABAY_API_KEY, PLUMB_FILE_KEY and UNSPLASH_ACCESS_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Plumb run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as plumb-studio at 0.12.0.

How current is this page?

The grade is for one exact copy of the source (805f5f08f253), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement