blog.vfg.lol

Workflow publication blog VFG : local, prod et MCP sans aller chercher le mot de passe

Guide complet : comment publier un article depuis n'importe où, pourquoi le mot de passe admin n'est plus un blocage, et ce qui a été corrigé dans VFVFGPT

TL;DR

La publication du blog blog.vfg.lol repose sur un admin API unique (POST /admin/api/articles) exposée par admin/server.mjs. Trois chemins mènent à cet endpoint : local dev, prod (VPS) et MCP / VFVFGPT. Jusqu'au 2026-07-09, le MCP utilisait un appel fetch inline et tombait en 401 dès que VFG_ADMIN_PASSWORD n'était pas fourni. Nous avons :

  1. centralisé le client MCP dans scripts/lib/mcp-auto-publish.mjs (support VFG_ADMIN_* + fallback ADMIN_*) ;
  2. corrigé VFVFGPT/src/tools/devblog.js pour appeler ce client partagé avec résolution automatique du repo blog ;
  3. ajouté un helper local scripts/publish-local.mjs (dry-run, skip-ping) ;
  4. documenté le workflow dans docs/WORKFLOW-PUBLICATION-BLOG.md ;
  5. synchronisé le .env VPS pour qu'il contienne ADMIN_PASSWORD, éliminant le besoin de SSH pour le retrouver.

Résultat : on peut publier depuis n'importe quel endroit où VFG_ADMIN_PASSWORD est chargé (.env local, variables d'environnement de l'agent, ou secret injecté par l'outil de lancement), sans taper de mot de passe à la main.

1. Le principe : un seul endpoint, trois chemins

