Legal noticePrivacy
Gaëtan Wittebolle.
UmamiContactFR
FR
← Guides
Claude Code, the guide
Chapter 15 / 22
  • 15Create visuals: artifacts, Design, Slides and images
  • 16Plugins and the marketplace
  • 17MCP: connect Claude to your tools
  • 18Let Claude work on its own: /goal, /loop, routines and workflows
  • 19Optimize costs and tokens: cache, model and tracking
  • 20Mods: change Claude Code itself
  • 21My complete setup

Part 6 · Going further

Create visuals: artifacts, Design, Slides and images

Chapter 15 · 15 min reading

A page, a mockup, a deck, a doc or an actual image: which tool to use for each one from Claude Code, all the way to plugging in your own image MCP server.

What Claude Code already does with nothing to install

Claude doesn't make pixel images (photos, painted illustrations). It writes code: HTML, CSS, SVG. For a diagram, a demo page, a dashboard, a deck or a one-pager, that code is enough. And since June 2026, Claude Code can publish it on claude.ai instead of leaving you a file in a folder.

Publishing a page as an artifact

Artifactpage published on claude.ai

A standalone web page (HTML, CSS, JavaScript, no backend) that Claude publishes from your session to a private claude.ai URL. It updates in place with every new publish, and you choose who sees it. For a comparison, a dashboard or a PR review, it's easier to read than a wall of text in the terminal, and you can send the link.

Available in Claude Code since June 2026, first on Team and Enterprise, now on Pro, Max, Team and Enterprise. You need a session signed in with your claude.ai account (/login): with an API key, or through Bedrock and Google Cloud, Claude writes a local HTML file instead.

