figma-code-agent-mcp 1.0.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.
- package/dist/assetServer.d.ts +34 -0
- package/dist/assetServer.js +168 -0
- package/dist/codeGenerator/componentDetector.d.ts +57 -0
- package/dist/codeGenerator/componentDetector.js +171 -0
- package/dist/codeGenerator/index.d.ts +77 -0
- package/dist/codeGenerator/index.js +184 -0
- package/dist/codeGenerator/jsxGenerator.d.ts +46 -0
- package/dist/codeGenerator/jsxGenerator.js +182 -0
- package/dist/codeGenerator/styleConverter.d.ts +95 -0
- package/dist/codeGenerator/styleConverter.js +306 -0
- package/dist/hints.d.ts +14 -0
- package/dist/hints.js +105 -0
- package/dist/hub.d.ts +9 -0
- package/dist/hub.js +252 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +146 -0
- package/dist/sandbox.d.ts +18 -0
- package/dist/sandbox.js +154 -0
- package/dist/toolRegistry.d.ts +19 -0
- package/dist/toolRegistry.js +729 -0
- package/dist/tools/captureScreenshot.d.ts +28 -0
- package/dist/tools/captureScreenshot.js +31 -0
- package/dist/tools/cloneNode.d.ts +43 -0
- package/dist/tools/cloneNode.js +46 -0
- package/dist/tools/createFrame.d.ts +157 -0
- package/dist/tools/createFrame.js +114 -0
- package/dist/tools/createInstance.d.ts +38 -0
- package/dist/tools/createInstance.js +41 -0
- package/dist/tools/createRectangle.d.ts +108 -0
- package/dist/tools/createRectangle.js +77 -0
- package/dist/tools/createText.d.ts +81 -0
- package/dist/tools/createText.js +67 -0
- package/dist/tools/deleteNode.d.ts +15 -0
- package/dist/tools/deleteNode.js +18 -0
- package/dist/tools/execute.d.ts +17 -0
- package/dist/tools/execute.js +68 -0
- package/dist/tools/getCurrentPage.d.ts +16 -0
- package/dist/tools/getCurrentPage.js +19 -0
- package/dist/tools/getDesignContext.d.ts +42 -0
- package/dist/tools/getDesignContext.js +55 -0
- package/dist/tools/getLocalComponents.d.ts +20 -0
- package/dist/tools/getLocalComponents.js +23 -0
- package/dist/tools/getNode.d.ts +30 -0
- package/dist/tools/getNode.js +33 -0
- package/dist/tools/getSelection.d.ts +10 -0
- package/dist/tools/getSelection.js +13 -0
- package/dist/tools/getStyles.d.ts +17 -0
- package/dist/tools/getStyles.js +20 -0
- package/dist/tools/getVariables.d.ts +26 -0
- package/dist/tools/getVariables.js +29 -0
- package/dist/tools/moveNode.d.ts +28 -0
- package/dist/tools/moveNode.js +31 -0
- package/dist/tools/openInEditor.d.ts +21 -0
- package/dist/tools/openInEditor.js +98 -0
- package/dist/tools/searchNodes.d.ts +30 -0
- package/dist/tools/searchNodes.js +46 -0
- package/dist/tools/searchTools.d.ts +28 -0
- package/dist/tools/searchTools.js +28 -0
- package/dist/tools/swapComponent.d.ts +23 -0
- package/dist/tools/swapComponent.js +26 -0
- package/dist/tools/updateNode.d.ts +194 -0
- package/dist/tools/updateNode.js +163 -0
- package/dist/types.d.ts +101 -0
- package/dist/types.js +1 -0
- package/dist/websocket.d.ts +30 -0
- package/dist/websocket.js +282 -0
- package/package.json +29 -0
|
@@ -0,0 +1,729 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry of all figma.* methods available in the execute sandbox.
|
|
3
|
+
* Powers the search_tools tool for progressive API discovery.
|
|
4
|
+
*/
|
|
5
|
+
const registry = [
|
|
6
|
+
// === CREATE ===
|
|
7
|
+
{
|
|
8
|
+
name: 'figma.createFrame',
|
|
9
|
+
category: 'create',
|
|
10
|
+
description: 'Create a new frame (container) with optional auto-layout, fill, stroke, and corner radius. Supports CSS-like layout config and hex colors.',
|
|
11
|
+
parameters: {
|
|
12
|
+
name: { type: 'string', description: 'Name of the frame', required: true },
|
|
13
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
14
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
15
|
+
width: { type: 'number', description: 'Width in pixels', default: 100 },
|
|
16
|
+
height: { type: 'number', description: 'Height in pixels', default: 100 },
|
|
17
|
+
parentId: { type: 'string', description: 'Parent node ID or target specifier ("selection", "name:Foo")' },
|
|
18
|
+
cornerRadius: { type: 'number', description: 'Corner radius' },
|
|
19
|
+
layout: { type: 'object', description: 'CSS-like layout: { direction: "row"|"column", gap, padding, alignItems, justifyContent, wrap }' },
|
|
20
|
+
fillColor: { type: 'string | { r, g, b, a? }', description: 'Fill color: hex "#FF0000", rgb(), or {r,g,b} (0-1). Alias: fill' },
|
|
21
|
+
strokeColor: { type: 'string | { r, g, b, a? }', description: 'Stroke color: hex, rgb(), or {r,g,b} (0-1). Alias: stroke' },
|
|
22
|
+
strokeWeight: { type: 'number', description: 'Stroke width in pixels' },
|
|
23
|
+
strokeAlign: { type: "'INSIDE' | 'OUTSIDE' | 'CENTER'", description: 'Stroke alignment' },
|
|
24
|
+
strokeCap: { type: "'NONE' | 'ROUND' | 'SQUARE'", description: 'Stroke cap style' },
|
|
25
|
+
strokeJoin: { type: "'MITER' | 'BEVEL' | 'ROUND'", description: 'Stroke join style' },
|
|
26
|
+
dashPattern: { type: 'number[]', description: 'Dash pattern e.g. [8, 4]' },
|
|
27
|
+
topLeftRadius: { type: 'number', description: 'Top-left corner radius' },
|
|
28
|
+
topRightRadius: { type: 'number', description: 'Top-right corner radius' },
|
|
29
|
+
bottomLeftRadius: { type: 'number', description: 'Bottom-left corner radius' },
|
|
30
|
+
bottomRightRadius: { type: 'number', description: 'Bottom-right corner radius' },
|
|
31
|
+
effects: { type: 'Effect[]', description: 'Effects: [{type:"DROP_SHADOW", color:"#00000033", offset:{x:0,y:4}, radius:12}] or [{type:"LAYER_BLUR", radius:10}]' },
|
|
32
|
+
gradient: { type: 'object', description: 'Gradient fill: {type:"LINEAR", angle:90, stops:[{position:0, color:"#F00"}, {position:1, color:"#00F"}]}' },
|
|
33
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
34
|
+
blendMode: { type: 'string', description: 'Blend mode: NORMAL, MULTIPLY, SCREEN, OVERLAY, etc.' },
|
|
35
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
36
|
+
constraints: { type: 'object', description: 'Constraints: {horizontal: "STRETCH", vertical: "MIN"}' },
|
|
37
|
+
minWidth: { type: 'number', description: 'Minimum width' },
|
|
38
|
+
maxWidth: { type: 'number', description: 'Maximum width' },
|
|
39
|
+
minHeight: { type: 'number', description: 'Minimum height' },
|
|
40
|
+
maxHeight: { type: 'number', description: 'Maximum height' },
|
|
41
|
+
layoutMode: { type: "'NONE' | 'HORIZONTAL' | 'VERTICAL'", description: 'Auto-layout direction' },
|
|
42
|
+
primaryAxisSizingMode: { type: "'FIXED' | 'AUTO'", description: 'Primary axis sizing' },
|
|
43
|
+
counterAxisSizingMode: { type: "'FIXED' | 'AUTO'", description: 'Counter axis sizing' },
|
|
44
|
+
primaryAxisAlignItems: { type: "'MIN' | 'CENTER' | 'MAX' | 'SPACE_BETWEEN'", description: 'Primary axis alignment' },
|
|
45
|
+
counterAxisAlignItems: { type: "'MIN' | 'CENTER' | 'MAX' | 'BASELINE'", description: 'Counter axis alignment' },
|
|
46
|
+
itemSpacing: { type: 'number', description: 'Gap between children' },
|
|
47
|
+
padding: { type: 'number', description: 'Padding on all sides' },
|
|
48
|
+
paddingTop: { type: 'number', description: 'Top padding' },
|
|
49
|
+
paddingBottom: { type: 'number', description: 'Bottom padding' },
|
|
50
|
+
paddingLeft: { type: 'number', description: 'Left padding' },
|
|
51
|
+
paddingRight: { type: 'number', description: 'Right padding' },
|
|
52
|
+
layoutSizingHorizontal: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Horizontal sizing in auto-layout parent' },
|
|
53
|
+
layoutSizingVertical: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Vertical sizing in auto-layout parent' },
|
|
54
|
+
},
|
|
55
|
+
returns: '{ id, name, type, x, y, width, height }',
|
|
56
|
+
example: `const frame = await figma.createFrame({
|
|
57
|
+
name: "Card",
|
|
58
|
+
width: 300, height: 200,
|
|
59
|
+
fillColor: { r: 1, g: 1, b: 1 },
|
|
60
|
+
layoutMode: "VERTICAL",
|
|
61
|
+
padding: 16, itemSpacing: 8
|
|
62
|
+
});`,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'figma.createRectangle',
|
|
66
|
+
category: 'create',
|
|
67
|
+
description: 'Create a rectangle shape with optional fill, stroke, and corner radius.',
|
|
68
|
+
parameters: {
|
|
69
|
+
name: { type: 'string', description: 'Name of the rectangle' },
|
|
70
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
71
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
72
|
+
width: { type: 'number', description: 'Width', default: 100 },
|
|
73
|
+
height: { type: 'number', description: 'Height', default: 100 },
|
|
74
|
+
fillColor: { type: 'string | { r, g, b, a? }', description: 'Fill color: hex "#FF0000", rgb(), or {r,g,b} (0-1). Alias: fill' },
|
|
75
|
+
parentId: { type: 'string', description: 'Parent node ID' },
|
|
76
|
+
cornerRadius: { type: 'number', description: 'Corner radius' },
|
|
77
|
+
strokeColor: { type: 'string | { r, g, b, a? }', description: 'Stroke color: hex, rgb(), or {r,g,b} (0-1). Alias: stroke' },
|
|
78
|
+
strokeWeight: { type: 'number', description: 'Stroke width' },
|
|
79
|
+
strokeAlign: { type: "'INSIDE' | 'OUTSIDE' | 'CENTER'", description: 'Stroke alignment' },
|
|
80
|
+
strokeCap: { type: "'NONE' | 'ROUND' | 'SQUARE'", description: 'Stroke cap style' },
|
|
81
|
+
strokeJoin: { type: "'MITER' | 'BEVEL' | 'ROUND'", description: 'Stroke join style' },
|
|
82
|
+
dashPattern: { type: 'number[]', description: 'Dash pattern e.g. [8, 4]' },
|
|
83
|
+
topLeftRadius: { type: 'number', description: 'Top-left corner radius' },
|
|
84
|
+
topRightRadius: { type: 'number', description: 'Top-right corner radius' },
|
|
85
|
+
bottomLeftRadius: { type: 'number', description: 'Bottom-left corner radius' },
|
|
86
|
+
bottomRightRadius: { type: 'number', description: 'Bottom-right corner radius' },
|
|
87
|
+
effects: { type: 'Effect[]', description: 'Effects array (shadows, blur)' },
|
|
88
|
+
gradient: { type: 'object', description: 'Gradient fill: {type, angle, stops}' },
|
|
89
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
90
|
+
blendMode: { type: 'string', description: 'Blend mode' },
|
|
91
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
92
|
+
layoutSizingHorizontal: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Horizontal sizing in auto-layout parent' },
|
|
93
|
+
layoutSizingVertical: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Vertical sizing in auto-layout parent' },
|
|
94
|
+
},
|
|
95
|
+
returns: '{ id, name, type, x, y, width, height }',
|
|
96
|
+
example: `const rect = await figma.createRectangle({
|
|
97
|
+
name: "Background",
|
|
98
|
+
width: 200, height: 100,
|
|
99
|
+
fillColor: { r: 0.2, g: 0.4, b: 0.8 },
|
|
100
|
+
cornerRadius: 8
|
|
101
|
+
});`,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'figma.createText',
|
|
105
|
+
category: 'create',
|
|
106
|
+
description: 'Create a text node with font, size, color, and content.',
|
|
107
|
+
parameters: {
|
|
108
|
+
text: { type: 'string', description: 'Text content', required: true },
|
|
109
|
+
name: { type: 'string', description: 'Node name' },
|
|
110
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
111
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
112
|
+
fontSize: { type: 'number', description: 'Font size in pixels', default: 16 },
|
|
113
|
+
fontFamily: { type: 'string', description: 'Font family', default: 'Inter' },
|
|
114
|
+
fontWeight: { type: 'string | number', description: 'Font weight: string ("Regular", "Bold") or number (400, 700)', default: 'Regular' },
|
|
115
|
+
fillColor: { type: 'string | { r, g, b, a? }', description: 'Text color: hex "#000000", rgb(), or {r,g,b} (0-1). Alias: fill' },
|
|
116
|
+
parentId: { type: 'string', description: 'Parent node ID' },
|
|
117
|
+
textAlign: { type: 'string', description: 'Text alignment: "left", "center", "right", "justified"' },
|
|
118
|
+
textColor: { type: 'string | {r,g,b,a?}', description: 'Text color (overrides fill if both set)' },
|
|
119
|
+
textAutoResize: { type: "'NONE' | 'WIDTH_AND_HEIGHT' | 'HEIGHT' | 'TRUNCATE'", description: 'Text auto-resize mode' },
|
|
120
|
+
lineHeight: { type: 'number | string | object', description: 'Line height: pixels (24), percent ("150%"), or {value, unit}' },
|
|
121
|
+
letterSpacing: { type: 'number | string | object', description: 'Letter spacing: pixels (2), percent ("5%"), or {value, unit}' },
|
|
122
|
+
textDecoration: { type: "'NONE' | 'UNDERLINE' | 'STRIKETHROUGH'", description: 'Text decoration' },
|
|
123
|
+
textCase: { type: "'ORIGINAL' | 'UPPER' | 'LOWER' | 'TITLE'", description: 'Text case transform' },
|
|
124
|
+
effects: { type: 'Effect[]', description: 'Effects array (shadows, blur)' },
|
|
125
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
126
|
+
blendMode: { type: 'string', description: 'Blend mode' },
|
|
127
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
128
|
+
layoutSizingHorizontal: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Horizontal sizing in auto-layout parent (FILL auto-enables text wrapping)' },
|
|
129
|
+
layoutSizingVertical: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Vertical sizing in auto-layout parent' },
|
|
130
|
+
},
|
|
131
|
+
returns: '{ id, name, type, x, y, width, height }',
|
|
132
|
+
example: `const title = await figma.createText({
|
|
133
|
+
text: "Hello World",
|
|
134
|
+
fontSize: 24, fontWeight: "Bold",
|
|
135
|
+
fillColor: { r: 0, g: 0, b: 0 },
|
|
136
|
+
parentId: frame.id
|
|
137
|
+
});`,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'figma.createEllipse',
|
|
141
|
+
category: 'create',
|
|
142
|
+
description: 'Create an ellipse (circle) shape with optional fill, stroke, and effects.',
|
|
143
|
+
parameters: {
|
|
144
|
+
name: { type: 'string', description: 'Name of the ellipse' },
|
|
145
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
146
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
147
|
+
width: { type: 'number', description: 'Width', default: 100 },
|
|
148
|
+
height: { type: 'number', description: 'Height', default: 100 },
|
|
149
|
+
fillColor: { type: 'string | { r, g, b, a? }', description: 'Fill color: hex "#FF0000", rgb(), or {r,g,b} (0-1). Alias: fill' },
|
|
150
|
+
parentId: { type: 'string', description: 'Parent node ID' },
|
|
151
|
+
strokeColor: { type: 'string | { r, g, b, a? }', description: 'Stroke color. Alias: stroke' },
|
|
152
|
+
strokeWeight: { type: 'number', description: 'Stroke width' },
|
|
153
|
+
effects: { type: 'Effect[]', description: 'Effects array (shadows, blur)' },
|
|
154
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
155
|
+
blendMode: { type: 'string', description: 'Blend mode' },
|
|
156
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
157
|
+
constraints: { type: 'object', description: 'Constraints: {horizontal, vertical}' },
|
|
158
|
+
layoutSizingHorizontal: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Horizontal sizing in auto-layout parent' },
|
|
159
|
+
layoutSizingVertical: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Vertical sizing in auto-layout parent' },
|
|
160
|
+
},
|
|
161
|
+
returns: '{ id, name, type, x, y, width, height }',
|
|
162
|
+
example: `const circle = await figma.createEllipse({
|
|
163
|
+
name: "Avatar",
|
|
164
|
+
width: 48, height: 48,
|
|
165
|
+
fillColor: "#E0E0E0"
|
|
166
|
+
});`,
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'figma.createLine',
|
|
170
|
+
category: 'create',
|
|
171
|
+
description: 'Create a line with optional stroke color and weight. Defaults to a black 1px stroke.',
|
|
172
|
+
parameters: {
|
|
173
|
+
name: { type: 'string', description: 'Name of the line' },
|
|
174
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
175
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
176
|
+
width: { type: 'number', description: 'Line length', default: 100 },
|
|
177
|
+
parentId: { type: 'string', description: 'Parent node ID' },
|
|
178
|
+
strokeColor: { type: 'string | { r, g, b, a? }', description: 'Stroke color. Alias: stroke' },
|
|
179
|
+
strokeWeight: { type: 'number', description: 'Stroke width', default: 1 },
|
|
180
|
+
strokeCap: { type: "'NONE' | 'ROUND' | 'SQUARE'", description: 'Stroke cap style' },
|
|
181
|
+
dashPattern: { type: 'number[]', description: 'Dash pattern e.g. [8, 4]' },
|
|
182
|
+
effects: { type: 'Effect[]', description: 'Effects array (shadows, blur)' },
|
|
183
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
184
|
+
blendMode: { type: 'string', description: 'Blend mode' },
|
|
185
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
186
|
+
constraints: { type: 'object', description: 'Constraints: {horizontal, vertical}' },
|
|
187
|
+
layoutSizingHorizontal: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Horizontal sizing in auto-layout parent' },
|
|
188
|
+
layoutSizingVertical: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Vertical sizing in auto-layout parent' },
|
|
189
|
+
},
|
|
190
|
+
returns: '{ id, name, type, x, y, width, height }',
|
|
191
|
+
example: `const divider = await figma.createLine({
|
|
192
|
+
name: "Divider",
|
|
193
|
+
width: 400,
|
|
194
|
+
strokeColor: "#CCCCCC",
|
|
195
|
+
strokeWeight: 1
|
|
196
|
+
});`,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: 'figma.createInstance',
|
|
200
|
+
category: 'create',
|
|
201
|
+
description: 'Create an instance of a component (local or published library).',
|
|
202
|
+
parameters: {
|
|
203
|
+
componentKey: { type: 'string', description: 'Component key (for published components)' },
|
|
204
|
+
componentId: { type: 'string', description: 'Node ID of a local component' },
|
|
205
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
206
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
207
|
+
parentId: { type: 'string', description: 'Parent node ID' },
|
|
208
|
+
},
|
|
209
|
+
returns: '{ id, name, type, componentId }',
|
|
210
|
+
example: `const btn = await figma.createInstance({
|
|
211
|
+
componentId: "1:234",
|
|
212
|
+
parentId: frame.id
|
|
213
|
+
});`,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'figma.cloneNode',
|
|
217
|
+
category: 'create',
|
|
218
|
+
description: 'Clone/duplicate a node with optional modifications and offset.',
|
|
219
|
+
parameters: {
|
|
220
|
+
nodeId: { type: 'string', description: 'ID of node to clone', required: true },
|
|
221
|
+
count: { type: 'number', description: 'Number of clones', default: 1 },
|
|
222
|
+
parentId: { type: 'string', description: 'Parent for clones (default: same as original)' },
|
|
223
|
+
offsetX: { type: 'number', description: 'X offset per clone', default: 0 },
|
|
224
|
+
offsetY: { type: 'number', description: 'Y offset per clone', default: 0 },
|
|
225
|
+
modifications: { type: 'object', description: 'Properties to modify on clones' },
|
|
226
|
+
},
|
|
227
|
+
returns: '{ nodes: [{ id, name, type }] }',
|
|
228
|
+
example: `const clones = await figma.cloneNode({
|
|
229
|
+
nodeId: "1:23",
|
|
230
|
+
count: 3,
|
|
231
|
+
offsetY: 50
|
|
232
|
+
});`,
|
|
233
|
+
},
|
|
234
|
+
// === READ ===
|
|
235
|
+
{
|
|
236
|
+
name: 'figma.getNode',
|
|
237
|
+
category: 'read',
|
|
238
|
+
description: 'Get info about a node. Use depth to control children traversal. Use detailed=true for full styling.',
|
|
239
|
+
parameters: {
|
|
240
|
+
nodeId: { type: 'string', description: 'Node ID, Figma URL, or target specifier ("selection", "name:Foo")', required: true },
|
|
241
|
+
depth: { type: 'number', description: 'Children depth (0=none, 1=direct)', default: 0 },
|
|
242
|
+
childLimit: { type: 'number', description: 'Max children per node', default: 20 },
|
|
243
|
+
detailed: { type: 'boolean', description: 'Include full styling details', default: false },
|
|
244
|
+
},
|
|
245
|
+
returns: '{ id, name, type, x, y, width, height, children?, ... }',
|
|
246
|
+
example: `const node = await figma.getNode({
|
|
247
|
+
nodeId: "1:23",
|
|
248
|
+
depth: 1, detailed: true
|
|
249
|
+
});`,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: 'figma.getSelection',
|
|
253
|
+
category: 'read',
|
|
254
|
+
description: 'Get the currently selected nodes in Figma.',
|
|
255
|
+
parameters: {},
|
|
256
|
+
returns: '[{ id, name, type, x, y, width, height }]',
|
|
257
|
+
example: `const sel = await figma.getSelection();
|
|
258
|
+
console.log("Selected:", sel.length, "nodes");`,
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'figma.getCurrentPage',
|
|
262
|
+
category: 'read',
|
|
263
|
+
description: 'Get a lightweight tree of the current page with id, name, type, and text content.',
|
|
264
|
+
parameters: {
|
|
265
|
+
depth: { type: 'number', description: 'Max traversal depth', default: 10 },
|
|
266
|
+
},
|
|
267
|
+
returns: '{ id, name, type, children: [...] }',
|
|
268
|
+
example: `const page = await figma.getCurrentPage({ depth: 2 });`,
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: 'figma.getStyles',
|
|
272
|
+
category: 'read',
|
|
273
|
+
description: 'Get local styles (colors, text, effects, grids).',
|
|
274
|
+
parameters: {
|
|
275
|
+
type: { type: "'PAINT' | 'TEXT' | 'EFFECT' | 'GRID' | 'ALL'", description: 'Style type filter', default: 'ALL' },
|
|
276
|
+
},
|
|
277
|
+
returns: '[{ id, name, type, ... }]',
|
|
278
|
+
example: `const colors = await figma.getStyles({ type: "PAINT" });`,
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: 'figma.getLocalComponents',
|
|
282
|
+
category: 'read',
|
|
283
|
+
description: 'Get all local components and component sets.',
|
|
284
|
+
parameters: {
|
|
285
|
+
nameFilter: { type: 'string', description: 'Filter by name (case-insensitive)' },
|
|
286
|
+
limit: { type: 'number', description: 'Max results', default: 50 },
|
|
287
|
+
},
|
|
288
|
+
returns: '[{ id, name, type, componentId, key, ... }]',
|
|
289
|
+
example: `const buttons = await figma.getLocalComponents({
|
|
290
|
+
nameFilter: "Button"
|
|
291
|
+
});`,
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: 'figma.getVariables',
|
|
295
|
+
category: 'read',
|
|
296
|
+
description: 'Get variables and variable collections (design tokens).',
|
|
297
|
+
parameters: {
|
|
298
|
+
collectionName: { type: 'string', description: 'Filter by collection name' },
|
|
299
|
+
type: { type: "'COLOR' | 'FLOAT' | 'STRING' | 'BOOLEAN' | 'ALL'", description: 'Variable type filter', default: 'ALL' },
|
|
300
|
+
limit: { type: 'number', description: 'Max results', default: 100 },
|
|
301
|
+
},
|
|
302
|
+
returns: '{ collections: [...], variables: [...] }',
|
|
303
|
+
example: `const tokens = await figma.getVariables({ type: "COLOR" });`,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'figma.searchNodes',
|
|
307
|
+
category: 'read',
|
|
308
|
+
description: 'Search nodes by name, type, or text content.',
|
|
309
|
+
parameters: {
|
|
310
|
+
query: { type: 'string', description: 'Search query (case-insensitive)' },
|
|
311
|
+
type: { type: 'string', description: "Node type filter (FRAME, TEXT, RECTANGLE, INSTANCE, COMPONENT, etc.)" },
|
|
312
|
+
caseSensitive: { type: 'boolean', description: 'Case-sensitive search', default: false },
|
|
313
|
+
limit: { type: 'number', description: 'Max results', default: 50 },
|
|
314
|
+
},
|
|
315
|
+
returns: '[{ id, name, type, path }]',
|
|
316
|
+
example: `const headers = await figma.searchNodes({
|
|
317
|
+
query: "Header", type: "FRAME"
|
|
318
|
+
});`,
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'figma.captureScreenshot',
|
|
322
|
+
category: 'read',
|
|
323
|
+
description: 'Capture a screenshot of a node. Returns base64 data (not MCP image type — use capture_screenshot tool for visual output).',
|
|
324
|
+
parameters: {
|
|
325
|
+
nodeId: { type: 'string', description: 'Node ID to capture', required: true },
|
|
326
|
+
scale: { type: 'number', description: 'Scale factor (1-4)', default: 1 },
|
|
327
|
+
format: { type: "'PNG' | 'JPG' | 'SVG' | 'PDF'", description: 'Export format', default: 'PNG' },
|
|
328
|
+
},
|
|
329
|
+
returns: '{ data: "<base64>", format: "PNG" }',
|
|
330
|
+
example: `const shot = await figma.captureScreenshot({
|
|
331
|
+
nodeId: frame.id, scale: 2
|
|
332
|
+
});`,
|
|
333
|
+
},
|
|
334
|
+
// === UPDATE ===
|
|
335
|
+
{
|
|
336
|
+
name: 'figma.updateNode',
|
|
337
|
+
category: 'update',
|
|
338
|
+
description: 'Update properties of an existing node. Colors accept hex strings. Supports CSS-like layout config.',
|
|
339
|
+
parameters: {
|
|
340
|
+
nodeId: { type: 'string', description: 'Node ID or target specifier ("selection", "name:Foo")', required: true },
|
|
341
|
+
properties: { type: 'object', description: 'Properties to update: name, description, x, y, width, height, fillColor/fill, strokeColor/stroke, gradient, opacity, visible, locked, text, fontSize, fontWeight (string or number), cornerRadius, topLeftRadius/topRightRadius/bottomLeftRadius/bottomRightRadius, strokeWeight, strokeAlign, strokeCap, strokeJoin, dashPattern, effects, rotation, blendMode, constraints, minWidth/maxWidth/minHeight/maxHeight, copyFillsFrom, copyStrokesFrom, textAlign, textColor, textAutoResize, lineHeight, letterSpacing, textDecoration, textCase, layout, layoutMode, primaryAxisSizingMode, counterAxisSizingMode, primaryAxisAlignItems, counterAxisAlignItems, itemSpacing, paddingTop/Bottom/Left/Right, layoutWrap, layoutSizingHorizontal, layoutSizingVertical', required: true },
|
|
342
|
+
},
|
|
343
|
+
returns: '{ id, name, type, ... }',
|
|
344
|
+
example: `await figma.updateNode({
|
|
345
|
+
nodeId: "1:23",
|
|
346
|
+
properties: {
|
|
347
|
+
fillColor: { r: 1, g: 0, b: 0 },
|
|
348
|
+
cornerRadius: 12,
|
|
349
|
+
layoutMode: "VERTICAL",
|
|
350
|
+
itemSpacing: 8
|
|
351
|
+
}
|
|
352
|
+
});`,
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'figma.moveNode',
|
|
356
|
+
category: 'update',
|
|
357
|
+
description: 'Move a node to a new parent or reorder within its current parent.',
|
|
358
|
+
parameters: {
|
|
359
|
+
nodeId: { type: 'string', description: 'Node ID to move', required: true },
|
|
360
|
+
parentId: { type: 'string', description: 'New parent node ID' },
|
|
361
|
+
index: { type: 'number', description: 'Position among siblings (0 = first)' },
|
|
362
|
+
},
|
|
363
|
+
returns: '{ id, name, type, parentId }',
|
|
364
|
+
example: `await figma.moveNode({
|
|
365
|
+
nodeId: "1:23",
|
|
366
|
+
parentId: frame.id,
|
|
367
|
+
index: 0
|
|
368
|
+
});`,
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: 'figma.swapComponent',
|
|
372
|
+
category: 'update',
|
|
373
|
+
description: 'Swap a component instance to a different component or variant.',
|
|
374
|
+
parameters: {
|
|
375
|
+
instanceId: { type: 'string', description: 'Instance node ID', required: true },
|
|
376
|
+
newComponentId: { type: 'string', description: 'New component ID (local)' },
|
|
377
|
+
newComponentKey: { type: 'string', description: 'New component key (library)' },
|
|
378
|
+
},
|
|
379
|
+
returns: '{ id, name, type, componentId }',
|
|
380
|
+
example: `await figma.swapComponent({
|
|
381
|
+
instanceId: "1:23",
|
|
382
|
+
newComponentId: "1:45"
|
|
383
|
+
});`,
|
|
384
|
+
},
|
|
385
|
+
// === DELETE ===
|
|
386
|
+
{
|
|
387
|
+
name: 'figma.deleteNode',
|
|
388
|
+
category: 'delete',
|
|
389
|
+
description: 'Delete a node from the canvas.',
|
|
390
|
+
parameters: {
|
|
391
|
+
nodeId: { type: 'string', description: 'Node ID to delete', required: true },
|
|
392
|
+
},
|
|
393
|
+
returns: '{ success: true }',
|
|
394
|
+
example: `await figma.deleteNode({ nodeId: "1:23" });`,
|
|
395
|
+
},
|
|
396
|
+
// === UNIFIED CREATE ===
|
|
397
|
+
{
|
|
398
|
+
name: 'figma.create',
|
|
399
|
+
category: 'create',
|
|
400
|
+
description: 'Unified create with semantic presets and recursive children. Works in both Figma Design and FigJam. In FigJam, frame→section and rectangle→shape are auto-remapped, but prefer explicit FigJam types.',
|
|
401
|
+
parameters: {
|
|
402
|
+
type: { type: 'string', description: 'Element type: frame, text, rectangle/rect, ellipse, line, card, button, nav, input, form. FigJam: section, sticky, shape/shape_with_text', required: true },
|
|
403
|
+
name: { type: 'string', description: 'Node name' },
|
|
404
|
+
x: { type: 'number', description: 'X position' },
|
|
405
|
+
y: { type: 'number', description: 'Y position' },
|
|
406
|
+
width: { type: 'number', description: 'Width (preset provides default)' },
|
|
407
|
+
height: { type: 'number', description: 'Height (preset provides default)' },
|
|
408
|
+
parentId: { type: 'string', description: 'Parent node ID or target specifier ("selection", "name:Foo")' },
|
|
409
|
+
fillColor: { type: 'string | {r,g,b,a?}', description: 'Fill color: hex "#FF0000", rgb "rgb(255,0,0)", or {r,g,b,a?} (0-1). Alias: fill' },
|
|
410
|
+
strokeColor: { type: 'string | {r,g,b,a?}', description: 'Stroke color (same formats). Alias: stroke' },
|
|
411
|
+
strokeWeight: { type: 'number', description: 'Stroke width' },
|
|
412
|
+
strokeAlign: { type: "'INSIDE' | 'OUTSIDE' | 'CENTER'", description: 'Stroke alignment' },
|
|
413
|
+
dashPattern: { type: 'number[]', description: 'Dash pattern e.g. [8, 4]' },
|
|
414
|
+
cornerRadius: { type: 'number', description: 'Uniform corner radius' },
|
|
415
|
+
topLeftRadius: { type: 'number', description: 'Top-left corner radius' },
|
|
416
|
+
topRightRadius: { type: 'number', description: 'Top-right corner radius' },
|
|
417
|
+
bottomLeftRadius: { type: 'number', description: 'Bottom-left corner radius' },
|
|
418
|
+
bottomRightRadius: { type: 'number', description: 'Bottom-right corner radius' },
|
|
419
|
+
effects: { type: 'Effect[]', description: 'Effects: shadows, blur' },
|
|
420
|
+
gradient: { type: 'object', description: 'Gradient fill: {type, angle, stops}' },
|
|
421
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
422
|
+
blendMode: { type: 'string', description: 'Blend mode' },
|
|
423
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
424
|
+
constraints: { type: 'object', description: 'Constraints: {horizontal, vertical}' },
|
|
425
|
+
textAlign: { type: 'string', description: 'Text alignment (text nodes)' },
|
|
426
|
+
textColor: { type: 'string | {r,g,b,a?}', description: 'Text color (text nodes, overrides fill)' },
|
|
427
|
+
lineHeight: { type: 'number | string', description: 'Line height (text nodes)' },
|
|
428
|
+
letterSpacing: { type: 'number | string', description: 'Letter spacing (text nodes)' },
|
|
429
|
+
textDecoration: { type: 'string', description: 'Text decoration (text nodes)' },
|
|
430
|
+
textCase: { type: 'string', description: 'Text case (text nodes)' },
|
|
431
|
+
layout: { type: 'object', description: 'CSS-like layout: { direction: "row"|"column", gap, padding, alignItems, justifyContent, wrap }' },
|
|
432
|
+
layoutSizingHorizontal: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Horizontal sizing in auto-layout parent' },
|
|
433
|
+
layoutSizingVertical: { type: "'FIXED' | 'HUG' | 'FILL'", description: 'Vertical sizing in auto-layout parent' },
|
|
434
|
+
children: { type: 'CreateParams[]', description: 'Nested children to create recursively (max depth 10)' },
|
|
435
|
+
},
|
|
436
|
+
returns: '{ id, name, type, ... , createdChildren? }',
|
|
437
|
+
example: `const card = await figma.create({
|
|
438
|
+
type: "card",
|
|
439
|
+
name: "Profile Card",
|
|
440
|
+
children: [
|
|
441
|
+
{ type: "text", content: "John Doe", fontSize: 24, fontWeight: "Bold" },
|
|
442
|
+
{ type: "text", content: "Software Engineer", fontSize: 14, fill: "#666666" },
|
|
443
|
+
{ type: "button", children: [
|
|
444
|
+
{ type: "text", content: "Follow", fill: "#FFFFFF" }
|
|
445
|
+
]}
|
|
446
|
+
]
|
|
447
|
+
});`,
|
|
448
|
+
},
|
|
449
|
+
// === TOKENS ===
|
|
450
|
+
{
|
|
451
|
+
name: 'figma.createToken',
|
|
452
|
+
category: 'tokens',
|
|
453
|
+
description: 'Create a Figma variable (design token). Finds or creates the collection by name.',
|
|
454
|
+
parameters: {
|
|
455
|
+
collection: { type: 'string', description: 'Variable collection name', required: true },
|
|
456
|
+
name: { type: 'string', description: 'Variable name', required: true },
|
|
457
|
+
type: { type: "'COLOR' | 'NUMBER' | 'STRING' | 'BOOLEAN'", description: 'Variable type', default: 'COLOR' },
|
|
458
|
+
value: { type: 'string | number | boolean', description: 'Value (COLOR accepts hex strings)', required: true },
|
|
459
|
+
},
|
|
460
|
+
returns: '{ id, name, type, collection }',
|
|
461
|
+
example: `await figma.createToken({
|
|
462
|
+
collection: "Colors",
|
|
463
|
+
name: "primary",
|
|
464
|
+
type: "COLOR",
|
|
465
|
+
value: "#0066FF"
|
|
466
|
+
});`,
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
name: 'figma.bindToken',
|
|
470
|
+
category: 'tokens',
|
|
471
|
+
description: 'Bind a variable to a node property. Finds variable by name (exact → suffix → partial match).',
|
|
472
|
+
parameters: {
|
|
473
|
+
target: { type: 'string', description: 'Node ID or target specifier', default: 'selection' },
|
|
474
|
+
token: { type: 'string', description: 'Variable name to bind', required: true },
|
|
475
|
+
property: { type: 'string', description: 'Property to bind: fill, stroke, cornerRadius, gap, paddingTop/Bottom/Left/Right, fontSize', required: true },
|
|
476
|
+
},
|
|
477
|
+
returns: '{ bound: true, node, variable, property }',
|
|
478
|
+
example: `await figma.bindToken({
|
|
479
|
+
target: "selection",
|
|
480
|
+
property: "fill",
|
|
481
|
+
token: "primary"
|
|
482
|
+
});`,
|
|
483
|
+
},
|
|
484
|
+
// === COMPONENTS ===
|
|
485
|
+
{
|
|
486
|
+
name: 'figma.toComponent',
|
|
487
|
+
category: 'components',
|
|
488
|
+
description: 'Convert a node to a component. Frames/groups convert directly; other types are wrapped first.',
|
|
489
|
+
parameters: {
|
|
490
|
+
target: { type: 'string', description: 'Node ID or target specifier', default: 'selection' },
|
|
491
|
+
name: { type: 'string', description: 'Optional new component name' },
|
|
492
|
+
},
|
|
493
|
+
returns: '{ id, name, type: "COMPONENT", ... }',
|
|
494
|
+
example: `await figma.toComponent({
|
|
495
|
+
target: "selection",
|
|
496
|
+
name: "Card"
|
|
497
|
+
});`,
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
name: 'figma.createVariants',
|
|
501
|
+
category: 'components',
|
|
502
|
+
description: 'Create a component variant set. Supports single property or multi-dimensional (cartesian product).',
|
|
503
|
+
parameters: {
|
|
504
|
+
target: { type: 'string', description: 'Node ID or target specifier', default: 'selection' },
|
|
505
|
+
property: { type: 'string', description: 'Single variant property name (simple form)' },
|
|
506
|
+
values: { type: 'string[]', description: 'Variant values for single property (min 2)' },
|
|
507
|
+
properties: { type: 'Record<string, string[]>', description: 'Multi-dimensional: { state: ["default","hover"], size: ["sm","lg"] }' },
|
|
508
|
+
},
|
|
509
|
+
returns: '{ componentSetId, componentSetName, variantCount, variants: [{id, name}] }',
|
|
510
|
+
example: `// Single property
|
|
511
|
+
await figma.createVariants({
|
|
512
|
+
target: "selection",
|
|
513
|
+
property: "state",
|
|
514
|
+
values: ["default", "hover", "disabled"]
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// Multi-dimensional (creates 6 variants)
|
|
518
|
+
await figma.createVariants({
|
|
519
|
+
target: "selection",
|
|
520
|
+
properties: {
|
|
521
|
+
state: ["default", "hover", "disabled"],
|
|
522
|
+
size: ["small", "large"]
|
|
523
|
+
}
|
|
524
|
+
});`,
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
name: 'figma.addComponentProperty',
|
|
528
|
+
category: 'components',
|
|
529
|
+
description: 'Add a property definition to a component (text override, boolean toggle, instance swap).',
|
|
530
|
+
parameters: {
|
|
531
|
+
target: { type: 'string', description: 'Component node ID or target specifier', default: 'selection' },
|
|
532
|
+
name: { type: 'string', description: 'Property name (e.g. "Label")', required: true },
|
|
533
|
+
type: { type: "'TEXT' | 'BOOLEAN' | 'INSTANCE_SWAP'", description: 'Property type', default: 'TEXT' },
|
|
534
|
+
defaultValue: { type: 'string | boolean', description: 'Default value', default: '""' },
|
|
535
|
+
},
|
|
536
|
+
returns: '{ propertyName, type, defaultValue, nodeId }',
|
|
537
|
+
example: `// Add text and boolean properties to a component
|
|
538
|
+
await figma.addComponentProperty({
|
|
539
|
+
target: "selection",
|
|
540
|
+
name: "Label",
|
|
541
|
+
type: "TEXT",
|
|
542
|
+
defaultValue: "Button"
|
|
543
|
+
});
|
|
544
|
+
await figma.addComponentProperty({
|
|
545
|
+
target: "selection",
|
|
546
|
+
name: "showIcon",
|
|
547
|
+
type: "BOOLEAN",
|
|
548
|
+
defaultValue: true
|
|
549
|
+
});`,
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
name: 'figma.setInstanceOverride',
|
|
553
|
+
category: 'components',
|
|
554
|
+
description: 'Set property overrides on a component instance. Matches property names by prefix (no need for #id suffix).',
|
|
555
|
+
parameters: {
|
|
556
|
+
target: { type: 'string', description: 'Instance node ID or target specifier', default: 'selection' },
|
|
557
|
+
properties: { type: 'Record<string, string | boolean>', description: 'Property overrides: { "Label": "Click me", "showIcon": false }', required: true },
|
|
558
|
+
},
|
|
559
|
+
returns: '{ id, name, type, componentProperties }',
|
|
560
|
+
example: `await figma.setInstanceOverride({
|
|
561
|
+
target: "selection",
|
|
562
|
+
properties: {
|
|
563
|
+
"Label": "Submit",
|
|
564
|
+
"showIcon": false
|
|
565
|
+
}
|
|
566
|
+
});`,
|
|
567
|
+
},
|
|
568
|
+
// === FIGJAM ===
|
|
569
|
+
{
|
|
570
|
+
name: 'figma.createSection',
|
|
571
|
+
category: 'figjam',
|
|
572
|
+
description: 'Create a FigJam section — a container that holds stickies, shapes, and text. Sections support nesting and can have fill colors. Use sections as the primary container type in FigJam (replaces frames).',
|
|
573
|
+
parameters: {
|
|
574
|
+
name: { type: 'string', description: 'Section name', required: true },
|
|
575
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
576
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
577
|
+
width: { type: 'number', description: 'Width in pixels', default: 400 },
|
|
578
|
+
height: { type: 'number', description: 'Height in pixels', default: 300 },
|
|
579
|
+
fillColor: { type: 'string | {r,g,b,a?}', description: 'Fill color: hex "#FF0000", rgb(), or {r,g,b}. Alias: fill' },
|
|
580
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
581
|
+
parentId: { type: 'string', description: 'Parent node ID (for nesting sections)' },
|
|
582
|
+
},
|
|
583
|
+
returns: '{ id, name, type: "SECTION", x, y, width, height }',
|
|
584
|
+
example: `const section = await figma.createSection({
|
|
585
|
+
name: "User Research",
|
|
586
|
+
width: 800, height: 600,
|
|
587
|
+
fillColor: "#F5F5F5"
|
|
588
|
+
});`,
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
name: 'figma.createSticky',
|
|
592
|
+
category: 'figjam',
|
|
593
|
+
description: 'Create a FigJam sticky note with text. Stickies are fixed-size (square or wide). Great for text-heavy content, notes, and brainstorming items.',
|
|
594
|
+
parameters: {
|
|
595
|
+
text: { type: 'string', description: 'Text content', required: true },
|
|
596
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
597
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
598
|
+
fillColor: { type: 'string | {r,g,b,a?}', description: 'Sticky color: hex, rgb(), or {r,g,b}. Alias: fill' },
|
|
599
|
+
fontSize: { type: 'number', description: 'Font size' },
|
|
600
|
+
isWideWidth: { type: 'boolean', description: 'Wide rectangular sticky (true) vs square (false)', default: false },
|
|
601
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
602
|
+
parentId: { type: 'string', description: 'Parent section ID' },
|
|
603
|
+
},
|
|
604
|
+
returns: '{ id, name, type: "STICKY", x, y, width, height, characters }',
|
|
605
|
+
example: `const note = await figma.createSticky({
|
|
606
|
+
text: "Key insight from user interview",
|
|
607
|
+
fillColor: "#FFF9B1",
|
|
608
|
+
isWideWidth: true,
|
|
609
|
+
parentId: section.id
|
|
610
|
+
});`,
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
name: 'figma.createShape',
|
|
614
|
+
category: 'figjam',
|
|
615
|
+
description: 'Create a FigJam shape with optional text. Supports multiple shape types. Use for diagrams, flowcharts, and visual containers.',
|
|
616
|
+
parameters: {
|
|
617
|
+
shapeType: { type: 'string', description: 'Shape type. Valid values: SQUARE, ELLIPSE, ROUNDED_RECTANGLE, DIAMOND, TRIANGLE_UP, TRIANGLE_DOWN, PARALLELOGRAM_RIGHT, PARALLELOGRAM_LEFT, ENG_DATABASE, ENG_QUEUE, ENG_FILE, ENG_FOLDER, TRAPEZOID, PREDEFINED_PROCESS, SHIELD, DOCUMENT_SINGLE, DOCUMENT_MULTIPLE, MANUAL_INPUT, HEXAGON, CHEVRON, PENTAGON, OCTAGON, STAR, PLUS, ARROW_LEFT, ARROW_RIGHT, SUMMING_JUNCTION, OR, SPEECH_BUBBLE, INTERNAL_STORAGE', default: 'ROUNDED_RECTANGLE' },
|
|
618
|
+
text: { type: 'string', description: 'Text content inside the shape' },
|
|
619
|
+
name: { type: 'string', description: 'Node name' },
|
|
620
|
+
x: { type: 'number', description: 'X position', default: 0 },
|
|
621
|
+
y: { type: 'number', description: 'Y position', default: 0 },
|
|
622
|
+
width: { type: 'number', description: 'Width in pixels', default: 208 },
|
|
623
|
+
height: { type: 'number', description: 'Height in pixels', default: 208 },
|
|
624
|
+
fillColor: { type: 'string | {r,g,b,a?}', description: 'Fill color: hex, rgb(), or {r,g,b}. Alias: fill' },
|
|
625
|
+
strokeColor: { type: 'string | {r,g,b,a?}', description: 'Stroke color. Alias: stroke' },
|
|
626
|
+
strokeWeight: { type: 'number', description: 'Stroke width' },
|
|
627
|
+
fontSize: { type: 'number', description: 'Text font size' },
|
|
628
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
629
|
+
parentId: { type: 'string', description: 'Parent section ID' },
|
|
630
|
+
},
|
|
631
|
+
returns: '{ id, name, type: "SHAPE_WITH_TEXT", x, y, width, height, characters, shapeType }',
|
|
632
|
+
example: `const box = await figma.createShape({
|
|
633
|
+
shapeType: "ROUNDED_RECTANGLE",
|
|
634
|
+
text: "Authentication Service",
|
|
635
|
+
width: 200, height: 100,
|
|
636
|
+
fillColor: "#E8F0FE",
|
|
637
|
+
strokeColor: "#4285F4",
|
|
638
|
+
parentId: section.id
|
|
639
|
+
});`,
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
name: 'figma.createConnector',
|
|
643
|
+
category: 'figjam',
|
|
644
|
+
description: 'Create a FigJam connector line between two nodes. Use for flowcharts, diagrams, and showing relationships. Supports arrows, labels, and line styles.',
|
|
645
|
+
parameters: {
|
|
646
|
+
startNodeId: { type: 'string', description: 'ID of the node where the connector starts', required: true },
|
|
647
|
+
endNodeId: { type: 'string', description: 'ID of the node where the connector ends', required: true },
|
|
648
|
+
startMagnet: { type: 'string', description: 'Start connection point: AUTO, TOP, BOTTOM, LEFT, RIGHT, CENTER', default: 'AUTO' },
|
|
649
|
+
endMagnet: { type: 'string', description: 'End connection point: AUTO, TOP, BOTTOM, LEFT, RIGHT, CENTER', default: 'AUTO' },
|
|
650
|
+
connectorLineType: { type: 'string', description: 'Line type: ELBOWED (default, right-angle), STRAIGHT, CURVED' },
|
|
651
|
+
startStrokeCap: { type: 'string', description: 'Start arrow: NONE, ARROW_LINES, ARROW_EQUILATERAL, CIRCLE_FILLED, DIAMOND_FILLED', default: 'NONE' },
|
|
652
|
+
endStrokeCap: { type: 'string', description: 'End arrow: NONE, ARROW_LINES, ARROW_EQUILATERAL, CIRCLE_FILLED, DIAMOND_FILLED', default: 'ARROW_LINES' },
|
|
653
|
+
strokeColor: { type: 'string | {r,g,b,a?}', description: 'Line color. Alias: stroke' },
|
|
654
|
+
strokeWeight: { type: 'number', description: 'Line width in pixels' },
|
|
655
|
+
dashPattern: { type: 'number[]', description: 'Dash pattern e.g. [8, 4] for dashed lines' },
|
|
656
|
+
text: { type: 'string', description: 'Text label on the connector. Alias: label' },
|
|
657
|
+
name: { type: 'string', description: 'Node name' },
|
|
658
|
+
opacity: { type: 'number', description: 'Opacity (0-1)' },
|
|
659
|
+
},
|
|
660
|
+
returns: '{ id, name, type: "CONNECTOR", connectorStart, connectorEnd, connectorLineType, characters }',
|
|
661
|
+
example: `const shapeA = await figma.createShape({ text: "Start", fillColor: "#E8F0FE" });
|
|
662
|
+
const shapeB = await figma.createShape({ text: "End", x: 400, fillColor: "#FCE8E6" });
|
|
663
|
+
const connector = await figma.createConnector({
|
|
664
|
+
startNodeId: shapeA.id,
|
|
665
|
+
endNodeId: shapeB.id,
|
|
666
|
+
endStrokeCap: "ARROW_EQUILATERAL",
|
|
667
|
+
text: "sends data",
|
|
668
|
+
strokeColor: "#333333"
|
|
669
|
+
});`,
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
name: 'figma.getEditorType',
|
|
673
|
+
category: 'read',
|
|
674
|
+
description: 'Get the current editor type. Returns "figma" for Figma Design files or "figjam" for FigJam files. Use this to decide which create methods to use.',
|
|
675
|
+
parameters: {},
|
|
676
|
+
returns: '{ editorType: "figma" | "figjam" }',
|
|
677
|
+
example: `const { editorType } = await figma.getEditorType();
|
|
678
|
+
if (editorType === "figjam") {
|
|
679
|
+
await figma.createSticky({ text: "Hello FigJam!" });
|
|
680
|
+
} else {
|
|
681
|
+
await figma.createFrame({ name: "Hello Figma!" });
|
|
682
|
+
}`,
|
|
683
|
+
},
|
|
684
|
+
// === ACCESSIBILITY ===
|
|
685
|
+
{
|
|
686
|
+
name: 'figma.checkAccessibility',
|
|
687
|
+
category: 'accessibility',
|
|
688
|
+
description: 'Check accessibility issues: text contrast (WCAG) and touch target sizes (44x44px minimum).',
|
|
689
|
+
parameters: {
|
|
690
|
+
target: { type: 'string', description: 'Node ID or target specifier', default: 'page' },
|
|
691
|
+
level: { type: "'AA' | 'AAA'", description: 'WCAG level', default: 'AA' },
|
|
692
|
+
autoFix: { type: 'boolean', description: 'Auto-fix issues (adjust text color, resize small targets)', default: false },
|
|
693
|
+
},
|
|
694
|
+
returns: '{ issues: [...], totalIssues, fixedCount, passed, level }',
|
|
695
|
+
example: `const result = await figma.checkAccessibility({
|
|
696
|
+
target: "page",
|
|
697
|
+
level: "AA",
|
|
698
|
+
autoFix: false
|
|
699
|
+
});
|
|
700
|
+
console.log(result.passed ? "All good!" : result.totalIssues + " issues found");`,
|
|
701
|
+
},
|
|
702
|
+
];
|
|
703
|
+
export function searchRegistry(query, category, detailLevel = 'description') {
|
|
704
|
+
// Split query into words — an entry matches if ANY word matches (OR logic)
|
|
705
|
+
const words = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
706
|
+
let results = registry.filter((entry) => {
|
|
707
|
+
const name = entry.name.toLowerCase();
|
|
708
|
+
const desc = entry.description.toLowerCase();
|
|
709
|
+
const matchesQuery = words.length === 0 ||
|
|
710
|
+
words.some((w) => name.includes(w) || desc.includes(w));
|
|
711
|
+
const matchesCategory = !category || entry.category === category;
|
|
712
|
+
return matchesQuery && matchesCategory;
|
|
713
|
+
});
|
|
714
|
+
switch (detailLevel) {
|
|
715
|
+
case 'name':
|
|
716
|
+
return results.map((e) => ({
|
|
717
|
+
name: e.name,
|
|
718
|
+
category: e.category,
|
|
719
|
+
}));
|
|
720
|
+
case 'description':
|
|
721
|
+
return results.map((e) => ({
|
|
722
|
+
name: e.name,
|
|
723
|
+
category: e.category,
|
|
724
|
+
description: e.description,
|
|
725
|
+
}));
|
|
726
|
+
case 'full':
|
|
727
|
+
return results;
|
|
728
|
+
}
|
|
729
|
+
}
|