Content
# 🧩 FigLocal MCP
🔍 **Local-first MCP and C# toolkit for Figma `.fig` files.**
FigLocal MCP opens exported `.fig` files directly on your machine, decodes the embedded Kiwi scene graph, builds a fast node tree, and exposes it through a compact local MCP server. It also includes a C# library, CLI, and simple debug web viewer.
> ⚠️ `.fig` is not an official public Figma format. This project is best-effort reverse engineering for local, read-only inspection.
## ✨ Features
- 📦 Reads `.fig` ZIP containers: `canvas.fig`, `meta.json`, `thumbnail.png`, `images/*`
- 🥝 Decodes embedded Kiwi schema and data chunks
- 🌳 Builds a scene tree from `nodeChanges`
- ⚡ Stores nodes in an `id -> node` index for O(1) lookup
- 🧰 Provides a CLI for quick inspection
- 🖥️ Provides a simple jsTree debug web viewer
- 🤖 Provides a compact MCP server for agent workflows
- 🔒 Read-only by design: no writes, no mutation, no Figma API auth
## 🧱 Repository Layout
```text
src/Figma.Fig Core read-only parser library
src/Figma.Fig.Cli CLI inspector
src/Figma.Fig.Web Simple debug web viewer
src/Figma.Fig.Mcp Stdio MCP server
```
## 📋 Requirements
- .NET SDK 8+
- Linux/macOS/Windows with `dotnet` on `PATH`
- `libz` available at runtime for raw deflate chunks
On this Linux workspace, `libz` is already available as `libz.so`.
## 📥 Install Dependencies
Restore NuGet packages:
```bash
dotnet restore
```
Build everything:
```bash
dotnet build
```
Main NuGet dependencies used by projects:
- `ZstdSharp.Port` for Zstandard chunk decoding
- `ModelContextProtocol` for MCP stdio server
- `Microsoft.Extensions.Hosting` for MCP host setup
## 🚀 Quick Start
### C# Library
```csharp
using Figma.Fig;
var fig = await FigFileReader.ReadAsync("/path/to/design.fig");
Console.WriteLine(fig.Metadata.FileName);
Console.WriteLine(fig.Canvas.Version);
Console.WriteLine(fig.Document.Nodes.Count);
var node = fig.Document.GetNode("3:5123");
Console.WriteLine($"{node?.Type} {node?.Name}");
```
### CLI
Inspect file summary:
```bash
dotnet run --project src/Figma.Fig.Cli -- inspect /path/to/design.fig
```
Print tree:
```bash
dotnet run --project src/Figma.Fig.Cli -- tree /path/to/design.fig --max-depth 3 --max-children 20
```
### Web Debug Viewer
```bash
dotnet run --project src/Figma.Fig.Web
```
Open the printed local URL. The viewer is intentionally plain:
- upload `.fig`
- browse tree with jsTree
- search visible loaded tree
- click a node to inspect JSON
## 🤖 MCP Server
Run the stdio MCP server:
```bash
dotnet run --project src/Figma.Fig.Mcp
```
### MCP Config
Example `.mcp.json`:
```json
{
"mcpServers": {
"figlocal": {
"command": "dotnet",
"args": [
"run",
"--project",
"/home/user/Projects/figma/src/Figma.Fig.Mcp"
]
}
}
}
```
Local MCP config files are intentionally ignored. Add the config above to your own MCP client settings.
### MCP Workflow
1. Start your MCP-capable client.
2. Load a file:
```text
load(path: "/absolute/path/to/file.fig")
```
3. Inspect structure:
```text
types(doc: "example")
tree(doc: "example", depth: 3, children: 50)
search(doc: "example", q: "Login", limit: 20)
node(doc: "example", id: "3:5123")
```
### MCP Tools
| Tool | Purpose |
| --- | --- |
| `load(path)` | Load local `.fig` file |
| `docs()` | List loaded docs |
| `tree(doc, depth, children)` | Return compact tree |
| `node(doc, id, raw, includeChildren)` | Return node by id in O(1) |
| `search(doc, q, type, limit)` | Search nodes by name/type |
| `types(doc)` | Count node types |
### Compact JSON Format
MCP responses use short keys to reduce tokens:
```json
{
"id": "3:5123",
"t": "FRAME",
"n": "Login Version 1",
"c": 3,
"ch": []
}
```
Key map:
- `id`: document or node id
- `t`: node type
- `n`: node name
- `c`: child count
- `ch`: children
- `v`: visible
- `p`: parent id
- `raw`: decoded Kiwi fields, only when requested
## 🧠 Data Model
Loaded documents are stored as:
```text
LoadedDoc
Roots: tree root nodes
Nodes: Dictionary<string, FigmaNode>
```
That means `node(doc, "session:local")` is an O(1) dictionary lookup.
## 🔒 Read-Only Contract
This project does **not**:
- write `.fig` files
- mutate nodes
- call Figma APIs
- require Figma tokens
- sync with live Figma documents
## 🧪 Build Check
```bash
dotnet build
```
No test project is currently included.
## 📝 Notes
Kiwi schemas are embedded in `.fig` files, so the parser decodes dynamic raw objects first and builds a small typed model on top. Unknown Figma fields remain available through raw node data.