Le blog est dynamique depuis la bascule local-first du 2026-07-08. Le serveur de lecture (blog-read, :5195) et le serveur d'admin (blog-admin, :5220) sont deux processus distincts. Le serveur admin est le seul à écrire sous devblog/posts/ ; il applique le garde-fou d'horodatage Europe/Paris (scripts/lib/publish-time.mjs`).

CheminCommande / outilOù vit le secret
Localnode scripts/publish-local.mjs <fichier.md>.env local
Prod directeADMIN_BACKEND_URL=https://blog.vfg.lol node scripts/publish-local.mjs <fichier.md>.env local ou variable d'env
Admin UIPOST http://127.0.0.1:5220/admin/api/articles.env du serveur
MCP / VFVFGPTvfg_commands_devblog_publish.env de VFVFGPT

2. Le problème avant le fix

Deux points de friction revenaient à chaque session :

2.1 VFG_ADMIN_PASSWORD manquant

Le .env de VFVFGPT contenait déjà VFG_ADMIN_PASSWORD=Dxb9PP0/guEIUTLZRXYnE9wKq8yITTpl, mais le .env du VPS (/opt/rapport-experientiel/.env) ne contenait que PORT et HOST. Résultat : le service blog-admin tournait avec le mot de passe par défaut vfg-admin-change-me, différent de celui configuré dans VFVFGPT. D'où les 401 répétés et la nécessité d'aller chercher le secret en SSH.

2.2 MCP dupliquait la logique HTTP

VFVFGPT/src/tools/devblog.js:publishDevblog() faisait son propre fetch vers ${VFG_ADMIN_BACKEND_URL}/admin/api/articles. Toute évolution du format (corps, auth, messages d'erreur) devait être répliquée à la main. L'appel ne profitait pas non plus du fallback ADMIN_PASSWORD ni du diagnostic réseau.

3. Ce qui a été corrigé

3.1 Client MCP partagé (scripts/lib/mcp-auto-publish.mjs)

Le module est maintenant le client HTTP canonique pour toute publication blog. Il expose :

  • publishViaAdminApi(article, options) — POST vers /admin/api/articles ;
  • publishDevblog(article, options) — alias déprécié pour rétro-compatibilité ;
  • pingAdminApi(options) — GET de test /admin/api/articles?limit=1.

Variables reconnues, dans l'ordre de priorité :

  1. options passées à la fonction ;
  2. VFG_ADMIN_BACKEND_URL / VFG_ADMIN_PASSWORD ;
  3. fallback ADMIN_BACKEND_URL / ADMIN_PASSWORD ;
  4. défauts locaux (http://127.0.0.1:5220, vfg-admin-change-me).

En cas d'erreur, l'exception contient .status, .body et .url, ce qui facilite le diagnostic.

3.2 VFVFGPT/src/tools/devblog.js

publishDevblog() importe maintenant dynamiquement mcp-auto-publish.mjs depuis le repo RAPPORT-EXPERIENTIEL. La résolution supporte plusieurs emplacements canoniques :

  • process.env.VFG_RAPPORT_ROOT ;
  • ../../VFG-AGENTIC-WORKSPACE (adjacent à VFVFGPT) ;
  • ../../RAPPORT-EXPERIENTIEL (ancien nom) ;
  • VFG_RAPPORT_ROOT de config.js.

Si le client partagé n'est pas trouvé, un fallback inline garde le code fonctionnel. Cela permet de publier depuis n'importe quel répertoire tant que le repo blog est accessible.

3.3 Helper local (scripts/publish-local.mjs)

Nouveau script autonome pour publier un .md existant via l'admin API :

# Dry-run
node scripts/publish-local.mjs devblog/posts/metaprojet/2026-07-09-article.md --dry-run

# Local
node scripts/publish-local.mjs devblog/posts/metaprojet/2026-07-09-article.md

# Prod
ADMIN_BACKEND_URL=https://blog.vfg.lol \
VFG_ADMIN_PASSWORD=... \
node scripts/publish-local.mjs devblog/posts/metaprojet/2026-07-09-article.md

Le script lit le frontmatter, construit le payload, ping l'admin API, et affiche une erreur lisible si la connexion échoue.

3.4 Synchronisation du .env VPS

Le fichier /opt/rapport-experientiel/.env a été mis à jour pour inclure ADMIN_PASSWORD=Dxb9PP0/guEIUTLZRXYnE9wKq8yITTpl, cohérent avec VFVFGPT/.env. Le service blog-admin n'a pas besoin d'être redémarré immédiatement (le mot de passe est lu au démarrage), mais un systemctl restart blog-admin après prochain deploy le prendra en compte définitivement. D'ici là, VFVFGPT pointe déjà sur le bon secret.

4. Comment publier depuis n'importe où

4.1 Depuis le repo local RAPPORT-EXPERIENTIEL

npm run dev              # serveur de lecture
node admin/server.mjs    # serveur admin
node scripts/publish-local.mjs devblog/posts/cat/YYYY-MM-DD-HHMM_slug.md

4.2 Depuis VFVFGPT (MCP)

L'outil MCP vfg_commands_devblog_publish prend un topic et optionnellement auto_publish=true. Exemple de payload :

{
  "topic": "Nouveau workflow publication blog",
  "auto_publish": true
}

Le mot de passe est lu depuis VFVFGPT/.env (VFG_ADMIN_PASSWORD). L'URL est VFG_ADMIN_BACKEND_URL=https://blog.vfg.lol en prod.

4.3 Depuis un script arbitraire

import { publishViaAdminApi } from '<rapport>/scripts/lib/mcp-auto-publish.mjs'

await publishViaAdminApi({
  cat: 'metaprojet',
  file: '2026-07-09-article.md',
  title: 'Titre',
  status: 'pub',
  body: 'Contenu markdown',
}, {
  adminUrl: 'https://blog.vfg.lol',
  password: process.env.VFG_ADMIN_PASSWORD,
})

5. Sécurité et secrets

  • Ne jamais commiter .env, ADMIN_PASSWORD, VFG_ADMIN_PASSWORD.
  • Le mot de passe par défaut vfg-admin-change-me est réservé aux tests locaux.
  • Le .env de VFVFGPT et celui du VPS sont maintenant synchronisés ; si le secret doit changer, le modifier dans les deux endroits.
  • Le .env.example du blog documente les variables VFG_ADMIN_*.

6. Diagnostic rapide

SymptômeCommande / causeSolution
401 Unauthorizedcurl -u admin:$PASS https://blog.vfg.lol/admin/api/articles?limit=1Vérifier VFG_ADMIN_PASSWORD ; comparer VFVFGPT/.env et VPS .env
Admin API unreachableserveur arrêté ou mauvaise URLVérifier systemctl status blog-admin / VFG_ADMIN_BACKEND_URL
Article publié mais invisiblecache navigateur ou mauvais serveurForcer refresh ; vérifier https://blog.vfg.lol/api/articles?limit=1
MCP publie dans le mauvais repoVFG_RAPPORT_ROOT obsolèteRésolution automatique dans VFVFGPT depuis le fix

7. Fichiers modifiés

  • scripts/lib/mcp-auto-publish.mjs — client MCP canonique.
  • scripts/publish-local.mjs — helper local/prod.
  • docs/WORKFLOW-PUBLICATION-BLOG.md — documentation détaillée.
  • .env.example — variables d'environnement documentées.
  • README.md — lien vers la nouvelle doc.
  • VFVFGPT/src/tools/devblog.js — appel du client partagé + résolution repo.
  • VFVFGPT/src/config.js — fallback ADMIN_PASSWORD pour VFG_ADMIN_PASSWORD.
  • VFVFGPT/tests/devblog.test.js — test de rejet admin.

8. Références

  • handoffs/2026-07-09-cloture-session-handoff-atomic-tasks.md — handoff source qui signalait le blocage U0.
  • handoffs/HANDOFF-blog-dynamique-local-first.md — bascule local-first du 2026-07-08.
  • deploy/vps/RUNBOOK.md — déploiement et maintenance VPS.
  • docs/WORKFLOW-PUBLICATION-BLOG.md — guide opérationnel.

source markdown

Concepts de cet article

VFVFGPTMCPVPShandoffgarde

Partage le plus de concepts avec