Create a Presentation with Claude Code: Full Workflow
A practical Claude Code presentation workflow: connect Variant over MCP, draft a real deck, preview slides, make hand edits, and export the result.
Author: Variant Team. Variant is built by a small team working on HTML-native presentation tools, MCP workflows, and agent-editable decks.
The short version: connect Variant's MCP server to Claude Code, give it a real brief, let it build the first pass as HTML slides, then tighten the deck with previews, targeted edits, and a final human polish. When it feels ready, export it as one HTML file, a PDF, or a PPTX.
That middle part matters. Most AI slide workflows feel impressive for five minutes and then get weird when you need to change one label, nudge a chart, or rewrite a headline without regenerating half the deck. Claude Code is much more useful when the deck has readable source and a visual feedback loop.
This walkthrough uses a concrete migration-review deck so the workflow has teeth: setup, prompt, generated structure, preview loop, hand edits, and export. You can also open the finished example: download the Claude Code migration deck.
#Quick answer
- Connect Variant's MCP server to Claude Code.
- Give Claude Code a real deck brief: audience, goal, slide count, source material, and export format.
- Let the agent create the first draft, then use previews and targeted edits instead of regenerating the whole deck.
- Polish the parts that need taste on the canvas or in the code tab.
- Export to HTML, PDF, or PPTX depending on where the deck needs to go.
#What you need before you start
Three things:
- A working Claude Code install.
- A Variant account.
- The Variant MCP server connected to Claude Code.
Wiring up MCP is a one-time setup. Drop this into your Claude Code MCP config:
{
"mcpServers": {
"variant": {
"transport": "http",
"url": "https://app.variant.art/mcp",
"auth": {
"type": "oauth",
"authorization_server": "https://app.variant.art/oauth"
}
}
}
}
If you're on a machine where the OAuth dance is annoying (a remote box, a CI runner, a quick sandbox), use a scoped bearer token instead:
{
"mcpServers": {
"variant": {
"transport": "http",
"url": "https://app.variant.art/mcp",
"headers": {
"Authorization": "Bearer ss_..."
}
}
}
}
You can mint tokens from your Variant account settings, scope them to specific decks, and revoke them later. Treat them like API keys.
Once it's connected, type /mcp in Claude Code and you should see variant listed with its tools attached. If it's there, you're done with setup.

