@atomixstudio/mcp 1.0.16 → 1.0.19

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 CHANGED
@@ -7,7 +7,8 @@ MCP (Model Context Protocol) server and CLI for Atomix Design System. Query and
7
7
  1. Go to [Atomix Studio](https://atomixstudio.eu)
8
8
  2. Sign in and create/access your design system
9
9
  3. Click **Publish** to make your DS available via API
10
- 4. Your `ds-id` is in the URL: `atomixstudio.eu/ds/[ds-id]`
10
+ 4. Your **ds-id** is in the URL: `atomixstudio.eu/ds/[ds-id]`
11
+ 5. Your **access token**: Export modal or Settings → Regenerate Atomix access token (required for MCP)
11
12
 
12
13
  ## MCP Server Setup
13
14
 
@@ -22,12 +23,14 @@ Create `.cursor/mcp.json` in your project root:
22
23
  "mcpServers": {
23
24
  "my-design-system": {
24
25
  "command": "npx",
25
- "args": ["@atomixstudio/mcp@latest", "--ds-id", "<your-ds-id>"]
26
+ "args": ["@atomixstudio/mcp@latest", "--ds-id", "<your-ds-id>", "--atomix-token", "<your-token>"]
26
27
  }
27
28
  }
28
29
  }
29
30
  ```
30
31
 
32
+ Both `--ds-id` and `--atomix-token` are required. Get your token from Atomix Studio: Export modal or Settings → Regenerate Atomix access token.
33
+
31
34
  ### Claude Desktop
32
35
 
33
36
  Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
@@ -37,7 +40,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
37
40
  "mcpServers": {
38
41
  "my-design-system": {
39
42
  "command": "npx",
40
- "args": ["@atomixstudio/mcp@latest", "--ds-id", "<your-ds-id>"]
43
+ "args": ["@atomixstudio/mcp@latest", "--ds-id", "<your-ds-id>", "--atomix-token", "<your-token>"]
41
44
  }
42
45
  }
43
46
  }
@@ -57,11 +60,12 @@ Once connected, the AI can call these tools:
57
60
  | `listTokens(category)` | List all tokens in a category |
58
61
  | `searchTokens(query)` | Search tokens by name or value |
59
62
  | `validateUsage(value)` | Check if a hardcoded value should use a token |
60
- | `syncTokens(options)` | Sync tokens to a local file |
63
+ | `syncAll(options?)` | Sync tokens, AI rules, skills (.cursor/skills/atomix-ds/*), and atomix-dependencies.json. One tool for full project sync. **/--sync** invokes this. Optional: `output` (default ./tokens.css), `format` (default css), `skipTokens` (if true, only skills + manifest). |
61
64
  | `getAIToolRules(tool)` | Generate AI coding rules for your design system |
62
65
  | `exportMCPConfig(tool)` | Get MCP configuration for different tools |
63
66
  | `getSetupInstructions(tool)` | Get detailed setup guide |
64
- | `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 **/--getstarted** prompt. |
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. |
65
69
 
66
70
  ### getDependencies
67
71
 
@@ -71,28 +75,38 @@ Returns DS-derived suggestions so the AI can build a "Suggested" vs "Already pre
71
75
 
72
76
  **Returns (JSON):**
73
77
 
74
- - **iconLibrary** — `package`, `nativePackage`, and a performance hint (use individual SVG imports for tree-shaking).
75
- - **fonts** — Font family names from typography tokens + performance hint (self-hosted `@font-face`, `font-display: swap`).
78
+ - **iconLibrary** — `package`, `nativePackage`, and a performance hint (use individual imports; apply the DS icon sizing/weight token when rendering icons).
79
+ - **fonts** — Font family names from typography tokens + hint to link fonts via URL (e.g. Google Fonts); no need to download or add font files to the repo.
76
80
  - **skill** — `path` (e.g. `.cursor/skills/atomix-ds/SKILL.md`) and `content` (generic, platform-agnostic SKILL.md).
