slide-mcp

slide-mcp

Create designed Figma Slides by chatting with GitHub Copilot or Claude. It generates polished, multi-layout decks with 31 layouts and 17 design systems directly in Figma.

Category
Visit Server

README

slide-mcp

Create designed Figma Slides by chatting with GitHub Copilot (or Claude).

You type "Make a 6-slide deck about our Q3 roadmap" in Copilot Chat, and a polished, multi-layout deck appears in your open Figma Slides file — 31 layouts, 17 design systems, charts, images, and more.

Contents

How it works

A Figma plugin runs sandboxed inside Figma and can't be called directly by an external MCP client. So this project has three parts:

┌──────────────────────┐  MCP (stdio)  ┌─────────────────────────┐   WebSocket   ┌──────────────────────┐
│ VS Code + Copilot    │ ────────────▶ │ MCP server + WS bridge  │ ◀───────────▶ │ Figma Slides plugin  │
│ (MCP client)         │               │ server/ (localhost:3055)│  ws://local…  │ ui.html + code.js    │
└──────────────────────┘               └─────────────────────────┘               └──────────────────────┘
   "make a deck…"      →  Copilot calls create_deck  →  bridge relays  →  plugin runs the Figma Slides API
  • server/ — one Node process that is both an MCP server (talks to Copilot over stdio) and a WebSocket server on localhost:3055 (the plugin connects to it).
  • code.ts → code.js / ui.html — the Figma plugin. The ui.html iframe holds the WebSocket connection and relays commands to the code.js main thread, which builds the slides.

By default everything runs on your machine — nothing is exposed to the internet.

Prerequisites

  • Node.js 18+ and npm
  • Figma desktop app (the plugin runs in the desktop app, on a Slides file)
  • VS Code with the GitHub Copilot extension (Chat / Agent mode)
  • (optional, for Codespaces) the gh CLI, logged in (gh auth login)

Install & build

The MCP server runs via npx — nothing to install or build. The plugin, though, must be built from source, because Figma loads it from local files (manifest.json → code.js + ui.html):

git clone https://github.com/Rikuto-des/slide-mcp.git
cd slide-mcp
npm install && npm run build      # builds the plugin → code.js

code.js and node_modules/ are git-ignored, so you build after cloning. Prefer running the server from source too? npm run setup builds both (see the "Run from source" note in step 2).

Setup step 1 — load the plugin in Figma

  1. Open the Figma desktop app and open (or create) a Figma Slides file.
  2. Menu → Plugins → Development → Import plugin from manifest…
  3. Select manifest.json from this repo.
  4. Run it: Plugins → Development → slide-mcp. A panel opens (it will say Disconnected until the server is running — that's expected).

You only import once. After code changes you just re-run it (see Updating).

Setup step 2 — connect from your IDE (VS Code + Copilot)

The repo ships .vscode/mcp.json. By default it runs the published server via npx — nothing to install:

{ "servers": { "slide-mcp": {
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "slide-mcp-server@latest"],
  "env": { "SLIDE_MCP_PORT": "3055" }
} } }
  1. Open this folder in VS Code.
  2. Open Copilot Chat and switch to Agent mode.
  3. Start the slide-mcp MCP server (VS Code prompts to start it, or use the MCP servers list / the "Start" code-lens above the server in .vscode/mcp.json). The first run downloads the package via npx (cached afterwards).
  4. Back in Figma, the plugin panel flips to Connected (it auto-reconnects every 2 seconds).

Use it in any project, not just this repo: drop the same slide-mcp block into that project's .vscode/mcp.json (or your user-level MCP config). npx fetches the server anywhere — only the plugin lives in this repo.

Run from source instead? Build the server once (npm run server:build) and point mcp.json at the local build:

{ "servers": { "slide-mcp": {
  "type": "stdio",
  "command": "node",
  "args": ["${workspaceFolder}/server/dist/index.js"],
  "env": { "SLIDE_MCP_PORT": "3055" }
} } }

Prefer the terminal? Run npx -y slide-mcp-server (or npm run server:start from source).

Setup step 3 — generate your first deck

In Copilot Chat (Agent mode), just ask — for example:

Use slide-mcp to make a 6-slide deck introducing our product. Cover, an agenda, two content slides with bullets, one stats slide, and a closing. Use the indigo design system.

Copilot calls the create_deck tool and the slides appear in Figma. Or run the bundled prompt: type /slide-design in Copilot Chat and give it a topic.

Choosing a design system

You can set the look in three places (most specific wins):

  1. In the plugin panel — the panel lists all 17 systems with color swatches. Click one; it becomes the default whenever the IDE doesn't specify a theme. Your choice is remembered across sessions.
  2. Per deck (from the IDE) — pass theme.preset in create_deck (e.g. "theme": { "preset": "ocean" }). This overrides the panel default.
  3. Per slide — set slide.theme.preset on a single slide (e.g. one dark section inside a light deck).

create_deck reference

create_deck is the main tool. Other tools: create_slides (append N blank slides), get_status (connection + slide count), get_presets (list systems).

