Skip to main content
Glama

slide-mcp

Create designed Figma Slides from a prompt — using your own LLM API key (BYOK).

Type "Make an 8-slide product intro" in the plugin, and a polished, multi-layout deck appears in your open Figma Slides file — 39 layouts, 17 design systems, charts, images, tables, and more. Everything runs inside the plugin: no server, no account, and your API key never leaves your machine.

Contents

Related MCP server: Figsor

How it works

The default mode is BYOK — a single Figma Slides plugin, no backend:

  1. You enter your API key and a topic in the plugin panel.

  2. The plugin calls your selected LLM (Anthropic, Google Gemini, or OpenAI) with your key, asking it to design the deck and return it as create_deck JSON (structure, layouts, colors).

  3. The plugin's layout engine builds the slides in Figma.

You can also paste a create_deck JSON directly to build an exact deck without calling any LLM (see Direct JSON), or drive it from an IDE assistant via the bundled MCP server (see IDE / MCP mode) — useful when you'd rather use a Copilot/Claude subscription than per-token API billing.

The API key is stored locally via Figma's clientStorage (this machine only) and is sent only to the provider you choose.

Install & build

The plugin loads from local files (manifest.jsoncode.js + ui.html), so build it once after cloning:

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.

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.

You only import once. After code changes you just re-run it (a manifest.json change needs a re-import — see Updating).

Use it (BYOK)

In the plugin panel:

  1. Provider — choose Anthropic (Claude), Google Gemini, or OpenAI (GPT).

  2. API key — paste your own key (stored on this machine only; remembered per provider). Get one:

  3. Model — pick or type a model id (suggestions per provider).

  4. (optional) Design system — pick one, or let the AI choose.

  5. Topic — describe the deck, then press 生成 / Generate.

Example topic:

自社プロダクトの紹介を8枚で。表紙、課題、解決策、主要機能3つ、実績の数値、料金、まとめ。

For very large decks (e.g. all 39 layouts) prefer a strong model — output can be long. See examples/ for ready-made prompts.

Direct JSON (no LLM)

Open "JSON直貼り" in the panel and paste a create_deck JSON ({ "slides": [ ... ] }) to build an exact deck with no API call — handy for reproducible decks or testing every layout. Example: examples/all-layouts.json renders all 39 layouts, one per slide.

IDE / MCP mode (optional — Copilot / use a subscription)

BYOK bills per token against your own API key. If you'd rather drive the plugin from an IDE assistant you already pay for (GitHub Copilot, or Claude Code/Desktop), use the bundled MCP server instead — the assistant calls the create_deck tool and the plugin builds the slides. The plugin itself never touches your subscription, so this stays within each tool's own terms.

Copilot / Claude ──stdio──▶ slide-mcp-server (MCP + WS bridge) ──WS──▶ this plugin
  1. Start the MCP server. The repo ships .vscode/mcp.json, which runs the published server via npx (npx -y slide-mcp-server@latest). In VS Code, start the slide-mcp server from the MCP list (Copilot Agent mode).

  2. In the plugin panel, open "IDE / MCP 連携" and press 接続. It connects to ws://localhost:3055 and flips to 接続済み.

  3. Ask the assistant: "slide-mcp で〜のデッキを作って".

Running in GitHub Codespaces (private tunnel, browser-only OK)

Figma runs on your local machine, so the plugin must reach the bridge inside the Codespace. Use GitHub's authenticated, private port forward — no public exposure:

  1. In the Codespace, the server binds 0.0.0.0 (set in .vscode/mcp.json via SLIDE_MCP_HOST=0.0.0.0). Start it from the Copilot MCP list.

  2. On your local machine, forward the port (works even if the Codespace is browser-only):

    gh codespace ports forward 3055:3055 -c <codespace-name>
    # optional one-word alias in ~/.zshrc:
    #   alias slidetunnel='gh codespace ports forward 3055:3055 -c <codespace-name>'

    The port stays Private (GitHub-authenticated) — it is not made public.

  3. The plugin's ws://localhost:3055 now tunnels to the Codespace. Press 接続.

