mcpField
F
figma-spec

figma-spec

github.com/figma文档处理2.1k203 次安装今天更新
代码仓库

关于 figma-spec

figma-spec 是用于读取、创建和编辑原生 Figma 规范文档的技能,文档采用 Markdown。它涵盖规范定位、内容安全编辑及评论标记保留。

主要功能

  1. 01跨页面查找规范文档
  2. 02读取并验证 Markdown 内容
  3. 03在画布中创建嵌入式规范
  4. 04定点修改文档内容
  5. 05保留评论锚点和链接

适用场景

  1. 01查找 Figma 文件中的嵌入式规范
  2. 02起草或更新规范文档
  3. 03修改文本而不替换整份文档

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/figma/mcp-server-guide --skill figma-spec

安装后在 Claude Code 中输入/figma-spec确认已加载。

详细介绍

使用 Figma 规格说明

在使用任何 figma.spec.* API 之前,必须始终调用 whoami,并确认目标文件所属方案(或新文件的目标方案)已启用 specs_enabled: true。whoami 无法识别文件所属的方案。如果方案不明确,必须询问用户;切勿根据文件键或其他方案的访问权限推断。如果该方案的 specs_enabled 为 false 或未设置,请说明 Specs 不可用,并停止工作流。

原生 Figma 规格说明是 SPEC_BLOCK 节点下的 GitHub 风格 Markdown(GFM)。独立的 Figma 规格说明只包含一个规格说明;FigJam 或 Design 文件可以包含多个嵌入式规格说明。

查找并选择 Figma 规格说明

如果提供的 URL 中包含 node-id,则使用 figma.getNodeByIdAsync 解析该 ID,并要求 type === "SPEC_BLOCK" 且 specBlockType === "DOCUMENT"。否则,使用 findAllWithCriteria({ types: ['SPEC_BLOCK'] }) 搜索当前页面,并筛选出 specBlockType === "DOCUMENT" 的节点(必要时使用 figma.spec.getContent 检查内容),直到找到目标。如果目标不在当前页面,则一次加载一个其他页面,使用 page.loadAsync() 并重复查询,直到找到目标。

将已解析的根 ID 传递给每次内容调用。仅当已知文件恰好包含一个 Figma 规格说明时,才省略 specNodeId;否则省略会导致错误。切勿将普通画布文本节点作为后备方案进行编辑。

在画布上创建 Figma 规格说明

// Creates an embedded Figma spec on a Design or FigJam canvas (not a standalone Figma spec file).
const { specNodeId } = await figma.spec.createOnCanvasAsync({
  title: 'Untitled spec',
  content: '# Title\n\nA paragraph.\n',
})

const specNode = await figma.getNodeByIdAsync(specNodeId)
if (!specNode) throw new Error('The created Figma spec could not be resolved')

const after = await figma.spec.getContent({ specNodeId })
if (!after.markdown.includes('A paragraph.')) {
  throw new Error('The new Figma spec content was not applied')
}

始终传递非空的 title 和 content 字符串(允许使用 '')。title 用于命名根节点;需要的 # H1 应包含在 content 中。

内容方法

// READ — returns specNodeId, markdown, title, etc.
// The body is `markdown`, not `content`.
const before = await figma.spec.getContent({ specNodeId: chosenSpec.id })
const page = await figma.spec.getContent({
  specNodeId: before.specNodeId,
  offset: 100,
  maxLines: 50,
})

// REPLACE — clears + recreates the document; use only for an empty first draft.
await figma.spec.setContent({
  specNodeId: before.specNodeId,
  content: '# Title\n\nA paragraph.\n',
})

// EDIT — find/replace; each oldText must match exactly once.
await figma.spec.editContent({
  specNodeId: before.specNodeId,
  edits: [{ oldText: 'First paragraph.', newText: 'Edited first paragraph.' }],
})

const after = await figma.spec.getContent({ specNodeId: before.specNodeId })
if (!after.markdown.includes('Edited first paragraph.')) {
  throw new Error('The targeted Figma spec edit was not applied')
}
  • 编辑前以及验证写入结果时,使用相同的 specNodeId 调用 getContent;不要依赖截图。
  • 默认使用适合多人协作且精确的 editContent。
  • 仅在空白的初稿或明确要求替换整个文档时,使用具有破坏性的 setContent。

重要规则

  1. editContent 要求恰好匹配一处。oldText 匹配零处或多处都会失败,且不会进行更改。添加上下文以确保匹配项唯一。
  2. **将 Markdown 作为纯字符串传递。**切勿使用 Buffer/base64 对其编码,也不要使用 atob() 解码。Base64 仅用于 Markdown 中的图像数据 URL。
  3. 将 Markdown 与节点遍历分开处理。figma.spec.* 负责处理内容;节点遍历只能访问文档根节点和嵌入式画布分支。
  4. **保留评论标记。**保持重叠的 [comment:<uuid>]…[/comment:<uuid>] 配对不变,并确保它们仍包围相同的文本;否则线程可能会脱离或消失。如有疑问,请原样复制带标记的文本段,只编辑其周围内容。
  5. **使用可移植的引用。**共享的 Figma 规格说明必须使用 GitHub 永久链接等链接,绝不能使用本机路径或 localhost URL。

样式

  • 标题区块必须始终位于最前面,并格式化为 H1,即使其文本为空也不例外。切勿移除它,也不要在它之前插入区块。
  • 表格标题行优先使用粗体文本。
  • 下划线使用 <ins>,包括组合格式:<ins>**粗体并带下划线**</ins>。不要使用 <u>,它仅在 HTML 导入时有效。

图像

在 setContent 或 editContent 中使用 GFM 图像语法:

  • ![alt](data:image/png;base64,...) 会嵌入字节数据,并对其解码和上传。
  • ![alt](https://host/img.png) 会在服务器端获取;不允许的主机将被拒绝。

getContent 会将图像 URL 输出为 https://<host>/spec/<fileKey>/image/<sha>?w=<width>&h=<height>。

评论

使用 figma.spec.comments.* 添加锚定线程。不确定如何更改时,优先添加评论,而不是悄悄编辑。

const comment = await figma.spec.comments.create({
  specNodeId: before.specNodeId,
  anchorText: 'the exact rendered text to anchor to', // MUST appear exactly once
  contextText: 'a longer unique substring containing anchorText', // optional; disambiguates repeats
  message: 'Comment body (markdown).',
})

const { root, replies, hasMore } = await figma.spec.comments.getThread({ uuid: comment.uuid })
await figma.spec.comments.reply({ uuid: comment.uuid, message: 'A reply.' })
  • anchorText 必须在渲染后的 Figma 规格说明中恰好匹配一处。使用包含该文本的较长 contextText,以区分重复文本。
  • getThread 和 reply 需要使用 [comment:<uuid>] 标记中显示的根评论 UUID;切勿将回复 UUID 传递给 reply。

评论

支持 Markdown