@ufira/vibma 0.3.0 → 0.3.2-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -0
- package/dist/mcp.cjs +61 -10
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +61 -10
- package/dist/mcp.js.map +1 -1
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
> **[简体中文](./README.zh-CN.md)**
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
# ✦ Vibma
|
|
6
|
+
|
|
7
|
+
**Vibe Design meets Figma.**
|
|
8
|
+
|
|
9
|
+
https://github.com/user-attachments/assets/bf38e37d-57bb-40b3-a2d1-f89216117c11
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
Let AI agents design directly in Figma — read layouts, create components,
|
|
13
|
+
modify styles, and build entire design systems through conversation.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Model Recommendations
|
|
18
|
+
|
|
19
|
+
Vibma works with any LLM that supports MCP. Based on our [benchmark](https://github.com/ufira-ai/vibma-benchmark):
|
|
20
|
+
|
|
21
|
+
- **Cheap one-shot builds:** GPT-5.3 Codex (medium reasoning) — proper components, all variables bound, clean output for under $1. Degrades on follow-up tasks.
|
|
22
|
+
- **Iterative design work:** GPT-5.3 Codex (xhigh), Gemini 3.1 Pro, or Claude Opus 4.6 — these maintain quality as context grows and handle multi-pass workflows.
|
|
23
|
+
- **Avoid:** Models that skip figma components building (e.g. Cursor Auto, Kimi K2.5) produce frames that look right but aren't structurally usable — no instances, no variants, no library.
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
Two paths:
|
|
28
|
+
|
|
29
|
+
| | Guide | For |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| 📦 | [**DRAGME.md**](./DRAGME.md) | Clone the repo, build from source, full control |
|
|
32
|
+
| ☁️ | [**CARRYME.md**](./CARRYME.md) | Install from npm, zero cloning |
|
|
33
|
+
| 📖 | [**Docs**](https://ufira-ai.github.io/Vibma/) | Tool reference with parameters, response schemas, and examples |
|
|
34
|
+
|
|
35
|
+
Or just paste this to your AI agent and let it figure it out:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
Set up Vibma so I can vibe-design in Figma.
|
|
39
|
+
Follow the instructions at https://raw.githubusercontent.com/ufira-ai/vibma/refs/heads/main/CARRYME.md
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Community
|
|
43
|
+
|
|
44
|
+
[](https://discord.gg/4XTedZdwV6)
|
|
45
|
+
|
|
46
|
+
[GitHub Issues](https://github.com/ufira-ai/vibma/issues) — bugs and feature requests
|
|
47
|
+
|
|
48
|
+
Vibma is the first open-source project from **[ufira](https://github.com/ufira-ai)** — a platform bridging creators and technology. We believe everyone who wants to create should have access to AI-powered tools, not just developers.
|
|
49
|
+
|
|
50
|
+
## Acknowledgments
|
|
51
|
+
|
|
52
|
+
Built on the foundation of [cursor-talk-to-figma-mcp](https://github.com/grab/cursor-talk-to-figma-mcp) by [sonnylazuardi](https://github.com/sonnylazuardi).
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
[MIT](./LICENSE)
|
package/dist/mcp.cjs
CHANGED
|
@@ -268,7 +268,10 @@ var sectionItem = import_zod6.z.object({
|
|
|
268
268
|
y: yPos,
|
|
269
269
|
width: import_zod6.z.coerce.number().optional().describe("Width (default: 500)"),
|
|
270
270
|
height: import_zod6.z.coerce.number().optional().describe("Height (default: 500)"),
|
|
271
|
-
parentId
|
|
271
|
+
parentId,
|
|
272
|
+
fillColor: flexJson(colorRgba).optional().describe("Fill color. Default: no fill (transparent)."),
|
|
273
|
+
fillStyleName: import_zod6.z.string().optional().describe("Apply a fill paint style by name (case-insensitive)."),
|
|
274
|
+
fillVariableId: import_zod6.z.string().optional().describe("Bind a color variable to the fill.")
|
|
272
275
|
});
|
|
273
276
|
var svgItem = import_zod6.z.object({
|
|
274
277
|
svg: import_zod6.z.string().describe("SVG markup string"),
|
|
@@ -280,7 +283,7 @@ var svgItem = import_zod6.z.object({
|
|
|
280
283
|
var tools5 = [
|
|
281
284
|
{
|
|
282
285
|
name: "create_section",
|
|
283
|
-
description: "Create section nodes to organize content on the canvas.",
|
|
286
|
+
description: "Create section nodes to organize content on the canvas. Default: no fill (transparent).",
|
|
284
287
|
schema: { items: flexJson(import_zod6.z.array(sectionItem)).describe("Array of sections to create"), depth },
|
|
285
288
|
tier: "create"
|
|
286
289
|
},
|
|
@@ -377,8 +380,8 @@ var textItem = import_zod8.z.object({
|
|
|
377
380
|
var tools7 = [
|
|
378
381
|
{
|
|
379
382
|
name: "create_text",
|
|
380
|
-
description: "Create text nodes.
|
|
381
|
-
schema: { items: flexJson(import_zod8.z.array(textItem)
|
|
383
|
+
description: "Create text nodes. Prefer textStyleName for typography and fontColorStyleName or fontColorVariableId for color \u2014 hardcoded values skip design tokens. Supports custom fonts via fontFamily.",
|
|
384
|
+
schema: { items: flexJson(import_zod8.z.array(textItem)).describe("Array of text nodes to create"), depth },
|
|
382
385
|
tier: "create"
|
|
383
386
|
}
|
|
384
387
|
];
|
|
@@ -441,8 +444,9 @@ var patchNodeItem = import_zod10.z.object({
|
|
|
441
444
|
// Appearance (nested)
|
|
442
445
|
fill: flexJson(import_zod10.z.object({
|
|
443
446
|
color: flexJson(colorRgba).optional(),
|
|
444
|
-
styleName: import_zod10.z.string().optional().describe("Paint style name (preferred over color)")
|
|
445
|
-
|
|
447
|
+
styleName: import_zod10.z.string().optional().describe("Paint style name (preferred over color)"),
|
|
448
|
+
clear: flexBool(import_zod10.z.boolean()).optional().describe("Set true to remove all fills")
|
|
449
|
+
})).optional().describe("Fill color, style, or clear"),
|
|
446
450
|
stroke: flexJson(import_zod10.z.object({
|
|
447
451
|
color: flexJson(colorRgba).optional(),
|
|
448
452
|
weight: import_zod10.z.coerce.number().positive().optional().describe("Stroke weight"),
|
|
@@ -903,7 +907,8 @@ var componentItem = import_zod17.z.object({
|
|
|
903
907
|
itemSpacing: import_zod17.z.coerce.number().optional().describe("Spacing between children (default: 0)")
|
|
904
908
|
});
|
|
905
909
|
var fromNodeItem = import_zod17.z.object({
|
|
906
|
-
nodeId
|
|
910
|
+
nodeId,
|
|
911
|
+
exposeText: flexBool(import_zod17.z.boolean()).default(true).describe("Auto-expose text children as editable TEXT properties and bind them (default: true). Set false to skip.")
|
|
907
912
|
});
|
|
908
913
|
var combineItem = import_zod17.z.object({
|
|
909
914
|
componentIds: flexJson(import_zod17.z.array(import_zod17.z.string())).describe("Component IDs to combine (min 2)"),
|
|
@@ -941,16 +946,16 @@ var tools15 = [
|
|
|
941
946
|
description: `CRUD endpoint for components.
|
|
942
947
|
create \u2192 {type, items, depth?} \u2192 {results: [{id}, ...]}
|
|
943
948
|
type 'component': create from scratch with layout/style params
|
|
944
|
-
type 'from_node': convert existing nodes to components
|
|
949
|
+
type 'from_node': convert existing nodes to components. Text children are auto-exposed as editable properties by default (exposeText: true) \u2014 instances can set text directly via properties.
|
|
945
950
|
type 'variant_set': combine components into variant sets
|
|
946
951
|
get \u2192 {id, fields?} \u2192 component object (full detail, field-filterable)
|
|
947
952
|
list \u2192 {name?, setsOnly?, fields?, offset?, limit?} \u2192 paginated stubs
|
|
948
|
-
update \u2192 {items: [{id, propertyName, type, defaultValue}]} \u2192
|
|
953
|
+
update \u2192 {items: [{id, propertyName, type, defaultValue}]} \u2192 creates property AND binds matching text node automatically`,
|
|
949
954
|
schema: (caps2) => endpointSchema(
|
|
950
955
|
["create", "get", "list", "update"],
|
|
951
956
|
caps2,
|
|
952
957
|
{
|
|
953
|
-
items: flexJson(import_zod17.z.array(import_zod17.z.any())).optional().describe("create (component): [{name, parentId?, ...layout}]. create (from_node): [{nodeId}]. create (variant_set): [{componentIds, name?}]. update: [{id, propertyName, type, defaultValue}]."),
|
|
958
|
+
items: flexJson(import_zod17.z.array(import_zod17.z.any())).optional().describe("create (component): [{name, parentId?, ...layout}]. create (from_node): [{nodeId, exposeText?}]. create (variant_set): [{componentIds, name?}]. update: [{id, propertyName, type, defaultValue}]."),
|
|
954
959
|
type: import_zod17.z.enum(["component", "from_node", "variant_set"]).optional().describe("Create type. Required for create: 'component' (from scratch), 'from_node' (convert existing), 'variant_set' (combine as variants)."),
|
|
955
960
|
depth,
|
|
956
961
|
name: import_zod17.z.string().optional().describe("Filter list by name (case-insensitive substring)."),
|
|
@@ -1229,6 +1234,45 @@ Transfer content overrides from a source instance to target instances.
|
|
|
1229
1234
|
description: "Strategy for transferring overrides between component instances in Figma"
|
|
1230
1235
|
})
|
|
1231
1236
|
);
|
|
1237
|
+
server2.registerPrompt(
|
|
1238
|
+
"missing_tools",
|
|
1239
|
+
{ description: "Why create or edit tools are missing and how to fix it" },
|
|
1240
|
+
() => ({
|
|
1241
|
+
messages: [{
|
|
1242
|
+
role: "assistant",
|
|
1243
|
+
content: {
|
|
1244
|
+
type: "text",
|
|
1245
|
+
text: `# Missing Create / Edit Tools
|
|
1246
|
+
|
|
1247
|
+
If the user asks you to create or modify something in Figma but you cannot find tools like \`create_frame\`, \`create_text\`, \`patch_nodes\`, \`delete_node\`, or \`set_text_content\`, the MCP server was started without the correct access tier flag.
|
|
1248
|
+
|
|
1249
|
+
Vibma filters tools at startup based on CLI flags passed in the MCP config \`args\` array:
|
|
1250
|
+
|
|
1251
|
+
| Flag | Tools available |
|
|
1252
|
+
|------|----------------|
|
|
1253
|
+
| _(none)_ | Read-only (inspect, search, export) |
|
|
1254
|
+
| \`--create\` | Read + creation tools |
|
|
1255
|
+
| \`--edit\` | All tools (read + create + edit + delete) |
|
|
1256
|
+
|
|
1257
|
+
Ask the user to add \`--edit\` (or \`--create\`) to their MCP config args:
|
|
1258
|
+
|
|
1259
|
+
\`\`\`json
|
|
1260
|
+
{
|
|
1261
|
+
"mcpServers": {
|
|
1262
|
+
"Vibma": {
|
|
1263
|
+
"command": "npx",
|
|
1264
|
+
"args": ["-y", "@ufira/vibma", "--edit"]
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
\`\`\`
|
|
1269
|
+
|
|
1270
|
+
After updating, the user must restart their AI tool or reload MCP servers \u2014 stdio-based servers cannot hot-reload.`
|
|
1271
|
+
}
|
|
1272
|
+
}],
|
|
1273
|
+
description: "Why create or edit tools are missing and how to fix it"
|
|
1274
|
+
})
|
|
1275
|
+
);
|
|
1232
1276
|
}
|
|
1233
1277
|
|
|
1234
1278
|
// src/tools/mcp-registry.ts
|
|
@@ -1266,6 +1310,13 @@ try {
|
|
|
1266
1310
|
VIBMA_VERSION = pkg.version;
|
|
1267
1311
|
break;
|
|
1268
1312
|
}
|
|
1313
|
+
if (pkg.workspaces) {
|
|
1314
|
+
try {
|
|
1315
|
+
VIBMA_VERSION = JSON.parse((0, import_fs.readFileSync)((0, import_path.join)(dir, "packages/core/package.json"), "utf8")).version;
|
|
1316
|
+
} catch {
|
|
1317
|
+
}
|
|
1318
|
+
break;
|
|
1319
|
+
}
|
|
1269
1320
|
} catch {
|
|
1270
1321
|
continue;
|
|
1271
1322
|
}
|