Gaëtan Wittebolle.EN
guides / claude-code / ch. 15
Chapitre 15 · Bonus, configuration d'un power user

🎨 Générer des images depuis Claude Code

15 min de lecture

🎯

Ce chapitre est pour toi si tu veux générer des images directement depuis Claude Code, sans quitter ton terminal. Niveau requis : avoir Claude Code installé et savoir créer un fichier.

Le problème

Claude Code ne sait pas générer d'images. Il faut lui brancher un outil externe via un serveur MCP (Model Context Protocol).

Les générateurs d'images IA produisent du stock photo par défaut. Pour obtenir des résultats qui ressemblent à ta marque, il faut des prompts précis et des workflows reproductibles.

Dans ce chapitre, on va :

  1. Construire un serveur MCP qui connecte Gemini Image à Claude Code
  2. Créer des skills qui encodent les bons prompts
  3. Centraliser les techniques dans un fichier partagé

J'aurais pu en faire un package npm. J'ai préféré te donner le code source directement : tu installes ton propre serveur MCP chez toi, tu le modifies comme tu veux, zéro dépendance à mon repo.

La façon la plus simple de prendre en main ce chapitre : lire en diagonal, envoyer le tout à Claude Code pour qu'il t'explique de façon pédagogique comment est construit le MCP et qu'il t'aide à mettre ta clé API Gemini de façon sécurisée.

Étape 1, construire le serveur MCP "Nano Banana"

Un serveur MCP est un petit programme qui expose des outils à Claude Code via le protocole MCP. On va en créer un qui connecte l'API Gemini Image.

Pré-requis

  • Une clé API Gemini (gratuite sur aistudio.google.com)
  • Node.js installé

Créer le projet

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

package.json

Crée le fichier package.json :

{
  "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, le code complet

C'est tout le serveur MCP en un seul fichier (~200 lignes). Copie-le dans 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",
});

// Le code complet (avec les fonctions callGemini, extractImageFromResponse,
// saveImage, et les deux outils generate_image / edit_image) est dans
// le repo public, le voir au lien en bas de chapitre.

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 et config

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

Puis ajoute le serveur dans ta config MCP Claude Code (~/.claude/mcp_servers.json) :

{
  "nano-banana": {
    "command": "node",
    "args": ["/Users/TON_USER/.claude/mcp-servers/nano-banana/build/index.js"],
    "env": {
      "GEMINI_API_KEY": "ta-cle-api-gemini"
    }
  }
}
⚠️

Remplace /Users/TON_USER/ par ton chemin home. Et mets ta vraie clé API Gemini.

Redémarre Claude Code. Teste :

> Génère une image d'un coucher de soleil

Si un PNG apparaît, c'est bon.

Étape 2, comprendre les deux outils

generate_image

Crée une image from scratch à partir d'un texte.

ParamètreDescriptionDéfaut
promptDescription de l'image à générer(requis)
aspect_ratio1:1, 4:5, 16:9, 9:16, etc.1:1
size512, 1K, 2K1K
output_pathChemin de sortie du fichiergenerated-image.png

Utiliser pour : illustrations, ambiances, paysages, visuels de projets.

edit_image

Modifie une image existante avec un prompt texte. C'est l'outil le plus puissant : tu peux prendre une vraie photo de toi et changer le décor.

ParamètreDescription
image_pathChemin de l'image source à modifier
promptDescription des modifications
aspect_ratioRatio de sortie
size512, 1K, 2K

Étape 3, le secret des prompts qui marchent

Le prompt fait toute la différence entre un rendu "stock photo" et un rendu crédible.

Le piège : le prompt naïf

"Photo d'un atelier Claude Code avec des gens et un tableau"

Résultat : sourires forcés, éclairage parfait, symétrie, zéro grain. Inutilisable.

La solution : parler en specs photo

Le modèle comprend le vocabulaire photographique. Lui donner des specs d'appareil change radicalement le résultat :

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 par contexte

ContexteObjectifISOLumière
Intérieur coworking35mm f/1.81600Fenêtre, ombres douces
Conférence85mm f/2.83200Spots scène, contrasté
Extérieur jour50mm f/2.0400Naturelle, golden hour
Voyage/lifestyle24-50mm f/2.0400-800Golden hour, 4500K

