TL;DR
Deckmark is an open-source MCP server that lets an AI agent generate a slide deck, open it in your browser, collect annotations you click directly on slide elements, then read those annotations back and apply the changes. No screenshots, no copy-paste, no "the third bullet on slide 4." It is also my bet on a pattern I think matters way beyond slides: tight human-in-the-loop review for agentic work.
The Problem: Editing an AI Deck Is Still Awkward
AI is genuinely good at producing a first draft of a slide deck now. You describe the topic, the audience, the tone, and a minute later you have something to look at. That part feels like magic.
Then comes the not-magical part. You open the deck in the browser, the agent is sitting in a different window waiting, and you have to translate what you see into words the agent can act on. "The title on slide 3 is too big." "The two photos on slide 4 are overlapping." "The footer line on slide 5 should be quieter." Sometimes you take a screenshot and paste it in. Sometimes you describe the slide indirectly and hope the agent picks the right element.
This is the part that breaks the loop. You are doing all the work of seeing the slide and the agent is doing none of it. By the time you finish typing the third correction, you have basically given up on review and accepted whatever is there.
The friction
Generation got 100x faster. Review did not. The bottleneck moved, and we are pretending it did not.
The Insight: Click the Element, Don't Describe It
The shift is small. Instead of describing the slide back to the agent in text, you click directly on the thing that is wrong, and leave the comment where it actually belongs.
That sentence sounds obvious. It is not how most tools work today. Most "AI assistants for X" still assume the human writes a paragraph describing the problem in the chat. Deckmark moves the comment onto the element. The element knows its own slide index, its own CSS selector, its own bounding box, its own text content. That becomes structured feedback the agent can act on without guessing.
Once I built it that way, the loop went from "generate, describe back in text, hope" to "generate, click, click, click, Done." The agent reads each annotation, knows exactly which element it points to, and changes the right thing.
What Deckmark Actually Does
One install, one slash command, then a loop. Here is the actual flow.
1. You give your agent a brief
In Claude Code (or any MCP-aware agent), you type the command with whatever brief you have in your head. It does not need to be structured. The example below is a real one I used to build a small tribute deck for my cat.

2. The agent confirms three design axes
Before it spends time generating anything, the agent runs through a short interview. It needs to pin down three orthogonal axes from Deckmark's design system: mode (light or dark), style (professional, academic, fashion, technical, fun), and motion (slide transitions, fragment reveals, auto-animate, or none). It skips whatever you already implied in your brief.

3. The agent builds the deck and starts a local review server
Under the hood the agent is calling MCP tools: init_deck scaffolds a project, the agent writes content.md from the brief, then build_deck renders it through a reveal.js adapter into ./build/index.html. Then start_review launches a Fastify server bound to 127.0.0.1 and prints the URL.

4. You annotate directly in the browser
You open the URL. Press A to flip into annotation mode. Hover any slide element and you see a dashed outline. Click. A popover opens right under the element with a textarea. You type the change you want. Cmd or Ctrl plus Enter submits it. A small numbered pin lands on the element. Move on.

It also works across multiple elements in the same slide, and across slides. The pin numbers help when you want to leave a few related notes on the same screen.

5. The keyboard shortcuts are the whole UX
The overlay is intentionally tiny. Press A to toggle annotation mode. Press H to hide the overlay while still navigating slides. Shift plus D opens the Done dialog. Esc cancels the current popover. The arrow keys are passed through to reveal.js so the deck still feels like a normal deck.

