faux-studio 0.3.5 → 0.3.6
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/index.js +132 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25422,6 +25422,107 @@ function annotate(tool) {
|
|
|
25422
25422
|
if (!annotations) return tool;
|
|
25423
25423
|
return { ...tool, annotations };
|
|
25424
25424
|
}
|
|
25425
|
+
var RESOURCES = [
|
|
25426
|
+
{
|
|
25427
|
+
uri: "figma://file",
|
|
25428
|
+
name: "Current File",
|
|
25429
|
+
description: "File name, pages, and current page info",
|
|
25430
|
+
mimeType: "application/json",
|
|
25431
|
+
script: `
|
|
25432
|
+
const root = figma.root;
|
|
25433
|
+
const page = figma.currentPage;
|
|
25434
|
+
return {
|
|
25435
|
+
name: root.name,
|
|
25436
|
+
currentPage: { id: page.id, name: page.name },
|
|
25437
|
+
pages: root.children.map(p => ({
|
|
25438
|
+
id: p.id,
|
|
25439
|
+
name: p.name,
|
|
25440
|
+
childCount: p.children.length,
|
|
25441
|
+
})),
|
|
25442
|
+
};
|
|
25443
|
+
`
|
|
25444
|
+
},
|
|
25445
|
+
{
|
|
25446
|
+
uri: "figma://selection",
|
|
25447
|
+
name: "Current Selection",
|
|
25448
|
+
description: "Nodes the user has selected in Figma",
|
|
25449
|
+
mimeType: "application/json",
|
|
25450
|
+
script: `
|
|
25451
|
+
const sel = figma.currentPage.selection;
|
|
25452
|
+
return {
|
|
25453
|
+
count: sel.length,
|
|
25454
|
+
selection: sel.map(n => ({
|
|
25455
|
+
id: n.id,
|
|
25456
|
+
name: n.name,
|
|
25457
|
+
type: n.type,
|
|
25458
|
+
x: 'x' in n ? n.x : undefined,
|
|
25459
|
+
y: 'y' in n ? n.y : undefined,
|
|
25460
|
+
width: 'width' in n ? n.width : undefined,
|
|
25461
|
+
height: 'height' in n ? n.height : undefined,
|
|
25462
|
+
})),
|
|
25463
|
+
};
|
|
25464
|
+
`
|
|
25465
|
+
},
|
|
25466
|
+
{
|
|
25467
|
+
uri: "figma://variables",
|
|
25468
|
+
name: "Design Tokens",
|
|
25469
|
+
description: "All variable collections and their variables (colors, spacing, typography tokens)",
|
|
25470
|
+
mimeType: "application/json",
|
|
25471
|
+
script: `
|
|
25472
|
+
const collections = figma.variables.getLocalVariableCollections();
|
|
25473
|
+
return collections.map(c => ({
|
|
25474
|
+
id: c.id,
|
|
25475
|
+
name: c.name,
|
|
25476
|
+
modes: c.modes,
|
|
25477
|
+
variableCount: c.variableIds.length,
|
|
25478
|
+
variables: c.variableIds.map(vid => {
|
|
25479
|
+
const v = figma.variables.getVariableById(vid);
|
|
25480
|
+
if (!v) return null;
|
|
25481
|
+
return {
|
|
25482
|
+
id: v.id,
|
|
25483
|
+
name: v.name,
|
|
25484
|
+
resolvedType: v.resolvedType,
|
|
25485
|
+
valuesByMode: v.valuesByMode,
|
|
25486
|
+
};
|
|
25487
|
+
}).filter(Boolean),
|
|
25488
|
+
}));
|
|
25489
|
+
`
|
|
25490
|
+
},
|
|
25491
|
+
{
|
|
25492
|
+
uri: "figma://components",
|
|
25493
|
+
name: "Components",
|
|
25494
|
+
description: "Local components and component sets in the file",
|
|
25495
|
+
mimeType: "application/json",
|
|
25496
|
+
script: `
|
|
25497
|
+
const nodes = figma.root.findAllWithCriteria({ types: ['COMPONENT', 'COMPONENT_SET'] });
|
|
25498
|
+
return nodes.map(c => ({
|
|
25499
|
+
id: c.id,
|
|
25500
|
+
name: c.name,
|
|
25501
|
+
type: c.type,
|
|
25502
|
+
description: c.description || undefined,
|
|
25503
|
+
parent: c.parent ? { id: c.parent.id, name: c.parent.name } : undefined,
|
|
25504
|
+
}));
|
|
25505
|
+
`
|
|
25506
|
+
},
|
|
25507
|
+
{
|
|
25508
|
+
uri: "figma://styles",
|
|
25509
|
+
name: "Styles",
|
|
25510
|
+
description: "Text styles, paint styles, and effect styles defined in the file",
|
|
25511
|
+
mimeType: "application/json",
|
|
25512
|
+
script: `
|
|
25513
|
+
const textStyles = figma.getLocalTextStyles();
|
|
25514
|
+
const paintStyles = figma.getLocalPaintStyles();
|
|
25515
|
+
const effectStyles = figma.getLocalEffectStyles();
|
|
25516
|
+
return {
|
|
25517
|
+
textStyles: textStyles.map(s => ({
|
|
25518
|
+
id: s.id, name: s.name, fontSize: s.fontSize, fontName: s.fontName,
|
|
25519
|
+
})),
|
|
25520
|
+
paintStyles: paintStyles.map(s => ({ id: s.id, name: s.name })),
|
|
25521
|
+
effectStyles: effectStyles.map(s => ({ id: s.id, name: s.name })),
|
|
25522
|
+
};
|
|
25523
|
+
`
|
|
25524
|
+
}
|
|
25525
|
+
];
|
|
25425
25526
|
var INSTRUCTIONS = `You are connected to Figma Desktop via faux-studio. You can create, modify, and inspect designs using the tools below.
|
|
25426
25527
|
|
|
25427
25528
|
## Workflow
|
|
@@ -25449,6 +25550,14 @@ var INSTRUCTIONS = `You are connected to Figma Desktop via faux-studio. You can
|
|
|
25449
25550
|
- \`get_components\` \u2014 list available components
|
|
25450
25551
|
- \`get_screenshot\` \u2014 visual capture of the canvas
|
|
25451
25552
|
|
|
25553
|
+
## Resources (via @mentions)
|
|
25554
|
+
Resources provide quick read-only access to Figma state without tool calls:
|
|
25555
|
+
- \`figma://file\` \u2014 file name, pages, current page
|
|
25556
|
+
- \`figma://selection\` \u2014 currently selected nodes
|
|
25557
|
+
- \`figma://variables\` \u2014 all design tokens and variable collections
|
|
25558
|
+
- \`figma://components\` \u2014 local component library
|
|
25559
|
+
- \`figma://styles\` \u2014 text, paint, and effect styles
|
|
25560
|
+
|
|
25452
25561
|
## Best Practices
|
|
25453
25562
|
- Always read the existing design system before creating new elements.
|
|
25454
25563
|
- Use auto-layout (horizontal/vertical) for responsive layouts \u2014 avoid absolute positioning.
|
|
@@ -25457,9 +25566,9 @@ var INSTRUCTIONS = `You are connected to Figma Desktop via faux-studio. You can
|
|
|
25457
25566
|
- Create components for reusable UI patterns.`;
|
|
25458
25567
|
function createMcpServer(deps) {
|
|
25459
25568
|
const server2 = new Server(
|
|
25460
|
-
{ name: "faux-studio", version: "0.3.
|
|
25569
|
+
{ name: "faux-studio", version: "0.3.6" },
|
|
25461
25570
|
{
|
|
25462
|
-
capabilities: { tools: { listChanged: true }, logging: {} },
|
|
25571
|
+
capabilities: { tools: { listChanged: true }, resources: {}, logging: {} },
|
|
25463
25572
|
instructions: INSTRUCTIONS
|
|
25464
25573
|
}
|
|
25465
25574
|
);
|
|
@@ -25598,6 +25707,27 @@ Run the \`login\` tool to re-authenticate.` : `Error: ${message}`
|
|
|
25598
25707
|
};
|
|
25599
25708
|
}
|
|
25600
25709
|
});
|
|
25710
|
+
server2.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
25711
|
+
resources: RESOURCES.map(({ uri, name, description, mimeType }) => ({
|
|
25712
|
+
uri,
|
|
25713
|
+
name,
|
|
25714
|
+
description,
|
|
25715
|
+
mimeType
|
|
25716
|
+
}))
|
|
25717
|
+
}));
|
|
25718
|
+
server2.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
25719
|
+
const { uri } = request.params;
|
|
25720
|
+
const resource = RESOURCES.find((r) => r.uri === uri);
|
|
25721
|
+
if (!resource) {
|
|
25722
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
25723
|
+
}
|
|
25724
|
+
log(`Reading resource: ${uri}`);
|
|
25725
|
+
const result = await deps.executeScript(resource.script);
|
|
25726
|
+
const text = result === void 0 || result === null ? "{}" : typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
25727
|
+
return {
|
|
25728
|
+
contents: [{ uri, mimeType: resource.mimeType, text }]
|
|
25729
|
+
};
|
|
25730
|
+
});
|
|
25601
25731
|
return server2;
|
|
25602
25732
|
}
|
|
25603
25733
|
async function startServer(server2) {
|