Skip to main content
Glama

get_figma_styles

Extract style data and CSS from Figma design nodes using file URLs to analyze design elements and generate code for development workflows.

Instructions

根据Figma URL获取节点的样式数据

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
generateCSSNo是否生成CSS代码
urlYesFigma文件URL,可以包含node-id参数指定特定节点

Implementation Reference

  • Handler method in the main server class that processes the 'get_figma_styles' tool request, delegates to FigmaStyleExtractor, optionally generates CSS, and formats the JSON response.
    private async handleGetStyles(args: any) { const { url, generateCSS = false } = args; const styleData = await this.styleExtractor.getStylesFromUrl(url); let cssCode = ''; if (generateCSS && styleData.styles.length > 0) { const cssRules = styleData.styles.map(style => { const selector = `.${style.nodeName.toLowerCase().replace(/\\s+/g, '-')}`; const css = this.styleExtractor.generateCSS(style); return css ? `${selector} {\\n ${css}\\n}` : ''; }).filter(rule => rule); cssCode = cssRules.join('\\n\\n'); } return { content: [ { type: 'text', text: JSON.stringify({ success: true, data: { fileInfo: styleData.fileInfo, styles: styleData.styles, globalStyles: styleData.globalStyles, ...(cssCode && { generatedCSS: cssCode }), }, }, null, 2), }, ], }; }
  • Core handler function in FigmaStyleExtractor that parses the Figma URL, fetches file/node data, identifies target nodes, extracts styles using helper methods, and returns structured ComponentStyles.
    async getStylesFromUrl(figmaUrl: string): Promise<ComponentStyles> { try { const urlInfo = this.figmaService.parseUrl(figmaUrl); const { fileId, nodeId } = urlInfo; const file = await this.figmaService.getFile(fileId); let targetNodes: FigmaNode[] = []; if (nodeId) { // 获取特定节点 const node = await this.figmaService.getNode(fileId, nodeId); if (node) { targetNodes = [node]; } } else { // 获取整个文件的主要组件 targetNodes = this.extractMainComponents(file.document); } const styles = targetNodes.map(node => this.extractNodeStyle(node)); return { fileInfo: { fileId, fileName: file.name, lastModified: file.lastModified, }, styles, globalStyles: file.styles, }; } catch (error) { throw new Error(`获取样式数据失败: ${error instanceof Error ? error.message : '未知错误'}`); } }
  • Input schema and metadata for the 'get_figma_styles' tool as registered in the ListTools response.
    { name: 'get_figma_styles', description: '根据Figma URL获取节点的样式数据', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Figma文件URL,可以包含node-id参数指定特定节点', }, generateCSS: { type: 'boolean', description: '是否生成CSS代码', default: false, }, }, required: ['url'], }, },
  • src/index.ts:200-201 (registration)
    Switch case registration that routes 'get_figma_styles' tool calls to the handleGetStyles method.
    case 'get_figma_styles': return await this.handleGetStyles(args);
  • Key helper function that extracts detailed style properties (fills, strokes, effects, text, etc.) from a single Figma node into the StyleData structure.
    private extractNodeStyle(node: FigmaNode): StyleData { const style: StyleData = { nodeId: node.id, nodeName: node.name, nodeType: node.type, }; // 位置和尺寸 if (node.absoluteBoundingBox) { style.position = { x: node.absoluteBoundingBox.x, y: node.absoluteBoundingBox.y, width: node.absoluteBoundingBox.width, height: node.absoluteBoundingBox.height, }; } // 填充样式 if (node.fills && node.fills.length > 0) { style.fills = node.fills.map(fill => ({ type: fill.type, color: fill.color ? { r: Math.round(fill.color.r * 255), g: Math.round(fill.color.g * 255), b: Math.round(fill.color.b * 255), a: fill.color.a || 1, } : undefined, gradientStops: fill.gradientStops?.map((stop: any) => ({ color: { r: Math.round(stop.color.r * 255), g: Math.round(stop.color.g * 255), b: Math.round(stop.color.b * 255), a: stop.color.a || 1, }, position: stop.position, })), })); } // 描边样式 if (node.strokes && node.strokes.length > 0) { style.strokes = node.strokes.map(stroke => ({ type: stroke.type, color: stroke.color ? { r: Math.round(stroke.color.r * 255), g: Math.round(stroke.color.g * 255), b: Math.round(stroke.color.b * 255), a: stroke.color.a || 1, } : undefined, })); } // 描边粗细 if (node.strokeWeight !== undefined) { style.strokeWeight = node.strokeWeight; } // 圆角 if (node.cornerRadius !== undefined) { style.cornerRadius = node.cornerRadius; } // 效果(阴影、模糊等) if (node.effects && node.effects.length > 0) { style.effects = node.effects.map(effect => ({ type: effect.type, visible: effect.visible !== false, radius: effect.radius, color: effect.color ? { r: Math.round(effect.color.r * 255), g: Math.round(effect.color.g * 255), b: Math.round(effect.color.b * 255), a: effect.color.a || 1, } : undefined, offset: effect.offset ? { x: effect.offset.x, y: effect.offset.y, } : undefined, })); } // 文本样式 if (node.style) { style.textStyle = { fontFamily: node.style.fontFamily, fontSize: node.style.fontSize, fontWeight: node.style.fontWeight, letterSpacing: node.style.letterSpacing, lineHeight: node.style.lineHeightPx, textAlign: node.style.textAlignHorizontal, }; // 如果有文本颜色信息 if (node.fills && node.fills.length > 0 && node.type === 'TEXT') { const textFill = node.fills[0]; if (textFill.color) { style.textStyle.textColor = { r: Math.round(textFill.color.r * 255), g: Math.round(textFill.color.g * 255), b: Math.round(textFill.color.b * 255), a: textFill.color.a || 1, }; } } } // 约束 if (node.constraints) { style.constraints = { vertical: node.constraints.vertical, horizontal: node.constraints.horizontal, }; } return style; }
  • TypeScript interfaces defining the structure of extracted style data (output schema).
    export interface StyleData { nodeId: string; nodeName: string; nodeType: string; position?: { x: number; y: number; width: number; height: number; }; fills?: Array<{ type: string; color?: { r: number; g: number; b: number; a: number; }; gradientStops?: Array<{ color: { r: number; g: number; b: number; a: number }; position: number; }>; }>; strokes?: Array<{ type: string; color?: { r: number; g: number; b: number; a: number; }; }>; strokeWeight?: number; cornerRadius?: number; effects?: Array<{ type: string; visible: boolean; radius?: number; color?: { r: number; g: number; b: number; a: number; }; offset?: { x: number; y: number; }; }>; textStyle?: { fontFamily?: string; fontSize?: number; fontWeight?: number; letterSpacing?: number; lineHeight?: number; textAlign?: string; textColor?: { r: number; g: number; b: number; a: number; }; }; constraints?: { vertical: string; horizontal: string; }; } export interface ComponentStyles { fileInfo: { fileId: string; fileName: string; lastModified: string; }; styles: StyleData[]; globalStyles?: Record<string, any>; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Echoxiawan/figma-mcp-full-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server