@atomixstudio/mcp 1.0.19 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/dist/index.js +42 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -65,7 +65,9 @@ Once connected, the AI can call these tools:
|
|
|
65
65
|
| `exportMCPConfig(tool)` | Get MCP configuration for different tools |
|
|
66
66
|
| `getSetupInstructions(tool)` | Get detailed setup guide |
|
|
67
67
|
| `getDependencies(platform?, stack?)` | Get suggested dependencies (icons, fonts, SKILL.md, token files). Optional: `platform` (web, ios, android), `stack` (e.g. react, vue, next). Use with **/--get-started** prompt. |
|
|
68
|
-
| `syncToFigma()` | Push design system to Figma (variables, paint styles, text styles, effect styles). Uses built-in bridge + Atomix plugin. If the plugin is not connected, the response includes `agentInstruction` to connect. |
|
|
68
|
+
| `syncToFigma()` | Push design system to Figma (variables, paint styles, text styles, effect styles). Uses built-in bridge + Atomix plugin. If the plugin is not connected, the response includes `agentInstruction` to connect. **Available on all tiers (Free and Pro).** |
|
|
69
|
+
|
|
70
|
+
Other Figma tools (getFigmaVariablesAndStyles, createDesignPlaceholder, resolveFigmaIdsForTokens, designCreateFrame, designCreateText, etc.) are **Pro only** — they appear when the design system owner has a Pro subscription.
|
|
69
71
|
|
|
70
72
|
### getDependencies
|
|
71
73
|
|
|
@@ -101,8 +103,8 @@ Run these prompts from your AI tool (e.g. **/--hello**, **/--get-started**):
|
|
|
101
103
|
| **/--rules** | Governance rules for your AI tool (Cursor, Copilot, Windsurf, etc.). |
|
|
102
104
|
| **/--sync** | Sync tokens, AI rules, skills files, and dependencies manifest (icons, fonts). Use **/--refactor** to migrate deprecated tokens. |
|
|
103
105
|
| **/--refactor** | Migrate deprecated tokens in codebase. Run after **/--sync**. |
|
|
104
|
-
| **/--sync-to-figma** | Push design system to Figma. Requires bridge + Atomix plugin; see [Sync to Figma](#sync-to-figma) below. |
|
|
105
|
-
| **/--design-in-figma** | Design UI in Figma: **3 passes** (wireframe → tokens/rules → audit), **getDesignScreenshot** after each pass, then **finalizeDesignFrame** (rename + ✅, remove placeholder) and summarise. No code generation. |
|
|
106
|
+
| **/--sync-to-figma** | Push design system to Figma. Requires bridge + Atomix plugin; see [Sync to Figma](#sync-to-figma) below. **Available on all tiers (Free and Pro).** |
|
|
107
|
+
| **/--design-in-figma** | Design UI in Figma: **3 passes** (wireframe → tokens/rules → audit), **getDesignScreenshot** after each pass, then **finalizeDesignFrame** (rename + ✅, remove placeholder) and summarise. No code generation. **Pro only.** |
|
|
106
108
|
|
|
107
109
|
## --get-started (get started)
|
|
108
110
|
|
|
@@ -123,6 +125,8 @@ The **/--get-started** prompt suggests dependencies for your design system so yo
|
|
|
123
125
|
|
|
124
126
|
**/--sync-to-figma** (or the **syncToFigma** tool) pushes your design system into the open Figma file: color variables, paint styles, number variables (spacing, radius, borders, sizing, breakpoints), text styles, and shadow effect styles. The **Figma bridge runs inside this MCP server** (no separate process). You only need the Atomix Figma plugin and "Connect to Cursor" (no Figma REST API or token).
|
|
125
127
|
|
|
128
|
+
**Tier:** Sync to Figma is available on **all tiers** (Free and Pro). The design-in-Figma prompt and design tools (getFigmaVariablesAndStyles, createDesignPlaceholder, resolveFigmaIdsForTokens, designCreateFrame, etc.) require a **Pro** subscription for the design system owner.
|
|
129
|
+
|
|
126
130
|
**Flow:**
|
|
127
131
|
|
|
128
132
|
1. **Plugin not connected?** The tool checks first. If the plugin is not connected, the response includes `bridgeNotRunning`, `agentInstruction`, and `userInstruction`. Ensure Cursor has this MCP server running, then in Figma run the Atomix plugin and click **Connect to Cursor**, then call **syncToFigma** again.
|
package/dist/index.js
CHANGED
|
@@ -1291,6 +1291,8 @@ function getTokenStats(data) {
|
|
|
1291
1291
|
// src/index.ts
|
|
1292
1292
|
import * as path2 from "path";
|
|
1293
1293
|
import * as fs2 from "fs";
|
|
1294
|
+
import { execSync } from "child_process";
|
|
1295
|
+
import { platform } from "os";
|
|
1294
1296
|
import WebSocket, { WebSocketServer } from "ws";
|
|
1295
1297
|
var FIGMA_BRIDGE_PORT = Number(process.env.FIGMA_BRIDGE_PORT) || 8765;
|
|
1296
1298
|
var FIGMA_BRIDGE_HOST = process.env.FIGMA_BRIDGE_HOST || "127.0.0.1";
|
|
@@ -1304,9 +1306,46 @@ var FIGMA_CONNECTION_INSTRUCTIONS = {
|
|
|
1304
1306
|
var bridgeWss = null;
|
|
1305
1307
|
var pluginWs = null;
|
|
1306
1308
|
var pendingBridgeRequests = /* @__PURE__ */ new Map();
|
|
1309
|
+
function ensureFigmaBridgePortFree(port) {
|
|
1310
|
+
const portStr = String(port);
|
|
1311
|
+
const ourPid = String(process.pid);
|
|
1312
|
+
try {
|
|
1313
|
+
if (platform() === "win32") {
|
|
1314
|
+
const out = execSync(`netstat -ano`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] });
|
|
1315
|
+
const pids = /* @__PURE__ */ new Set();
|
|
1316
|
+
for (const line of out.split(/\r?\n/)) {
|
|
1317
|
+
if (line.includes(`:${portStr}`) && line.includes("LISTENING")) {
|
|
1318
|
+
const parts = line.trim().split(/\s+/);
|
|
1319
|
+
const pid = parts[parts.length - 1];
|
|
1320
|
+
if (/^\d+$/.test(pid) && pid !== ourPid) pids.add(pid);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
for (const pid of pids) {
|
|
1324
|
+
try {
|
|
1325
|
+
execSync(`taskkill /PID ${pid} /F`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] });
|
|
1326
|
+
console.error(`[atomix-mcp] Freed Figma bridge port ${port} (killed PID ${pid})`);
|
|
1327
|
+
} catch (_) {
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
} else {
|
|
1331
|
+
const out = execSync(`lsof -ti :${portStr}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
1332
|
+
if (!out) return;
|
|
1333
|
+
const pids = out.split(/\s+/).filter((p) => p && p !== ourPid);
|
|
1334
|
+
for (const pid of pids) {
|
|
1335
|
+
try {
|
|
1336
|
+
execSync(`kill -9 ${pid}`, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] });
|
|
1337
|
+
console.error(`[atomix-mcp] Freed Figma bridge port ${port} (killed PID ${pid})`);
|
|
1338
|
+
} catch (_) {
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
} catch {
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1307
1345
|
function startFigmaBridge() {
|
|
1308
1346
|
if (bridgeWss) return;
|
|
1309
1347
|
try {
|
|
1348
|
+
ensureFigmaBridgePortFree(FIGMA_BRIDGE_PORT);
|
|
1310
1349
|
bridgeWss = new WebSocketServer({
|
|
1311
1350
|
host: FIGMA_BRIDGE_HOST,
|
|
1312
1351
|
port: FIGMA_BRIDGE_PORT,
|
|
@@ -2755,7 +2794,7 @@ ${tokenResponseText}` : summary;
|
|
|
2755
2794
|
};
|
|
2756
2795
|
}
|
|
2757
2796
|
case "getDependencies": {
|
|
2758
|
-
const
|
|
2797
|
+
const platform2 = args?.platform;
|
|
2759
2798
|
const stack = args?.stack;
|
|
2760
2799
|
const tokens = data.tokens;
|
|
2761
2800
|
const typography = tokens?.typography;
|
|
@@ -2799,14 +2838,14 @@ ${tokenResponseText}` : summary;
|
|
|
2799
2838
|
files: ["tokens.css", "tokens.json"],
|
|
2800
2839
|
copyInstructions: "Call the syncAll MCP tool to create the token file, skills, and atomix-dependencies.json; do not only suggest the user run sync later."
|
|
2801
2840
|
},
|
|
2802
|
-
showcase:
|
|
2841
|
+
showcase: platform2 === "web" || !platform2 ? {
|
|
2803
2842
|
path: "atomix-setup-showcase.html",
|
|
2804
2843
|
template: SHOWCASE_HTML_TEMPLATE,
|
|
2805
2844
|
substitutionInstructions: "Replace placeholders with values from the synced token file. MCP/sync/export use the --atmx- prefix. {{TOKENS_CSS_PATH}} = path to the synced token file (e.g. ./tokens.css, same as syncAll output). {{DS_NAME}} = design system name. {{BRAND_PRIMARY_VAR}} = var(--atmx-color-brand-primary). {{BRAND_PRIMARY_FOREGROUND_VAR}} = var(--atmx-color-brand-primary-foreground). {{HEADING_FONT_VAR}} = var(--atmx-typography-font-family-heading) or var(--atmx-typography-font-family-display). {{FONT_FAMILY_VAR}} = var(--atmx-typography-font-family-body). {{FONT_LINK_TAG}} = Google Fonts <link> for the font, or empty string. Do not invent CSS variable names; use only vars that exist in the export."
|
|
2806
2845
|
} : void 0,
|
|
2807
2846
|
meta: {
|
|
2808
2847
|
dsName: data.meta.name,
|
|
2809
|
-
platform:
|
|
2848
|
+
platform: platform2 ?? void 0,
|
|
2810
2849
|
stack: stack ?? void 0,
|
|
2811
2850
|
designSystemVersion: data.meta.version ?? "1.0.0",
|
|
2812
2851
|
designSystemExportedAt: data.meta.exportedAt
|