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 retrieve visual properties.

Instructions

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

Input Schema

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

Implementation Reference

  • Core handler that parses Figma URL, fetches file and node, extracts relevant styled nodes, and computes style data for the get_figma_styles tool.
    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 : '未知错误'}`); } }
  • Tool dispatch handler in switch statement that calls the style extractor and formats response, optionally generating CSS.
    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), }, ], }; }
  • src/index.ts:75-93 (registration)
    Tool registration including name, description, and input schema 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'], }, },
  • Type definitions for style data structures used as output schema for the tool.
    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>; }
  • Helper function to generate CSS from extracted style data, used when generateCSS=true.
    generateCSS(styleData: StyleData): string { const cssRules: string[] = []; // 位置和尺寸 if (styleData.position) { cssRules.push(`width: ${styleData.position.width}px`); cssRules.push(`height: ${styleData.position.height}px`); } // 背景色 if (styleData.fills && styleData.fills.length > 0) { const fill = styleData.fills[0]; if (fill.color) { const { r, g, b, a } = fill.color; if (a === 1) { cssRules.push(`background-color: rgb(${r}, ${g}, ${b})`); } else { cssRules.push(`background-color: rgba(${r}, ${g}, ${b}, ${a})`); } } } // 边框 if (styleData.strokes && styleData.strokes.length > 0) { const stroke = styleData.strokes[0]; const weight = styleData.strokeWeight || 1; if (stroke.color) { const { r, g, b, a } = stroke.color; if (a === 1) { cssRules.push(`border: ${weight}px solid rgb(${r}, ${g}, ${b})`); } else { cssRules.push(`border: ${weight}px solid rgba(${r}, ${g}, ${b}, ${a})`); } } } // 圆角 if (styleData.cornerRadius !== undefined) { cssRules.push(`border-radius: ${styleData.cornerRadius}px`); } // 文本样式 if (styleData.textStyle) { const textStyle = styleData.textStyle; if (textStyle.fontFamily) { cssRules.push(`font-family: "${textStyle.fontFamily}"`); } if (textStyle.fontSize) { cssRules.push(`font-size: ${textStyle.fontSize}px`); } if (textStyle.fontWeight) { cssRules.push(`font-weight: ${textStyle.fontWeight}`); } if (textStyle.letterSpacing) { cssRules.push(`letter-spacing: ${textStyle.letterSpacing}px`); } if (textStyle.lineHeight) { cssRules.push(`line-height: ${textStyle.lineHeight}px`); } if (textStyle.textAlign) { cssRules.push(`text-align: ${textStyle.textAlign.toLowerCase()}`); } if (textStyle.textColor) { const { r, g, b, a } = textStyle.textColor; if (a === 1) { cssRules.push(`color: rgb(${r}, ${g}, ${b})`); } else { cssRules.push(`color: rgba(${r}, ${g}, ${b}, ${a})`); } } } // 阴影效果 if (styleData.effects && styleData.effects.length > 0) { const shadows = styleData.effects .filter(effect => effect.type === 'DROP_SHADOW' && effect.visible) .map(effect => { const x = effect.offset?.x || 0; const y = effect.offset?.y || 0; const blur = effect.radius || 0; if (effect.color) { const { r, g, b, a } = effect.color; return `${x}px ${y}px ${blur}px rgba(${r}, ${g}, ${b}, ${a})`; } return ''; }) .filter(shadow => shadow); if (shadows.length > 0) { cssRules.push(`box-shadow: ${shadows.join(', ')}`); } } return cssRules.length > 0 ? cssRules.join(';\n ') + ';' : ''; }

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