Skip to main content
Glama

deck

PowerPoint for agents. Your agent writes the deck as plain markdown. You open it and draw on it while you record.

No account, no cloud, no binary format. The deck is a file on your disk that you can edit in any editor, and it stays yours.

The deck window: storyline list, the slide stage, the tool rail

npx @bassotov/deck ~/Notes/Decks

That is the whole install. It opens your browser on whatever markdown is in that folder, and writes nothing you did not ask for.

Keep it around with npm i -g @bassotov/deck, then just deck ~/Notes/Decks.

Working on it instead? Clone it, npm install, and npm run dev opens the two example decks in decks/.

What it does

Markdown in, slides out. One file is one deck, slides split by --- on its own line. No binary format, no editor lock-in.

A title slide

Layouts pick themselves. A heading on its own centres. A blockquote becomes a pull quote. Everything else gets the house shape: title on top, content below, air underneath.

The columns layout

Ask for columns, stats, flow, timeline, versus or image by name when you want them. They all read the same shape, so learning one teaches you the rest.

The timeline layout

Draw on the slide while you talk. Pen, highlighter, arrow, shapes, text, eraser. Vector rather than pixels, so a mark stays crisp at any window size and survives a resize.

An annotated stats slide

Tuned for a trackpad, not a stylus. Stroke width comes from velocity, jitter is smoothed hard, and Shift snaps to a straight line.

Paste a screenshot straight onto a slide. It floats over the slide instead of pushing the text around. Drag it, resize it, undo it.

Marks save themselves, per slide, and survive a reload. The example deck ships with a few on it, so you can see the ink layer before you draw anything.

Related MCP server: MakeSlates MCP Server

Why I built it

I record build-in-public videos every week, and every deck tool I tried was built for a room instead of a screen recording.

Keynote wanted me in Keynote. The web ones wanted an account and a subscription, and my slides ended up in someone else's database. Both of them made drawing on a slide a whole mode I had to remember how to enter.

What I actually wanted was to write the story as a text file, the same place I write everything else, and then have something to scribble on while I talked over it. So the markdown stays a plain file you can edit anywhere, and the drawing sits on top and never touches it.

The default slide is title on top, content below, air underneath. Short slides leave the bottom empty on purpose. That is the shape, not a bug to fix ;)

Write a storyline

decks/how-deck-works.md is the reference deck, and it documents the format by being written in it. Open the app and read it there.

The short version:

# Title slide

Everything before the first `---` is the title.

---

<span class="eyebrow">day 42</span>

## A normal slide

Headings, **bold**, `code`, lists, tables, quotes, images.

<!-- note: speaker note. renders under the stage, outside the recording crop. -->

---

<!-- layout: stats -->

## Numbers do the talking

### 7,000

The h3 is the figure

### **~25%**

Bold one to make it the point

Two accents, both optional: <span class="hand">handwritten</span> and <span class="eyebrow">mono label</span>.

Keys

1 cursor · 2 pen · 3 highlighter · 4 arrow · 5 shape · 6 text · 7 eraser

Press 5 again to cycle square → oval → triangle → line. Letters work too (V P H A S T E).

← → space scroll

Move through slides

Shift while drawing

Snap to a straight line

⇧1⇧4 · C

Pick a colour · cycle it

⌘A ⌘C ⌘V ⌘D

Select all, copy, paste, duplicate