How it works:

  1. You ask: "make me a page comparing our three plans and publish it as an artifact"
  2. Claude writes the HTML and publishes it. The page starts out private: only you can see it
  3. You ask for a change, Claude republishes to the same URL. Each publish becomes a version
  4. You find everything in the terminal with /artifacts (this session's first, then yours and the ones shared with you; o opens, c copies the link) or in the gallery at claude.ai/code/artifacts

To share, open the page in your browser and use the Share button. On Pro and Max, you switch from "Only you" to "Anyone with the link", or invite people by email (in beta). On Team and Enterprise, sharing stays inside the organization by default (the public link only exists if an Owner has allowed it), and you can make someone an editor. When the page is shared in your organization, Claude Code can read the comments and reply to them (v2.1.221 or later).

A page can also declare capabilities when it's published, meaning features a static HTML page doesn't have:

  • reading your connectors (Pro and up; each viewer connects their own)
  • storing data, per viewer or shared between viewers (Pro and up, 20 MB of text)
  • asking Claude a question from the page. Careful, that usage is billed to each viewer's plan, not yours

Before switching a page to "Anyone with the link", reread it. Claude puts in whatever you gave it, customer numbers and internal notes included. Once the link is out, you no longer control who reads it.

/design: Claude Design artboards from the terminal

For a website mockup, a prototype, slides or a one-pager that follow your design system, Anthropic has Claude Design. It came out of beta on October 8, 2026, on every plan including Free. The tool itself is covered in the ecosystem guide, chapter 5.

In Claude Code:

/design a landing page for a budget tracking app, understated tone, mobile first

/design [brief] draws artboards on a canvas and publishes it as a Claude Design artifact. You open it in a desktop browser, edit an element directly, and export each artboard as PNG or PDF. /design and /slides need Claude Code v2.1.265 or later, and the Claude Code docs still list these templates as a beta. /design-sync, which arrived with the June 2026 update, connects things to your design system. Run it in your repo and read what it proposes before you approve.

Design burns through usage fast. Since June 17, 2026, it shares your plan's limits with the rest of Claude. I redid my site in 2 hours in Claude Design: 51% of my Max plan went into it. Keep it for the mockups that matter, and read chapter 19 before a big session.

The standalone claude.ai/design site closes on December 14, 2026. If you have design systems there, migrate them before then ("Migrate team design systems" option): that site's chats, comments and public links disappear when it closes.

/slides: a deck

/slides 8 slides to present the quarterly review to my co-founder, based on NOTES.md

/slides [brief] creates a Claude Slides artifact. You edit the slides directly, present from Claude, then export to PPTX or PDF, or send it to Google Slides as an editable version.

Claude Docs, through the claude.ai connector

For a spec or a document that needs review, Claude Docs gives you rich text across several tabs, co-edited in real time. You comment section by section, and an @Claude in a comment gets it to make the change. Export to Word, PDF, Markdown or Google Docs.

In Claude Code, it goes through a connector provided by Anthropic: wherever Claude Docs is available, /mcp shows claude.ai Claude Docs with nothing to configure (chapter 17). You ask "write the spec for this feature in a Claude Doc", Claude creates the doc and sends you the link. A document that lives with the code (a README) stays a file in the repo.

Sharing: by link on Free, Pro and Max; inside the organization on Team and Enterprise. Charts pulled from connectors don't refresh on their own.

Going from Claude Design to Claude Code

The reverse path works too. In Claude Design, the share menu sends the project to a local coding agent (your Claude Code) or to Claude Code on the web, or exports it as a handoff bundle. Claude Code picks up the design and implements it in your repo, with your stack.

One limit: Claude Design doesn't output MP4. For a video, record your screen, or hand the project to Claude Code and render it with a tool like Hyperframes. Motion, Claude Design's animation template, exports to MP4, but it's in beta and limited to Team and Enterprise.

Which tool for which need

NeedTool
A demo page, a comparison, a dashboardArtifact published from Claude Code
A website or screen mockup/design
A deck/slides
A document to get reviewed and commented onClaude Docs
A photo, an illustration, a visual backgroundYour own image MCP server (below)

When to build your own image MCP server

Everything above produces code. As soon as you need pixels (a realistic photo, an illustration, a retouched real photo, a thumbnail background), Claude Code needs an external tool plugged in through an MCP (Model Context Protocol) server. If MCP doesn't ring a bell, chapter 17 covers the full setup.

Building your own makes sense when you generate images every week, want a look that matches your brand rather than stock photography, and want control over the parameters. For one image a month, an online generator is enough.

In what follows, we build an MCP server that connects Gemini Image to Claude Code, then skills that encode the right prompts, with a shared file to centralize the techniques.

There are several image generation MCP servers (OpenAI, Ideogram, Replicate, Leonardo). We'll go with Gemini through a homemade MCP server called Nano Banana, for three reasons: the API is free to start, the Flash Image model is good at photo editing, and coding your own MCP server gives you control over the parameters.

I could have made it an npm package. I chose to give you the skeleton instead: you install your own server on your machine and change it however you like, without depending on my repo.

The easiest way to get through the rest: skim it, send the whole thing to Claude Code so it explains how the MCP server is built, fills in the code and helps you wire in your Gemini API key properly.

Step 1, build the "Nano Banana" MCP server

An MCP server is a small program that exposes tools to Claude Code over the MCP protocol. We'll build one that connects the Gemini Image API.

Prerequisites

  • A Gemini API key (free on aistudio.google.com)
  • Node.js installed

Create the project

mkdir -p ~/.claude/mcp-servers/nano-banana/src
cd ~/.claude/mcp-servers/nano-banana

package.json

Create the package.json file:

{
  "name": "nano-banana-mcp",
  "version": "1.0.0",
  "description": "MCP server for Gemini image generation and editing",
  "type": "module",
  "bin": {
    "nano-banana": "./build/index.js"
  },
  "scripts": {
    "build": "tsc && chmod 755 build/index.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.12.0",
    "zod": "^3.25.0"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "typescript": "^5.7.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

src/index.ts, the skeleton

The server fits in a single file (~200 lines once complete). Here's the skeleton to copy into src/index.ts:

#!/usr/bin/env node

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import * as fs from "fs";
import * as path from "path";

const GEMINI_API_BASE =
  "https://generativelanguage.googleapis.com/v1beta/models";
const DEFAULT_MODEL = "gemini-3.1-flash-image-preview";

const VALID_ASPECT_RATIOS = [
  "1:1",
  "2:3",
  "3:2",
  "3:4",
  "4:3",
  "4:5",
  "5:4",
  "9:16",
  "16:9",
  "21:9",
] as const;

const VALID_SIZES = ["512", "1K", "2K"] as const;

function getApiKey(): string {
  const key = process.env.GEMINI_API_KEY;
  if (!key) {
    throw new Error(
      "GEMINI_API_KEY not set. Get a key at https://aistudio.google.com/",
    );
  }
  return key;
}

function resolveOutputPath(outputPath: string): string {
  if (path.isAbsolute(outputPath)) return outputPath;
  const cwd = process.env.NANO_BANANA_CWD || process.cwd();
  return path.resolve(cwd, outputPath);
}

const server = new McpServer({
  name: "nano-banana",
  version: "1.0.0",
});

// To complete: the callGemini, extractImageFromResponse and saveImage
// functions, and the two tools generate_image / edit_image.
// Ask Claude Code to write them from the tables in step 2.

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Nano Banana MCP server running on stdio");
}

main().catch((error) => {
  console.error("Fatal error:", error);
  process.exit(1);
});

Build and config

cd ~/.claude/mcp-servers/nano-banana
npm install
npm run build

Then register the server with Claude Code. --scope user makes it available in all your projects, -e passes the key as an environment variable:

claude mcp add nano-banana --scope user \
  -e GEMINI_API_KEY=your-gemini-api-key \
  -- node /Users/YOUR_USER/.claude/mcp-servers/nano-banana/build/index.js

Replace /Users/YOUR_USER/ with your home path and put in your real Gemini API key. With user scope, the config is stored in your personal folder, not in the repo: the key doesn't end up on GitHub.

Check with claude mcp list, then restart Claude Code. Test it:

> Generate an image of a sunset

If a PNG shows up, you're set.

Step 2, understand the two tools

generate_image

Creates an image from scratch based on text.

ParameterDescriptionDefault
promptDescription of the image to make(required)
aspect_ratio1:1, 4:5, 16:9, 9:16, etc.1:1
size512, 1K, 2K1K
output_pathOutput file pathgenerated-image.png

Use it for: illustrations, moods, landscapes, project visuals.

edit_image

Modifies an existing image with a text prompt. This is the one you'll use most: you take a real photo of yourself and change the setting.

ParameterDescription
image_pathPath of the source image to edit
promptDescription of the changes
aspect_ratioOutput ratio
size512, 1K, 2K

Step 3, write prompts that give a photo look

A "stock photo" result or a believable one: it depends on the prompt.

What a naive prompt gives you

"Photo of a Claude Code workshop with people and a whiteboard"

Result: forced smiles, perfect lighting, symmetry, zero grain. Unusable.

The fix: talk in camera specs

The model understands photography vocabulary. With camera specs, the result becomes believable:

Shot on Sony A7III with 35mm f/1.8 lens at ISO 1600.
Shallow depth of field, background slightly soft.
Natural window light from the left, soft shadows.
Visible film grain, slight chromatic aberration at frame edges.
Rule of thirds composition, not centered.

Presets by context

ContextLensISOLight
Indoor coworking35mm f/1.81600Window, soft shadows
Conference85mm f/2.83200Stage spots, contrasty
Outdoor daytime50mm f/2.0400Natural, golden hour
Travel/lifestyle24-50mm f/2.0400-800Golden hour, 4500K

The anti-AI block

Add this at the end of every photorealistic prompt:

This must look like real candid photography, not AI-generated.
Imperfections: slightly uneven lighting,
natural skin texture with visible pores,
clothes with real fabric folds and wrinkles,
no perfectly symmetrical composition.

Step 4, create the /photo-gaetan skill

This skill takes one of your real professional photos as a base and places it in a new setting with edit_image.

The workflow

  1. Pick a source photo whose light and angle are close to the final result
  2. Build a prompt in 4 blocks:
    • Block 1: Subject preservation ("Keep this exact person unchanged")
    • Block 2: Scene with imperfections (mismatched chairs, someone on their phone...)
    • Block 3: Camera specs (lens, ISO, grain)
    • Block 4: Anti-AI (imperfections, asymmetry)
  3. Call edit_image with the right parameters
  4. Review and iterate if needed

Key rule: match the light and angle

The bigger the gap between the source photo and the requested scene, the more the model alters the face. For the best result:

  • Outdoor golden hour scene: outdoor source photo in warm light
  • Indoor office scene: source photo with window light
  • Conference scene: source photo with contrasty lighting

Full prompt example

Keep this exact person unchanged: face, glasses, hair,
facial hair, clothing, skin tone.
Do not alter any facial features.

Place him in a real workshop setting. He is standing,
turned slightly toward a whiteboard behind him, one hand
raised. The whiteboard is slightly out of focus.

The room is a real French coworking space: mismatched chairs,
a long wooden table with 4-5 attendees, some with stickers
on their laptop lids, one person has a coffee cup, another
is taking notes on paper. Not everyone is paying attention.
Diverse mixed-gender audience.

Shot on Sony A7III with 35mm f/1.8 lens, shallow depth of
field, natural window light from the left, visible grain
at ISO 1600. Rule of thirds, not centered.

Text in the image: never ask for readable text (on a whiteboard, a screen...). The model generates gibberish. Keep the visual (AI) and the text (HTML or overlay) separate.

Step 5, create the /image skill

This skill generates visuals with no identifiable person: article illustrations, SaaS project visuals, carousel backgrounds, thumbnail backgrounds.

Available templates

TemplateUseRatio
--template articleArticle/blog illustration16:9
--template projectConcept visual for a SaaS16:9
--template carousel-coverSlide 1 background4:5
--template thumbnail-bgYouTube thumbnail background16:9

Calibrating realism for project visuals

The visual should be appealing without looking like stock photography. Aim for a photo a happy customer might have taken.

Add light imperfections: uneven ivy, mismatched chairs, unmowed grass. Without going as far as run-down.

Step 6, centralize the techniques

Create an image-techniques.md file that both skills read:

brand/prompts/image-techniques.md

Contains:
→ Brand palette (prompt suffix)
→ Photo presets by context
→ Anti-AI block
→ Templates by visual type
→ Constraints (no text, diversity)

When the model changes, you update one file instead of editing every skill.

The 3 rules after 30 tests

  1. Keep visual and text separate. The AI generates the image, HTML displays the text on top. The model can't write French without gibberish.
  2. Talk in camera specs. Lens, ISO, grain, depth of field. The model understands that vocabulary.
  3. Start from a real photo for portraits. From scratch never looks enough like you. edit_image with a source photo whose light matches the final result gives the best output.

Limits to know

  • The model can't generate public figures (Gemini blocks it)
  • Never mention facial or body hair in a prompt: the model adds more instead of removing it
  • Face likeness is never perfect. The closer the source light is to the result, the better
  • No reproducibility: same prompt, different result. Save the good ones

Question

You want a realistic photo of yourself on stage for a meetup poster. What do you use from Claude Code?

Pick an answer to see the explanation.

Key takeaways

  • For a page, a deck, a mockup or a doc, start with what's built in: artifacts, /slides, /design, Claude Docs. Nothing to install.
  • An artifact starts private and updates at the same URL. /artifacts lists them all.
  • Claude Design draws from the same limits as everything else, and fast. Its standalone site closes on December 14, 2026.
  • For pixels, plug in your own MCP server with claude mcp add, then encode your prompts in skills and a shared image-techniques.md file.
  • Always keep AI visuals and HTML text separate: the model writes gibberish.

Sources

  • Share session output as artifacts (Claude Code docs)
  • Claude Docs (help center)
  • Claude Slides (help center)
  • Claude Design (help center)
  • Dashboards and Motion, October 8, 2026 announcement
← Chapter 14

The services to put your app online

Chapter 16 →

Plugins and the marketplace