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 :
- Construire un serveur MCP qui connecte Gemini Image à Claude Code
- Créer des skills qui encodent les bons prompts
- 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ètre | Description | Défaut |
|---|---|---|
prompt | Description de l'image à générer | (requis) |
aspect_ratio | 1:1, 4:5, 16:9, 9:16, etc. | 1:1 |
size | 512, 1K, 2K | 1K |
output_path | Chemin de sortie du fichier | generated-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ètre | Description |
|---|---|
image_path | Chemin de l'image source à modifier |
prompt | Description des modifications |
aspect_ratio | Ratio de sortie |
size | 512, 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
| Contexte | Objectif | ISO | Lumière |
|---|---|---|---|
| Intérieur coworking | 35mm f/1.8 | 1600 | Fenêtre, ombres douces |
| Conférence | 85mm f/2.8 | 3200 | Spots scène, contrasté |
| Extérieur jour | 50mm f/2.0 | 400 | Naturelle, golden hour |
| Voyage/lifestyle | 24-50mm f/2.0 | 400-800 | Golden 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
- Choisir une photo source dont la lumière et l'angle sont proches du résultat final
- 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)
- Bloc 1 : Préservation du sujet (
- Appeler edit_image avec les bons paramètres
- 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
| Template | Usage | Ratio |
|---|---|---|
--template article | Illustration d'article/blog | 16:9 |
--template project | Visuel conceptuel pour un SaaS | 16:9 |
--template carousel-cover | Background de slide 1 | 4:5 |
--template thumbnail-bg | Fond de thumbnail YouTube | 16: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
- 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.
- 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.
- 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