Run the server in one place only. Don't also start a local slide-mcp-server while the tunnel is up — two servers fighting for port 3055 is the usual cause of "connected but nothing happens".

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 a deck doesn't specify a theme. Your choice is remembered across sessions.

  2. Per deck — set theme.preset (e.g. "theme": { "preset": "ocean" }).

  3. Per slide — set slide.theme.preset on a single slide (e.g. one dark section inside a light deck).

create_deck data format

This is the JSON the LLM produces — and what you can paste into JSON直貼り:

{
  "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/quote/code it's the message/code
      "bullets": ["string", "..."],
      "items": [                         // structured rows (charts, cards, steps, …)
        { "title": "", "value": "", "label": "", "desc": "", "bullets": ["..."], "image": "https://…" }
      ],
      "image": "https://…",              // for image-right/left, hero, gallery, team
      "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 side color panel

kicker, title, subtitle

cover-bold

full-bleed accent bg, centered title

kicker, title, subtitle

cover-minimal

editorial whitespace, left-aligned + rule

kicker, title, subtitle

cover-split

50/50 accent panel + title

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

quadrant

2×2 matrix of four cards

title, items[].title/desc (4)

statement

one big quote / takeaway

body, subtitle

quote

designed pull-quote + author

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

gauge

single circular % gauge + label

title, items[0].value/label/desc

bars

horizontal bar chart

title, items[].label/value

columns

vertical column 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

roadmap

horizontal phased roadmap

title, items[].title/desc (3–5)

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, columns, progress, donut, line, funnel, pyramid, gauge) read a number out of items[].value (e.g. "68%", "1,200").

  • Covers: cover (side panel), cover-bold (full accent, centered), cover-minimal (editorial), cover-split (50/50).

  • 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.

Troubleshooting

  • "APIエラー" / API error. Check the API key, the model id, and that the key has credit. The exact provider message is shown in the panel.

  • "呼び出しに失敗 (CORS / Failed to fetch)". A provider's API blocked the direct browser request. Anthropic supports direct calls; if Gemini or OpenAI is blocked in your environment, switch providers or open an issue.

  • "生成結果の解析に失敗". The model's output wasn't valid JSON — usually it was cut off because the deck was too long. Ask for fewer slides or use a stronger model (Opus / Sonnet / GPT‑4o / Gemini Pro).

  • Images show as gray boxes. The image URL was unreachable/blocked or timed out (~7 s).

  • 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.

Updating the plugin

  • 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? Re-import the plugin (Plugins → Development → Import plugin from manifest…). A re-run is not enough for manifest changes.

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 — BYOK panel + JSON-paste + IDE/MCP connect
tsconfig.json              Plugin TS config (target es2017 — required by Figma)
.vscode/mcp.json           VS Code MCP server config (for the IDE/MCP path)
server/                    MCP server + WebSocket bridge (optional — IDE/MCP mode)
  src/index.ts             MCP server (stdio) + WS bridge; generate.mjs CLI
examples/                  Ready-made prompts + create_deck JSON (incl. all-layouts.json)
assets/community/          Figma Community publishing assets

Notes & limitations

  • BYOK / privacy: your API key is stored locally (clientStorage) and sent only to the provider you pick. The plugin has no backend and collects nothing.

  • Network access: manifest.json allows * so the plugin can reach the three provider APIs and fetch user-supplied image URLs (any host).

  • Speaker notes: Figma's plugin API has no native speaker-notes field, so notes are stored on the slide via setSharedPluginData("slide_mcp", "notes").

  • TypeScript target: the plugin builds to es2017 — Figma's plugin runtime rejects newer syntax. Don't raise the target.

  • 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

After changing the plugin, re-run it from Figma's Plugins → Development menu.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Rikuto-des/slide-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server