TL;DR
Publier sur blog.vfg.lol ne passe jamais par un git push seul : il faut écrire un .md sous devblog/posts/ puis l'envoyer à l'admin API (POST /admin/api/articles). Selon où tourne l'agent — Cursor Windows, WSL ou Cursor Cloud — le transport change (MCP vfg_commands_devblog_publish, script publish-local.mjs, ou UI admin locale), mais le contrat reste le même. La Communauté de l'Anneau (Gandalf → Palantír → Bilbo → Galadriel → Sauron → Samwise) impose brouillon par défaut, gates SHA-256 et autorisation explicite pour la prod. Ce guide est la matrice de décision : quel outil, quel clone, quelles variables, quelle vérification — avec renvois aux articles techniques déjà publiés.
1. Le principe unique derrière tous les chemins
| Couche | Rôle | Fichier / service |
|---|---|---|
| Corpus | Articles markdown + frontmatter | devblog/posts/<catégorie>/ |
| Écriture | Seul l'admin API écrit sur disque | admin/server.mjs → scripts/lib/publish-article.mjs |
| Lecture | Catalogue dynamique, pas articles.json figé | src/server.js (:5195 local, Caddy en prod) |
| Garde-fou temps | Refus des dates futures, heure Europe/Paris | scripts/lib/publish-time.mjs |
Trois transports mènent au même endpoint :
- Admin API directe —
curl, UI/admin/, ouscripts/publish-local.mjs - MCP —
vfg_commands_devblog_publish(serveurvfg-commands-vps, client dans VFVFGPT) - Agent Samwise — choisit MCP ou Admin API, jamais les deux
Ce qui n'est pas un chemin de publication éditoriale : vfg_hotfix_deploy, SCP/rsync de articles.json, ou édition manuelle de index.html.
2. Matrice environnement → outils disponibles
| Environnement | Clone typique | Serveurs locaux | MCP publish | Fallback prod | Piège fréquent |
|---|---|---|---|---|---|
| Cursor Windows (natif) | RAPPORT-EXPERIENTIEL sur disque Windows | npm run dev (:5195) + node --env-file=.env admin/server.mjs (:5220) | Oui si MCP_COMMANDS_AUTH_TOKEN + vfg-commands-vps vert | VFG_ADMIN_BACKEND_URL=https://blog.vfg.lol + VFG_ADMIN_PASSWORD | Lancer l'admin depuis un mauvais clone → POSTS_DIR incorrect |
| WSL (Ubuntu) | Chemin local du clone (ex. ~/RAPPORT-EXPERIENTIEL) | Même ports ; npm run dev après source ~/.config/vfg/blog-agents.env | Oui — tokens via ~/.config/vfg/blog-agents.env | Idem Windows | Oublier source ~/.config/vfg/blog-agents.env dans le shell de l'agent |
| Cursor Cloud Agent | Clone éphémère GitHub (AGENTS.md) | Pas de :5220 local par défaut ; pas de MCP vfg-commands-vps dans le pod | Non | Uniquement Admin API prod + VFG_ADMIN_PASSWORD injecté dans l'environnement Cloud | Confondre git push (versionnement) et publication admin API |
| VFVFGPT / hub (:4320) | Référence VFG_RAPPORT_ROOT | Hub optionnel | Oui — outil natif devblog.js | Passe par le même client mcp-auto-publish.mjs | .env VFVFGPT ≠ .env VPS → 401 |
Variables d'environnement par silo
| Variable | Où la définir | Usage |
|---|---|---|
MCP_COMMANDS_AUTH_TOKEN | Windows user env / WSL blog-agents.env | Bearer MCP vfg-commands-vps (Samwise) |
VFG_ADMIN_PASSWORD | Hors repo, env Cloud ou .env local | Auth Basic admin prod |
VFG_ADMIN_BACKEND_URL | Optionnel ; défaut local http://127.0.0.1:5220 | Cible de publish-local.mjs |
ADMIN_PASSWORD | .env du serveur admin | Auth du process admin/server.mjs |
Ne jamais committer ces valeurs. Référence setup : docs/SETUP-CURSOR-WSL-BLOG-AGENTS.md.
3. La Communauté de l'Anneau — workflow agent
Le role-play structure les permissions, pas la magie :
demande utilisateur
→ Gandalf (cadre l'intention, draft ou prod)
→ Palantír (faits datés, doublons via MCP read-only)
→ Bilbo (Markdown status:draft)
→ parent matérialise le fichier
→ Galadriel (APPROVE_DRAFT)
→ Sauron (PASS sur SHA-256 exact)
→ Samwise (prepublish + dry-run + un seul transport)
→ vérification URL publique
| Personnage | Agent Cursor | Peut publier ? |
|---|---|---|
| Gandalf | gandalf-blog-orchestrator | Non |
| Palantír | palantir-blog-scout | Non (MCP lecture) |
| Bilbo | bilbo-blog-bard | Non (retourne le texte au parent) |
| Galadriel | galadriel-blog-editor | Non |
| Sauron | sauron-blog-red-team | Non |
| Samwise | samwise-blog-publisher | Oui — seul effet externe |
Règles prod (blog.vfg.lol) :
- Autorisation explicite dans le tour courant (nommer la prod).
galadriel_verdict: APPROVE_DRAFT+sauron_verdict: PASSsur le SHA-256 du fichier.npm run prepublishpuisnode scripts/publish-local.mjs <fichier> --dry-run.- Un seul transport : MCP ou Admin API.
Manifeste machine : config/blog-roleplay-agents.json · Architecture : docs/BLOG-AGENTS-ROLEPLAY.md.
4. Procédures par environnement
4.1 Cursor Windows — brouillon local
cd RAPPORT-EXPERIENTIEL
npm run dev # :5195 lecture
# autre terminal :
node --env-file=.env admin/server.mjs # :5220 admin
Créer ou éditer devblog/posts/<cat>/<fichier>.md avec status: draft, puis :
node scripts/publish-local.mjs devblog/posts/<cat>/<fichier>.md --dry-run
node scripts/publish-local.mjs devblog/posts/<cat>/<fichier>.md
Vérifier : http://127.0.0.1:5195/api/articles.
Sandbox isolée (ne touche pas devblog/posts/) : npm run dev:sandbox + npm run admin:sandbox — voir docs/WORKFLOW-PUBLICATION-BLOG.md §1.
4.2 WSL — publication prod via Samwise / script
source ~/.config/vfg/blog-agents.env # MCP + VFG_ADMIN_PASSWORD
cd /path/to/RAPPORT-EXPERIENTIEL # voir SETUP-CURSOR-WSL-BLOG-AGENTS.md
npm run prepublish
node scripts/publish-local.mjs devblog/posts/<cat>/<fichier>.md --dry-run
VFG_ADMIN_BACKEND_URL=https://blog.vfg.lol \
node scripts/publish-local.mjs devblog/posts/<cat>/<fichier>.md
Invocation agent : /samwise-blog-publisher publie ce dossier scellé sur blog.vfg.lol.
4.3 Cursor Cloud — prod sans serveur local
Le pod Cloud n'a en général ni :5220 ni le MCP vfg-commands-vps (serveur logique vfg-commands). Chemin documenté :
- Rédiger le
.mddans le clone (status: pubaprès gates et autorisation prod). - Configurer
VFG_ADMIN_PASSWORDdans l'environnement Cloud Cursor (dashboard → secrets). - Exécuter
npm run prepublishpuisnode scripts/publish-local.mjs <fichier> --dry-run. - Publier (le script lit le fichier local ; un
git commitversionne le dépôt mais ne met pas l'article en ligne) :
VFG_ADMIN_BACKEND_URL=https://blog.vfg.lol \
node scripts/publish-local.mjs devblog/posts/<cat>/<fichier>.md
- Vérifier
https://blog.vfg.lol/api/articleset l'URL.md.htmlretournée.
Sans secret injecté → blocage attendu (401). Ne pas utiliser le mot de passe dev vfg-admin-change-me en prod.
4.4 VFVFGPT — MCP depuis le chat
Si vfg-commands-vps est authentifié :
{
"server": "vfg-commands-vps",
"toolName": "vfg_commands_devblog_publish",
"arguments": {
"category": "workflows-agentiques",
"slug": "2026-07-17-mon-article",
"title": "Mon article",
"markdown": "## Section\n\nContenu sans frontmatter.",
"tags": ["demo"],
"status": "pub"
}
}
Le tool appelle scripts/lib/mcp-auto-publish.mjs → même admin API. Détails : article 2026-07-09-2023_workflow-publication-blog-local-prod-mcp et annonce initiale du tool 2026-06-27-vfg-commands-devblog-publish.
5. Frontmatter minimal
---
title: "Titre factuel"
subtitle: "Optionnel"
date: 2026-07-17
time: "20:01"
author: cursor-agent
category: workflows-agentiques
status: pub # draft tant que prod non autorisée
tags: [workflows-agentiques, guide]
---
date/time: Europe/Paris, jamais dans le futur.categoryoucat: dossier existant sousdevblog/posts/.- Le corps commence après le second
---(pas de frontmatter dansbodyAPI).
6. Vérification après publication
Une réponse HTTP 200 du POST ne suffit pas.
| Étape | Local | Prod |
|---|---|---|
| API lecture | GET :5195/api/articles | GET https://blog.vfg.lol/api/articles |
| Entrée ciblée | url, date, time, status | idem |
| Page publique | http://127.0.0.1:5195/devblog/posts/...md.html | https://blog.vfg.lol/devblog/posts/...md.html |
| Santé | GET /healthz → 200 | idem |
MCP lecture (sans publier) : vfg_health, vfg_gate_health sur vfg-feed / vfg-gate.
7. Dépannage rapide
| Symptôme | Cause probable | Action |
|---|---|---|
401 Unauthorized | VFG_ADMIN_PASSWORD absent ou désaligné VPS/VFVFGPT | Vérifier secret env Cloud ou /opt/rapport-experientiel/.env sur VPS |
| Article absent du catalogue | Admin lancé depuis mauvais clone | Contrôler POSTS_DIR dans publish-article.mjs |
prepublish échoue | Lien cassé ou fuite localhost dans dist/ | Corriger le .md, relancer |
| MCP publish introuvable | vfg-commands-vps non configuré (typique Cloud) | Fallback publish-local.mjs + secret prod ; ne pas utiliser --skip-ping en prod |
| Date « corrigée » en log | Garde-fou publish-time.mjs | Normal — ne pas forcer une date future |
| Double publication | MCP puis Admin API | Interdit — un seul transport par Samwise |
8. Où approfondir
| Sujet | Ressource |
|---|---|
| Workflow technique local/prod/MCP | docs/WORKFLOW-PUBLICATION-BLOG.md |
| Agents role-play et gates | docs/BLOG-AGENTS-ROLEPLAY.md |
| Activation Cursor + WSL | docs/SETUP-CURSOR-WSL-BLOG-AGENTS.md |
| Guide local-first + déploiement statique | Article 2026-07-08 local-first |
| Fix mot de passe / client MCP unifié | Article 2026-07-09 workflow MCP |
| Audit Communauté de l'Anneau | Article draft 2026-07-12 Anneau |
9. Arbre de décision (résumé)
L'utilisateur demande-t-il blog.vfg.lol explicitement ?
├─ Non → status:draft, preview locale optionnelle, STOP avant Samwise
└─ Oui → gates Galadriel + Sauron sur SHA-256
→ npm run prepublish && publish-local --dry-run
→ Environnement ?
├─ Windows/WSL avec MCP commands OK → Samwise via vfg_commands_devblog_publish
├─ Windows/WSL sans MCP → publish-local.mjs + VFG_ADMIN_*
└─ Cursor Cloud → publish-local.mjs + secret Cloud obligatoire
→ GET /api/articles + URL .md.html → VÉRIFIÉ
La publication reste un acte volontaire : le dépôt versionne le texte, l'admin API le rend visible. Les agents portent l'Anneau jusqu'à la prod ; seul Samwise le dépose, une fois, avec preuve.