@sxl-studio/bridge 1.2.0

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.
Files changed (56) hide show
  1. package/README.md +153 -0
  2. package/dist/bridge-version.d.ts +4 -0
  3. package/dist/bridge-version.js +18 -0
  4. package/dist/bridge-version.js.map +1 -0
  5. package/dist/command-http.d.ts +13 -0
  6. package/dist/command-http.js +29 -0
  7. package/dist/command-http.js.map +1 -0
  8. package/dist/command-queue.d.ts +29 -0
  9. package/dist/command-queue.js +168 -0
  10. package/dist/command-queue.js.map +1 -0
  11. package/dist/http-api.d.ts +8 -0
  12. package/dist/http-api.js +146 -0
  13. package/dist/http-api.js.map +1 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.js +35 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/mcp-factory.d.ts +7 -0
  18. package/dist/mcp-factory.js +30 -0
  19. package/dist/mcp-factory.js.map +1 -0
  20. package/dist/mcp-server.d.ts +9 -0
  21. package/dist/mcp-server.js +16 -0
  22. package/dist/mcp-server.js.map +1 -0
  23. package/dist/session.d.ts +22 -0
  24. package/dist/session.js +64 -0
  25. package/dist/session.js.map +1 -0
  26. package/dist/sxl-mcp-instructions.d.ts +5 -0
  27. package/dist/sxl-mcp-instructions.js +36 -0
  28. package/dist/sxl-mcp-instructions.js.map +1 -0
  29. package/dist/tools/composition.d.ts +6 -0
  30. package/dist/tools/composition.js +47 -0
  31. package/dist/tools/composition.js.map +1 -0
  32. package/dist/tools/data.d.ts +6 -0
  33. package/dist/tools/data.js +56 -0
  34. package/dist/tools/data.js.map +1 -0
  35. package/dist/tools/diagnostics.d.ts +6 -0
  36. package/dist/tools/diagnostics.js +70 -0
  37. package/dist/tools/diagnostics.js.map +1 -0
  38. package/dist/tools/figma-nodes.d.ts +9 -0
  39. package/dist/tools/figma-nodes.js +347 -0
  40. package/dist/tools/figma-nodes.js.map +1 -0
  41. package/dist/tools/figma-rc-extended.d.ts +6 -0
  42. package/dist/tools/figma-rc-extended.js +54 -0
  43. package/dist/tools/figma-rc-extended.js.map +1 -0
  44. package/dist/tools/git.d.ts +6 -0
  45. package/dist/tools/git.js +40 -0
  46. package/dist/tools/git.js.map +1 -0
  47. package/dist/tools/tokens.d.ts +6 -0
  48. package/dist/tools/tokens.js +66 -0
  49. package/dist/tools/tokens.js.map +1 -0
  50. package/dist/types.d.ts +44 -0
  51. package/dist/types.js +5 -0
  52. package/dist/types.js.map +1 -0
  53. package/dist/ws-server.d.ts +31 -0
  54. package/dist/ws-server.js +120 -0
  55. package/dist/ws-server.js.map +1 -0
  56. package/package.json +36 -0