81
+ - **skillFigmaDesign** — `path` (`.cursor/skills/atomix-ds/design-in-figma.md`) and `content` (design-in-Figma skill: principal product designer, correct token use, prefer existing Figma variables).
77
82
  - **tokenFiles** — e.g. `["tokens.css", "tokens.json"]` with copy instructions.
83
+ - **meta** — `dsName`, `platform`, `stack`, `designSystemVersion`, `designSystemExportedAt`. Use `designSystemVersion` to compare with skill frontmatter `atomixDsVersion` and suggest **syncAll** when the design system is newer.
78
84
 
79
85
  If the design system is unavailable, the tool may fail; the client should tell the user the design system could not be reached.
80
86
 
87
+ ### syncAll
88
+
89
+ **syncAll** is the single sync tool: tokens file, AI rules, skills (`.cursor/skills/atomix-ds/SKILL.md`, `design-in-figma.md`), and **atomix-dependencies.json**. The manifest records icon library, font families, and paths. The **/--sync** prompt invokes it. Optional: `output` (default `./tokens.css`), `format` (default `css`), `skipTokens` (if true, only writes skills and manifest).
90
+
91
+ **Skill versioning:** Synced skills get frontmatter `atomixDsVersion` and `atomixDsExportedAt` (from the design system at sync time). The manifest’s `skills.syncedAtVersion` matches. The AI can compare the skill’s `atomixDsVersion` to **getDependencies**’ `meta.designSystemVersion`; if the design system is newer, it can suggest running **syncAll** to update.
92
+
81
93
  ## MCP Prompts
82
94
 
83
- Run these prompts from your AI tool (e.g. **/--hello**, **/--getstarted**):
95
+ Run these prompts from your AI tool (e.g. **/--hello**, **/--get-started**):
84
96
 
85
97
  | Prompt | Description |
86
98
  |--------|-------------|
87
99
  | **/--hello** | Get started — overview, tokens, and tools. Run this first. |
88
- | **/--getstarted** | Get started with design system in project. Three phases; creates files only after you approve. |
100
+ | **/--get-started** | Get started with design system in project. Three phases; creates files only after you approve. |
89
101
  | **/--rules** | Governance rules for your AI tool (Cursor, Copilot, Windsurf, etc.). |
90
- | **/--sync** | Sync tokens to a local file. Use **/--refactor** to migrate deprecated tokens. |
102
+ | **/--sync** | Sync tokens, AI rules, skills files, and dependencies manifest (icons, fonts). Use **/--refactor** to migrate deprecated tokens. |
91
103
  | **/--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. |
92
106
 
93
- ## --getstarted (get started)
107
+ ## --get-started (get started)
94
108
 
95
- The **/--getstarted** prompt suggests dependencies for your design system so you can get up and running quickly. It does **not** install anything by default; the AI presents a list and asks before making changes.
109
+ The **/--get-started** prompt suggests dependencies for your design system so you can get up and running quickly. It does **not** install anything by default; the AI presents a list and asks before making changes.
96
110
 
97
111
  **Flow (phased instructions):**
98
112
 
@@ -100,10 +114,37 @@ The **/--getstarted** prompt suggests dependencies for your design system so you
100
114
  2. **Get suggested dependencies** — Call `getDependencies(platform, stack)`. If the call fails, tell the user the design system could not be reached and stop.