{
  "replace": true,                       // optional: delete existing slides first
  "theme": {                             // optional; omit to use the panel default
    "preset": "light",                   // one of the 17 systems (see below)
    "accent": "#2563eb",                 // optional per-field color overrides:
    "background": "#ffffff",
    "titleColor": "#0f172a",
    "bodyColor": "#334155",
    "secondaryColor": "#64748b",
    "surfaceColor": "#f1f5f9",
    "font": "Inter",                     // preferred font family (best-effort)
    "pageNumbers": true                  // footer page numbers (default true)
  },
  "slides": [
    {
      "layout": "content",               // optional; auto-detected if omitted
      "kicker": "string",                // small eyebrow label above the title
      "title": "string",
      "subtitle": "string",
      "body": "string",                  // paragraph; for statement/callout it's the message
      "bullets": ["string", "..."],
      "items": [                         // structured rows (charts, cards, steps, …)
        { "title": "", "value": "", "label": "", "desc": "", "bullets": ["..."], "image": "https://…" }
      ],
      "image": "https://…",              // for image-right/left, hero
      "table": { "headers": ["A","B"], "rows": [["1","2"],["3","4"]] },
      "notes": "string",                 // speaker notes (stored as plugin data)
      "background": "#0B1021",           // per-slide background (hex or a name)
      "theme": { "preset": "dark" }      // per-slide design-system override
    }
  ]
}

Layout reference

Omit layout to auto-detect: a title-only slide becomes cover (first slide) or section; anything with body/bullets/items becomes content.

layout shows main fields
cover title slide with a color panel kicker, title, subtitle
section divider with a big ghost number kicker, title, subtitle
closing closing / thank-you slide kicker, title, subtitle
content title + numbered bullets kicker, title, subtitle, body, bullets[]
two-col bullets in two columns kicker, title, bullets[]
checklist ✓ checklist kicker, title, bullets[]
agenda numbered table of contents title, bullets[]
split term / definition rows title, items[].title + items[].desc
statement one big quote / takeaway body, subtitle
callout highlighted message box body, subtitle
stats 2–4 big numbers title, items[].value/label/desc
big-number one huge KPI kicker, items[0].value/label/desc
bars horizontal bar chart title, items[].label/value
progress percent progress bars title, items[].label/value (0–100)
donut donut / pie chart + legend title, items[].label/value
line line chart title, items[].label/value
funnel funnel title, items[].label/value
pyramid hierarchy pyramid title, items[].label (+value)
steps numbered process row title, items[].title/desc
timeline vertical timeline title, items[].title/desc
compare two cards side by side title, items[0..1].title + bullets[]
cards 2–4 feature cards title, items[].title/desc
table data table (zebra rows) title, table.headers[], table.rows[][]
split-mix text left + image/chart right title, bullets/body + image OR items[]
team profile cards with avatars title, items[].image/title/desc
testimonial quote + avatar + name/role body, image, subtitle, items[0].desc
image-right text left, image right kicker, title, bullets[], image
image-left image left, text right kicker, title, body, image
hero full-bleed image + overlaid title kicker, title, subtitle, image
gallery grid of images with captions title, items[].image/title
code code on a dark panel (monospace) title, body (the code; newlines kept)

Notes:

  • Charts (bars, progress, donut, line, funnel, pyramid) read a number out of items[].value (e.g. "68%", "1,200").
  • Images accept any https PNG / JPEG / GIF URL (max 4096 px). A bad/slow URL falls back to a plain placeholder after ~7 s.

Design systems (theme.preset)

17 systems, each a 6-color palette (some with a preferred font):

  • Light: light (default), sky, ocean, emerald, forest, warm, sunset, rose, plum, indigo, mono, paper (serif)
  • Dark: dark, midnight, graphite, carbon, royal

See Choosing a design system for how to select one. get_presets returns the list at runtime.

Skills (Copilot & Claude)

  • GitHub Copilot
    • .github/copilot-instructions.md — always-on guidance so Copilot knows how to use create_deck and design well.
    • .github/prompts/slide-design.prompt.md — a reusable prompt: type /slide-design in Copilot Chat and give it a topic.
  • Claude / Claude Code
    • .claude/skills/slide-design/SKILL.md — invoke /slide-design to design and generate a varied deck.

Generate without Copilot (CLI)

server/generate.mjs drives the plugin directly over the WebSocket — handy for scripting or testing without an MCP client.

# 1) make sure the plugin is running in Figma (panel shows Connected / Connecting)
# 2) stop the MCP server so the port is free
pkill -f 'slide-mcp/server/dist/index.js'
# 3) write your deck (the create_deck params) to a file and run:
node server/generate.mjs deck.json
# 4) restart the server for Copilot use
npm run server:start

deck.json is exactly the create_deck params ({ replace?, theme?, slides: [...] }). Env: SLIDE_MCP_PORT (default 3055), SLIDE_MCP_HOST, SLIDE_MCP_TIMEOUT (ms), SLIDE_MCP_WANT_V (require a specific plugin hello version).

Run from GitHub Codespaces (private, gh-authenticated)

