AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Figma Canvas Ops

skill-atezer-fmcp-figma-canvas-ops · by atezer

F-MCP Bridge ile Figma tuvalinde güvenli yazma/düzenleme için zorunlu önkoşul kılavuzu. figma_execute çağrısı öncesi bu skill yüklenmelidir.

No reviews yet
0 installs
38 views
0.0% view→install

Install

$ agentstack add skill-atezer-fmcp-figma-canvas-ops

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-atezer-fmcp-figma-canvas-ops)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

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 →
Are you the author of Figma Canvas Ops? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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.mdStatus: ✅

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

  1. return ile veri dön. figma.closePlugin() çağırma.
  1. 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) |

  1. figma.notify() çalışmaz — kullanma.
  1. console.log() dönmezreturn kullan.
  1. 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 return et, sonraki execute getNodeByIdAsync ile al
  • Her execute sonrası 1 satır Türkçe micro-report
  1. Renkler 0–1 aralığında (0–255 değil). Hardcoded renk YASAK — DS'den oku.
  1. 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; ``

  1. 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

  1. import keyword yasağı. Plugin sandbox'ta reserved word. async function getVar(k) kullan.
  1. setEffectStyleIdAsync zorunlu. Sync node.effectStyleId = id hata verir.
  1. setTextStyleIdAsync kullan, fontSize binding YASAK:

``js const style = await figma.importStyleByKeyAsync("KEY"); await textNode.setTextStyleIdAsync(style.id); ``

  1. 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); ``

  1. Escaped quote dikkat. figma_execute code'da \" yerine düz " kullan.
  1. Style Import Sessiz Fail. importStyleByKeyAsync null/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).

  1. Component Discovery Fallback. figma_search_assets boş 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.

  1. figma_validate_screen Timeout 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
  1. 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)textStyleIdgetStyleByIdAsync (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.

Versions

  • v0.1.0 Imported from the upstream source.