101
115
  3. **Scan codebase and build suggestion list** — Scan for `package.json` (or equivalent), existing skill path, token files, font/icon usage. Build **Suggested dependencies** (from getDependencies minus what's present) and **Already present**. Do not install or copy anything in this phase.
102
116
  4. **Present list and ask before install** — Reply with "Suggested dependencies: …" and "Already present: …" and state: "Do not install or copy anything until you confirm. Would you like me to install or add these?" Only perform steps the user approves.
103
- 5. **Optional: suggest global styles** — If the project has no global styles that use the design system tokens, ask verbatim: "Your project doesn't appear to have global styles that use the design system tokens (e.g. semantic typography scale or semantic color classes). Would you like me to suggest or generate a minimal set (e.g. typography scale + semantic utilities) so you can develop consistently with the DS?"
117
+ 5. **Optional: suggest global typeset** — If the project has no global styles that use the design system tokens, offer to build a full typeset (Display, Heading, body, caption) from the DS typography tokens via getToken/listTokens, including fontFamily, fontSize, fontWeight, lineHeight, letterSpacing—not just font imports.
104
118
  6. **Report what was created** — After any install/copy steps, list what was created or updated (e.g. "Installed: lucide-react. Added: .cursor/skills/atomix-ds/SKILL.md. Synced: tokens.css.").
105
119
 
106
- **Single SKILL.md:** The getstarted flow suggests adding a generic, coding-platform agnostic SKILL at `.cursor/skills/atomix-ds/SKILL.md`. It instructs the AI to call `getAIToolRules({ tool: "<tool>" })` where `<tool>` matches the current environment (cursor, windsurf, copilot, cline, continue, zed, generic).
120
+ **SKILLs:** The get-started flow suggests adding (1) a generic SKILL at `.cursor/skills/atomix-ds/SKILL.md` (coding-platform agnostic; calls `getAIToolRules` for the current environment), and (2) a **Figma design skill** at `.cursor/skills/atomix-ds/design-in-figma.md` for designing in Figma using granular MCP commands (syncToFigma, resolveFigmaIdsForTokens, designCreateFrame, designCreateText, etc.) with no code generation.
121
+
122
+ ## Sync to Figma
123
+
124
+ **/--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
+
126
+ **Flow:**
127
+
128
+ 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.
129
+ 2. **Only if that fails** should the user check MCP configuration and plugin connection manually.
130
+
131
+ **User steps (when needed):**
132
+
133
+ 1. **Ensure MCP is running** — Cursor should have this MCP server configured and running (the bridge is built in; no separate bridge process).
134
+ 2. **Install and run the Atomix plugin** — In Figma: Open Plugins and run the Atomix plugin (Atomix Token Extractor). If it's not installed yet, install it from the Figma Community or your team's plugin library, then run it.
135
+ 3. **Connect** — In the plugin UI, tap **Connect to Cursor** and wait until the status shows "Connected".
136
+ 4. Run **Sync to Figma** again.
137
+
138
+ ## Design in Figma
139
+
140
+ **/--design-in-figma** designs in the open Figma file using **granular MCP commands** (no script execution) and a **three-pass flow**:
141
+
142
+ 1. **Setup:** **syncToFigma** → **createDesignPlaceholder** (save `frameId`) → **getAIToolRules** + **listTokens** → **resolveFigmaIdsForTokens**.
143
+ 2. **Pass 1 — Layout and contents (wireframe):** Build structure with designCreateFrame, designCreateText, designCreateRectangle, designSetAutoLayout, designSetLayoutConstraints, designAppendChild. You must use auto-layout/fill/hug. Then **getDesignScreenshot** and check the image;
144
+ 3. **Pass 2 — Apply design tokens and AI rules:** Set all fills and text styles from the resolved map; follow getAIToolRules for all design foundations. Prioritise colors, typography, and buttons. No hardcoded values only use Figma variables. Then **getDesignScreenshot** and verify.
145
+ 4. **Pass 3 — Confirm no hardcoded values:** Audit that every value uses an id from resolved. **getDesignScreenshot** again, then **finalizeDesignFrame** with `frameId`, `name` (e.g. "Login card ✅"), and `fillVariableId`/`fillPaintStyleId` for surface (removes placeholder gray). Summarise what was built.
146
+
147
+ **If the bridge is not reachable:** ensure the Atomix plugin is running in Figma and **Connect to Cursor** is clicked; leave the plugin open. The MCP server (and bridge) must be running in Cursor.
107
148
 
108
149
  ## Token Categories
109
150
 
@@ -185,6 +226,8 @@ Creates:
185
226
  | Option | Description |
186
227
  |--------|-------------|
187
228
  | `--ds-id` | Design system ID (or set in .atomixrc) |
229
+ | `--atomix-token` | Access token (required for MCP; from Export modal or Settings → Regenerate) |
230
+ | `--api-base` | API base URL (default: https://atomixstudio.eu). Use only for self-hosted instances. |
188
231
  | `--api-key` | API key for private design systems |
189
232
  | `--output, -o` | Output file path [./tokens.css] |
190
233
  | `--format` | Output format (see below) |
@@ -230,6 +273,8 @@ npx heyatomix sync
230
273
 
231
274
  ## Troubleshooting
232
275
 
276
+ **MCP shows "requires authentication" or no tools:** Add both `--ds-id` and `--atomix-token` to your MCP server args. Get your token from Atomix Studio (Export modal or Settings → Regenerate Atomix access token), then restart your IDE.
277
+
233
278
  **MCP shows old prompts or tools after updating:** Your IDE or npx may be using a cached version. Quit the IDE, clear the npx cache (`rm -rf ~/.npm/_npx` on macOS/Linux, or delete the `_npx` folder inside your [npm cache directory](https://docs.npmjs.com/cli/v10/commands/npm-cache)), then reopen the IDE and reconnect the MCP server.
234
279
 
235
280
  ## Links
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/figma-bridge-protocol.ts
4
+ var BRIDGE_METHODS = [
5
+ "get_document_info",
6
+ "get_selection",
7
+ "get_node_info",
8
+ "get_figma_variables_and_styles",
9
+ "create_color_variables",
10
+ "create_paint_styles",
11
+ "create_text_styles",
12
+ "create_number_variables",
13
+ "apply_fill_to_selection",
14
+ "create_design_placeholder",
15
+ "design_create_frame",
16
+ "design_create_text",
17
+ "design_create_rectangle",
18
+ "design_set_auto_layout",
19
+ "design_set_layout_constraints",
20
+ "design_append_child",
21
+ "get_design_screenshot",
22
+ "finalize_design_frame"
23
+ ];
24
+ function isBridgeRequest(msg) {
25
+ if (!msg || typeof msg !== "object") return false;
26
+ const m = msg;
27
+ return typeof m.id === "string" && m.id.length > 0 && typeof m.method === "string" && m.method.length > 0;
28
+ }
29
+ function normalizeBridgeMethod(method) {
30
+ if (typeof method !== "string" || !method) return method;
31
+ return method.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
32
+ }
33
+ function isAllowedMethod(method) {
34
+ const normalized = normalizeBridgeMethod(method);
35
+ return BRIDGE_METHODS.includes(normalized);
36
+ }
37
+
38
+ export {
39
+ BRIDGE_METHODS,
40
+ isBridgeRequest,
41
+ normalizeBridgeMethod,
42
+ isAllowedMethod
43
+ };
44
+ //# sourceMappingURL=chunk-FFAGTYRZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/figma-bridge-protocol.ts"],"sourcesContent":["/**\n * Bridge wire protocol (merged from figma-bridge).\n * All messages are JSON. Only whitelisted methods are allowed.\n * Used by the in-process Figma bridge (WebSocket server in mcp-user).\n */\n\nexport const BRIDGE_METHODS = [\n \"get_document_info\",\n \"get_selection\",\n \"get_node_info\",\n \"get_figma_variables_and_styles\",\n \"create_color_variables\",\n \"create_paint_styles\",\n \"create_text_styles\",\n \"create_number_variables\",\n \"apply_fill_to_selection\",\n \"create_design_placeholder\",\n \"design_create_frame\",\n \"design_create_text\",\n \"design_create_rectangle\",\n \"design_set_auto_layout\",\n \"design_set_layout_constraints\",\n \"design_append_child\",\n \"get_design_screenshot\",\n \"finalize_design_frame\",\n] as const;\n\nexport type BridgeMethod = (typeof BRIDGE_METHODS)[number];\n\nexport interface BridgeRequest {\n id: string;\n method: string;\n params?: Record<string, unknown>;\n}\n\nexport interface BridgeSuccessResponse {\n id: string;\n result: unknown;\n}\n\nexport interface BridgeErrorResponse {\n id: string;\n error: string;\n}\n\nexport type BridgeResponse = BridgeSuccessResponse | BridgeErrorResponse;\n\nexport function isBridgeRequest(msg: unknown): msg is BridgeRequest {\n if (!msg || typeof msg !== \"object\") return false;\n const m = msg as Record<string, unknown>;\n return (\n typeof m.id === \"string\" &&\n m.id.length > 0 &&\n typeof m.method === \"string\" &&\n m.method.length > 0\n );\n}\n\n/** Convert camelCase to snake_case for bridge (e.g. getFigmaVariablesAndStyles -> get_figma_variables_and_styles). */\nexport function normalizeBridgeMethod(method: string): string {\n if (typeof method !== \"string\" || !method) return method;\n return method.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n}\n\nexport function isAllowedMethod(method: string): method is BridgeMethod {\n const normalized = normalizeBridgeMethod(method);\n return (BRIDGE_METHODS as readonly string[]).includes(normalized);\n}\n"],"mappings":";;;AAMO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsBO,SAAS,gBAAgB,KAAoC;AAClE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,IAAI;AACV,SACE,OAAO,EAAE,OAAO,YAChB,EAAE,GAAG,SAAS,KACd,OAAO,EAAE,WAAW,YACpB,EAAE,OAAO,SAAS;AAEtB;AAGO,SAAS,sBAAsB,QAAwB;AAC5D,MAAI,OAAO,WAAW,YAAY,CAAC,OAAQ,QAAO;AAClD,SAAO,OAAO,QAAQ,UAAU,CAAC,MAAM,IAAI,EAAE,YAAY,CAAC,EAAE;AAC9D;AAEO,SAAS,gBAAgB,QAAwC;AACtE,QAAM,aAAa,sBAAsB,MAAM;AAC/C,SAAQ,eAAqC,SAAS,UAAU;AAClE;","names":[]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Bridge wire protocol (merged from figma-bridge).
3
+ * All messages are JSON. Only whitelisted methods are allowed.
4
+ * Used by the in-process Figma bridge (WebSocket server in mcp-user).
5
+ */
6
+ declare const BRIDGE_METHODS: readonly ["get_document_info", "get_selection", "get_node_info", "get_figma_variables_and_styles", "create_color_variables", "create_paint_styles", "create_text_styles", "create_number_variables", "apply_fill_to_selection", "create_design_placeholder", "design_create_frame", "design_create_text", "design_create_rectangle", "design_set_auto_layout", "design_set_layout_constraints", "design_append_child", "get_design_screenshot", "finalize_design_frame"];
7
+ type BridgeMethod = (typeof BRIDGE_METHODS)[number];
8
+ interface BridgeRequest {
9
+ id: string;
10
+ method: string;
11
+ params?: Record<string, unknown>;
12
+ }
13
+ interface BridgeSuccessResponse {
14
+ id: string;
15
+ result: unknown;
16
+ }
17
+ interface BridgeErrorResponse {
18
+ id: string;
19
+ error: string;
20
+ }
21
+ type BridgeResponse = BridgeSuccessResponse | BridgeErrorResponse;
22
+ declare function isBridgeRequest(msg: unknown): msg is BridgeRequest;
23
+ /** Convert camelCase to snake_case for bridge (e.g. getFigmaVariablesAndStyles -> get_figma_variables_and_styles). */
24
+ declare function normalizeBridgeMethod(method: string): string;
25
+ declare function isAllowedMethod(method: string): method is BridgeMethod;
26
+
27
+ export { BRIDGE_METHODS, type BridgeErrorResponse, type BridgeMethod, type BridgeRequest, type BridgeResponse, type BridgeSuccessResponse, isAllowedMethod, isBridgeRequest, normalizeBridgeMethod };
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BRIDGE_METHODS,
4
+ isAllowedMethod,
5
+ isBridgeRequest,
6
+ normalizeBridgeMethod
7
+ } from "./chunk-FFAGTYRZ.js";
8
+ export {
9
+ BRIDGE_METHODS,
10
+ isAllowedMethod,
11
+ isBridgeRequest,
12
+ normalizeBridgeMethod
13
+ };
14
+ //# sourceMappingURL=figma-bridge-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}