A Model Context Protocol (MCP) server that processes Figma designs into Claude-readable images with automatic tiling, compression, and smart cropping.
Note: The canonical source for the server lives in figma-smart-image-mcp/. The root directory only contains docs and deployment helpers.
Public URL: https://figma-smart-image-mcp-production.up.railway.app/
The live deployment supports multi-tenant authentication - multiple users can each use their own Figma token simultaneously.
- Smart Export: Automatic SVG/PNG export from Figma
- Auto Tiling: Large designs automatically split into manageable tiles
- Compression: Optimized for Claude's context size limits
- Smart Crops: Heuristic detection of UI patterns for better crops
- Multi-Tenant: Each user authenticates with their own Figma token
- Redis-Backed: Reliable token storage across sessions
Run this command in your terminal:
claude mcp add --transport http figma-smart-image https://figma-smart-image-mcp-production.up.railway.app/mcpThat's it! Now skip to Step 2 below.
Create or update .clauderc in your project directory:
{
"mcpServers": {
"figma-smart-image": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"https://figma-smart-image-mcp-production.up.railway.app/mcp"
]
}
}
}When you first use the MCP server, click Authenticate in Claude. The server will start Figma OAuth automatically and return you to Claude when finished. If Claude later shows Auth: not authenticated, just click Authenticate again to re-authorize.
If you prefer a Personal Access Token:
- Get a token from Figma Settings
- Open https://figma-smart-image-mcp-production.up.railway.app/
- Enter your token and click "Connect to Figma"
Now you can use Figma Smart Image tools in Claude:
// Ask Claude to process a Figma design
"Please extract the hero section from this Figma link:
https://www.figma.com/design/..."┌─────────────────┐
│ Claude Client │
└────────┬────────┘
│ 1. Request MCP connection
▼
┌─────────────────────────────┐
│ Railway Deployment │
│ (Multi-Tenant Server) │
└────────┬────────────────────┘
│ 2. Returns device_code + user_code
▼
┌─────────────────────────────┐
│ User visits auth page │
│ - Enters user_code │
│ - Enters Figma token │
└────────┬────────────────────┘
│ 3. Token stored in Redis
▼
┌─────────────────────────────┐
│ Client polls for token │
│ - Gets access_token │
│ - Uses Bearer auth │
└────────┬────────────────────┘
│ 4. Ready to use tools!
▼
┌─────────────────────────────┐
│ Figma Smart Image Tools │
│ - process_figma_link │
│ - get_figma_components │
│ - get_figma_node_details │
│ - get_figma_variables │
│ - list_figma_frames │
└─────────────────────────────┘
Processes a Figma URL and exports images + tiles to disk.
Input:
{
"url": "https://www.figma.com/design/...",
"out_dir": "/path/to/output",
"prefer_format": "webp"
}Lists all components and component sets in a Figma file.
Input:
{
"url": "https://www.figma.com/design/..."
}Returns layout + styling details for a specific node.
Input:
{
"url": "https://www.figma.com/design/...?...&node-id=1-123"
}Returns design variables (requires Figma Pro plan or higher).
Input:
{
"url": "https://www.figma.com/design/..."
}Lists top-level frames/components using a shallow fetch.
Input:
{
"url": "https://www.figma.com/design/...",
"max_frames": 200
}Shows which Figma user the token belongs to and whether the file is accessible.
Input:
{
"url": "https://www.figma.com/design/..."
}Claude Desktop uses the authorization_code + PKCE flow. If no token is available yet, the server will redirect directly to Figma OAuth and resume automatically.
The server uses the OAuth 2.0 Device Authorization Grant:
- Device Authorization Request
POST /device/authorize
Content-Type: application/json
{
"client_id": "mcp_client"
}
Response:
{
"device_code": "device_xxx",
"user_code": "ABC123",
"verification_uri": "https://...",
"expires_in": 600
}- User Authentication
POST /auth
Content-Type: application/x-www-form-urlencoded
user_code=ABC123&token=figd_xxx- Token Polling
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=device_xxx
Response:
{
"access_token": "device_xxx",
"token_type": "Bearer",
"expires_in": 3600
}- Authenticated Requests
POST /message?sessionId=xxx
Authorization: Bearer device_xxx
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { ... }
}MCP_TOOL_TIMEOUT_MS/FIGMA_TOOL_TIMEOUT_MS(default:60000) controls total tool execution time.FIGMA_REQUEST_TIMEOUT_MScontrols individual Figma API + image download requests.
Recommendation: For large Figma files, set both to 120000 (120s) to avoid timeouts.
If tools return Invalid token or 403:
- Clear cached OAuth tokens:
curl -s "https://figma-smart-image-mcp-production.up.railway.app/health?debug=clear_oauth" - Re-run Authenticate in Claude.
- Verify with:
debug_figma_access {"url":"https://www.figma.com/design/..."}
Figma URLs often encode or format node IDs differently. The server normalizes these, but you can also use one of these forms:
node-id=1:1234node-id=1-1234node-id=1%3A1234(URL-encoded)
If you see No image URL returned for node ..., try a normalized node-id or use:
list_figma_frames
{"url":"https://www.figma.com/design/..."}
To run locally:
# Install dependencies
npm install
# Set your Figma token (optional - multi-tenant mode works without it)
export FIGMA_TOKEN="your_figma_token_here"
# Build
npm run build
# Run server
npm startFor local development with Redis:
# Using Docker
docker run -d -p 6379:6379 redis
# Set Redis URL
export REDIS_URL="redis://localhost:6379"Environment variables:
| Variable | Description | Default |
|---|---|---|
FIGMA_TOKEN |
Figma Personal Access Token (optional for multi-tenant) | - |
REDIS_URL |
Redis connection URL for multi-tenant token storage | - |
PORT |
HTTP server port | 3845 |
- Transport: HTTP with Server-Sent Events (SSE)
- Storage: Redis for device codes and session tokens
- Authentication: OAuth 2.0 Device Authorization Grant
- Deployment: Railway (Docker container)
- Each user's Figma token is isolated in Redis
- Tokens expire after 1 hour
- Device codes expire after 10 minutes
- Bearer token required for all MCP requests
MIT
For issues and questions, please use the GitHub Issues page.