Atlas / MCP servers / deven-bryant / rolling-design-sync

rolling-design-syncBLOCK

mcp/deven-bryant/rolling-design-sync

Per-node design-implementation ledger: a Figma plugin, API, and agent tooling that tell coding agents exactly which design changes aren't built yet.

Verdict
BLOCK
Grade
F
Trust score
57 /100
Exposed tools
1 0r · 1w · 0d
Transport
stdio
License
Apache-2.0
Stars
0
01

Overview

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

Tell your coding agent exactly which parts of a Figma design aren't built yet.

[](https://github.com/deven-bryant/rolling-design-sync/actions/workflows/ci.yml) [](https://github.com/deven-bryant/rolling-design-sync/actions/workflows/e2e.yml) [](LICENSE) [](apps/api/LICENSE.md)

Rolling Design Sync is a per-node design-implementation ledger for Figma. A Figma plugin records what the design says, coding agents mark nodes as implemented once the code matches, and what's left is exactly the design work that hasn't been built — node by node, property by property.

https://github.com/user-attachments/assets/1b32ff1d-47f8-40c0-9097-fc93ffc743ac

A sync from the Figma plugin, then the changed nodes waiting in the portal.

Status: 0.14 beta. It works end to end, but the API, plugin protocol, MCP tools and CLI may still change between minor releases until 1.0. What's promised, and when, is in the compatibility policy.

Quickstart → from a clean machine to an agent clearing its first Figma changes.

Why

Asking an agent to "implement this Figma frame" works the first time. After that it breaks down:

  • Agents start cold. They re-scan the whole frame, get the big structure

right, and quietly drop details.

  • Figma has no "what changed" API. Webhooks tell you a file changed, not

which nodes or properties.

  • **The real question is "what changed since the code caught up
Read from source at commit 037b82fda4e4OBSERVED · 2026-10-14
Advertisement
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
claude mcp add e2e-portal --env RDS_AGENT_TOKEN=${RDS_AGENT_TOKEN} --env RDS_PLUGIN_TOKEN=${RDS_PLUGIN_TOKEN} --env RDS_TOKENS_FILE=${RDS_TOKENS_FILE} --env RDS_VIEWER_TOKEN=${RDS_VIEWER_TOKEN} -- npx -y @rolling-design-sync/[email protected]
claude-desktop
{
  "mcpServers": {
    "e2e-portal": {
      "command": "npx",
      "args": [
        "-y",
        "@rolling-design-sync/[email protected]"
      ],
      "env": {
        "RDS_AGENT_TOKEN": "${RDS_AGENT_TOKEN}",
        "RDS_PLUGIN_TOKEN": "${RDS_PLUGIN_TOKEN}",
        "RDS_TOKENS_FILE": "${RDS_TOKENS_FILE}",
        "RDS_VIEWER_TOKEN": "${RDS_VIEWER_TOKEN}"
      }
    }
  }
}
03

Exposed tools (1)

0 read · 1 write · 0 destructive.

ToolRiskDescription
rds_sessionwriteThe browser session POST /v3/session mints: a cookie of the same role as the token it was minted from.
04

Trust audit

BLOCKgrade F · trust 57/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
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 (6 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
apps/api/src/server.js:37
const ssl = process.env.PGSSLMODE === 'disable' ? false : { rejectUnauthorized: false };
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.env.example:14
DATABASE_URL=postgresql://postgres:[email protected]_REF.supabase.co:5432/postgres
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
apps/api/src/server.js:24
console.log(`Generated ${local.generated.join(' and ')} token(s), stored in ${local.file} (shown only once):`);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:61
# http://127.0.0.1:<port>, comma-separated; anything else fails startup.
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/e2e.yml:25
DATABASE_URL: postgresql://postgres:[email protected]:5432/fds
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
tests/README.md:30
DATABASE_URL=postgresql://postgres:[email protected]:5433/postgres PGSSLMODE=disable \
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
tests/README.md:34
DATABASE_URL=postgresql://postgres:[email protected]:5433/postgres \
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
apps/portal/src/features/nodes/format.test.ts:20
expect(sideLabel({ token: 'Colors/Background/bg-primary', value: [] })).toBe('bg-primary');
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
apps/portal/src/theme/noFlash.test.ts:13
const run = () => new Function(script)();
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/api/src/schemaCheck.js:13
const MIGRATIONS_DIR = path.resolve(__dirname, '../../../supabase/migrations');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/api/src/store/pglite.js:16
const DEFAULT_MIGRATIONS_DIR = path.resolve(__dirname, '../../../../supabase/migrations');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/api/src/v3/index.js:28
const { version: SERVER_VERSION } = require('../../package.json');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/api/src/v3/status.js:4
const { version } = require('../../package.json');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/api/tests/fixtures/broken-stores.js:4
const { MemoryStore } = require('../../src/store/memory');
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
.github/workflows/e2e.yml:28
RDS_API_URL: http://127.0.0.1:8787
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
.github/workflows/e2e.yml:93
RDS_API_URL: http://127.0.0.1:8787
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
.github/workflows/e2e.yml:133
RDS_API_URL: http://127.0.0.1:8787
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
.github/workflows/e2e.yml:220
RDS_API_URL: http://127.0.0.1:8787
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
apps/api/package.json
@fastify/cors, @rolling-design-sync/core, pg
Why it matters. 3 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
apps/figma-plugin/package.json
@rolling-design-sync/core
Why it matters. 1 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
apps/mcp/package.json
@rolling-design-sync/core, @rolling-design-sync/api
Why it matters. 2 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:134
(the SDK's OAuth client could send credentials to an authorization server
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
apps/figma-plugin/README.md:132
- **Upload token** — one of the server's `RDS_PLUGIN_TOKENS`.
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
apps/figma-plugin/ui.html:13
<label for="token">Upload token</label><input type="password" id="token" placeholder="One of the server's RDS_PLUGIN_TOKENS" autocomplete="off">
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
apps/mcp/README.md:132
| `RDS_AGENT_TOKEN` | yes | An agent token (`RDS_AGENT_TOKENS` on the API; `agent` in `tokens.json` for `RDS_STORE=local` — [docs/agents.md](https://github.com/deven-bryant/rolling-design-sync/blob/ma
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-10-14 · audit v0.4.1 · source sha 037b82fda4e4full audit observations/trust-audit/mcp-server/deven-bryant__rolling-design-sync.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-14037b82fda4e4BLOCKF57first audit
06

Questions

What is the rolling-design-sync MCP server?

Per-node design-implementation ledger: a Figma plugin, API, and agent tooling that tell coding agents exactly which design changes aren't built yet.

What tools does rolling-design-sync expose?

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

Is rolling-design-sync safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (57/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does rolling-design-sync need?

It reads RDS_AGENT_TOKEN, RDS_PLUGIN_TOKEN, RDS_TOKENS_FILE and RDS_VIEWER_TOKEN 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 rolling-design-sync run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as @rolling-design-sync/e2e-portal at 0.0.0.

How current is this page?

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

Advertisement