@atomixstudio/mcp 1.0.20 → 1.0.22

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.
@@ -10,6 +10,7 @@ var BRIDGE_METHODS = [
10
10
  "create_paint_styles",
11
11
  "create_text_styles",
12
12
  "create_number_variables",
13
+ "create_effect_styles",
13
14
  "apply_fill_to_selection",
14
15
  "create_design_placeholder",
15
16
  "design_create_frame",
@@ -41,4 +42,4 @@ export {
41
42
  normalizeBridgeMethod,
42
43
  isAllowedMethod
43
44
  };
44
- //# sourceMappingURL=chunk-FFAGTYRZ.js.map
45
+ //# sourceMappingURL=chunk-BXWOCXYT.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 \"create_effect_styles\",\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;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":[]}
@@ -3,7 +3,7 @@
3
3
  * All messages are JSON. Only whitelisted methods are allowed.
4
4
  * Used by the in-process Figma bridge (WebSocket server in mcp-user).
5
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"];
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", "create_effect_styles", "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
7
  type BridgeMethod = (typeof BRIDGE_METHODS)[number];
8
8
  interface BridgeRequest {
9
9
  id: string;
@@ -4,7 +4,7 @@ import {
4
4
  isAllowedMethod,
5
5
  isBridgeRequest,
6
6
  normalizeBridgeMethod
7
- } from "./chunk-FFAGTYRZ.js";
7
+ } from "./chunk-BXWOCXYT.js";
8
8
  export {
9
9
  BRIDGE_METHODS,
10
10
  isAllowedMethod,
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  isAllowedMethod,
4
4
  normalizeBridgeMethod
5
- } from "./chunk-FFAGTYRZ.js";
5
+ } from "./chunk-BXWOCXYT.js";
6
6
 
7
7
  // src/index.ts
8
8
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -1480,6 +1480,25 @@ function figmaColorNameWithGroup(key) {
1480
1480
  const groupDisplay = group.charAt(0).toUpperCase() + group.slice(1).toLowerCase();
1481
1481
  return `${groupDisplay} / ${name}`;
1482
1482
  }
1483
+ var FIGMA_COLOR_GROUP_ORDER = {
1484
+ background: 0,
1485
+ text: 1,
1486
+ border: 2,
1487
+ icon: 3,
1488
+ brand: 4,
1489
+ action: 5,
1490
+ feedback: 6
1491
+ };
1492
+ var FIGMA_SHADOW_ORDER = {
1493
+ none: 0,
1494
+ xs: 1,
1495
+ sm: 2,
1496
+ md: 3,
1497
+ lg: 4,
1498
+ xl: 5,
1499
+ "2xl": 6,
1500
+ focus: 7
1501
+ };
1483
1502
  function tokenValueToNumber(s) {
1484
1503
  if (typeof s !== "string" || !s.trim()) return 0;
1485
1504
  const t = s.trim();
@@ -1593,6 +1612,25 @@ function buildFigmaPayloadsFromDS(data) {
1593
1612
  }
1594
1613
  }
1595
1614
  if (variables.length === 0 && modes.length === 0) modes.push("Light");
1615
+ const colorSortKey = (figmaName) => {
1616
+ const slash = figmaName.indexOf(" / ");
1617
+ const group = slash >= 0 ? figmaName.slice(0, slash).toLowerCase() : "";
1618
+ const name = slash >= 0 ? figmaName.slice(slash + 3) : figmaName;
1619
+ const order = FIGMA_COLOR_GROUP_ORDER[group] ?? 999;
1620
+ return [order, name];
1621
+ };
1622
+ variables.sort((a, b) => {
1623
+ const [oA, nA] = colorSortKey(a.name);
1624
+ const [oB, nB] = colorSortKey(b.name);
1625
+ if (oA !== oB) return oA - oB;
1626
+ return nA.localeCompare(nB);
1627
+ });
1628
+ paintStyles.sort((a, b) => {
1629
+ const [oA, nA] = colorSortKey(a.name);
1630
+ const [oB, nB] = colorSortKey(b.name);
1631
+ if (oA !== oB) return oA - oB;
1632
+ return nA.localeCompare(nB);
1633
+ });
1596
1634
  const collectionName = data.meta?.name ? `${data.meta.name} Colors` : "Atomix Colors";