6. Click Done. The agent applies everything.
You click ✓ Done in the toolbar (or hit Shift+D), optionally leave an overall summary, and go back to your agent window. The agent calls get_annotations, which reads the structured JSON the overlay wrote to ./annotations/session-<timestamp>.json, then walks the comments one by one, edits content.md, and rebuilds. Want another round? Repeat. Want to ship? Ask the agent to publish, and publish_deck emits either a single self-contained .html file or a published/ folder with cacheable assets.
Why This Pattern Matters Beyond Slides
I did not really build Deckmark because the world needs another slide tool. I built it because the human-in-the-loop part of agentic work is the part nobody has figured out yet, and slides happen to be a very honest place to figure it out.
Think about every domain where an AI agent produces something visual: dashboards, marketing pages, design mocks, documents, charts, video storyboards. The generate step is solved. The "is this what I actually want?" step is still done by squinting at the screen and typing a paragraph into a chat box. That is a terrible interface for review. It throws away most of the information the human is already carrying in their eyes.
The pattern Deckmark uses is small, and I think portable:
- Agent generates an artifact and opens it in a real viewing context, not just a preview pane in a terminal.
- Human reviews in context, with the artifact behaving the way it would behave in production.
- Human annotates precisely, attaching feedback to the actual element (or region, or token, or frame) instead of to a paragraph of prose.
- Agent reads structured feedback through a stable interface (MCP, in this case), applies it, and the loop repeats.
Slides today. Dashboards tomorrow. Probably code reviews too, eventually, in a form that does not look like GitHub.
What I Learned Building This
MCP is the right substrate for this kind of thing
I did not want Deckmark to be a "Claude Code feature." I wanted it to be a tool any agent can call. MCP made that almost free. The same seven tools (init_deck, build_deck, start_review, wait_for_close, get_annotations, stop_review, publish_deck) are callable from Claude Code, Gemini CLI, Codex, Copilot CLI, Cursor, anything that speaks MCP. The Claude Code packaging adds the nice slash command and the design-system skill on top, but the core is portable.
The lesson there is broader: when you are building agent tooling in 2026, picking an open protocol over a vendor SDK is the difference between "this works for one agent today" and "this will still be useful when the agent ecosystem looks different."
Local-first is not a slogan, it is a trust budget
The review server binds to 127.0.0.1 only. Annotations are plain JSON files in your project folder. There is no cloud, no account, no telemetry. I could have done none of that, and the tool would have shipped faster. But the moment you ask a user to put their unreleased deck in front of a third-party server, the install rate drops, and so does the willingness to use it for real work. Local-first buys trust cheaply.
There is one honest caveat I document in the README: the bundled themes load typefaces from Google Fonts. If you open the deck offline, system fonts kick in, but in the normal case Google sees the requesting IP. A future minor release will add a loadFonts: false build option to skip that entirely.
Stable CSS selectors are harder than they look
For annotations to survive a rebuild, the selector on each element needs to be stable across builds. Naive selectors break the moment you add a slide, reorder elements, or change the markdown. I ended up walking the rendered DOM and generating selectors that combine slide index plus a structural path plus a content hash, so the same element on the same logical slide gets the same selector even if the slide before it changed.
This is the kind of detail nobody asks you about, but if you get it wrong, the whole loop falls apart on the second rebuild.
Session storage has to be boring and atomic
Annotation writes are atomic (temp file plus rename) and serialized per deck. The reason is simple. The browser is writing while the user is clicking, and the agent might be reading at the same time. If those two race, you lose a comment, and now the user does not trust the tool. I burned a couple of evenings on this before I stopped trying to be clever and just did the boring, well-known thing.
The overlay does not know about reveal.js, on purpose
reveal.js is just the first engine adapter. The overlay walks the rendered DOM and does not import anything from reveal. That is what makes it possible to add Slidev or Impress or Marp adapters later without touching the overlay code. Engine-agnostic by construction, not by promise. If I had wired the overlay directly into reveal's slide API, I would have boxed myself in on day one.
Where Deckmark Fits in My Bigger Bet on Agentic Tools
Deckmark is one piece of a broader interest of mine: the next generation of engineering tools will not just generate code or content, they will support tight human feedback loops, structured review, and safe iteration. That is the part I keep coming back to.
For the last decade, "developer tools" mostly meant "things that help a human write code." The interesting tools of the next decade are going to be the ones that help a human direct an agent: tools for review, for approval, for rollback, for in-context annotation, for structured handoffs between agent and human, and back. Generation gets cheaper every quarter. Judgement does not. The tools that respect that asymmetry are the ones that will matter.
Building Deckmark was a way to think this through in code, not in a deck about decks. It made me much more concrete about how agent workflows, browser-based UX, and developer workflows can actually fit together. It also gave me a thing I use myself, which is the only honest test for whether a tool is good.
The bet
Build for the loop, not for the prompt. The agent is the easy part. The human in the loop is the design problem.
If you want to try it, the repo is here: github.com/sowenzhang/deckmark. Install snippet for Claude Code:
/plugin marketplace add sowenzhang/deckmark
/plugin install deckmark@deckmark-marketplace Restart the agent, then /deckmark:use-deckmark <topic> is yours. For Gemini CLI, Codex, Cursor, and other MCP-aware agents, the README has the JSON config snippet that points npx at the latest release tarball.
FAQ
What is Deckmark, in one sentence?
An open-source MCP server that lets an AI agent build a slide deck, collect element-level annotations you click in the browser, and apply them back to the source.
Does it work with Claude Code?
Yes. Install with /plugin marketplace add sowenzhang/deckmark and then /plugin install deckmark@deckmark-marketplace. Restart Claude Code, verify with /mcp, then run /deckmark:use-deckmark <topic>.
Does it work with Gemini CLI, Codex, Cursor, Copilot CLI?
Yes. Add the MCP server config from the README to your agent's MCP config file. The seven tools work in any MCP-aware agent. The Claude-specific slash command and skill do not, but you can just describe what you want in natural language and the agent will pick the right tool.
Where does my data go?
Nowhere. The review server binds to 127.0.0.1. Annotations are JSON files in your project folder. There is no telemetry. Fonts are loaded from Google Fonts by default, with system font fallbacks if you are offline. A loadFonts: false flag is on the roadmap.
What engine does it use to render slides?
reveal.js, vendored via npm so it works offline. The annotation overlay is engine-agnostic, so Slidev, Impress, or Marp adapters can be added without changing overlay code.
How do I publish the final deck?
Ask the agent to publish. publish_deck emits either a single self-contained .html (good for email or USB) or a published/ folder with index.html plus cacheable assets (good for GitHub Pages, Netlify, S3, etc.).
Is it free?
Yes. MIT licensed.