Skip to content
Conduit

mcp server

dali

salvadorsru/dalicommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 26, 2026

Dalí

Local search and indexing engine for Figma .fig files.

Dalí parses Figma .fig files on disk, builds a rebuildable local SQLite index (full-text, structural and vector), and exposes search through a CLI and an MCP server. Figma does not need to be open, and designs stay local.

The .fig file remains the source of truth. Everything Dalí generates is a rebuildable local index under .dali/.

Why Dalí

Unlike other .fig tools that dump a tree or relay the Figma REST API, Dalí is the only offline engine that combines full-text, structural and semantic search with analysis and code generation in a single binary.

DalíFigReader MCPfig-mcpfigmatojsonfigmingo MCPOpenPencil
Offline .fig parsing✅✅✅✅❌ (REST)✅
Persistent local index✅ SQLite❌❌❌✅❌
Full-text search✅ FTS5partial❌❌✅❌
Semantic/vector search✅ hybrid❌❌❌❌❌
Structural DSL + XPath✅❌❌❌❌find/tree
Lint, geometry, diff✅❌❌❌❌lint
Codegen + tokens✅❌renderJSON/repackHTML❌
MCP server✅ ~22 tools✅✅❌✅✅ 90 tools
CLI✅❌partial✅❌✅

Features

Search

  • Structural — query the document tree and node relationships (query_figma DSL, XPath subset via a leading /).
  • Full-text — SQLite FTS5 over node names and text content.
  • Semantic — conceptual vector search via sqlite-vec, with local embeddings (llama.cpp + EmbeddingGemma), Ollama, or a remote provider. Only missing or changed embeddings are rebuilt.
  • Name suggestions — near-miss hints when a search or filter matches nothing.

Index

  • Local .fig parsing — decode Figma's Kiwi binary format directly, no Figma running, so any design file is searchable offline.
  • SQLite index — persistent, rebuildable index stored under .dali/.
  • Asset extraction — images written next to the original .fig.

Analysis

  • Design linting — accessibility and design-quality checks with presets.
  • Geometry analysis — layout gaps, repeated sizes, sibling overlaps.
  • Version diff — match two .fig files by stable node ID and report added, removed, modified nodes.

Codegen

  • Component code generation — semantic HTML with inline CSS (or Tailwind) plus design tokens (CSS variables, Style Dictionary JSON, Figma Tokens JSON).

MCP

  • MCP server — expose one or many .fig files to MCP clients.

Architecture

            .fig
             │
         parser.Open            ── kiwi decode
             │
        model.Build             ── document tree
             │
      ┌──────┴───────┐
      ▼              ▼
   SQLite          Semantic
   index           indexing
   FTS5               │
   query/             ▼
             embeddings (sqlite-vec)
      │              │
      └──────┬───────┘
             ▼
      query.Service
        │        │
       CLI      MCP

The same query.Service powers the CLI and the MCP server.

Core pipeline: internal/kiwi/ → internal/parser/ → internal/model/ → internal/index/ → internal/query/, plus internal/embed/, internal/semantic/, internal/mcp/ and cmd/dali/.

Installation

Prebuilt binary

Requires only sh and curl. The latest release is downloaded, its checksum verified, and the binary installed into ~/.local/bin:

curl -fsSL https://raw.githubusercontent.com/salvadorsru/dali/master/install.sh | sh

Environment knobs: DALI_BIN overrides the install directory, DALI_VERSION pins a release tag, DALI_REPO targets a fork:

DALI_VERSION=v1.2.0 DALI_BIN=$HOME/bin sh install.sh

If the install directory is not on your PATH, add it:

export PATH="$HOME/.local/bin:$PATH"

Verify the install:

dali version

From source

Requires Go. Clone and build:

git clone https://github.com/salvadorsru/dali
cd dali
go build -o dali ./cmd/dali

or install straight from the module:

go install github.com/salvadorsru/dali/cmd/dali@latest

Updating

dali update

Resolves the latest release, verifies it against the published checksums and replaces the running binary in place; it reports when there is nothing to do. Re-running install.sh does the same thing from outside the tool.

Usage

The general form is:

dali [<file.fig>] <command> [args]

