Install
$ agentstack add skill-atezer-fmcp-figma-canvas-ops ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Figma Canvas Ops — figma_execute Güvenli Kullanım Kılavuzu
Araç Eşleme (topluluk → F-MCP)
| Topluluk | F-MCP Bridge | Not | |---|---|---| | use_figma | figma_execute | JS çalıştırma | | get_metadata | figma_get_file_data | Yapı/metadata | | get_screenshot | figma_capture_screenshot | Görsel doğrulama | | search_design_system | figma_search_components + figma_get_design_system_summary | İki araç birlikte |
Prerequisites
- F-MCP Bridge plugin bağlı olmalı (
figma_get_status()) - Aktif DS context:
.claude/design-systems/active-ds.md→Status: ✅
0. Design System Context (ZORUNLU)
0a — Active DS check
1. Read .claude/design-systems/active-ds.md
2. ✅ Aktif → Library Name not al, 0b'ye geç
❌ Seçilmedi → 0c'ye geç
"DS bypass mode" → DS'siz devam
0b — DS asset cache hazırlığı
1. .claude/design-systems//components.md var mı?
2. .claude/design-systems//tokens.md var mı?
3. Yoksa: figma_get_library_variables + figma_search_assets ile keşfet, cache'e yaz
0c — Kullanıcıya DS seçimi sor
active-ds.md ❌ ise: "Hangi DS? (SUI / Material / HIG / Kendi / Hiçbiri)". Yanıt sonrası active-ds.md güncelle, 0b'ye geç. Sonraki turlarda TEKRAR SORMA.
1. Kritik Kurallar
returnile veri dön.figma.closePlugin()çağırma.
- Düz JS, top-level
await. Kod otomatik async sarılır.(async()=>{})()sarma. Async API zorunlu — dynamic-page mode'da sync API'ler throws:
| ❌ YASAK (sync) | ✅ ZORUNLU (async) | |---|---| | instance.mainComponent | await instance.getMainComponentAsync() | | figma.getNodeById(id) | await figma.getNodeByIdAsync(id) | | figma.variables.importVariableByKey(key) | await figma.variables.importVariableByKeyAsync(key) | | figma.importComponentByKey(key) | await figma.importComponentByKeyAsync(key) | | figma.importStyleByKey(key) | await figma.importStyleByKeyAsync(key) | | node.effectStyleId = x | await node.setEffectStyleIdAsync(x) | | node.textStyleId = x | await node.setTextStyleIdAsync(x) | | figma.listAvailableFonts() | await figma.listAvailableFontsAsync() | | figma.loadFont(...) | await figma.loadFontAsync(...) | | figma.variables.getVariableCollectionById(id) | await figma.variables.getVariableCollectionByIdAsync(id) |
figma.notify()çalışmaz — kullanma.
console.log()dönmez —returnkullan.
- Küçük adımlarla çalış. Timeout: varsayılan 15000ms, max 30000ms.
### 5a. CHUNKING MANDATE (v2.0)
Her figma_execute max 15 atomic operation. Atomic op'lar: node/instance oluşturma, variable/style/component import, font load, bind operasyonu, getNodeByIdAsync, getMainComponentAsync.
- 1 execute = 1 mega-goal (discovery, frame+structure, 3-4 component placement)
- 25+ op → 2-3 execute'a böl
- Execute arası state: nodeId'leri
returnet, sonraki executegetNodeByIdAsyncile al - Her execute sonrası 1 satır Türkçe micro-report
- Renkler 0–1 aralığında (0–255 değil). Hardcoded renk YASAK — DS'den oku.
- Fills/strokes read-only array — klonla, değiştir, ata:
``js const fills = [...node.fills]; fills[0] = { ...fills[0], color: DS_COLOR }; node.fills = fills; ``
- Font yükleme zorunlu. Sıra: (a) DS cache'ten font oku → (b) Yoksa kullanıcıya sor → (c) "Sen seç" → Inter.
8a-1) Font weight check (ZORUNLU): loadFontAsync öncesi listAvailableFontsAsync ile kontrol et. Fallback helper: ```js const allFonts = await figma.listAvailableFontsAsync(); const styles = allFonts.filter(f => f.fontName.family === "SHBGrotesk").map(f => f.fontName.style); function pickStyle(desired, available) { if (available.indexOf(desired) >= 0) return desired; var fb = { "Medium":["Semi Bold","Regular"], "ExtraBold":["Bold"], "Black":["Bold"], "Thin":["Light","Regular"] }; var alts = fb[desired] || []; for (var i = 0; i = 0) return alts[i]; } return available.find(s => s.indexOf("Italic") 0 && !(node.boundVariables && node.boundVariables[p])) { throw new Error("UNBOUNDPADDING: " + node.name + "." + p + "=" + node[p] + " — setBoundVariable cagrisi eksik"); } } if (typeof node.itemSpacing === "number" && node.itemSpacing > 0 && !(node.boundVariables && node.boundVariables.itemSpacing)) { throw new Error("UNBOUNDITEMSPACING: " + node.name + " — setBoundVariable('itemSpacing', v) cagrisi eksik"); } var radProps = ["cornerRadius","topLeftRadius","topRightRadius","bottomLeftRadius","bottomRightRadius"]; for (var k = 0; k 0 && !(node.boundVariables && node.boundVariables[r])) { throw new Error("UNBOUNDRADIUS: " + node.name + "." + r + "=" + node[r]); } } } // Text style if (node.type === "TEXT" && !(node.textStyleId && typeof node.textStyleId === "string" && node.textStyleId !== "")) { throw new Error("UNBOUNDTEXTSTYLE: '" + (node.characters||"").slice(0,30) + "' — setTextStyleIdAsync(style.id) cagrisi eksik"); } }
// Tüm oluşturulan node'ları doğrula: for (var n = 0; n ({ w: n.width, h: n.height, children: n.children?.length }));
// İYİ — toplu (birden fazla node) return Promise.all(ids.map(async id => { const n = await figma.getNodeByIdAsync(id); return { id, name: n?.name, size: n ? [n.width, n.height] : null }; }));
// KÖTÜ — 30 satır "defensive" kod boyut sorgusu için // await figma.loadAllPagesAsync(); for (var pg of ...) { if (...) ... } ```
Kural: Tek nodeId için size → 1 satır. Multi-node metadata → 1 Promise.all. Complex traversal sadece üretim mantığında gerekli — keşifte değil.
2. Sayfa Kuralları
const page = figma.root.children.find(p => p.name === "Sayfa");
await figma.setCurrentPageAsync(page);
Sync figma.currentPage = page HATA verir. Her figma_execute'ta currentPage sıfırlanır.
3. Auto-Layout Kalıpları
const frame = figma.createFrame();
frame.layoutMode = "VERTICAL";
frame.primaryAxisSizingMode = "AUTO";
frame.counterAxisSizingMode = "AUTO";
frame.itemSpacing = 16;
frame.paddingTop = frame.paddingBottom = 24;
frame.paddingLeft = frame.paddingRight = 24;
FILL boyutlandırma: ÖNCE appendChild, SONRA layoutSizingHorizontal = "FILL" (Rule 11).
4. Bileşen ve Instance Kalıpları
// Local component
const comp = figma.root.findOne(n => n.type === "COMPONENT" && n.name === "Button");
const instance = comp.createInstance();
// Variant seçimi
const set = figma.root.findOne(n => n.type === "COMPONENT_SET" && n.name === "Button");
const variant = set.children.find(c => c.name === "Size=Large, Type=Primary");
const inst = variant.createInstance();
5. Variable Bağlama
const variable = await figma.variables.importVariableByKeyAsync("KEY");
// Fill bind
const fills = [...node.fills];
node.fills = [figma.variables.setBoundVariableForPaint(fills[0], "color", variable)];
// Spacing bind
node.setBoundVariable("paddingLeft", variable);
6. Ek API Gotcha'lar
importkeyword yasağı. Plugin sandbox'ta reserved word.async function getVar(k)kullan.
setEffectStyleIdAsynczorunlu. Syncnode.effectStyleId = idhata verir.
setTextStyleIdAsynckullan, fontSize binding YASAK:
``js const style = await figma.importStyleByKeyAsync("KEY"); await textNode.setTextStyleIdAsync(style.id); ``
setExplicitVariableModeForCollection— string ID çalışmaz. Library API chain ile collection OBJECT al:
``js var colls = await figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync(); var sem = colls.find(c => c.name.indexOf("Semantic Colors") !== -1); var vars = await figma.teamLibrary.getVariablesInLibraryCollectionAsync(sem.key); var first = await figma.variables.importVariableByKeyAsync(vars[0].key); var coll = await figma.variables.getVariableCollectionByIdAsync(first.variableCollectionId); var darkMode = coll.modes.find(m => m.name === "Dark"); frame.setExplicitVariableModeForCollection(coll, darkMode.modeId); ``
- Escaped quote dikkat.
figma_executecode'da\"yerine düz"kullan.
- Style Import Sessiz Fail.
importStyleByKeyAsyncnull/throws olabilir. Her zaman try-catch:
``js let style = null; try { style = await figma.importStyleByKeyAsync("KEY"); } catch(e) {} if (style) { await textNode.setTextStyleIdAsync(style.id); await figma.loadFontAsync(textNode.fontName); textNode.characters = "Metin"; } else { await figma.loadFontAsync({ family: "Inter", style: "Regular" }); textNode.fontName = { family: "Inter", style: "Regular" }; textNode.characters = "Metin (fallback)"; } ` **Fast Path:** roleMap hazırsa setTextStyleIdAsync(roleMap[role].id)` direkt kullan, import atla (bkz. fmcp-screen-recipes Adım 1.6).
- Component Discovery Fallback.
figma_search_assetsboş dönerse manuel instance scan:
``js const instances = figma.currentPage.findAll(n => n.type === "INSTANCE"); const map = new Map(); for (const inst of instances) { const main = await inst.getMainComponentAsync(); if (main && main.remote && main.key && !map.has(main.name)) map.set(main.name, { name: main.name, key: main.key }); } return Array.from(map.values()); ` Sıra: (1) Cache → (2) figmasearchassets → (3) Manuel scan → (4) Key biliniyor → importComponentByKeyAsync(key)` direkt.
figma_validate_screenTimeout Fallback. 3 seviyeli:
- Seviye 1:
figma_validate_screen(nodeId, minScore=80)— timeout olursa: - Seviye 2: Content Body wrapper'ı validate et (daha küçük tree), minScore=70
- Seviye 3: Manuel QA Checklist üret:
- [ ] Instance coverage ≥60%
- [ ] Rastgele 5 fill'de variable icon 🎨 var mı
- [ ] Rastgele 3 spacing variable-bound mu
- [ ] Auto-layout tüm frame'lerde aktif mi
- [ ] Dark mode renkleri doğru mu
- Component Property Discovery — Tek Execute.
``js const comp = await figma.importComponentByKeyAsync(key); let set = comp.parent?.type === "COMPONENT_SET" ? comp.parent : comp; const propDefs = set.componentPropertyDefinitions || {}; return { componentName: comp.name, propertyDefinitions: Object.entries(propDefs).map(([n, d]) => ({ name: n, type: d.type, defaultValue: d.defaultValue, variantOptions: d.variantOptions || [] })) }; ` figmainstantiatecomponent timeout olursa: figma_execute içinde importComponentByKeyAsync(key) + comp.createInstance()`.
Text Style Discovery: (1) Instance scan: findAll(TEXT) → textStyleId → getStyleByIdAsync (2) Boşsa figma_search_assets (3) Boşsa team library API (4) Fallback Inter + hardcoded size.
7. Hata Kurtarma
| Hata | Çözüm | |---|---| | Cannot read property of undefined | Node ID geçersiz / sayfa yüklenmemiş | | Font not loaded | loadFontAsync eksik | | Font could not be loaded | Weight yok → pickStyle() fallback (Rule 8a-1) | | Cannot set FILL before appendChild | Rule 11 sırası | | Maximum call stack | Küçük parçalara böl | | Resource links not supported | Yanlış MCP (resmi) → F-MCP kullan |
8. Doğrulama
Her yazma sonrası: figma_capture_screenshot + gerekirse figma_get_file_data.
Skill Koordinasyonu
- fmcp-screen-orchestrator — DS GATE, Fast Path routing
- fmcp-screen-recipes — Fast Path (Rule 25 validate, Rule 26 discovery referans alınır)
- generate-figma-screen — Tam workflow
- generate-figma-library / apply-figma-design-system / fix-figma-design-system-finding / figjam-diagram-builder
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: atezer
- Source: atezer/FMCP
- License: MIT
- Homepage: https://www.npmjs.com/package/@atezer/figma-mcp-bridge
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.