1597
1635
  const textStyles = [];
1598
1636
  const sizeToPx = (val, basePx = 16) => {
@@ -1619,8 +1657,8 @@ function buildFigmaPayloadsFromDS(data) {
1619
1657
  };
1620
1658
  const firstFont = (obj) => {
1621
1659
  if (typeof obj === "string") {
1622
- const match = obj.match(/['"]?([^'",\s]+)['"]?/);
1623
- return match ? match[1] : "Inter";
1660
+ const primary = obj.split(",")[0].trim().replace(/^['"]|['"]$/g, "");
1661
+ return primary || "Inter";
1624
1662
  }
1625
1663
  if (obj && typeof obj === "object" && !Array.isArray(obj)) {
1626
1664
  const v = obj.body ?? obj.heading ?? obj.display ?? Object.values(obj)[0];
@@ -1693,49 +1731,70 @@ function buildFigmaPayloadsFromDS(data) {
1693
1731
  textStyles.push(payload);
1694
1732
  }
1695
1733
  }
1696
- const numberVariables = [];
1734
+ textStyles.sort((a, b) => {
1735
+ if (a.fontSize !== b.fontSize) return a.fontSize - b.fontSize;
1736
+ return (a.name || "").localeCompare(b.name || "");
1737
+ });
1697
1738
  const dsName = data.meta?.name ?? "Atomix";
1698
- const primitivesCollectionName = `${dsName} Primitives`;
1739
+ const numberVariableCollections = [];
1699
1740
  const spacing = tokens?.spacing;
1700
1741
  if (spacing?.scale && typeof spacing.scale === "object") {
1742
+ const variables2 = [];
1701
1743
  for (const [key, val] of Object.entries(spacing.scale)) {
1702
1744
  const n = tokenValueToNumber(val);
1703
- if (n >= 0) numberVariables.push({ name: `Spacing / ${key}`, value: n });
1745
+ if (n >= 0) variables2.push({ name: key, value: n });
1704
1746
  }
1747
+ variables2.sort((a, b) => a.value - b.value);
1748
+ if (variables2.length > 0) numberVariableCollections.push({ collectionName: `${dsName} Spacing`, categoryKey: "Spacing", variables: variables2, scopes: ["GAP"] });
1705
1749
  }
1706
1750
  const radius = tokens?.radius;
1707
1751
  if (radius?.scale && typeof radius.scale === "object") {
1752
+ const variables2 = [];
1708
1753
  for (const [key, val] of Object.entries(radius.scale)) {
1709
1754
  const n = tokenValueToNumber(val);
1710
- if (n >= 0) numberVariables.push({ name: `Radius / ${key}`, value: n });
1755
+ if (n >= 0) variables2.push({ name: key, value: n });
1711
1756
  }
1757
+ variables2.sort((a, b) => a.value - b.value);
1758
+ if (variables2.length > 0) numberVariableCollections.push({ collectionName: `${dsName} Radius`, categoryKey: "Radius", variables: variables2, scopes: ["CORNER_RADIUS"] });
1712
1759
  }
1713
1760
  const borders = tokens?.borders;
1714
1761
  if (borders?.width && typeof borders.width === "object") {
1762
+ const variables2 = [];
1715
1763
  for (const [key, val] of Object.entries(borders.width)) {
1716
1764
  const n = tokenValueToNumber(val);
1717
- if (n >= 0) numberVariables.push({ name: `Borders / ${key}`, value: n });
1765
+ if (n >= 0) variables2.push({ name: key, value: n });
1718
1766
  }
1767
+ variables2.sort((a, b) => a.value - b.value);
1768
+ if (variables2.length > 0) numberVariableCollections.push({ collectionName: `${dsName} Borders`, categoryKey: "Borders", variables: variables2, scopes: ["STROKE_FLOAT"] });
1719
1769
  }
1720
1770
  const sizing = tokens?.sizing;
1721
1771
  if (sizing?.height && typeof sizing.height === "object") {
1772
+ const variables2 = [];
1722
1773
  for (const [key, val] of Object.entries(sizing.height)) {
1723
1774
  const n = tokenValueToNumber(val);
1724
- if (n >= 0) numberVariables.push({ name: `Height / ${key}`, value: n });
1775
+ if (n >= 0) variables2.push({ name: key, value: n });
1725
1776
  }
1777
+ variables2.sort((a, b) => a.value - b.value);
1778
+ if (variables2.length > 0) numberVariableCollections.push({ collectionName: `${dsName} Height`, categoryKey: "Height", variables: variables2, scopes: ["WIDTH_HEIGHT"] });
1726
1779
  }
1727
1780
  if (sizing?.icon && typeof sizing.icon === "object") {
1781
+ const variables2 = [];
1728
1782
  for (const [key, val] of Object.entries(sizing.icon)) {
1729
1783
  const n = tokenValueToNumber(val);
1730
- if (n >= 0) numberVariables.push({ name: `Icon / ${key}`, value: n });
1784
+ if (n >= 0) variables2.push({ name: key, value: n });
1731
1785
  }
1786
+ variables2.sort((a, b) => a.value - b.value);
1787
+ if (variables2.length > 0) numberVariableCollections.push({ collectionName: `${dsName} Icon`, categoryKey: "Icon", variables: variables2, scopes: ["WIDTH_HEIGHT"] });
1732
1788
  }
1733
1789
  const layout = tokens?.layout;
1734
1790
  if (layout?.breakpoint && typeof layout.breakpoint === "object") {
1791
+ const variables2 = [];
1735
1792
  for (const [key, val] of Object.entries(layout.breakpoint)) {
1736
1793
  const n = tokenValueToNumber(val);
1737
- if (n >= 0) numberVariables.push({ name: `Breakpoint / ${key}`, value: n });
1794
+ if (n >= 0) variables2.push({ name: key, value: n });
1738
1795
  }
1796
+ variables2.sort((a, b) => a.value - b.value);
1797
+ if (variables2.length > 0) numberVariableCollections.push({ collectionName: `${dsName} Breakpoint`, categoryKey: "Breakpoint", variables: variables2, scopes: ["WIDTH_HEIGHT"] });
1739
1798
  }
1740
1799
  const effectStyles = [];
1741
1800
  const shadows = tokens?.shadows;
@@ -1757,22 +1816,33 @@ function buildFigmaPayloadsFromDS(data) {
1757
1816
  effectStyles.push({ name: "Shadow / focus", effects });
1758
1817
  }
1759
1818
  }
1819
+ effectStyles.sort((a, b) => {
1820
+ const nameA = a.name.startsWith("Shadow / ") ? a.name.slice(9) : a.name;
1821
+ const nameB = b.name.startsWith("Shadow / ") ? b.name.slice(9) : b.name;
1822
+ const orderA = FIGMA_SHADOW_ORDER[nameA] ?? 100;
1823
+ const orderB = FIGMA_SHADOW_ORDER[nameB] ?? 100;
1824
+ if (orderA !== orderB) return orderA - orderB;
1825
+ return nameA.localeCompare(nameB);
1826
+ });
1760
1827
  return {
1761
1828
  colorVariables: { collectionName, modes, variables },
1762
1829
  paintStyles,
1763
1830
  textStyles,
1764
- numberVariables: { collectionName: primitivesCollectionName, variables: numberVariables },
1831
+ numberVariableCollections,
1765
1832
  effectStyles
1766
1833
  };
1767
1834
  }
1768
1835
  function getExpectedFigmaNamesFromDS(data) {
1769
1836
  const payloads = buildFigmaPayloadsFromDS(data);
1837
+ const numberVariableNames = payloads.numberVariableCollections.flatMap(
1838
+ (c) => c.variables.map((v) => `${c.categoryKey} / ${v.name}`)
1839
+ );
1770
1840
  return {
1771
1841
  colorVariableNames: payloads.colorVariables.variables.map((v) => v.name),
1772
1842
  paintStyleNames: payloads.paintStyles.map((s) => s.name),
1773
1843
  textStyleNames: payloads.textStyles.map((s) => s.name),
1774
1844
  effectStyleNames: payloads.effectStyles.map((s) => s.name),
1775
- numberVariableNames: payloads.numberVariables.variables.map((v) => v.name)
1845
+ numberVariableNames
1776
1846
  };
1777
1847
  }
1778
1848
  function parseArgs() {
@@ -1810,8 +1880,8 @@ function hasValidAuthConfig() {
1810
1880
  }
1811
1881
  var AUTH_REQUIRED_MESSAGE = "Atomix MCP requires authentication. Add both --ds-id and --atomix-token to your MCP config (Settings \u2192 MCP), then restart Cursor. Get your token from Atomix Studio: Export modal or Settings \u2192 Regenerate Atomix access token.";
1812
1882
  var lastChangeSummary = null;
1813
- var FIGMA_TOOL_NAMES = /* @__PURE__ */ new Set([
1814
- "syncToFigma",
1883
+ var FIGMA_SYNC_TOOL_NAME = "syncToFigma";
1884
+ var FIGMA_DESIGN_TOOL_NAMES = /* @__PURE__ */ new Set([
1815
1885
  "getFigmaVariablesAndStyles",
1816
1886
  "createDesignPlaceholder",
1817
1887
  "resolveFigmaIdsForTokens",
@@ -1824,6 +1894,7 @@ var FIGMA_TOOL_NAMES = /* @__PURE__ */ new Set([
1824
1894
  "getDesignScreenshot",
1825
1895
  "finalizeDesignFrame"
1826
1896
  ]);
1897
+ var FIGMA_TOOL_NAMES = /* @__PURE__ */ new Set([FIGMA_SYNC_TOOL_NAME, ...FIGMA_DESIGN_TOOL_NAMES]);
1827
1898
  var lastSyncAffectedTokens = null;
1828
1899
  function getLastChangeSummary() {
1829
1900
  return lastChangeSummary;
@@ -1860,7 +1931,7 @@ var TOKEN_CATEGORIES = ["colors", "typography", "spacing", "sizing", "shadows",
1860
1931
  var server = new Server(
1861
1932
  {
1862
1933
  name: "atomix-mcp-user",
1863
- version: "1.0.19"
1934
+ version: "1.0.22"
1864
1935
  },
1865
1936
  {
1866
1937
  capabilities: {
@@ -1883,7 +1954,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
1883
1954
  console.error("[Atomix MCP] Resolved tier = pro. Figma sync/design tools are available.");
1884
1955
  } else if (cachedMcpTier === "free") {
1885
1956
  console.error(
1886
- "[Atomix MCP] Resolved tier = free. Figma sync/design tools are hidden. Pro tools appear when the DS owner has Pro and the pro_figma_export flag is enabled."
1957
+ "[Atomix MCP] Resolved tier = free. Figma design tools and --design-in-figma are hidden. syncToFigma and /--sync-to-figma are available. Pro design tools appear when the DS owner has Pro and the pro_figma_export flag is enabled."
1887
1958
  );
1888
1959
  }
1889
1960
  } catch (err) {
@@ -2212,7 +2283,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
2212
2283
  }
2213
2284
  }
2214
2285
  ];
2215
- const tools = cachedMcpTier === "pro" ? toolsList : toolsList.filter((t) => !FIGMA_TOOL_NAMES.has(t.name));
2286
+ const tools = cachedMcpTier === "pro" ? toolsList : toolsList.filter((t) => !FIGMA_DESIGN_TOOL_NAMES.has(t.name));
2216
2287
  return { tools };
2217
2288
  });
2218
2289
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -2229,12 +2300,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2229
2300
  try {
2230
2301
  const shouldForceRefresh = name === "syncAll";
2231
2302
  const data = await fetchDesignSystemForMCP(shouldForceRefresh);
2232
- if (FIGMA_TOOL_NAMES.has(name) && cachedMcpTier !== "pro") {
2303
+ if (FIGMA_DESIGN_TOOL_NAMES.has(name) && cachedMcpTier !== "pro") {
2233
2304
  return {
2234
2305
  content: [
2235
2306
  {
2236
2307
  type: "text",
2237
- text: "This design system does not have Pro Figma access. Figma sync and design tools are available when the design system owner has a Pro subscription."
2308
+ text: "This design system does not have Pro Figma access. Figma design tools (design-in-Figma, createDesignPlaceholder, resolveFigmaIdsForTokens, etc.) are available when the design system owner has a Pro subscription. Sync to Figma (syncToFigma) is available on all tiers."
2238
2309
  }
2239
2310
  ],
2240
2311
  isError: true
@@ -2880,7 +2951,7 @@ ${tokenResponseText}` : summary;
2880
2951
  variables: payloads.colorVariables.variables,
2881
2952
  paintStyles: payloads.paintStyles,
2882
2953
  textStyles: payloads.textStyles,
2883
- numberVariables: payloads.numberVariables,
2954
+ numberVariableCollections: payloads.numberVariableCollections,
2884
2955
  effectStyles: payloads.effectStyles
2885
2956
  };
2886
2957
  return {
@@ -2897,12 +2968,18 @@ ${tokenResponseText}` : summary;
2897
2968
  if (payloads.paintStyles.length > 0) {
2898
2969
  out.paintStyles = await sendBridgeRequest("create_paint_styles", { styles: payloads.paintStyles });
2899
2970
  }
2900
- if (payloads.numberVariables.variables.length > 0) {
2971
+ if (payloads.numberVariableCollections.length > 0) {
2972
+ const numberResults = [];
2901
2973
  try {
2902
- out.numberVariables = await sendBridgeRequest("create_number_variables", {
2903
- collectionName: payloads.numberVariables.collectionName,
2904
- variables: payloads.numberVariables.variables
2905
- });
2974
+ for (const coll of payloads.numberVariableCollections) {
2975
+ const result = await sendBridgeRequest("create_number_variables", {
2976
+ collectionName: coll.collectionName,
2977
+ variables: coll.variables,
2978
+ scopes: coll.scopes
2979
+ });
2980
+ numberResults.push({ collectionName: coll.collectionName, result });
2981
+ }
2982
+ out.numberVariables = numberResults;
2906
2983
  } catch (e) {
2907
2984
  const msg = e instanceof Error ? e.message : String(e);
2908
2985
  out.numberVariables = { error: msg };
@@ -2923,7 +3000,7 @@ ${tokenResponseText}` : summary;
2923
3000
  variables: payloads.colorVariables.variables,
2924
3001
  paintStyles: payloads.paintStyles,
2925
3002
  textStyles: payloads.textStyles,
2926
- numberVariables: payloads.numberVariables,
3003
+ numberVariableCollections: payloads.numberVariableCollections,
2927
3004
  effectStyles: payloads.effectStyles
2928
3005
  };
2929
3006
  } catch (e) {
@@ -2934,7 +3011,7 @@ ${tokenResponseText}` : summary;
2934
3011
  variables: payloads.colorVariables.variables,
2935
3012
  paintStyles: payloads.paintStyles,
2936
3013
  textStyles: payloads.textStyles,
2937
- numberVariables: payloads.numberVariables,
3014
+ numberVariableCollections: payloads.numberVariableCollections,
2938
3015
  effectStyles: payloads.effectStyles
2939
3016
  };
2940
3017
  const errMsg = out.error.toLowerCase();
@@ -3049,9 +3126,20 @@ ${tokenResponseText}` : summary;
3049
3126
  const response = raw;
3050
3127
  const variableByName = /* @__PURE__ */ new Map();
3051
3128
  if (response.variableCollections) {
3129
+ const numberCategorySuffixes = [" Spacing", " Radius", " Borders", " Height", " Icon", " Breakpoint"];
3052
3130
  for (const coll of response.variableCollections) {
3053
- for (const v of coll.variables || []) {
3054
- variableByName.set(v.name, v.id);
3131
+ if (coll.name.endsWith(" Colors")) {
3132
+ for (const v of coll.variables || []) {
3133
+ variableByName.set(v.name, v.id);
3134
+ }
3135
+ continue;
3136
+ }
3137
+ const numberSuffix = numberCategorySuffixes.find((s) => coll.name.endsWith(s));
3138
+ if (numberSuffix) {
3139
+ const category = numberSuffix.slice(1);
3140
+ for (const v of coll.variables || []) {
3141
+ variableByName.set(`${category} / ${v.name}`, v.id);
3142
+ }
3055
3143
  }
3056
3144
  }
3057
3145
  }
@@ -3495,7 +3583,7 @@ Get your DS ID and token from the Export modal or Settings \u2192 Regenerate Ato
3495
3583
  }
3496
3584
  throw new Error(`Unknown resource: ${uri}`);
3497
3585
  });
3498
- var FIGMA_PROMPT_NAMES = /* @__PURE__ */ new Set(["--sync-to-figma", "--design-in-figma"]);
3586
+ var FIGMA_DESIGN_PROMPT_NAMES = /* @__PURE__ */ new Set(["--design-in-figma"]);
3499
3587
  server.setRequestHandler(ListPromptsRequestSchema, async () => {
3500
3588
  if (!hasValidAuthConfig()) {
3501
3589
  authFailedNoTools = true;
@@ -3520,7 +3608,7 @@ server.setRequestHandler(ListPromptsRequestSchema, async () => {
3520
3608
  { name: "--sync-to-figma", description: "Push this design system to Figma (variables, color + typography styles). Uses local bridge + plugin; no Figma token." },
3521
3609
  { name: "--design-in-figma", description: "Design UI in Figma: 3 passes (wireframe \u2192 tokens/rules \u2192 audit), getDesignScreenshot after each pass, then finalizeDesignFrame (rename + \u2705, remove placeholder) and summarise." }
3522
3610
  ];
3523
- const prompts = cachedMcpTier === "pro" ? allPrompts : allPrompts.filter((p) => !FIGMA_PROMPT_NAMES.has(p.name));
3611
+ const prompts = cachedMcpTier === "pro" ? allPrompts : allPrompts.filter((p) => !FIGMA_DESIGN_PROMPT_NAMES.has(p.name));
3524
3612
  return { prompts };
3525
3613
  });
3526
3614
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
@@ -3622,7 +3710,7 @@ Both are required. Configure the MCP server in your Cursor settings, then restar
3622
3710
  }
3623
3711
  throw error;
3624
3712
  }
3625
- if (FIGMA_PROMPT_NAMES.has(name) && cachedMcpTier !== "pro") {
3713
+ if (FIGMA_DESIGN_PROMPT_NAMES.has(name) && cachedMcpTier !== "pro") {
3626
3714
  return {
3627
3715
  description: "Pro Figma required",
3628
3716
  messages: [
@@ -3630,7 +3718,7 @@ Both are required. Configure the MCP server in your Cursor settings, then restar
3630
3718
  role: "user",
3631
3719
  content: {
3632
3720
  type: "text",
3633
- text: "This design system does not have Pro Figma access. Figma sync and design prompts are available when the design system owner has a Pro subscription."
3721
+ text: "This design system does not have Pro Figma access. The design-in-Figma prompt is available when the design system owner has a Pro subscription. Sync to Figma (/--sync-to-figma) is available on all tiers."
3634
3722
  }
3635
3723
  }
3636
3724
  ]