Le bloc anti-IA

Ajouter à la fin de tout prompt photoréaliste :

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.

Étape 4, créer le skill /photo-gaetan

Ce skill prend une de tes vraies photos pro comme base et la place dans un nouveau décor via edit_image.

Le workflow

  1. Choisir une photo source dont la lumière et l'angle sont proches du résultat final
  2. Construire un prompt en 4 blocs :
    • Bloc 1 : Préservation du sujet ("Keep this exact person unchanged")
    • Bloc 2 : Scène avec imperfections (chaises dépareillées, quelqu'un sur son tel...)
    • Bloc 3 : Specs photo (objectif, ISO, grain)
    • Bloc 4 : Anti-IA (imperfections, asymétrie)
  3. Appeler edit_image avec les bons paramètres
  4. Review et itérer si nécessaire

Règle importante : proximité lumière/angle

Plus l'écart entre la photo source et la scène demandée est grand, plus le modèle altère le visage. Pour un meilleur résultat :

  • Scène extérieure golden hour : photo source outdoor en lumière chaude
  • Scène intérieure bureau : photo source avec lumière fenêtre
  • Scène conférence : photo source avec éclairage contrasté

Exemple de prompt complet

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.
⚠️

Texte dans l'image : ne jamais demander du texte lisible (sur un tableau, un écran...). Le modèle génère du charabia. Séparer le visuel (IA) et le texte (HTML ou overlay).

Étape 5, créer le skill /image

Ce skill génère des visuels sans personne identifiable : illustrations d'articles, visuels de projets SaaS, backgrounds de carousel, fonds de thumbnails.

Templates disponibles

TemplateUsageRatio
--template articleIllustration d'article/blog16:9
--template projectVisuel conceptuel pour un SaaS16:9
--template carousel-coverBackground de slide 14:5
--template thumbnail-bgFond de thumbnail YouTube16:9

Calibrage réalisme pour les visuels projet

Le visuel doit donner envie sans tomber dans le stock photo. Penser "photo prise par un client content", pas "shooting du service com".

Ajouter des imperfections légères : lierre irrégulier, chaises dépareillées, herbe pas taillée. Sans aller jusqu'au délabré.

Étape 6, centraliser les techniques

Créer un fichier image-techniques.md lu par les deux skills :

brand/prompts/image-techniques.md

Contient :
→ Palette brand (suffixe de prompt)
→ Presets photo par contexte
→ Bloc anti-IA
→ Templates par type de visuel
→ Contraintes (pas de texte, diversité)

Quand le modèle change, un seul fichier à mettre à jour au lieu de modifier chaque skill.

Les 3 règles après 30 tests

  1. Séparer visuel et texte. L'IA génère l'image, le HTML affiche le texte par-dessus. Le modèle ne sait pas écrire en français.
  2. Parler en specs photo. Objectif, ISO, grain, profondeur de champ. Le modèle comprend ce vocabulaire et le résultat change du tout au tout.
  3. Partir d'une vraie photo pour les portraits. Le from scratch ne ressemble jamais assez. edit_image avec une photo source dont la lumière matche le résultat final donne les meilleurs résultats.
⚠️

Limites à connaître - Le modèle ne peut pas générer de personnalités publiques (Gemini bloque) - Ne jamais mentionner la pilosité dans un prompt (le modèle en rajoute au lieu d'en réduire) - La ressemblance du visage n'est jamais parfaite. Plus la lumière source est proche du résultat, mieux c'est - Pas de reproductibilité : même prompt = résultat différent. Sauvegarder les bons résultats

✅

Résumé du chapitre 1. Crée le serveur MCP : 3 fichiers (package.json, tsconfig.json, index.ts), npm install && npm run build, ajoute la config MCP 2. Crée /photo-gaetan : un skill qui prend tes vraies photos comme base et construit des prompts en 4 blocs 3. Crée /image : un skill avec des templates pour chaque type de visuel 4. Centralise dans image-techniques.md : un fichier partagé avec tous les presets et contraintes 5. Toujours séparer visuel IA et texte HTML : le modèle ne sait pas écrire

← Chapitre 14

🏗️ Monter l'infrastructure

Chapitre 16 →

🧠 Ma configuration complète

📖 Retour au sommaire