Figma always runs on your local machine, so the local plugin must reach the bridge in the Codespace — over GitHub's authenticated tunnel to your local localhost. No public port is needed; the port stays Private.

  1. In the Codespace, run the MCP server bound to all interfaces so the tunnel can reach it:

    SLIDE_MCP_HOST=0.0.0.0 npx -y slide-mcp-server
    

    (or add "env": { "SLIDE_MCP_HOST": "0.0.0.0", "SLIDE_MCP_PORT": "3055" } to the Codespace's .vscode/mcp.json so Copilot launches the npx server that way.)

  2. Forward port 3055 to your machine over the gh-authenticated tunnel — keep visibility Private:

    • VS Code Desktop attached to the Codespace (Remote Explorer → open the Codespace): port 3055 auto-forwards to localhost:3055 (Ports panel; stays Private). Nothing else to do.
    • Or from a local terminal: gh codespace ports forward 3055:3055 --codespace <name>
  3. Leave the Figma plugin on its default ws://localhost:3055. It now tunnels to the Codespace, authenticated by your GitHub login.

The tunnel is private to your GitHub account — you never make the port Public.

Troubleshooting

  • Plugin panel says "Disconnected". The bridge isn't running. Start the slide-mcp MCP server in VS Code, or run npm run server:start. The panel retries every 2 s; you can also click 接続 / Reconnect.
  • Copilot says create_deck isn't available. The MCP server isn't started or Chat isn't in Agent mode. Start the server from the MCP list and retry.
  • I changed the code but nothing changed. Re-run the plugin from Plugins → Development → slide-mcp (the panel's Reconnect button does not reload code — it only reopens the socket). See Updating.
  • Images show as gray boxes. The image URL was unreachable/blocked or timed out, or manifest.json's networkAccess change wasn't picked up — re-import the plugin (manifest changes need a re-import, not just a re-run).
  • Japanese text looks wrong / boxes. Install/keep Noto Sans JP in Figma (the plugin auto-prefers it for CJK and falls back to Inter). Override with theme.font.
  • Port already in use. Another bridge is running on 3055. Stop it (pkill -f 'slide-mcp/server/dist/index.js') or change SLIDE_MCP_PORT.

Updating the plugin / server

  • Changed code.ts or ui.html? npm run build, then re-run the plugin in Figma (Plugins → Development → slide-mcp). Re-running reloads code.js + ui.html from disk.
  • Changed manifest.json (e.g. networkAccess)? Re-import the plugin (Plugins → Development → Import plugin from manifest…). A re-run is not enough for manifest changes.
  • Changed the server (server/src)? npm run server:build, then restart the slide-mcp server from the VS Code MCP list (or your terminal).
  • "Reconnect" vs "Re-run": Reconnect only reopens the WebSocket. To load new code you must re-run (or re-import) the plugin.

Configuration

Env var Default Used by Purpose
SLIDE_MCP_PORT 3055 server, CLI WebSocket / bridge port
SLIDE_MCP_HOST 127.0.0.1 server, CLI Bind host (0.0.0.0 for Codespaces)
SLIDE_MCP_TIMEOUT 60000 CLI Wait (ms) for the plugin before giving up
SLIDE_MCP_WANT_V — CLI Require a specific plugin hello version

If you change the port, update SLIDE_MCP_PORT in .vscode/mcp.json and the URL in the plugin panel (and, if you publish the plugin, manifest.json's networkAccess). networkAccess currently allows ws://localhost:3055 plus * (so user-supplied image URLs and gh-tunneled hosts work).

Project structure

manifest.json              Figma plugin manifest (entry: code.js, ui: ui.html)
code.ts                    Plugin main thread — layout engine (build code.js)
ui.html                    Plugin UI — WebSocket client + design-system picker
tsconfig.json              Plugin TS config (target es2017 — required by Figma)
.vscode/mcp.json           VS Code MCP server config
.github/                   Copilot instructions + /slide-design prompt
.claude/skills/            Claude /slide-design skill
server/
  src/index.ts             MCP server (stdio) + WebSocket bridge
  generate.mjs             Direct-generation CLI (no Copilot)
  tsconfig.json            Server TS config (NodeNext, ESM)

Notes & limitations

  • Speaker notes: Figma's plugin API has no native speaker-notes field, so notes are stored on the slide via setSharedPluginData("slide_mcp", "notes"). The text is preserved on the node but does not appear in Figma's Notes panel.
  • TypeScript target: the plugin builds to es2017 — Figma's plugin runtime rejects newer syntax (optional catch binding, ??). Don't raise the target.
  • Why localhost by default: Figma is a desktop app and the plugin can only make outbound connections, so the bridge runs on your machine (or is tunneled in, privately, for Codespaces).
  • Disclaimer: an unofficial, community project — not affiliated with, sponsored by, or endorsed by Figma or Anthropic. "Figma" is a trademark of Figma, Inc., used here only descriptively to say what this tool works with.

Develop

npm run watch                  # rebuild code.ts → code.js on save (plugin)
npm --prefix server run dev    # rebuild the server on save

After changing the server, restart it from the VS Code MCP list. After changing the plugin, re-run it from Figma's Plugins → Development menu.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured