webmcpify

Par github · awesome-copilot

Rend une application web compatible agents — propose un manifeste d'outils WebMCP, intègre, vérifie dans un vrai navigateur, corrige ; le code sans rapport reste intact. Utilise pour « webmcpify », « add WebMCP » ou « expose app actions to AI agents ».

npx skills add https://github.com/github/awesome-copilot --skill webmcpify

webmcpify — rendre n'importe quelle app web compatible agent, vérifiablement

Vous exécutez le pipeline webmcpify. Il prend une application web existante et expose sa fonctionnalité orientée utilisateur comme des outils WebMCP (document.modelContext — un standard web proposé incubé dans le groupe communautaire W3C Web Machine Learning, actuellement en essai d'origine Chrome), afin que les agents IA du navigateur puissent faire fonctionner l'app via des appels d'outils structurés au lieu de deviner le DOM.

DETECT ──▶ INVENTORY ──▶ [PORTAIL HUMAIN : approbation du manifest] ──▶ INTEGRATE ──▶ VERIFY ──▶ HEAL ──▶ AUDIT
              ▲  boucle            par-zone lot sur les grandes app       ▲  boucle      ▲ boucle   ▲ boucle
              └── par zone                                                └── par entrée du manifest ──┘

Tout ce dont vous avez besoin se trouve dans ce répertoire skill : les guides de phase dans references/, et le code vendorable dans templates/ (runtime, types ambiants, variante JS, typages React JSX, spec de vérification). Ne supposez jamais que les fichiers existent en dehors du répertoire skill.

Hors scope (arrêtez-vous et dites-le) : serveurs MCP backend uniquement (c'est du MCP classique, pas WebMCP), automatiser des sites tiers que vous ne contrôlez pas, et du travail SEO générique.

Modes d'invocation

L'utilisateur peut passer un argument (/webmcpify <mode> ou du texte simple) :

Argument Exécuter Arrêter à
(aucun) ou full toutes les phases, reprendre depuis l'état du manifest actuel terminé
inventory / map boucles DETECT + INVENTORY uniquement — zéro changement de code présenter le tableau du manifest pour révision
integrate boucle INTEGRATE uniquement (requiert des outils approuvés dans le manifest) intégrés + compilés
verify boucles VERIFY + HEAL sur les outils intégrés/vérifiés rapport vert/ignoré
status lire .webmcpify/manifest.jsonlecture seule rapporter la phase, les comptes d'outils par statut, et la commande suivante recommandée

Tout autre texte est un guide de scope (ex. « uniquement la zone de paiement », « outils lecture seule uniquement »).

Règles fondamentales (non négociables, appliquez-les à chaque phase)

  1. Zéro changement non lié. Chaque hunk diff que vous produisez doit être traçable à une entrée du manifest ou à la configuration unique enregistrée. Ne refactorisez jamais, ne reformatez jamais, ne renommez jamais, ni « n'améliorez » rien d'autre — notez les problèmes dans le rapport à la place. Les fichiers déjà sales au baseline (enregistrés dans le manifest) sont intouchables : ne les modifiez ni ne les ramenez jamais.
  2. Outils lecture seule en premier. Les mutations sont à trois états : mutating: false, "client" (navigateur local uniquement : prefs, localStorage), ou "server" (données quittent le navigateur). Les outils mutants serveur requièrent une approbation humaine explicite par-outil enregistrée dans le manifest ; les outils mutants client peuvent être approuvés en lot à la portail. N'exposez jamais les actions destructrices, irréversibles, ou de paiement dans une première intégration.
  3. Le serveur est la seule limite de confiance. La fonction execute() d'un outil ne peut appeler que les chemins de code que l'UI utilise déjà (mêmes endpoints, mêmes validations, mêmes auth). Ne créez jamais de nouveaux endpoints, ne contournez jamais les contrôles existants, ne mettez jamais de secrets dans les outils.
  4. Spec-shaped et sans dépendances. Enregistrez via document.modelContext.registerTool() avec le cycle de vie AbortSignal (détection de la rétrocompatibilité fallback navigator.modelContext déprécié). Aucune dépendance de runtime WebMCP tierce. Tout est détecté de manière dynamique : l'app se comporte de manière identique dans les navigateurs sans WebMCP.
  5. Ne jamais toolautosubmit sur les formulaires qui changent d'état — ni mutating: "client" ni "server". Uniquement sur les formulaires de lecture pure (recherche, filtre, disponibilité).
  6. L'état vit dans les fichiers, pas dans votre contexte. Lisez/écrivez .webmcpify/ constamment ; supposez que votre contexte peut être effacé entre n'importe quelles deux étapes. Écrivez le manifest de manière atomique (écrivez manifest.json.tmp, puis renommez sur manifest.json).
  7. Les commits sont opt-in. Ne commitez jamais à moins que l'humain n'ait choisi une politique de commit à la portail (voir ci-dessous). Sans git ou sans permission, laissez les changements dans l'arborescence de travail et enregistrez la progression dans le manifest uniquement.

Orientation fraîche et autorisée

WebMCP est une API en essai d'origine en évolution — la surface a déjà changé pendant l'essai (testing API supprimée 2026-07 ; navigatordocument). Avant la Phase 2, si le réseau est disponible, tirez les guides officiels actuels de Google plutôt que de compter sur la mémoire :

npx -y modern-web-guidance@latest retrieve "webmcp,agentic-forms,agentic-javascript-tools"

Si hors ligne, utilisez references/integrate.md — mais préférez les guides en direct quand ils entrent en conflit.

Le protocole d'état — .webmcpify/ dans le repo cible

Fichier Objectif
manifest.json Source unique de vérité (schema ci-dessous ; écritures atomiques)
areas/<id>.tools.json Sortie de shard du sous-agent pendant la fan-out d'inventory (fusionné, puis supprimé)
report.md Rapport en cours orienté humain ; finalisé à la fin

Règle de reprise : si manifest.json existe, reprenez — ne recalculez rien de déjà enregistré. Fusionnez d'abord les shards restants : tout fichier areas/<id>.tools.json existant est fusionné dans le manifest (marquez ces zones inventoried, supprimez les shards) avant de redistribuer les sous-agents. Puis continuez à pipeline.phase, la première zone pending, ou le premier outil dont le statut n'est pas terminal. Statuts terminaux : verified, skipped, rejected.

Transitions de phase (faites l'écriture atomique du manifest au moment où la condition se tient) :

  • detect → inventory : app enregistré, baselineSha/baselineDirty capturés.
  • inventory → gate : aucune zone pending, la passe de complétude a tourné.
  • gate → integrate : chaque outil discovered est approved/rejected, et commitPolicy + commitWebmcpifyDir sont définis.
  • integrate → verify : aucun outil approved ne reste (chacun integrated ou terminal), build vert.
  • verify → heal : la boucle verify a visité chaque outil integrated et ≥1 est failed (aucun failed → directement à audit).
  • heal → audit : aucun outil failed et re-vérification complète post-healing passée.
  • audit → done : chaque hunk mappé-ou-flaggé, report.md finalisé.

Manifest schema (Webmcpify Manifest v3) :

{
  "webmcpify": 3,
  "app": { "stack": "react-vite", "typescript": true, "entry": "src/main.tsx",
           "baseUrl": "http://localhost:5173", "startCommand": "npm run dev",
           "authFixtures": {                    // comment verify OBTIENT chaque session
             "member": { "obtain": "npm run seed:test-user, puis connectez-vous à /login",
                         "account": "member@example.test",
                         "env": ["TEST_MEMBER_PASSWORD"] }  // noms de variables d'env uniquement — jamais de valeurs secrètes
           } },
  "pipeline": {
    "phase": "inventory",          // detect|inventory|gate|integrate|verify|heal|audit|done — règles de transition ci-dessus
    "setup": {                     // CHEMINS créés/modifiés par étape de configuration unique ([] = pas encore fait)
      "runtimeVendored": ["src/webmcp/webmcpify.ts", "src/webmcp/webmcp.d.ts"],
      "harnessInstalled": [".webmcpify/webmcp.spec.ts"],
      "originTrialNoted": ["README.md"]
    },
    "baselineSha": "abc1234",      // HEAD au démarrage du pipeline ; null sans git
    "baselineDirty": ["src/wip.ts"], // chemins sales au démarrage — intouchables (règle fondamentale 1)
    "commitPolicy": null,          // défini à la portail : "commit-per-batch" | "no-commit"
    "commitWebmcpifyDir": null,    // défini à la portail : committer .webmcpify/ lui-même ? true | false
    "blockers": []                 // ex. « app ne démarre pas localement : a besoin de $API_KEY » — surfacé à la portail
  },
  "areas": [
    { "id": "checkout", "paths": ["src/features/checkout/"], "status": "pending" } // pending|inventoried
  ],
  "tools": [
    {
      "id": "create_ticket",
      "area": "tickets",
      "kind": "imperative",        // imperative | declarative
      "mutating": "server",        // false | "client" (navigateur local uniquement : prefs, localStorage) | "server" (données quittent le navigateur)
      "priority": 1,               // 1 = exposer en premier ; 2/3 = vagues ultérieures
      "description": "Crée un nouveau ticket dans le projet actuellement ouvert.",
      "inputSchema": { /* JSON Schema */ },
      "annotations": { "readOnlyHint": false, "untrustedContentHint": false }, // verify affirme ces propriétés sur l'outil énuméré
      "source": ["src/features/tickets/NewTicket.tsx:42"], // le chemin de code UI qu'il enveloppe
      "route": "/projects/demo/tickets",                    // où verify navigue
      "auth": ["role:member"],     // "none" | "session" | ["role:<name>", ...] — clés dans app.authFixtures ; verify tourne une fois par rôle listé
      "examples": { "valid": { "title": "Test ticket" }, "invalid": {} },
                                   // invalid: null UNIQUEMENT pour les outils readOnlyHint sans/vides params —
                                   // verify affirme alors dual-outcome : rejette OU résout sans effet secondaire
      "expect": { "result": "created", "navigation": null, "ui": "new row appears in the ticket list" },
                                   // exactement un de result|navigation : result = substring de la chaîne résolue ;
                                   // navigation = destination URL/pattern quand executeTool résout null (navigué)
      "cleanup": "supprimez le ticket créé via le chemin delete de l'UI (données de test uniquement)", // requis pour mutating:"server", recommandé pour "client"
      "status": "discovered",      // discovered|approved|rejected*|integrated|verified*|failed|skipped*  (* = terminal)
      "approval": null,            // outils mutant serveur, une fois approuvés : { "note": "...", "at": "2026-07-12",
                                   //   "productionSideEffect": null } — défini uniquement quand la vérification inévitablement
                                   //   cause un vrai effet en production (voir VERIFY : politique d'effet côté production)
      "attempts": 0,               // cycles heal-fix ; l'échec verify déclencheur est attempt 0
      "batchCommit": null,         // sha sous commit-per-batch — arrive dans le manifest un commit PLUS TARD
      "notes": ""
    }
  ],
  "log": [ "2026-07-12 inventory: area checkout done, 4 candidates" ]
}

Migration v2→v3 : la reprise d'un manifest "webmcpify": 2 migre sur place à la première écriture — auth string → array ; setup booléens → tableaux de chemins (false[] ; true → récupérer les chemins de git/log, sinon null = fait-mais-non-enregistré, audit traite ces fichiers flag-only) ; mutating: true"server" ; ajouter annotations (par défaut du tableau d'inventory), blockers: [], commitWebmcpifyDir: null, expect.navigation: null ; puis augmenter à 3.

Phase 0 — DETECT

Identifiez la pile, les commandes build + dev-server, TypeScript ou non, le modèle d'auth (incluant comment verify obtient chaque session de test → app.authFixtures), la configuration de test, et comment l'app démarre localement ; enregistrez sous app. Enregistrez le baseline git : pipeline.baselineSha = HEAD actuel et pipeline.baselineDirty = chemins git status --porcelain (tous deux null/[] sans git). Si l'app ne peut pas être démarrée localement, ajoutez le blocker à pipeline.blockers — l'intégration peut procéder, mais la vérification sera bloquée et cela doit être surfacé à la portail. Détails : references/inventory.md.

Phase 1 — INVENTORY (boucle ; s'adapte à n'importe quelle taille)

Ne mappez jamais une grande codebase en une seule passe.

  1. Cartographie de zone en premier (bon marché, structurel) : énumérez les routes/vues/modules de fonctionnalités depuis la config du routeur, le répertoire pages, ou la navigation — sans lire les fichiers d'implémentation. Écrivez chaque zone dans areas avec "pending".
  2. Boucle d'inventory — une zone par itération : lisez en profondeur uniquement les fichiers de cette zone ; rédigez un outil candidat par action utilisateur (conventions, budget de compte d'outils, et règles de chevauchement : references/inventory.md) avec TOUS les champs du manifest remplis, incluant route, auth, annotations, examples, expect, et cleanup (requis pour mutating: "server", recommandé pour "client") — la phase verify s'exécute uniquement depuis ces champs. Ajoutez comme "discovered", marquez la zone "inventoried", écrivez le manifest, répétez.
    • Fan-out du sous-agent : les sous-agents n'écrivent jamais manifest.json. Chacun écrit uniquement son propre shard areas/<id>.tools.json — schema { "webmcpifyShard": 3, "area": "<id>", "tools": [ /* full v3 tool entries */ ] }, écrit de manière atomique (tmp + rename). Vous (le coordinateur) fusionnez les shards dans le manifest séquentiellement, puis les supprimez ; en reprise, fusionnez les shards existants EN PREMIER avant de redistribuer (Règle de reprise).
  3. Sortie : aucune zone pending ne reste, plus une passe de complétude — parcourez la navigation de l'app et demandez-vous « y a-t-il une action utilisateur visible manquante ? »

PORTAIL — approbation du manifest (le seul vrai checkpoint)

Présentez le manifest de manière compacte (id, zone, kind, mutating, priority, description d'une ligne) — par-zone lot sur les grandes app. Demandez à l'humain de décider, en un seul échange si possible :

  1. Quels outils sont approved vs rejected (rejected est terminal — les outils rejetés sont exclus de chaque phase ultérieure et des conditions de sortie). Les outils mutating: "server" requièrent l'approbation individuelle → enregistrer dans approval ; les outils mutating: "client" peuvent être approuvés en lot.
  2. Politique de commit : commit-per-batch (chaque lot d'intégration commité, réversible — recommandé sur un baseline propre) ou no-commit (laisser les changements uncommités pour que l'humain révise/committe) → pipeline.commitPolicy. Aussi si .webmcpify/ lui-même doit être commité (recommandé : oui — cela documente l'intégration) → pipeline.commitWebmcpifyDir.
  3. Chaque entrée dans pipeline.blockers (ex. app ne démarre pas). Si la vérification d'un outil causera inévitablement un vrai effet côté production (ex. un mailer avec un endpoint origin-allow-listed), récupérez l'approbation ICI et enregistrez-la dans approval.productionSideEffect de l'outil — voir VERIFY.

Appliquez references/security.md à chaque outil mutant avant de présenter.

Phase 2 — INTEGRATE (boucle)

Configuration unique en premier — enregistrez les chemins des fichiers créés/modifiés dans pipeline.setup (ex. runtimeVendored: ["src/webmcp/webmcpify.ts", ...]) : vendorisez le runtime depuis les templates/ de cette skill (webmcpify.ts, ou webmcpify.js pour les projets non-TS, plus webmcp.d.ts pour TS et webmcp-jsx.d.ts pour React TSX — conservez le header MIT complet ; voir references/runtime.md) et notez la condition de l'essai d'origine/flag dans le README cible (originTrialNoted). Puis boucle :

  1. Choisissez le lot suivant d'outils approved — une zone ou ≤5 outils.
  2. Implémentez par references/integrate.md : attributs déclaratifs pour les formulaires HTML standards (incluant les formulaires rendus par framework et les fetch-interceptés) ; enregistrement impératif via le runtime vendorisé pour les actions non-formulaire ou à état contrôlé.
  3. Build + typecheck ; corrigez uniquement ce que le lot a cassé.
  4. Marquez les outils "integrated", écrivez le manifest. Sous commit-per-batch : exigez un index propre avant staging (changements staged non liés → arrêtez et surfacez) ; stagez uniquement les fichiers du lot par chemin — jamais git add -A, -u, ., ou commit -a ; commitez feat(webmcp): expose <ids> (webmcpify). Le sha du commit arrive dans batchCommit sur l'écriture suivante du manifest — un commit plus tard (le manifest ne peut pas contenir le sha de son propre commit). Ne jamais amender un commit de lot précédent.
  5. Répétez jusqu'à ce qu'aucun outil approved ne reste.

Phase 3 — VERIFY (boucle)

Configurez une fois depuis templates/webmcp.spec.ts par references/verify.md (vrai Chrome headed ; surface de production getTools()/executeTool() avec sonde de fallback legacy). Puis bouclez sur chaque outil integrated, en utilisant ses champs du manifest route, auth, examples, expect, et annotations :

  • affirmer que l'outil est enregistré avec le schema attendu (le inputSchema énuméré est un JSON Schema stringifié — parsez avant de comparer) et les annotations du manifest ;
  • exécuter l'exemple valide (outils mutants : données dev/test uniquement, puis exécutez cleanup) et un exemple invalide (invalid: null outils lecture seule zéro-param : affirmation dual-outcome — voir references/verify.md) ;
  • affirmer sur le résultat retourné et l'état UI résultant par expect (un delta UI, ou expect.navigation quand l'exécution résout null).

Passage → "verified". Échec → "failed" + note d'échec. Outils scope-rôle : exécutez la boucle une fois par rôle listé dans auth, en vous connectant via l'entrée app.authFixtures correspondante.

Politique d'effet côté production — quand la vérification d'un outil inévitablement cause un effet réel en production (ex. un email réellement envoyé), LES TROIS sont requis : (1) l'humain l'a approuvé à la portail, enregistré dans approval.productionSideEffect ; (2) chaque payload de test est marqué [webmcpify verification] ; (3) l'effet est listé dans report.md. Sans l'approbation enregistrée, n'exécutez pas le chemin live — marquez l'outil skipped avec une note de blocker.

Phase 4 — HEAL (boucle)

Tant qu'un outil est "failed" : diagnostiquez par references/heal.md, corrigez uniquement l'intégration de cet outil — corrections implémentation-uniquement ; si la correction changerait le contrat approuvé (schema, description, classe mutating, annotations, expect), retournez à la portail pour re-approbation au lieu de changer silencieusement le manifest. L'échec verify déclencheur est attempt 0 ; incrémentez attempts par cycle de correction et re-vérifiez. À attempts = 3 → "skipped" avec une note de blocker claire (une escalade explicite à l'humain, pas un abandon silencieux). Ne jamais élargissez le diff ou simulez une réussite. Après healing, re-lancez la vérification une fois pour tous les outils avec le statut integrated ou verified (guérir un outil peut en casser un autre — collisions de scope).

Sortie : chaque outil est verified, skipped, ou rejected ; build vert.

Final — AUDIT + rapport

  1. Audit diff (flag-only, jamais auto-revert) : collectez les changements du pipeline — git diff <baselineSha>..HEAD plus l'index et les fichiers non suivis sous commit-per-batch, ou l'arborescence de travail + index + non-suivis sous no-commit. Chaque hunk doit être mappé à une entrée du manifest ou un chemin pipeline.setup enregistré. Un hunk non mappé → flaggez-le dans le rapport avec fichier/ligne et une disposition suggérée ; ne revertez jamais rien vous-même. Un hunk dans un fichier baselineDirty → intouchable, flaggez uniquement. Sans baselineSha, auditez les fichiers nommés dans les champs source du manifest et les chemins pipeline.setup (entrées de setup enregistrées comme null par la migration v2→v3 : revenez à flag-only pour ces fichiers).
  2. Finalisez .webmcpify/report.md : couverture d'outil par zone, outils skipped/rejected avec raisons, notes de sécurité (quels outils mutants existent, qu'est-ce qui les protège, les effets côté production enregistrés), comment tester manuellement (flag, DevTools WebMCP pane, extension inspector), et chaque blocker qui requiert un humain.
  3. Dites à l'humain : ce qui est exposé, ce qui est skipped et pourquoi, et comment l'essayer.

Références (lire à la demande, pas en avant)

  • references/inventory.md — cartographie de zone, conventions de naming/schema, budgets/chevauchement
  • references/integrate.md — patterns déclaratifs + impératifs par stack
  • references/runtime.md — vendorisation + câblage du runtime templates/
  • references/verify.md — installation du harnais : flags, surfaces, Playwright/Puppeteer, evals
  • references/heal.md — taxonomie des échecs → corrections
  • references/security.md — la checklist de sécurité (appliquez avant la portail et à l'audit)

Skills similaires