The file is optional: when omitted, Dalí uses the single .fig in the current directory (dali . does the same). The first command builds the .dali/<name>.db index on demand — a SQLite index that is rebuilt automatically whenever the source file changes. The .fig itself is never modified.

Orient yourself

dali design.fig inspect       # document counts
dali design.fig components    # list components
dali design.fig fonts         # fonts in use, ranked by count
dali design.fig variables     # design tokens (variables) per mode
dali design.fig styles        # style definitions: kind, value, usage
dali design.fig assets        # image assets

Explore the tree

dali design.fig path 123:456        # root-to-node path
dali design.fig context 123:456     # path, parent, children, styles, assets
dali design.fig children 123:456    # direct children
dali design.fig parent 123:456      # parent node
dali design.fig subtree 123:456     # whole subtree (--depth N to cap it)
dali design.fig node 123:456        # one node's geometry and styles
dali design.fig vector 123:456      # exact SVG of the vectors under it

Search

Full-text over node names and text content:

dali design.fig search "payment"
dali design.fig search "card" --limit 20

Structural queries, as a DSL or XPath subset:

dali design.fig query 'type=FRAME name~"card"'
dali design.fig query 'text~price AND width>=200'
dali design.fig query '//FRAME[@name~"card"]' --limit 10   # leading / = XPath subset

