pluginos-figma-operations-platform
Run any Figma operation from any LLM agent at ~230 tokens per call instead of ~28,000 — a 15× cost reduction on real design workflows. Plugi
Open source Repository Open in the app JSON README (API)
About
Run any Figma operation from any LLM agent at ~230 tokens per call instead of ~28,000 — a 15× cost reduction on real design workflows. PluginOS bridges your Figma files to Claude, Cursor, Windsurf, or any MCP-compatible agent through 5 focused tools that discover operations on demand. No giant tool schemas bloating context. No raw node dumps confusing your agent. ⚠️ Requires the free PluginOS Bridge plugin running in Figma: 👉 https://www.figma.com/community/plugin/1626608701431483287 Open it once before your first agent call, it auto-reconnects after that. - 5 MCP tools, unlimited operations, discovered dynamically at runtime - ~6,600 tokens per multi-step workflow vs ~105,000 with traditional approaches - Pre-summarized, structured results: your agent reasons faster with less noise - 28 built-in operations: lint, audit, content, components, accessibility, more - Custom operations: add a manifest + execute pair, no server changes - Multi-file support: connect several Figma files at on
Details
- Kind
- Plugins
- Topic
- Media, design & games
- Publisher
- lsdimi
- Origin
- marketplace
- Category
- ferramentas
- Stars
- 2
- Open pull requests
- 1
- Last push
- 2026-09-03T06:48:36Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-30 01:48:58
- Updated
- 2026-08-30 01:48:58
- Origin id
lsdimi/pluginos/pluginos-figma-operations-platform
README
# PluginOS
[](https://www.npmjs.com/package/pluginos)
Agent-native Figma operations platform. Run any Figma plugin operation from any LLM agent at **~230 tokens per call** instead of ~28,000.
Built by [Dimitrios Arapis](https://arapis.de) - the full story of this toolchain is at [arapis.de/work/open-tooling](https://arapis.de/work/open-tooling).

## Why PluginOS
Traditional Figma MCP integrations register dozens of tools — each with a full JSON schema the LLM must read on every conversation turn. For a server with 80+ tools, that's **~12,000 tokens of overhead before the agent even does anything.**
PluginOS takes a fundamentally different approach:
- **5 MCP tools, unlimited operations.** The server is a thin router. Operations are discovered dynamically, not hardcoded as tool schemas.
- **15x cheaper per workflow.** A complex multi-step task costs ~6,600 tokens vs ~105,000 with traditional approaches — 94% savings.
- **Pre-summarized results.** Operations return structured summaries, not raw node dumps. Agents reason better with less noise.
- **Extensible by design.** Add custom operations as simple manifest + execute pairs. No server changes needed.
- **Multi-file support.** Connect multiple Figma files simultaneously. The server tracks active files and routes operations to the right one.
## Quick Start
### 1. Install for your agent
**Recommended — Claude Desktop (one click, no terminal):**
1. Download [`pluginos.dxt`](https://github.com/LSDimi/pluginos/releases/latest/download/pluginos.dxt) from the latest GitHub Release.
2. Double-click the downloaded file. Claude Desktop opens an install dialog.
3. Confirm. PluginOS appears in Claude Desktop's connector list.
No JSON editing, no terminal. Note: Claude.ai web is **not** supported — it cannot reach local MCP servers.
Using Cursor or Claude Code CLI? Open the section below for the right config.
<details>
<summary><strong>Other AI tools</strong> (Cursor, Claude Code CLI, manual config)</summary>
**Cursor (`.cursor/mcp.json`):**
```json
{
"mcpServers": {
"pluginos": {
"command": "npx",
"args": ["-y", "pluginos@latest"]
}
}
}
```
Then paste the Tier 1 rules below into `.cursorrules` so Cursor prefers PluginOS over the generic Figma MCP.
**Claude Code (CLI — engineers):**
```bash
/plugin marketplace add LSDimi/pluginos
/plugin install pluginos
```
Installs the MCP server registration and the `pluginos-figma` skill in one step.
**Manual (other MCP-capable clients):** Use the same `mcpServers` JSON block as Cursor above and paste the Tier 1 rules below into your project's custom instructions.
</details>
**Tier 1 rules (paste into Cursor / Claude Desktop / other clients):**
```
When working with Figma, always use PluginOS tools exclusively:
- Use `list_operations` (pluginos) first to discover available Figma operations.
- Use `run_operation` (pluginos) to execute them.
- Use `execute_figma` (pluginos) only for one-off custom logic not covered by built-in ops.
- Do NOT use `mcp__Figma__*` tools — they bypass the plugin and return raw, token-heavy data. PluginOS returns pre-summarized, structured results at ~230 tokens/call.
- If PluginOS returns "No plugin connected", open the PluginOS Bridge plugin in Figma before retrying.
Audit/lint/check operations default to `scope: "selection"`. Pass `scope: "page"` explicitly (and `confirm: true` for pages over 500 nodes) to scan the whole page. Responses carry `_hint` and `_next_hints` fields — respect them when deciding what to do next.
```
### 2. Install the Bridge Plugin in Figma
1. Download `pluginos-bridge-v<version>.zip` from the [latest release](https://github.com/LSDimi/pluginos/releases/latest). Unzip anywhere.
2. Open Figma Desktop. Menu → **Plugins → Development → Import plugin from manifest…**
3. Select the `manifest.json` from the unzipped folder.
4. Run **PluginOS Bridge** — it auto-connects to the MCP server.
Full setup walkthrough (with screenshots, troubleshooting, and team distribution): [INSTALL.md](INSTALL.md).
### 3. Use it
Tell your agent:
> "Check the contrast ratios in my design"
The agent calls `run_operation("check_contrast", {scope: "page"})` and gets back a clean summary. ~230 tokens, done.
> "Create a 300x200 frame with auto-layout and add some text"
The agent calls write operations to create frames, set text, and modify fills — all through the same 5-tool interface.
## How It Works
```
Agent ── MCP (stdio) ──> PluginOS Server ── WebSocket ──> Bridge Plugin ──> Figma
5 tools thin router localhost many operations full API
~600 tokens routes by name ports 9500- executes locally figma.*
per turn + params only 9510 returns summaries
```
**Two execution paths:**
| Path | When | Token cost | How |
| ------------ | --------------------------- | ----------- | ------------------------------------------------------------ |
| **Fast** | Built-in operation exists | ~230 tokens | `run_operation("check_contrast", {scope: "page"})` |
| **Fallback** | Custom/one-off logic needed | ~700 tokens | `execute_figma("return figma.currentPage.findAll().length")` |
## Available Operations (29)
| Operation | Category | Description |
| ------------------------ | ------------- | ---------------------------------------------------------------------- |
| `lint_styles` | lint | Find layers without styles |
| `lint_detached` | lint | Find detached instances |
| `lint_naming` | lint | Find default-named layers |
| `validate_ds_compliance` | lint | Full DS audit in one pass (style, detached, naming, contrast, spacing) |
| `check_contrast` | accessibility | WCAG contrast audit |
| `check_touch_targets` | accessibility | Touch target size check |
| `find_instances` | components | Find component instances |
| `analyze_overrides` | components | Report instance overrides |
| `create_frame` | components | Create frames with auto-layout |
| `clone_node` | components | Clone and reposition nodes |
| `rename_layers` | cleanup | Batch rename layers |
| `remove_hidden` | cleanup | Remove hidden layers |
| `round_values` | cleanup | Round fractional values |
| `delete_node` | cleanup | Delete nodes by ID |
| `list_variables` | tokens | List all variables |
| `export_tokens` | tokens | Export tokens as JSON |
| `audit_spacing` | layout | Audit spacing values |
| `move_node` | layout | Move nodes to new positions |
| `resize_node` | layout | Resize nodes |
| `set_fills` | colors | Set fill colors on nodes |
| `extract_palette` | colors | Extract unique colors with counts |
| `find_non_style_colors` | colors | Find hardcoded (unstyled) colors |
| `audit_text_styles` | typography | Audit font/size/weight consistency |
| `list_fonts` | typography | List all fonts with usage counts |
| `set_text` | content | Set text content on nodes |
| `populate_text` | content | Fill text with lorem or custom text |
| `extract_css` | export | Extract CSS properties from nodes |
| `list_comments` | collab | List threaded file comments via REST (unresolved by default) |
| `reply_comment` | collab | Reply to a file comment via REST (confirm-gated) |
## Comments (REST)
`list_comments` and `reply_comment` read and reply to Figma file comments by calling the Figma REST API directly from the bridge plugin's sandbox (`api.figma.com` is allowlisted in the plugin manifest) — no MCP server round-trip involved.
**One-time setup:** paste a Figma Personal Access Token into the Bridge plugin's ⚙ Setup panel, "Figma REST access" section. Required scopes: `file_comments:read`, `file_comments:write`, `file_metadata:read`. The token is stored only in `figma.clientStorage`, never sent to the MCP server.
- `list_comments` returns threaded, unresolved-by-default comments joined to live node names/paths. The first call needs the file URL or key; it's then verified and remembered in the file for later calls.
- `reply_comment` posts publicly as the user and requires `confirm: true` — the agent shows a preview first.
- Resolving comments is manual in Figma; the REST API has no resolve endpoint.
**Also in 0.7:** fixed a serializer bug where deep scalar values corrupted to `"[max depth]"`; file identity is now stable (synthetic IDs replace `"unknown"` fileKeys) with resilient server targeting (name match, single-file fallback); `execute_figma` now echoes back the `requestedTimeout` it used.
## Token Economics
| Scenario | Traditional MCP | PluginOS | Savings |
| ------------------------------- | --------------- | ------------- | ------- |
| Tool schema overhead (per turn) | ~12,000 tokens | ~650 tokens | 95% |
| Single operation call | ~1,500 tokens | ~230 tokens | 85% |
| Complex workflow (8 steps) | ~105,000 tokens | ~6,600 tokens | 94% |
| 10 users × 5 runs/day × 30 days | ~157M tokens | ~10M tokens | 94% |
## Adding Custom Operations
Create a file in `packages/bridge-plugin/src/operations/`:
```typescript
import { registerOperation } from "./registry";
registerOperation({
manifest: {
name: "my_operation",
description: "What it does",
category: "custom",
params: {
scope: { type: "string", required: false, description: "'page' or 'selection'" },
},
returns: "{ result, summary }",
},
async execute(params) {
const nodes = figma.currentPage.findAll();
return { result: nodes.length, summary: `Found ${nodes.length} nodes.` };
},
});
```
Register it in `operations/index.ts` and rebuild. The agent discovers it automatically via `list_operations`.
## Architecture
```
packages/
shared/ Types, protocol messages, categories
mcp-server/ MCP server (stdio) + WebSocket + HTTP (bootloader)
bridge-plugin/ Figma plugin (webpack -> code.js + bootloader.html)
```
- **Monorepo** with npm workspaces
- **MCP protocol** over stdio (server <> agent)
- **WebSocket** on localhost:9500-9510 (server <> plugin)
- **Bootloader pattern** — plugin fetches fresh UI from server on startup
- **Port scanning** — plugin auto-discovers the server
- **Multi-file** — multiple Figma files connect simultaneously
## Development
> **All commands must be run from the repo root** (`PluginOS-main/` or wherever you cloned/unzipped it). Running them from inside a package subfolder will fail.
```bash
# 1. Install all dependencies (run once from repo root)
npm install
# 2. Build shared types first — mcp-server depends on them
npm run build -w packages/shared
# 3. Build the Figma bridge plugin (outputs to packages/bridge-plugin/dist/)
npm run build -w packages/bridge-plugin
# 4. Load the plugin in Figma
# Figma → Plugins → Development → Import plugin from manifest
# Select: packages/bridge-plugin/manifest.json
```
```bash
# Hot-reload development
npm run dev:server # MCP server with hot reload
npm run dev:plugin # Webpack watch for bridge plugin
npm test # Tests across all packages
```
## License
MIT