---
title: "Hugo MCP Server : connecter Claude.ai à un site Hugo statique"
description: "Tutoriel complet pour installer un serveur MCP sur Hugo dans une VM KVM et connecter Claude.ai pour créer et modifier des pages statiques depuis une conversation."
url: "https://www.arleo.eu/posts/hugo-mcp-server/"
language: "fr"
datePublished: "2026-05-03T19:00:00+02:00"
dateModified: "2026-05-15T23:51:25+02:00"
tags: ["mcp","claude","homelab","infrastructure","nginx"]
categories: ["infrastructure"]
contentSignal: "ai-train=no, search=yes, ai-input=yes"
---

# Hugo MCP Server : connecter Claude.ai à un site Hugo statique
Tutoriel complet pour installer un serveur MCP sur Hugo dans une VM KVM et connecter Claude.ai pour créer et modifier des pages statiques depuis une conversation.



## ⚡ En bref

Connecter Claude.ai à un site **Hugo** hébergé dans une VM KVM en 30 minutes : un serveur FastAPI expose 6 outils MCP (lire, créer, modifier, supprimer des pages, rebuilder le site) via JSON-RPC 2.0, un proxy OAuth réutilise l'infrastructure existante, et chaque modification déclenche automatiquement un rebuild Hugo + une purge du cache Cloudflare.

Le code est disponible sur GitHub :