#A real brief, not a "hello world"
Generic prompts make generic decks. Let's use a brief that has actual constraints, the kind you'd get on a Tuesday afternoon.
I'm presenting to our exec team on Friday. Topic: a proposed migration from a self-hosted Postgres cluster to a managed provider. 10–12 slides. Cover: current pain points, options considered, recommendation, cost comparison, migration plan with a timeline, risk register, and an ask. Tone: confident but not hand-wavy. Audience knows infra, not Postgres internals. Include one chart slide and one table slide.
Notice the things in there: number of slides, audience knowledge level, tone, structure, and two specific slide types. The more of that you put in the prompt, the less cleanup you'll do later.
Open Claude Code in any directory (it doesn't have to be a project repo) and ask:
Create a Variant deck for me using the brief below. Use the variant MCP. Then show me the deck URL when you're done.
>
[paste brief]
Claude Code will think for a beat, plan the slides, then start calling MCP tools. You'll see something like this in the tool log:
variant.deck.create → new deck "Postgres Migration Proposal"
variant.deck.update → set theme + metadata
variant.slides.batchUpdate → write 11 slides with titles, body HTML, notes
variant.slide.preview → render thumbnail for slides 1, 5, 9
variant.deck.get → return the deck URL
That's roughly the sequence for a fresh deck. deck.create makes the container. slides.batchUpdate is the workhorse: Claude Code sends an array of slide HTML in one shot rather than poking each slide one at a time. slide.preview is how it sanity-checks layout without you having to open a browser, and it's the same call our editor uses for the filmstrip.
A first generation usually takes 30–90 seconds depending on slide count and how much research Claude Code decides to do. Don't be surprised if it pauses to look at something on the web for the cost comparison slide. That's fine; it's filling in numbers it doesn't know.
#Reviewing the first pass
Open the deck URL. You'll land on the canvas with all 11 slides in the filmstrip on the left.

What I look for, in this order:
- Slide order. Did the structure match what I asked for? In this case: pain points → options → recommendation → cost → plan → risks → ask. If it's wrong, fix it before touching anything else, because reordering after polish is annoying.
- Title slide and section breaks. These set the tone. If the title slide says "Postgres Migration Proposal" in 96px Inter and looks like a default, it works. If it tries too hard, I tell Claude to make it boring on purpose.
- Chart and table slides. These are the most likely to need real work. AI tends to make charts that *describe* a chart rather than render one. Variant decks are HTML, so charts can be real SVG or canvas, but the model will sometimes pick a CSS-only approximation. Worth checking.
- Speaker notes. Variant stores notes per slide; Claude Code populates them from the brief. They're often the most useful part of the first pass.
If something is structurally off, fix it with a follow-up message:
Move the risk register before the migration plan. Drop the "Why now?" slide. Tighten the cost slide so it fits one screen without scrolling.
Claude Code will use slide.move, then slide.replace or slide.edit for the trims. The deck updates live in the canvas while you watch, which is mildly entertaining the first time.
#Hand-editing the parts that matter
Here's the philosophy bit, and it's load-bearing for the rest of this post: don't regenerate a slide to fix a word. It's the AI equivalent of bulldozing your kitchen because the toaster is in the wrong spot.
Variant gives you three editing surfaces, and you pick whichever is fastest:
- Canvas. Click the title, retype it. Drag the chart to the right column. Resize the table. This is best for layout and copy nits.
- Code tab. Open the slide's HTML/CSS directly. Best for tweaks that are easier to type than to mouse: changing a color token, adjusting padding, swapping a class.
- Ask Claude Code. "On slide 6, change the y-axis label to 'Monthly cost (USD)' and round the bars to 4px." It'll call
slide.editwith a targeted patch. Good for things you'd rather describe than do.
The canvas and code tab stay in sync, so you can flip between them without losing work. If you nudge a box on the canvas, the CSS updates. If you change a class in code, the canvas reflects it.

A workflow I keep coming back to: generate the deck, fix structure with Claude, then go to the canvas for the last 20% of polish. The last 20% is where you really *want* hands on the wheel. Claude Code is great at "make me 11 slides about X." It's less great at "make this exact callout box feel slightly less corporate." That's a you job. Variant just gets out of your way so you can do it in 30 seconds instead of fighting a proprietary slide format.
#Iterating with Claude Code without losing your place
Two tools matter for iteration:
selection.getlets Claude Code see what you've selected on the canvas. So you can highlight a slide, switch to your terminal, and say "tighten this." It knows what "this" means.deck.versions.listanddeck.version.restoregive you a safety net. Variant snapshots versions on big edits. If Claude does something weird, you roll back.
In practice that means you can be aggressive with prompts. "Rewrite the recommendation slide as a single-sentence headline plus three bullets, drop the icons, use the brand orange for the headline." If you hate it, restore. If you like it, keep going.
One pattern I'd recommend stealing: at the end of a working session, ask Claude Code to do a final pass.
Read the whole deck. Check that titles are consistent in tone, that bullets aren't repeating, and that the cost numbers on slide 7 match the totals on slide 9. Fix anything that's off.
It'll call deck.listSlides, walk through, and patch the inconsistencies. This is the kind of cross-slide consistency check that's tedious to do by hand and that tools without a real underlying source format can't do at all.
#Exporting
When the deck looks right, ask Claude Code (or click the export menu) for the format you need.
variant.deck.export → format: "html" → returns a single self-contained HTML file
variant.deck.export → format: "pdf" → returns a PDF
variant.deck.export → format: "pptx" → returns a PowerPoint file
variant.deck.export → format: "json" → returns the raw deck for archival
The HTML export is my default. It's one file, no external dependencies, opens in any browser, and presents in fullscreen. Email it, drop it on a static host, send it to a coworker who's offline on a flight.
PPTX is there because some audiences need it. The fidelity is good for text, layout, and most charts. Heavy CSS effects (custom shaders, exotic gradients) won't survive the round-trip cleanly, but the kind of slide you'd actually present to an exec team will look right.
#Limitations worth knowing
A few things Variant won't do for you, at least not yet, and a few things to keep in mind.
- Animations beyond standard transitions. Variant decks support slide transitions and basic CSS animations. If you want a Keynote-style choreographed build with timed reveals, you can hand-write it in CSS, but there's no animation timeline UI yet.
- Live data. Slides are static HTML once exported. You can embed an iframe to a dashboard during the live preview, but exports freeze at the moment you click export.
- Long decks. The model handles 10–15 slides comfortably in one batch. For 40+ slide decks, it's better to generate sections in passes.
- Brand kits. Variant has theming, but there's no full enterprise brand kit yet. If you have strict brand rules, prime the prompt with your color tokens and font family up front.
These are real tradeoffs. Worth being upfront about them so you know when to pick a different tool.
#Try it on something real
If you've read this far, the fastest way to know whether this fits your workflow is to point Claude Code at a brief you actually have on your plate this week. Not a demo deck, a real one. Set up the MCP server, paste the brief, see how close the first pass gets. Twenty minutes is enough to know.
If you want to test the same loop in Variant, use a small real deck first and export the finished version as HTML. Add that exported example here before publishing so readers can see the result, not just the process.
#Related reading
- How to connect Claude Code to an MCP presentation editor
- Building agent-editable presentation decks with MCP
- How to export AI-generated slides as one HTML file
#FAQ
Does this work with Cursor, Codex, or other agents?
Yes. Variant's MCP server is a standard HTTP MCP endpoint, so any MCP-capable client can connect. The walkthrough uses Claude Code because that's where most people are landing right now, but the same tool sequence works from Cursor, Codex, or your own MCP client. The OAuth and bearer-token configs are identical.
Can Claude Code edit a deck I made by hand in Variant?
Yes. deck.get, slide.get, and slide.edit work the same on hand-built decks as on generated ones. There's no separate "AI deck" format; everything is just slides with HTML. Hand-build slide 1, ask Claude Code to draft slides 2–10 in the same style, hand-polish slide 11.
What stops Claude Code from blowing away my deck?
A few things. Edits are scoped: slide.edit patches one slide, not the whole deck. Versions snapshot automatically on bigger changes, so deck.version.restore is always there. And bearer tokens can be scoped to specific decks if you want to give an agent access to one deck and nothing else.
Is the HTML export really one file?
Yes. Images, fonts, and styles all get inlined. You get a single .html file you can email, host, or open offline. It's the export I use for almost everything that isn't being routed to a stakeholder who has asked specifically for PPTX.
How does Variant handle copy edits without regenerating the slide?
Each slide is HTML, and slide.edit accepts a targeted patch (a CSS selector and a new value, or a replacement chunk of HTML). Claude Code uses it whenever you ask for a small change. So "fix the typo on slide 4" doesn't re-roll the whole slide, it changes the eight characters that were wrong. This is the difference between editing a Google Doc and re-prompting an AI to "make a Google Doc but with the typo fixed."
Can I version control my decks?
The JSON export gives you the raw deck format, which is fine for archival but isn't the most diff-friendly thing. If you want decks-as-code, the HTML export per slide is the more useful artifact: each slide is a self-contained HTML chunk, and git diff does the right thing. Some teams keep their flagship decks in a repo and let Claude Code edit them via PRs. It works.