@@ -0,0 +1,347 @@
1
+ /**
2
+ * MCP tools for direct Figma node manipulation.
3
+ *
4
+ * These tools give the agent full control over the Figma file:
5
+ * reading nodes, modifying properties, navigation, creation, deletion.
6
+ */
7
+ import { z } from "zod";
8
+ export function registerFigmaNodeTools(server, queue) {
9
+ // ─── Reading ───
10
+ server.tool("get_node_info", "Get detailed information about selected nodes or a specific node by ID. Returns type, name, size, position, text content, component properties, composition binding, and child count.", {
11
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
12
+ }, async ({ nodeId }) => {
13
+ const result = await queue.execute("get_node_info", nodeId ? { nodeId } : {});
14
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
15
+ });
16
+ server.tool("get_node_tree", "Get the node tree (hierarchy) of selected nodes or a specific node. Returns nested children up to a specified depth.", {
17
+ nodeId: z.string().optional().describe("Root node ID. Omit to use current selection."),
18
+ depth: z.number().optional().describe("Max tree depth (1-10, default 3)"),
19
+ }, async ({ nodeId, depth }) => {
20
+ const payload = {};
21
+ if (nodeId)
22
+ payload.nodeId = nodeId;
23
+ if (depth)
24
+ payload.depth = depth;
25
+ const result = await queue.execute("get_node_tree", payload);
26
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
27
+ });
28
+ // ─── Selection & Navigation ───
29
+ server.tool("select_nodes", "Select specific nodes in Figma by their IDs. Scrolls viewport to show selected nodes.", {
30
+ nodeIds: z.array(z.string()).describe("Array of node IDs to select"),
31
+ }, async ({ nodeIds }) => {
32
+ const result = await queue.execute("select_nodes", { nodeIds });
33
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
34
+ });
35
+ server.tool("get_pages", "List all pages in the current Figma file. Shows which page is currently active.", {}, async () => {
36
+ const result = await queue.execute("get_pages", {});
37
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
38
+ });
39
+ server.tool("set_current_page", "Switch to a different page in the Figma file.", {
40
+ pageId: z.string().optional().describe("Page ID to switch to"),
41
+ pageName: z.string().optional().describe("Page name to switch to (alternative to pageId)"),
42
+ }, async ({ pageId, pageName }) => {
43
+ const payload = {};
44
+ if (pageId)
45
+ payload.pageId = pageId;
46
+ if (pageName)
47
+ payload.pageName = pageName;
48
+ const result = await queue.execute("set_current_page", payload);
49
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
50
+ });
51
+ // ─── Visual Properties ───
52
+ server.tool("set_node_fill", "Set the fill color of selected nodes or a specific node. Uses hex color format.", {
53
+ color: z.string().describe("Hex color (e.g. '#FF5733', '#000')"),
54
+ opacity: z.number().optional().describe("Fill opacity 0-1 (default 1)"),
55
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
56
+ }, async ({ color, opacity, nodeId }) => {
57
+ const payload = { color };
58
+ if (opacity !== undefined)
59
+ payload.opacity = opacity;
60
+ if (nodeId)
61
+ payload.nodeId = nodeId;
62
+ const result = await queue.execute("set_node_fill", payload);
63
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
64
+ });
65
+ server.tool("set_node_fill_variable", "Bind the first fill of selected nodes (or a node by ID) to a local COLOR variable. Requires variableId from the current file (e.g. from export_variables / variables API).", {
66
+ variableId: z.string().describe("Figma variable id (COLOR)"),
67
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
68
+ }, async ({ variableId, nodeId }) => {
69
+ const payload = { variableId };
70
+ if (nodeId)
71
+ payload.nodeId = nodeId;
72
+ const result = await queue.execute("set_node_fill_variable", payload);
73
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
74
+ });
75
+ server.tool("rename_node", "Rename selected nodes or a specific node.", {
76
+ name: z.string().describe("New name for the node(s)"),
77
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
78
+ }, async ({ name, nodeId }) => {
79
+ const payload = { name };
80
+ if (nodeId)
81
+ payload.nodeId = nodeId;
82
+ const result = await queue.execute("rename_node", payload);
83
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
84
+ });
85
+ server.tool("set_node_visibility", "Show or hide selected nodes or a specific node.", {
86
+ visible: z.boolean().describe("true = visible, false = hidden"),
87
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
88
+ }, async ({ visible, nodeId }) => {
89
+ const payload = { visible };
90
+ if (nodeId)
91
+ payload.nodeId = nodeId;
92
+ const result = await queue.execute("set_node_visibility", payload);
93
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
94
+ });
95
+ server.tool("set_node_size", "Resize selected nodes or a specific node.", {
96
+ width: z.number().optional().describe("New width in pixels"),
97
+ height: z.number().optional().describe("New height in pixels"),
98
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
99
+ }, async ({ width, height, nodeId }) => {
100
+ const payload = {};
101
+ if (width !== undefined)
102
+ payload.width = width;
103
+ if (height !== undefined)
104
+ payload.height = height;
105
+ if (nodeId)
106
+ payload.nodeId = nodeId;
107
+ const result = await queue.execute("set_node_size", payload);
108
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
109
+ });
110
+ // ─── Batch Data Insertion ───
111
+ server.tool("insert_data", "Insert data into selected nodes by matching layer names to data keys. Supports single object or array of objects. When array is provided, each row maps to one selected node. Example: { 'label': 'Hello', 'description': 'World' } sets text on layers named 'label' and 'description'.", {
112
+ data: z.union([
113
+ z.record(z.string()),
114
+ z.array(z.record(z.string())),
115
+ ]).describe("Object { layerName: textValue } or array of such objects for multiple nodes"),
116
+ nodeId: z.string().optional().describe("Specific node ID. Omit to use current selection."),
117
+ }, async ({ data, nodeId }) => {
118
+ const payload = { data };
119
+ if (nodeId)
120
+ payload.nodeId = nodeId;
121
+ const result = await queue.execute("insert_data", payload);
122
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
123
+ });
124
+ // ─── Create Nodes ───
125
+ server.tool("create_frame", "Create a new frame on the current page or under an optional parent. Supports Auto Layout fields when layoutMode is HORIZONTAL or VERTICAL.", {
126
+ name: z.string().optional().describe("Frame name (default 'New Frame')"),
127
+ width: z.number().optional().describe("Width in pixels (default 100)"),
128
+ height: z.number().optional().describe("Height in pixels (default 100)"),
129
+ x: z.number().optional().describe("X position (default 0)"),
130
+ y: z.number().optional().describe("Y position (default 0)"),
131
+ parentId: z.string().optional().describe("Parent node id (frame/group/component set/instance with children)"),
132
+ layoutMode: z.enum(["NONE", "HORIZONTAL", "VERTICAL"]).optional(),
133
+ padding: z.number().optional().describe("Uniform padding (sets all sides)"),
134
+ paddingLeft: z.number().optional(),
135
+ paddingRight: z.number().optional(),
136
+ paddingTop: z.number().optional(),
137
+ paddingBottom: z.number().optional(),
138
+ itemSpacing: z.number().optional(),
139
+ primaryAxisAlignItems: z.enum(["MIN", "MAX", "CENTER", "SPACE_BETWEEN"]).optional(),
140
+ counterAxisAlignItems: z.enum(["MIN", "MAX", "CENTER", "BASELINE"]).optional(),
141
+ primaryAxisSizingMode: z.enum(["FIXED", "AUTO"]).optional(),
142
+ counterAxisSizingMode: z.enum(["FIXED", "AUTO"]).optional(),
143
+ clipsContent: z.boolean().optional(),
144
+ layoutGrow: z.number().optional(),
145
+ layoutSizingHorizontal: z.enum(["FIXED", "HUG", "FILL"]).optional(),
146
+ layoutSizingVertical: z.enum(["FIXED", "HUG", "FILL"]).optional(),
147
+ }, async (args) => {
148
+ const payload = {};
149
+ const keys = [
150
+ "name",
151
+ "width",
152
+ "height",
153
+ "x",
154
+ "y",
155
+ "parentId",
156
+ "layoutMode",
157
+ "padding",
158
+ "paddingLeft",
159
+ "paddingRight",
160
+ "paddingTop",
161
+ "paddingBottom",
162
+ "itemSpacing",
163
+ "primaryAxisAlignItems",
164
+ "counterAxisAlignItems",
165
+ "primaryAxisSizingMode",
166
+ "counterAxisSizingMode",
167
+ "clipsContent",
168
+ "layoutGrow",
169
+ "layoutSizingHorizontal",
170
+ "layoutSizingVertical",
171
+ ];
172
+ for (const k of keys) {
173
+ const v = args[k];
174
+ if (v !== undefined)
175
+ payload[k] = v;
176
+ }
177
+ const result = await queue.execute("create_frame", payload);
178
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
179
+ });
180
+ server.tool("create_text", "Create a new text node on the current page or inside a parent (e.g. Auto Layout frame). Optional layout* fields apply when the parent uses Auto Layout.", {
181
+ text: z.string().describe("Text content"),
182
+ name: z.string().optional().describe("Layer name (default 'Text')"),
183
+ fontSize: z.number().optional().describe("Font size (default 16)"),
184
+ x: z.number().optional().describe("X position (default 0)"),
185
+ y: z.number().optional().describe("Y position (default 0)"),
186
+ parentId: z.string().optional().describe("Parent node id"),
187
+ layoutGrow: z.number().optional(),
188
+ layoutAlign: z.enum(["MIN", "CENTER", "MAX", "STRETCH", "INHERIT"]).optional(),
189
+ layoutSizingHorizontal: z.enum(["FIXED", "HUG", "FILL"]).optional(),
190
+ layoutSizingVertical: z.enum(["FIXED", "HUG", "FILL"]).optional(),
191
+ }, async (args) => {
192
+ const payload = { text: args.text };
193
+ const keys = [
194
+ "name",
195
+ "fontSize",
196
+ "x",
197
+ "y",
198
+ "parentId",
199
+ "layoutGrow",
200
+ "layoutAlign",
201
+ "layoutSizingHorizontal",
202
+ "layoutSizingVertical",
203
+ ];
204
+ for (const k of keys) {
205
+ const v = args[k];
206
+ if (v !== undefined)
207
+ payload[k] = v;
208
+ }
209
+ const result = await queue.execute("create_text", payload);
210
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
211
+ });
212
+ server.tool("create_rectangle", "Create a rectangle shape on the page or inside a parent frame. Optional hex fill and corner radius.", {
213
+ name: z.string().optional(),
214
+ width: z.number().optional(),
215
+ height: z.number().optional(),
216
+ x: z.number().optional(),
217
+ y: z.number().optional(),
218
+ parentId: z.string().optional(),
219
+ fillColor: z.string().optional().describe("Hex e.g. #E2E8F0"),
220
+ cornerRadius: z.number().optional(),
221
+ }, async (args) => {
222
+ const payload = {};
223
+ for (const k of ["name", "width", "height", "x", "y", "parentId", "fillColor", "cornerRadius"]) {
224
+ const v = args[k];
225
+ if (v !== undefined)
226
+ payload[k] = v;
227
+ }
228
+ const result = await queue.execute("create_rectangle", payload);
229
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
230
+ });
231
+ server.tool("set_auto_layout", "Configure Auto Layout on a single FRAME, COMPONENT, or INSTANCE (same payload fields as create_frame layout*: layoutMode or direction alias, padding, itemSpacing or spacing alias, alignment, etc.).", {
232
+ nodeId: z.string().optional().describe("Target node; omit if exactly one node is selected"),
233
+ layoutMode: z.enum(["NONE", "HORIZONTAL", "VERTICAL"]).optional(),
234
+ direction: z.enum(["NONE", "HORIZONTAL", "VERTICAL"]).optional().describe("Alias of layoutMode"),
235
+ padding: z.number().optional(),
236
+ paddingLeft: z.number().optional(),
237
+ paddingRight: z.number().optional(),
238
+ paddingTop: z.number().optional(),
239
+ paddingBottom: z.number().optional(),
240
+ itemSpacing: z.number().optional(),
241
+ spacing: z.number().optional().describe("Alias of itemSpacing"),
242
+ primaryAxisAlignItems: z.enum(["MIN", "MAX", "CENTER", "SPACE_BETWEEN"]).optional(),
243
+ counterAxisAlignItems: z.enum(["MIN", "MAX", "CENTER", "BASELINE"]).optional(),
244
+ primaryAxisSizingMode: z.enum(["FIXED", "AUTO"]).optional(),
245
+ counterAxisSizingMode: z.enum(["FIXED", "AUTO"]).optional(),
246
+ clipsContent: z.boolean().optional(),
247
+ layoutGrow: z.number().optional(),
248
+ layoutSizingHorizontal: z.enum(["FIXED", "HUG", "FILL"]).optional(),
249
+ layoutSizingVertical: z.enum(["FIXED", "HUG", "FILL"]).optional(),
250
+ }, async (args) => {
251
+ const payload = {};
252
+ for (const k of [
253
+ "nodeId",
254
+ "layoutMode",
255
+ "direction",
256
+ "padding",
257
+ "paddingLeft",
258
+ "paddingRight",
259
+ "paddingTop",
260
+ "paddingBottom",
261
+ "itemSpacing",
262
+ "spacing",
263
+ "primaryAxisAlignItems",
264
+ "counterAxisAlignItems",
265
+ "primaryAxisSizingMode",
266
+ "counterAxisSizingMode",
267
+ "clipsContent",
268
+ "layoutGrow",
269
+ "layoutSizingHorizontal",
270
+ "layoutSizingVertical",
271
+ ]) {
272
+ const v = args[k];
273
+ if (v !== undefined)
274
+ payload[k] = v;
275
+ }
276
+ const result = await queue.execute("set_auto_layout", payload);
277
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
278
+ });
279
+ // ─── Delete / Clone ───
280
+ server.tool("delete_nodes", "Delete nodes by their IDs or delete the current selection.", {
281
+ nodeIds: z.array(z.string()).optional().describe("Node IDs to delete. Omit to delete current selection."),
282
+ }, async ({ nodeIds }) => {
283
+ const result = await queue.execute("delete_nodes", nodeIds ? { nodeIds } : {});
284
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
285
+ });
286
+ server.tool("clone_node", "Clone (duplicate) selected nodes or a specific node. The clone is placed next to the original.", {
287
+ nodeId: z.string().optional().describe("Node ID to clone. Omit to clone current selection."),
288
+ }, async ({ nodeId }) => {
289
+ const result = await queue.execute("clone_node", nodeId ? { nodeId } : {});
290
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
291
+ });
292
+ server.tool("duplicate_subtree", "Deep-clone a node subtree and append it under targetParentId (documentation templates, layout duplication).", {
293
+ sourceNodeId: z.string().optional().describe("Root of subtree to clone; omit if exactly one node selected"),
294
+ targetParentId: z.string().describe("Parent frame/group to insert the duplicate under"),
295
+ offsetX: z.number().optional(),
296
+ offsetY: z.number().optional(),
297
+ }, async ({ sourceNodeId, targetParentId, offsetX, offsetY }) => {
298
+ const payload = { targetParentId };
299
+ if (sourceNodeId)
300
+ payload.sourceNodeId = sourceNodeId;
301
+ if (offsetX !== undefined)
302
+ payload.offsetX = offsetX;
303
+ if (offsetY !== undefined)
304
+ payload.offsetY = offsetY;
305
+ const result = await queue.execute("duplicate_subtree", payload);
306
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
307
+ });
308
+ server.tool("create_component_instance", "Create an instance from a local COMPONENT (mainComponentId or componentId alias) or a published library (componentKey).", {
309
+ mainComponentId: z.string().optional().describe("Node id of a COMPONENT in the current file"),
310
+ componentId: z.string().optional().describe("Alias of mainComponentId (local COMPONENT node id)"),
311
+ componentKey: z.string().optional().describe("Published component key from team library"),
312
+ parentId: z.string().optional(),
313
+ x: z.number().optional(),
314
+ y: z.number().optional(),
315
+ }, async (args) => {
316
+ const payload = {};
317
+ for (const k of ["mainComponentId", "componentId", "componentKey", "parentId", "x", "y"]) {
318
+ const v = args[k];
319
+ if (v !== undefined)
320
+ payload[k] = v;
321
+ }
322
+ const result = await queue.execute("create_component_instance", payload);
323
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
324
+ });
325
+ server.tool("apply_documentation_payload", "Fill TEXT layers by layer name under targetRootId. Use after duplicating a doc template (entries: { layerName, text }[]).", {
326
+ targetRootId: z.string().describe("Frame or group root to search under"),
327
+ entries: z.array(z.object({
328
+ layerName: z.string(),
329
+ text: z.string(),
330
+ })).describe("Match TextNode.name; set characters"),
331
+ }, async ({ targetRootId, entries }) => {
332
+ const result = await queue.execute("apply_documentation_payload", { targetRootId, entries });
333
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
334
+ });
335
+ // ─── Notifications ───
336
+ server.tool("notify", "Show a notification message in Figma. Useful for user feedback during automated workflows.", {
337
+ message: z.string().describe("Notification message text"),
338
+ error: z.boolean().optional().describe("Show as error notification (red). Default: false"),
339
+ }, async ({ message, error }) => {
340
+ const payload = { message };
341
+ if (error)
342
+ payload.error = error;
343
+ const result = await queue.execute("notify", payload);
344
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
345
+ });
346
+ }
347
+ //# sourceMappingURL=figma-nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-nodes.js","sourceRoot":"","sources":["../../src/tools/figma-nodes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP tools for extended SXL Remote Connect canvas commands (parity with common remote canvas APIs).
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { CommandQueue } from "../command-queue.js";
6
+ export declare function registerRcExtendedCanvasTools(server: McpServer, queue: CommandQueue): void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * MCP tools for extended SXL Remote Connect canvas commands (parity with common remote canvas APIs).
3
+ */
4
+ import { z } from "zod";
5
+ /** Accepts arbitrary JSON object keys (Remote Connect canvas payloads). */
6
+ const loosePayload = z.record(z.string(), z.unknown());
7
+ function registerLooseCanvasTool(server, queue, name, description) {
8
+ server.registerTool(name, { description, inputSchema: loosePayload }, async (payload) => {
9
+ const result = await queue.execute(name, payload);
10
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
11
+ });
12
+ }
13
+ /** Extended direct canvas handlers (beyond figma-nodes base set). */
14
+ const RC_EXTENDED_TOOL_DEFS = [
15
+ { name: "create_ellipse", description: "Create an ellipse. Optional: name, x, y, width, height, fillColor, parentId." },
16
+ { name: "create_line", description: "Create a line. Optional: name, x, y, length, color, strokeWeight, rotation, parentId." },
17
+ { name: "create_svg_node", description: "Create nodes from an SVG string. Required: svg. Optional: name, x, y, width, height, parentId." },
18
+ { name: "create_vector", description: "Create a vector (pen). Optional: vectorNetwork, vectorPaths, fillColor, gradient, stroke*, parentId." },
19
+ { name: "modify_node", description: "Update a node by id: name, x, y, width, height, fillColor, opacity, cornerRadius, visible, rotation, text fields, layout*." },
20
+ { name: "set_stroke", description: "Set solid stroke on a node. nodeId, color, weight, strokeAlign, dashPattern." },
21
+ { name: "set_effects", description: "Replace effects (DROP_SHADOW, INNER_SHADOW, LAYER_BLUR, BACKGROUND_BLUR). nodeId, effects[]." },
22
+ { name: "set_fill", description: "Replace fills array (SOLID + gradient types). nodeId, fills[]." },
23
+ { name: "set_image_fill", description: "IMAGE fill from imageBytes (number[]), or placeholder gradient. nodeId or x/y/width/height/parentId for new rect." },
24
+ { name: "delete_node", description: "Remove a single node by nodeId." },
25
+ { name: "get_selection", description: "Return current page selection as lightweight serialized nodes (depth 2)." },
26
+ { name: "get_page_structure", description: "Serialize current page children. Optional maxDepth (default 4)." },
27
+ { name: "read_node_properties", description: "Read one node as serialized tree. nodeId, optional depth." },
28
+ { name: "find_nodes", description: "Search under current page or rootNodeId by name query and/or type. Optional limit." },
29
+ { name: "set_selection", description: "Select nodes by nodeIds[]; scrolls viewport." },
30
+ { name: "move_to_parent", description: "Reparent nodeId under parentId. Optional index for insertChild." },
31
+ { name: "get_local_styles", description: "List local paint, text, and effect styles in the file." },
32
+ { name: "list_components", description: "List COMPONENT / COMPONENT_SET. Optional pageOnly, nameFilter, limit." },
33
+ { name: "detach_instance", description: "Detach INSTANCE to frame. nodeId." },
34
+ { name: "import_component_by_key", description: "Import published component or set by key; optional variantName, parentId, x, y, size, name." },
35
+ { name: "import_style_by_key", description: "Import a remote style by key." },
36
+ { name: "boolean_operation", description: "UNION | SUBTRACT | INTERSECT | EXCLUDE on nodeIds[] (min 2). Optional name." },
37
+ { name: "flatten_nodes", description: "Flatten nodeIds[] to vector(s). Optional name." },
38
+ { name: "style_text_range", description: "Style TEXT ranges: nodeId, ranges[{start,end, font*, fillColor, decoration, ...}]." },
39
+ { name: "set_constraints", description: "Set layout constraints. nodeId, horizontal, vertical." },
40
+ { name: "create_component", description: "Create empty component. name, x, y, width, height, fillColor, cornerRadius, description, parentId." },
41
+ { name: "create_component_set", description: "combineAsVariants from componentIds[] (min 2). Optional name." },
42
+ { name: "create_variable_collection", description: "Create variable collection. name, optional modes[]" },
43
+ { name: "create_variable", description: "createVariable: name, collectionId, type, optional values{ modeId: value }" },
44
+ { name: "bind_variable", description: "Bind variable to node field (Plugin API setBoundVariable). nodeId, variableId, field." },
45
+ { name: "get_variables", description: "List local variable collections and variables. Optional type filter, limit." },
46
+ { name: "list_available_fonts", description: "List fonts available in Figma + project text styles. Optional query, limit." },
47
+ { name: "export_as_svg", description: "Export node as SVG string. nodeId; optional exportChildren for each child." },
48
+ ];
49
+ export function registerRcExtendedCanvasTools(server, queue) {
50
+ for (const def of RC_EXTENDED_TOOL_DEFS) {
51
+ registerLooseCanvasTool(server, queue, def.name, def.description);
52
+ }
53
+ }
54
+ //# sourceMappingURL=figma-rc-extended.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-rc-extended.js","sourceRoot":"","sources":["../../src/tools/figma-rc-extended.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP tools — Git pull from the active Sync connection (same as plugin footer Pull).
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { CommandQueue } from "../command-queue.js";
6
+ export declare function registerGitTools(server: McpServer, queue: CommandQueue): void;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * MCP tools — Git pull from the active Sync connection (same as plugin footer Pull).
3
+ */
4
+ import { z } from "zod";
5
+ export function registerGitTools(server, queue) {
6
+ server.tool("git_pull", "Pull latest token files, config, and datasets from the remote Git branch configured in SXL Studio Sync. Uses the active connection if connectionId is omitted. Equivalent to Pull in the plugin footer.", {
7
+ connectionId: z
8
+ .string()
9
+ .optional()
10
+ .describe("Sync connection UUID from the plugin. Omit to use the currently active connection."),
11
+ }, async ({ connectionId }) => {
12
+ const payload = {};
13
+ if (connectionId)
14
+ payload.connectionId = connectionId;
15
+ const result = await queue.execute("git_pull", payload);
16
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
17
+ });
18
+ server.tool("git_hard_pull", "Hard pull: reset local workspace for the connection scope then pull (use when branch/scope changed). Same as hard pull in the plugin when switching remotes.", {
19
+ connectionId: z.string().optional().describe("Sync connection UUID; omit for active connection."),
20
+ }, async ({ connectionId }) => {
21
+ const payload = {};
22
+ if (connectionId)
23
+ payload.connectionId = connectionId;
24
+ const result = await queue.execute("git_hard_pull", payload);
25
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
26
+ });
27
+ server.tool("git_push", "Push local token/dataset/mapping changes to the remote Git branch (same as Push in the plugin footer). Uses the active Sync connection unless connectionId is set.", {
28
+ connectionId: z.string().optional().describe("Sync connection UUID; omit for active connection."),
29
+ message: z.string().optional().describe("Commit message (default: Remote push)."),
30
+ }, async ({ connectionId, message }) => {
31
+ const payload = {};
32
+ if (connectionId)
33
+ payload.connectionId = connectionId;
34
+ if (message)
35
+ payload.message = message;
36
+ const result = await queue.execute("git_push", payload);
37
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
38
+ });
39
+ }
40
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,KAAmB;IACrE,MAAM,CAAC,IAAI,CACT,UAAU,EACV,yMAAyM,EACzM;QACE,YAAY,EAAE,CAAC;aACZ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,oFAAoF,CAAC;KAClG,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;QACzB,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,IAAI,YAAY;YAAE,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACxD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,8JAA8J,EAC9J;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;KAClG,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;QACzB,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,IAAI,YAAY;YAAE,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC7D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,UAAU,EACV,oKAAoK,EACpK;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;QACjG,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;KAClF,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE;QAClC,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,IAAI,YAAY;YAAE,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;QACtD,IAAI,OAAO;YAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACxD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP tools for Vars / Tokens operations.
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { CommandQueue } from "../command-queue.js";
6
+ export declare function registerTokenTools(server: McpServer, queue: CommandQueue): void;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * MCP tools for Vars / Tokens operations.
3
+ */
4
+ import { z } from "zod";
5
+ export function registerTokenTools(server, queue) {
6
+ server.tool("export_variables", "Export design token variables and styles to Figma. By default exports ALL collections with codeSyntax and scopes enabled. Use 'collection' to filter by name.", {
7
+ collection: z.string().optional().describe("Export only this collection (by name). Omit to export all."),
8
+ applyCodeSyntaxAndScopes: z.boolean().optional().describe("Apply codeSyntax and scopes from $extensions (default: true)"),
9
+ forceUpdateAll: z.boolean().optional().describe("Force re-export of all variables even if unchanged (default: false)"),
10
+ deleteOrphans: z.boolean().optional().describe("Delete Figma variables that no longer exist in token files (default: false)"),
11
+ }, async ({ collection, applyCodeSyntaxAndScopes, forceUpdateAll, deleteOrphans }) => {
12
+ const settings = {};
13
+ if (collection)
14
+ settings.selectedCollections = [collection];
15
+ if (applyCodeSyntaxAndScopes !== undefined)
16
+ settings.applyCodeSyntaxAndScopes = applyCodeSyntaxAndScopes;
17
+ if (forceUpdateAll !== undefined)
18
+ settings.forceUpdateAll = forceUpdateAll;
19
+ if (deleteOrphans !== undefined)
20
+ settings.deleteOrphans = deleteOrphans;
21
+ const result = await queue.execute("export_variables", { settings });
22
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
23
+ });
24
+ server.tool("reset_diff", "Reset all Diff-IDs across all token files. Forces re-export of all variables on next export.", {}, async () => {
25
+ const result = await queue.execute("reset_diff");
26
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
27
+ });
28
+ server.tool("reset_diff_collection", "Reset Diff-IDs for a specific collection.", { collectionName: z.string().describe("Name of the collection to reset") }, async ({ collectionName }) => {
29
+ const result = await queue.execute("reset_diff_collection", { collectionName });
30
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
31
+ });
32
+ server.tool("reset_diff_file", "Reset Diff-IDs for a specific token file.", {
33
+ fileId: z.string().describe("Token file ID"),
34
+ fileName: z.string().describe("Token file name"),
35
+ }, async ({ fileId, fileName }) => {
36
+ const result = await queue.execute("reset_diff_file", { fileId, fileName });
37
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
38
+ });
39
+ server.tool("reapply_token_bindings", "Re-apply token bindings to nodes. Scope can be 'selection', 'page', or 'document'.", { scope: z.string().describe("Scope: selection, page, or document") }, async ({ scope }) => {
40
+ const result = await queue.execute("reapply_token_bindings", { scope });
41
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
42
+ });
43
+ server.tool("cross_file_sync_fetch", "Fetch remote variables from a published Figma file for cross-file sync.", {
44
+ fileKey: z.string().describe("Figma file key"),
45
+ accessToken: z.string().describe("Figma access token"),
46
+ }, async ({ fileKey, accessToken }) => {
47
+ const result = await queue.execute("cross_file_sync_fetch", { fileKey, accessToken });
48
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
49
+ });
50
+ server.tool("cross_file_sync_apply", "Apply cross-file sync entries to local variables.", { entries: z.array(z.unknown()).describe("Sync entries to apply") }, async ({ entries }) => {
51
+ const result = await queue.execute("cross_file_sync_apply", { entries });
52
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
53
+ });
54
+ server.tool("get_token_file_content", "Read raw JSON text of a token file from the plugin workspace (by internal fileId from list_token_files).", { fileId: z.string().describe("Token file id (tf_...) from the plugin") }, async ({ fileId }) => {
55
+ const result = await queue.execute("get_token_file_content", { fileId });
56
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
57
+ });
58
+ server.tool("save_token_file", "Write token file JSON content into the plugin workspace (updates in-memory model and marks file dirty for Git).", {
59
+ fileId: z.string().describe("Token file id"),
60
+ content: z.string().describe("Full file body (JSON string)"),
61
+ }, async ({ fileId, content }) => {
62
+ const result = await queue.execute("save_token_file", { fileId, content });
63
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
64
+ });
65
+ }
66
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/tools/tokens.ts"],"names":[],"mappings":"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"}