⌘] ⌘[

Bring to front, send to back

⌘Z ⇧⌘Z · X

Undo, redo · clear the slide

⌘B · F · Esc

Sidebar · focus mode · back out one step

Arrows nudge whatever is selected and only move slides when nothing is. space, j and k always move, so advancing mid-recording never depends on remembering to hit Esc first.

Configuration

Both are optional, and both have a CLI flag that wins over them. An explicit deck ~/notes is never overridden by an env file left in the working directory. Set them in the shell, or in a .env.local (gitignored) next to where you run deck.

DECKS_DIR

Folder to read decks from. Default ./decks.

ASSET_ROOT

Widens image lookup by bare name to a whole notes folder, the way Obsidian resolves ![[shot.png]]. Must be a parent of DECKS_DIR. Default: DECKS_DIR itself.

DECKS_DIR=~/Notes/Decks npm run dev

Keeping decks outside the repo is the point if you already write in Obsidian, iCloud, or anything synced. The app only ever reads your .md files. Annotations go beside them in a .ink/ dot-folder, and pasted images in images/.

Export to PNG

Every image in this README came out of the deck itself:

npm i -D playwright && npx playwright install chromium
npm run export                          # every slide of every deck
npm run export -- how-deck-works        # one deck
npm run export -- how-deck-works 0,7    # particular slides, 0-indexed
npm run export -- how-deck-works --app  # the whole window, not just the stage

PNGs land in exports/ at 2×, annotations included. Playwright is not a dependency, because it pulls a browser down on install and you do not need one to run the app.

The CLI

deck [dir]                 serve the decks in dir           (default ./decks)
deck new <name> [dir]      start a new storyline and open it
deck export [args…]        render slides to PNG
deck mcp [dir]             run the MCP server on stdio

  -p, --port <n>           port to serve on                 (default 5290)
  -h, --host <host>        host to bind                     (default 127.0.0.1)
      --asset-root <dir>   widen image lookup to this folder
      --no-open            do not open a browser

It binds to localhost and serves off your own disk. Nothing is uploaded, and there is no account.

Let an agent write the deck

deck mcp is an MCP server, so Claude (or anything else speaking MCP) can build a deck for you, and you then open it, fix it, and draw on it. The output is a markdown file you own, not a blob inside someone's product.

Claude Desktop, one click

Grab deck-x.y.z.mcpb from Releases, then Settings → Extensions → Install Extension and pick it. It asks for the folder your decks live in and that is the whole setup. The bundle carries its own dependencies, so it does not care whether you have ever run npm.

Build one yourself with npm run bundle.

Claude Code

claude mcp add deck -- npx -y @bassotov/deck mcp ~/Notes/Decks

Anything else

{
  "mcpServers": {
    "deck": { "command": "npx", "args": ["-y", "@bassotov/deck", "mcp", "~/Notes/Decks"] }
  }
}

Both use npx, so nothing has to be installed first. If you already have it globally, "command": "deck" with ["mcp", "~/Notes/Decks"] works too.

Tool

What it does

deck_syntax

The whole format: layouts, the blocks each one expects, accents, notes, images

list_decks

Every deck, with titles, slide counts and slide headings

read_deck

One deck as raw markdown

write_deck

Write a deck. Refuses to clobber unless you pass overwrite

append_slide

Add one slide to the end, without rewriting the file

open_deck

Start the viewer and hand back the URL

export_deck

Render to PNG

deck_syntax exists because the layouts are not guessable. An agent that reads it first writes decks that use stats and timeline properly; one that does not writes eighteen identical bullet slides.

The write path is deliberately careful: write_deck will not overwrite an existing deck unless you say so explicitly, and nothing in the MCP surface deletes anything.

Where this is going

The CLI, the MCP server, the Claude Desktop extension and the npm package all landed. What is left:

  • Publish to npm. npx @bassotov/deck works.

  • A Windows/Linux pass on the shortcuts, which are written for a Mac keyboard today.

  • PDF export alongside PNG, if anyone wants it.

If you want one of these, open an issue and say so, it genuinely helps me pick.

Notes

  • macOS is what this is developed and recorded on. It should run anywhere Node does, but the shortcuts are written for a Mac keyboard.

  • Everything runs locally. The deck and annotation APIs read and write your own filesystem, and the server binds to 127.0.0.1 unless you tell it otherwise.

  • The app never writes to a .md you did not ask it to. Annotations and pasted-image placements live beside your decks in .ink/, so your markdown stays yours.

  • CLAUDE.md in the repo root is the working reference for the internals, including why a lot of the fiddly interaction decisions went the way they did. It is written for an agent but it reads fine as a design doc.

Privacy Policy

deck collects nothing. No telemetry, no analytics, no account, and no outbound network requests at all. The fonts are bundled rather than fetched, so it works with the wifi off. It reads and writes only the decks folder you point it at, the viewer binds to 127.0.0.1, and it never deletes a deck.

Full policy: PRIVACY.md.

Security

Report a vulnerability privately through the repository's Security tab, not a public issue. Policy and threat model: SECURITY.md.

Disclaimer

deck is a personal open-source project, not a commercial product. It is free, there is no company behind it, no subscription, and nothing is being sold. I built it for my own recordings and put it in the open because it might be useful to someone else.

Use it because you want to. Nobody is asking you to, and installing it is entirely your own choice.

It is provided as is, with no warranty of any kind, express or implied. I wrote it carefully and in good faith: it collects nothing, it sends nothing anywhere, and it never deletes a deck. That is what it is built to do and what I intend, but it is not a guarantee. Software has bugs, including this one.

To the fullest extent the law allows, I accept no liability for any loss, damage or claim arising out of using it, including lost or damaged work. Your decks are your own files on your own disk. Back them up the way you back up anything you would be sorry to lose.

If that is not a trade you want to make, do not install it. That is a completely reasonable choice.

License

MIT. See LICENSE.

The bundled typefaces (Instrument Serif, Inter, Caveat and JetBrains Mono) are SIL Open Font License 1.1 and are redistributed unmodified with their notices in THIRD-PARTY-LICENSES.md.

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

Maintenance

Maintainers
Response time
0dRelease cycle
5Releases (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.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP-native collaborative markdown editor with real-time AI document editing

  • Presentations.AI MCP server — create designed slide decks from a topic, text, or document.

  • OCR, transcription, file extraction, and image generation for AI agents via MCP.

View all MCP Connectors

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/bassotov/deck'

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