Spaces:
Running
Running
#!/usr/bin/env python3 | |
""" | |
๐จ Figma MCP Server - Hosted on Hugging Face Spaces | |
MCP Server to control Figma via Claude/Cursor with real REST API | |
""" | |
import gradio as gr | |
import asyncio | |
import json | |
import logging | |
from PIL import Image | |
import base64 | |
import io | |
# Configuration du logging | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
# Import all MCP tools from the tools folder | |
# Gradio will automatically detect all functions with docstrings/type hints | |
try: | |
from tools import * | |
logger.info( "โ All MCP tools successfully imported" ) | |
except Exception as e: | |
logger.error( f"โ Error importing MCP tools: {e} " ) | |
raise | |
# === GRADIO APPLICATION CONFIGURATION === | |
def setup_demo(): | |
"Configure the Gradio interface for the MCP server" | |
with gr.Blocks( | |
title="๐จ Figma MCP Server", | |
theme=gr.themes.Soft(), | |
) as demo: | |
gr.Markdown(""" | |
# ๐จ Figma MCP Server | |
**MCP Server to control Figma via Claude/Cursor with REST API** | |
## ๐ **Instructions de configuration :** | |
### 1. **Get a Figma token:** | |
- Aller sur [Figma Settings > Personal Access Tokens](https://www.figma.com/settings) | |
- Create a new token | |
- Copy the token (starts with `figd_` or `figc_`) | |
### 2. **Getting the ID of a file:** | |
- Open your Figma file | |
- Copy the ID from the URL: `https://www.figma.com/file/FILE_ID/file-name` | |
### 3. **Configure:** | |
```json | |
{ | |
"mcpServers": { | |
"figure": { | |
"command": "sse", | |
"args": ["https://underground-digital-middle-fig.hf.space/gradio_api/mcp/sse"] | |
} | |
} | |
} | |
``` | |
""") | |
# Test interface (optional) | |
with gr.Tab("๐งช Test"): | |
with gr.Row(): | |
token_input = gr.Textbox( | |
placeholder="figd_...", | |
label="Token Figma", | |
type="password" | |
) | |
token_btn = gr.Button("Configurer Token") | |
with gr.Row(): | |
file_input = gr.Textbox( | |
placeholder= "file ID" , | |
label= "Figma file ID" | |
) | |
file_btn = gr.Button( "Configure File" ) | |
status_output = gr.Textbox(label="Status", lines=3) | |
# Test actions | |
with gr.Row(): | |
test_info_btn = gr.Button("๐ Info Fichier") | |
test_comments_btn = gr.Button( "๐ Comments" ) | |
test_user_btn = gr.Button( "๐ค User Info" ) | |
# New buttons for detailed user info | |
with gr.Row(): | |
test_user_detailed_btn = gr.Button( "๐ค Detailed Profile" ) | |
test_teams_btn = gr.Button( "๐ข My Teams" ) | |
test_permissions_btn = gr.Button("๐ Permissions") | |
with gr.Row(): | |
test_stats_btn = gr.Button("๐ Stats Workspace") | |
with gr.Row(): | |
test_limitations_btn = gr.Button("๐ Limitations API") | |
# Event Connections | |
token_btn.click( | |
configure_figma_token, | |
inputs=[token_input], | |
outputs=[status_output] | |
) | |
file_btn.click( | |
configure_figma_file_id, | |
inputs=[file_input], | |
outputs=[status_output] | |
) | |
test_info_btn.click( | |
get_figma_file_info, | |
outputs=[status_output] | |
) | |
test_comments_btn.click( | |
get_figma_comments, | |
outputs=[status_output] | |
) | |
test_user_btn.click( | |
get_figma_user_info, | |
outputs=[status_output] | |
) | |
test_user_detailed_btn.click( | |
get_figma_user_detailed_info, | |
outputs=[status_output] | |
) | |
test_teams_btn.click( | |
list_figma_user_teams, | |
outputs=[status_output] | |
) | |
test_permissions_btn.click( | |
get_figma_current_user_permissions, | |
outputs=[status_output] | |
) | |
test_stats_btn.click( | |
get_figma_workspace_usage_stats, | |
outputs=[status_output] | |
) | |
test_limitations_btn.click( | |
get_figma_api_limitations_info, | |
outputs=[status_output] | |
) | |
gr.Markdown(""" | |
--- | |
### ๐ ๏ธ **Available MCP tools (auto-detection):** | |
**๐ Configuration :** | |
- `configure_figma_token(token)` - Configure le token d'accรจs | |
- `configure_figma_file_id(file_id)` - Configure l'ID du fichier | |
**๐ Navigation :** | |
- `get_figma_file_info()` - Gets file info | |
- `get_figma_comments()` - Retrieves comments | |
- `get_figma_user_info()` - Logged in user info | |
**๐ค User account and team:** | |
- `get_figma_user_detailed_info()` - Detailed user information (full profile) | |
- `list_figma_user_teams()` - Lists all user's teams with roles and plans | |
- `get_figma_team_info(team_id)` - Detailed team info (plan, limits, storage) | |
- `get_figma_current_user_permissions()` - Permissions in the current file (via Plugin API) | |
- `get_figma_workspace_usage_stats()` - Workspace usage statistics | |
- `list_figma_team_projects(team_id)` - Projects of a team | |
- `get_figma_api_limitations_info()` - Explique les limitations API Plugin vs REST | |
**๐จ Creation of basic elements (Figma Design):** | |
- `create_figma_rectangle(x, y, width, height, name, color)` - Crรฉe un rectangle | |
- `create_figma_frame(x, y, width, height, name)` - Crรฉe un frame | |
- `create_figma_text(x, y, text, name, font_size)` - Creates a text | |
**๐ก FigJam - Basic Elements:** | |
- `create_figjam_sticky_note(x, y, text, width, height)` - Post-it (dรฉfaut: 240ร240px) | |
- `create_figjam_connector_between_elements(element1_name, element2_name, style)` - Connector between elements | |
- `create_figjam_shape_with_text(x, y, shape_type, text, width, height)` - Shape with text (default: 208ร208px) | |
- `create_figjam_table(rows, columns, x, y)` - Tableau interactif | |
- `create_figjam_code_block(x, y, code, language)` - Code block with syntax highlighting | |
**๐ FigJam - Zones and organization:** | |
- `create_figjam_background_shape(x, y, width, height, color, title, corner_radius)` - Zone de fond rectangulaire | |
- `create_figjam_organized_zone(title, x, y, width, height, max_stickies)` - Zone avec grille de post-its | |
- `create_figjam_workshop_template(template_type, x, y)` - Templates d'atelier complets | |
**๐ญ FigJam - Stickers and reactions:** | |
- `create_figjam_sticker(x, y, sticker_type, size)` - Stickers/emoji for reactions | |
**๐ฏ Available types:** | |
- **Formes:** rectangle, circle, triangle, diamond, star, hexagon | |
- **Stickers:** thumbs_up, thumbs_down, heart, star, fire, rocket, bulb, warning, check, cross, question, idea, clock, money, target, celebrate, thinking, confused | |
- **Templates:** retrospective, brainstorm, user_journey | |
**๐ก Recommended workflow:** | |
1. Create a background area with `create_figjam_background_shape()` | |
2. Add sticky notes with `create_figjam_sticky_note()` | |
3. Connect the elements with `create_figjam_connector_between_elements()` | |
4. Add stickers for reactions with `create_figjam_sticker()` | |
**โจ All functions generate JavaScript code ready to use in a Figma plugin!** | |
--- | |
## ๐ **Documentation Gradio MCP** | |
Selon la [documentation officielle](https://www.gradio.app/guides/building-mcp-server-with-gradio) : | |
- Gradio **automatically** detects all functions with docstrings and type hints | |
- Just set `mcp_server=True` in `.launch()` | |
- No need for manual exposure of tools | |
""") | |
return demo | |
# === LAUNCHING THE APPLICATION === | |
if __name__ == "__main__": | |
try: | |
demo = setup_demo() | |
logger.info( "๐ Starting MCP Figma server..." ) | |
# Configuration for Hugging Face Spaces with MCP | |
# Gradio will automatically detect all imported functions | |
demo.launch( | |
mcp_server= True , # ๐ Enables MCP server with auto-detection! | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False, | |
show_error=True | |
) | |
except Exception as e: | |
logger.error( f"โ Error launching: {e} " ) | |
raise | |