- 🔌 Serveur MCP Hugo : [jmrGrav/hugo-mcp](https://github.com/jmrGrav/hugo-mcp)
- 🔐 Proxy OAuth : [jmrGrav/mcp-oauth-proxy](https://github.com/jmrGrav/mcp-oauth-proxy)

## 🧠 Pourquoi

Le protocole [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) d'Anthropic permet à Claude.ai de se connecter à des sources de données externes via des outils standardisés. Contrairement à Grav CMS qui est dynamique (PHP), Hugo génère du HTML statique — ce qui rend la gestion de contenu via MCP encore plus puissante : chaque modification est compilée et déployée instantanément.

Ce stack maison permet de :

- **Créer et modifier des pages Hugo** directement depuis Claude.ai sans toucher aux fichiers manuellement
- **Rebuilder le site automatiquement** après chaque modification via `hugo --minify`
- **Purger le cache Cloudflare** de façon ciblée après chaque changement
- **Gérer le contenu bilingue** (FR + EN) en une seule conversation

## 🔧 Ce qui a été fait

### 🏗️ Architecture globale

```
        Claude.ai
            │
            │ HTTPS (OAuth 2.1 + PKCE)
            ▼
    ┌───────────────┐
    │  Cloudflare   │  WAF + Cache
    └───────┬───────┘
            │
            ▼
    ┌───────────────┐
    │     nginx     │  SSL termination
    │mcp-hugo.arleo │  location /mcp → proxy
    └───────┬───────┘
            │
            ▼
    ┌───────────────┐
    │ FastAPI proxy │  Port 8084 (host NUC)
    │  OAuth 2.1    │  Token validation
    │  mcp-proxy    │  SHA-256 hashing
    └───────┬───────┘
            │
            ▼
    ┌───────────────┐
    │  hugo-mcp     │  Port 8000 (VM KVM)
    │  FastAPI      │  6 outils MCP
    │  Python 3.12  │  192.168.122.69
    └───────┬───────┘
            │
    ┌───────┴────────┐
    ▼                ▼
~/hugo-site/    deploy.sh → /var/www/hugo
content/*.md    + purge Cloudflare
```

### 📦 Composants

| Composant | Technologie | Rôle |
|---|---|---|
| `hugo-mcp` | FastAPI + Python 3.12 | Expose les 6 outils MCP via JSON-RPC 2.0 |
| `mcp-oauth-proxy` | FastAPI + Python | Gère OAuth 2.1, PKCE S256, tokens |
| nginx vhost | nginx | Reverse proxy SSL, location `/mcp` |
| deploy.sh | bash | Hugo rebuild + rsync vers /var/www/hugo |
| systemd units | systemd | Services hardenés VM + host |

### 🔌 Étape 1 — Installer hugo-mcp dans la VM

```bash
# Cloner le repo dans la VM
git clone https://github.com/jmrGrav/hugo-mcp.git ~/hugo-mcp
cd ~/hugo-mcp

# Créer l'environnement virtuel Python
sudo apt install -y python3.12-venv
python3 -m venv venv
venv/bin/pip install -r requirements.txt

# Générer le token MCP
MCP_TOKEN=$(openssl rand -hex 32)

# Configurer les secrets
cat > .env << EOF
MCP_TOKEN=$MCP_TOKEN
CF_TOKEN=<votre_token_cloudflare>
CF_ZONE_ID=<votre_zone_id>
EOF

# Installer le service systemd
sudo cp systemd/hugo-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now hugo-mcp

# Vérifier
curl -s http://localhost:8000/health
```

### 🔐 Étape 2 — Configurer le proxy OAuth sur le host

Le proxy OAuth réutilise [mcp-oauth-proxy](https://github.com/jmrGrav/mcp-oauth-proxy) déjà installé pour Grav, comme une 2e instance indépendante sur le port 8084 :

```bash
# Créer les secrets pour Hugo MCP
sudo mkdir -p /etc/hugo-mcp
sudo tee /etc/hugo-mcp/secrets.env << EOF
HUGO_MCP_URL=http://192.168.122.69:8000
HUGO_MCP_TOKEN=$MCP_TOKEN
MCP_CLIENT_ID=hugo-mcp
MCP_CLIENT_SECRET=$(openssl rand -hex 32)
TOKEN_SECRET=$(openssl rand -hex 32)
PROXY_PORT=8084
PROXY_BASE_URL=https://mcp-hugo.votre-domaine.com
EOF
sudo chmod 600 /etc/hugo-mcp/secrets.env

# Ouvrir le port 8000 dans le firewall VM
# uniquement depuis le host NUC
sudo ufw allow from 192.168.122.1 to any port 8000 proto tcp

# Installer et démarrer le service proxy
sudo systemctl enable --now hugo-mcp-proxy
```

### 🌐 Étape 3 — Configurer nginx

```nginx
server {
    listen 443 ssl http2;
    server_name mcp-hugo.votre-domaine.com;

    include snippets/ssl.conf;

    location /mcp {
        proxy_pass http://127.0.0.1:8084/mcp;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /.well-known/oauth-authorization-server {
        proxy_pass http://127.0.0.1:8084/.well-known/oauth-authorization-server;
        proxy_set_header Host $host;
    }

    location /oauth/ {
        proxy_pass http://127.0.0.1:8084/oauth/;
        proxy_set_header Host $host;
    }
}
```

### 🤝 Étape 4 — Connecter Claude.ai

1. Aller sur [claude.ai](https://claude.ai) → **Settings** → **Connectors**
2. Cliquer **Add connector**
3. Entrer l'URL : `https://mcp-hugo.votre-domaine.com/mcp`
4. Suivre le flux OAuth — autoriser l'accès
5. Les 6 outils apparaissent dans la liste des connecteurs ✅

### 🛠️ Les 6 outils disponibles

| Outil | Description |
|---|---|
| `list_pages` | Lister toutes les pages avec filtres par langue et section |
| `get_page` | Lire le frontmatter et le contenu Markdown d'une page |
| `create_page` | Créer une page + rebuild Hugo + purge CF ciblée |
| `update_page` | Modifier une page + rebuild Hugo + purge CF ciblée |
| `delete_page` | Supprimer une page + rebuild Hugo + purge CF totale |
| `build_site` | Rebuild complet Hugo + déploiement + purge CF totale |

### 🔒 Sécurité

- **OAuth 2.1 + PKCE S256** — flux d'authentification sécurisé conforme RFC 9728
- **SHA-256 token hashing** — les tokens ne sont jamais stockés en clair
- **UFW** — port 8000 de la VM ouvert uniquement depuis le host NUC (192.168.122.1)
- **Systemd hardening** — `NoNewPrivileges`, service isolé dans la VM
- **Purge CF ciblée** — seules les URLs modifiées sont purgées

### 🔄 Flux de modification d'une page

```
Claude.ai → create_page / update_page
                │
                ▼
        hugo-mcp écrit le .md
                │
                ▼
        deploy.sh : hugo --minify
                │
                ▼
        rsync public/ → /var/www/hugo/
                │
                ▼
        Cloudflare API : purge_cache (ciblée)
                │
                ▼
        Page visible en ~2 secondes
```

## 🏁 Conclusion

Ce stack transforme Hugo en source de contexte active pour Claude.ai — créer, modifier, gérer le site statique par simple conversation, avec rebuild et purge cache automatiques. L'ensemble réutilise l'infrastructure OAuth déjà en place et est entièrement disponible sur GitHub sous licence MIT.

**Pour aller plus loin :**

- 💡 Ajouter un outil `list_assets` pour gérer les images et fichiers statiques
- 💡 Implémenter un webhook Git pour rebuilder automatiquement après un push
- 💡 Migrer le contenu de Grav vers Hugo en automatisant la conversion des frontmatter



## Tags

- mcp
- claude
- homelab
- infrastructure
- nginx

## Categories

- infrastructure