The DSL terms combine with AND: type=, name~, text~, font=, page~, component=, visible=, width>=, height<=, descendants(). A leading / routes to the XPath subset (//FRAME[@name~'card'], /DOCUMENT/CANVAS, //*[contains(@name,'button')]). When nothing matches, Dalí suggests near-miss names.

Semantic search for conceptual queries — it builds the vector index on first run and needs a download confirmed once (skip the prompt with --yes or DALI_EMBED_YES=1):

dali design.fig semantic-search "checkout flow"
dali design.fig semantic-search "checkout flow" --hybrid --limit 10

See Semantic search for how the local embedding server works.

Lint and geometry

dali design.fig lint --preset recommended   # recommended | strict | accessibility
dali design.fig analyze spacing             # spacing | clusters | overlaps
dali design.fig analyze overlaps --min-ratio 0.3
dali diff old.fig new.fig                   # added, removed, modified nodes

Code generation

dali design.fig generate                          # all components into ./generated
dali design.fig generate --id 1:123 --out ./components
dali design.fig generate --name "VideoCaption" --out ./components
dali design.fig generate --tokens css             # css | style-dict | figma
dali design.fig generate --style tailwind         # inline (default) | tailwind

Assets

dali design.fig assets           # list assets
dali design.fig extract-assets   # write them to design.assets/images/

Global flags

--json prints machine-readable output, --yes skips download prompts, and -q/--quiet hides progress. dali --help lists every command and flag.

MCP

Mount one or many .fig files and let MCP clients query them through Dalí's tools. Config helpers cover OpenCode, Cursor, Claude Code, VS Code, Cline, Roo Code, and Windsurf. Generate per-client configs with:

dali mcp-config --opencode        # also: cursor, claude, vscode, cline, roo, windsurf, all

--all writes configs for every supported editor; existing config files are merged, never clobbered.

Starting the server

The argument decides the mode:

dali /designs mcp                      # context: every design under the directory
dali /designs/woments/woments.fig mcp  # figma: one design, mounted at startup
  • Context mode (dali /designs mcp, or no argument for the current directory): every .fig and .deck below the directory is a project, named by its path relative to the directory without the extension (woments/woments). A directory that holds a single design still starts in context mode: it is a root with one project, not a mounted file.
  • Figma mode (dali /designs/woments/woments.fig mcp): the server serves exactly that design. list_figs and use_figma are not registered, tools never take file, and naming another design returns an error that explains the mode.

Catalog, selection, queries

  1. list_figs lists the projects under the root. It accepts an optional name filter and limit (default 50), and reports truncated when more projects matched. The catalog is scanned once per session; pass refresh to rescan the directory.
  2. use_figma selects one project by its name from list_figs and returns the confirmed name and absolute path. A partial name resolves when it fits a single design, and a directory holding one design answers to its own name.
  3. Every later tool call defaults to that project and omits file. Passing file switches to another project for that call. Every response reports the project that answered it, and a search that matches nothing adds a hint naming the other projects when the catalog holds more than one.

When a request could match more than one design, list the candidates and ask the user; never guess.

ClientConfiguration
OpenCodeopencode.json
Cursor.cursor/mcp.json
Claude Code.mcp.json
VS Code.vscode/mcp.json
Cline.cline/mcp.json
Roo Code.roo/mcp.json
Windsurf~/.codeium/windsurf/mcp_config.json

Tools

Tools exposed to MCP clients (list_figs and use_figma only in context mode):

analyze_figma    design-quality checks (spacing, clusters, overlaps)
find_assets      list image assets
find_components  list components
find_instances   list component instances
generate_figma   semantic HTML codegen (inline CSS or Tailwind) for components and tokens
get_assets       list image assets
get_context      structural context for a node
get_descendants  fetch a whole subtree in one call
get_dependents   impact analysis of component placement
get_styles       list style definitions
get_tokens       aggregate design tokens (incl. fonts, variables)
get_usages       list page placements of a component
get_vector       exact SVG of the vectors under a node, with local overrides
index_embeddings build the vector index (the only embedding builder)
list_figs        list projects under the designs directory (context mode)
list_pages       list document pages
lint_figma       design-quality and accessibility linting
query_figma      structural DSL query over the document tree (leading "/" = XPath)
search_figma     find nodes: mode = text | semantic | hybrid
section_figma    resolve a named section/component with its subtree
use_figma        select the project later calls default to (context mode)

Search contracts

  • search_figma is the only search entry point. Arguments: mode, query, type, page, limit (default 20), plus structural filters. Search never builds embeddings.
  • index_embeddings is the only tool that builds embeddings. Searches never do — call index_embeddings first when semantic/hybrid search fails with a hint.
  • query_figma operates structurally and never uses embeddings; a leading / routes to the XPath subset.
  • Instances are found via find_instances; assets via find_assets.
ToolEmbeddingsIndexes
search_figma (mode=text, query_figma, ...)nevernever
search_figma (mode=semantic/hybrid)only if vector index exists + DALI_EMBEDDINGS=1never
index_embeddingsyes — the only tool that doesyes

Semantic search

mode=auto manages an official llama.cpp llama-server bundling ggml-org/embeddinggemma-300M-GGUF, downloaded into ~/.cache/dali. The server stays alive so later commands reuse it.

Supported providers: auto, ollama, llama, remote. Set DALI_EMBED_PROVIDER=off to disable.

Configuration

VariablePurpose
DALI_EMBED_PROVIDERauto, ollama, llama, remote, or off
DALI_EMBEDDINGS=1opt-in: enable embeddings in the MCP server
DALI_CACHE_DIRDalí cache directory
DALI_LLAMA_URLreuse an existing llama-server
DALI_EMBED_URLOllama embedding endpoint
DALI_EMBED_YES=1skip download confirmation
DALI_LLAMA_KEEP=0stop the managed server after each command
DALI_LLAMA_PARALLELoverride llama-server parallelism
DALI_LLAMA_THREADSoverride llama-server threads
DALI_EMBED_CONCURRENCYembedding worker concurrency
DALI_EMBED_BATCHembedding batch size
DALI_NET_TEST=1enable live network tests
DALI_MANAGED_TEST=1enable managed-server tests

Embedding generation uses a worker pool and a single SQLite writer. If the model or semantic.GeneratorVersion changes, the vector index is rebuilt.

Files

Dalí never modifies the original .fig.

design.fig        original (untouched)
.dali/design.db   rebuildable SQLite index (deletable)
design.assets/
  images/         extracted user-facing assets

Deleting .dali/ removes generated index data only; the design stays intact.

Development

Requirements: Go.

go build -o dali ./cmd/dali
go test ./...
go vet ./...

Integration tests and the parser benchmark read ../dali.fig and are skipped automatically when absent.

Note: never downgrade modernc.org/sqlite — FTS5 is compiled into it. sqlite-vec is provided via modernc.org/sqlite/vec and registers itself through a blank import.

License

GNU General Public License v3.0
↑↓ navigate openesc close