Chapitre 23 · Partie III · En pratique
WebMCP : un agent au travail dans le Sandbox
Ce qu’un agent IA dans le navigateur peut faire avec le Sandbox grâce à ses 36 outils WebMCP (regarder les pages, changer n’importe quel réglage, modifier le texte, ajouter images, tableaux et polices, lancer les vérifications, exporter) et comment appeler chacun d’eux, avec de vrais arguments et de vraies réponses
En bref
Cette page s’adresse aux personnes qui veulent qu’un assistant d’intelligence artificielle travaille pour elles sur un livre dans le Sandbox. Tant que le Sandbox est ouvert, il donne à l’assistant une série d’outils : regarder n’importe quelle page, changer la maquette, modifier le texte, ajouter des images et des tableaux, trouver les problèmes et enregistrer des fichiers. Vous demandez avec vos propres mots, par exemple « grossissez un peu le texte et vérifiez que le livre tient toujours en 40 pages », et l’assistant utilise les outils et vous montre les pages. Tout reste dans votre navigateur. La page explique comment connecter un assistant, ce qu’il peut faire et comment chaque outil s’appelle.
Un agent dans votre navigateur travaille sur le livre ouvert dans le Sandbox : il regarde les pages, les modifie et les regarde de nouveau.
Le Sandbox donne à un agent ses propres outils via
WebMCP, un projet de norme web
qui permet à une page de fournir des outils au modèle d’IA avec lequel dialogue le navigateur. Grâce à eux,
l’agent ne clique pas dans l’interface : il lit le livre, demande une
image de la page 12, règle bodyText.fontSize sur 10,5 pt, constate que le chapitre
est passé de 18 à 19 pages, et revient en arrière. Il fait ce que vous faites à l’œil, et
il le fait avec votre livre, dans votre navigateur.
Il y a 36 outils dont le nom commence par sandbox_, enregistrés tant que le
Sandbox est à l’écran, et 8 outils du site, site_*, sur chaque page de
postext.dev. Cette page les classe selon ce que vous demanderiez à un agent, et
donne l’appel de chacun.
#Connecter un agent
#Dans un navigateur qui prend en charge WebMCP
Les outils sont enregistrés auprès de document.modelContext quand le Sandbox se monte
et retirés quand vous le quittez. Un agent à qui le navigateur fournit les outils de la page
les y trouve. Il n’y a rien à installer ni à configurer du côté de Postext.
WebMCP est encore un brouillon. Chrome le propose en origin trial, et derrière le
flag chrome://flags/#enable-webmcp-testing. Les outils suivent la page : sur
la page d’accueil ou dans la documentation, l’agent dispose des outils site_* ; dès que le
Sandbox est à l’écran, les 36 outils sandbox_* apparaissent aussi.
#Dans tout autre navigateur : window.postextWebMcp
La page place aussi les mêmes outils sur window.postextWebMcp, avec ou sans
WebMCP. Tout agent capable d’exécuter du script dans la page peut les utiliser : un
outil d’automatisation comme Puppeteer ou Playwright, un serveur MCP qui pilote le
navigateur et évalue du script (Chrome DevTools MCP), une extension de navigateur, ou
vous-même, dans la console de développement :
// What is on this page
postextWebMcp.listTools().map((t) => t.name);
// Run one tool: the name, then an object with its arguments
await postextWebMcp.executeTool('sandbox_get_state', {});
await postextWebMcp.executeTool('sandbox_set_config', {
changes: [{ path: 'bodyText.fontSize', value: '10.5pt' }],
});La même chose depuis un script Puppeteer, qui enregistre une page sous forme d’image :
import fs from 'node:fs';
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://postext.dev/en/sandbox');
await page.waitForFunction(() => window.postextWebMcp?.listTools().some((t) => t.name === 'sandbox_get_state'));
await page.waitForFunction(async () => (await window.postextWebMcp.executeTool('sandbox_get_state', {})).ready);
const result = await page.evaluate(() =>
window.postextWebMcp.executeTool('sandbox_render_page', { chapter: 1, position: 1, width: 1200, format: 'png' }),
);
const picture = result.content.find((part) => part.type === 'image');
fs.writeFileSync('page-1.png', Buffer.from(picture.data, 'base64'));
await browser.close();Un profil de navigateur neuf a son propre stockage : il part donc des exemples, pas de vos projets. Pour travailler sur vos propres livres, utilisez le navigateur dans lequel vous les avez créés.
#À quoi ressemble chaque réponse
Un outil répond par un objet JSON : ok: true et ce qui a été demandé, ou ok: false et une error qui dit ce qui n’allait pas et quoi demander à la place :
{
"ok": false,
"error": "bodyText.fontSize is a length: give { \"value\": 11, \"unit\": \"pt\" }, a number (in pt) or a text such as \"11pt\". The units: cm, mm, in, pt, px, em, rem."
}Les arguments sont vérifiés par rapport au schéma de l’outil avant toute exécution : un
paramètre mal orthographié est donc refusé avec la liste des bons. Un outil qui
renvoie des images (sandbox_render_page) répond sous la forme MCP, { content: [...] } : une partie texte avec du JSON qui décrit les pages, puis une partie
image par page, encodée en base64.
#La boucle de travail
Chaque outil qui modifie le livre attend que la mise en page suive avant de répondre, et indique combien de pages compte désormais chaque chapitre. Le coup d’œil suivant porte donc toujours sur les nouvelles pages, et l’agent peut travailler comme un graphiste :
- Faire le point :
sandbox_get_statedonne le livre, ses chapitres avec leurs pages, le chapitre et la page à l’écran et le panneau ouvert. - Regarder :
sandbox_render_pagepeint une page,sandbox_inspect_pagesla décrit sous forme de données,sandbox_get_warningsliste ce que les vérifications ont trouvé. - Modifier :
sandbox_set_config,sandbox_edit_text,sandbox_save_resource… - Regarder de nouveau, puis garder la modification ou revenir en arrière.
Une page est mise en page et peinte pour l’outil quelle que soit la visionneuse à l’écran : l’agent peut donc regarder le chapitre 7 pendant que vous lisez le chapitre 2.
#Ce que vous pouvez demander, et comment c’est fait
#Savoir ce qui est ouvert
// sandbox_get_state
{}{
"ok": true,
"ready": true,
"book": { "kind": "sample", "id": "postext-guide", "name": "Postext guide" },
"pages": 3,
"chapters": [
{ "chapter": 1, "id": "a", "title": "Opening", "onScreen": true, "words": 1007, "pages": 2 },
{ "chapter": 2, "id": "b", "title": "Second", "words": 101, "pages": 1 }
],
"view": { "viewer": "canvas", "panel": "none", "scope": "chapter", "chapter": 1 },
"resources": 0,
"warnings": 0
}ready: false s’accompagne de waitingFor, qui en donne la raison (un livre encore en cours de chargement).
question et notice apparaissent quand le Sandbox attend quelque chose de vous ; voir
Questions et messages.
Tout outil qui prend un chapter accepte sa position dans le livre (à partir de 1),
son titre ou son identifiant. S’il est omis, c’est le chapitre à l’écran.
#Regarder une page
Une image. « Montrez-moi l’ouverture du chapitre 3 », « à quoi ressemble la double page 24-25 ? » :
// sandbox_render_page: a spread, 1200 px wide per page
{ "chapter": 3, "page": 24, "count": 2, "width": 1200 }page est le numéro imprimé sur la page ; position est la place de la page
parmi les pages du chapitre (à partir de 1), pour les pages sans numéro. Sans
l’un ni l’autre, c’est la page à l’écran. crop agrandit une partie de la page, en
fractions de sa largeur et de sa hauteur depuis le coin supérieur gauche, pour juger de près
les caractères et l’espacement :
// sandbox_render_page: the bottom right quarter, magnified
{ "chapter": 3, "page": 24, "crop": { "x": 0.5, "y": 0.5, "width": 0.5, "height": 0.5 }, "width": 1600 }printPreview: true peint l’épreuve écran du profil d’impression avec les repères de format,
de fond perdu et de zone de sécurité ; trimmed: true retire la marge qui porte
les traits de coupe.
La même page sous forme de données. « Quelles lignes de cette page sont lâches ? », « la deuxième colonne est-elle pleine ? » :
// sandbox_inspect_pages: without a page, one line per page of the chapter
{ "chapter": 1 }{
"chapter": 1, "title": "Opening", "chapterPages": 2, "converged": true,
"pages": [
{ "position": 1, "label": "1", "role": "opener", "blank": false, "lines": 45, "figures": 0, "starts": "Opening" },
{ "position": 2, "label": "2", "role": "body", "blank": false, "lines": 37, "figures": 0, "starts": "decades. Print typography spent five centuries…" }
]
}Avec page ou position, il liste chaque bloc de la page : son type, sa colonne, son
texte, son nombre de lignes, les lignes qui se terminent par un trait d’union et les lignes justifiées
lâches avec la largeur de leurs espaces, sa boîte sur la page, ainsi que le taux de remplissage de chaque
colonne (fill: 0.99).
Ce qui se trouve en un point. Quand l’agent voit quelque chose dans une image, il demande ce que c’est avec les mêmes fractions que pour le recadrage :
// sandbox_inspect_point
{ "chapter": 3, "page": 24, "x": 0.71, "y": 0.42 }La réponse donne le bloc, la ligne et la colonne de la source Markdown à cet endroit
(et le mot), un lien et la page vers laquelle il mène, la cellule de tableau ou la légende d’une
ressource. Avec select: true, il fait aussi ce que fait un clic : le
panneau Texte s’ouvre avec le curseur à cet endroit (word: true sélectionne le
mot, to sélectionne jusqu’à un second point).
#Changer la maquette
N’importe quel réglage de la configuration peut être modifié par son chemin. Un agent connaît rarement le chemin d’emblée, alors il le cherche :
// sandbox_find_setting
{ "query": "orphans" }{
"ok": true,
"paths": [
{ "path": "bodyText.avoidOrphans", "effective": true },
{ "path": "bodyText.avoidOrphansInLists", "effective": true }
],
"sections": [{ "section": "Body text", "group": "Typography", "settingsGroup": "text", "configKeys": ["bodyText"] }]
}sandbox_get_config lit un réglage ou une section entière : set est ce que le livre
stocke, effective ce que cela donne une fois les valeurs par défaut complétées, ce qui
montre aussi tous les réglages de la section.
// sandbox_get_config
{ "path": "headings.levels[level=2]" }Les chemins désignent un élément d’une liste par ce qui le distingue :
headings.levels[level=2].fontSize, header.elements[id=titleOdd].italic,
calloutStyles[id=note].title. Ensuite, sandbox_set_config modifie autant de
réglages que vous voulez en un seul appel :
// sandbox_set_config
{
"changes": [
{ "path": "bodyText.fontSize", "value": "10.5pt" },
{ "path": "page.margins.top", "value": { "value": 2.5, "unit": "cm" } },
{ "path": "headings.levels[level=2].color", "value": "#1f3a5f" },
{ "path": "bodyText.avoidOrphans", "value": true }
]
}Une longueur s’écrit "2.5cm", { "value": 2.5, "unit": "cm" } ou un nombre dans l’unité
du réglage ; une couleur s’écrit "#1f3a5f". Une valeur null supprime le réglage, si bien que
la valeur de la maquette revient. La réponse dit comment juger la modification, et comment
revenir en arrière :
{
"ok": true,
"changed": [
{
"path": "bodyText.fontSize",
"from": null,
"to": { "value": 10.5, "unit": "pt" },
"effective": { "from": { "value": 10, "unit": "pt" }, "to": { "value": 10.5, "unit": "pt" } }
}
],
"followed": [
{ "path": "captionStyle.fontSize.value", "from": 10, "to": 10.5 },
{ "path": "tableStyle.bodyFontSize.value", "from": 10, "to": 10.5 }
],
"pagesBefore": 212,
"pagesAfter": 219,
"chapters": [{ "chapter": 1, "title": "Opening", "pages": 19, "pagesBefore": 18 }]
}from est la valeur stockée auparavant (ici null : le livre ne la définissait pas), si bien que
le même appel avec from comme valeur annule la modification. followed liste les
réglages qui dépendent de celui-ci et ont bougé avec lui. Une note apparaît quand le
moteur a résolu autre chose que ce qui était demandé (une limite, un réglage qui
dépend d’un autre), et une valeur de forme incorrecte, ou une configuration que le
moteur ne peut pas résoudre, est refusée sans que rien ne change.
Pour des changements plus importants, patch fusionne un objet dans la configuration (les objets
fusionnent, null supprime, les listes sont remplacées en entier) et replace met une
configuration complète à la place de celle du livre, par exemple un export postext-config.json.
sandbox_reset_to_original avec part: "config" rétablit la maquette dont le
livre est parti.
Les polices sont aussi des réglages : sandbox_list_fonts avec search: "Garamond" trouve
des familles dans le catalogue ouvert, et écrire le nom dans un réglage fontFamily
la charge.
#Modifier le texte
Le texte de chaque chapitre est du Markdown avec les extensions de Postext (voir Format du document). L’agent le lit avec les numéros de ligne, trouve un passage et remplace des passages exacts :
// sandbox_read_text: lines 40 to 80 of chapter 2
{ "chapter": 2, "fromLine": 40, "toLine": 80 }// sandbox_search_text: where a passage occurs, and on which page
{ "query": "baseline grid", "pages": true }// sandbox_edit_text
{
"chapter": 2,
"edits": [
{ "find": "The last words of the opening.", "replace": "The closing words of the opening." },
{ "find": "colour", "replace": "color", "all": true }
]
}Chaque find doit correspondre exactement à la source et n’apparaître qu’une fois, sauf si all est
défini. Soit toutes les modifications s’appliquent, soit aucune : un passage absent est
refusé avec le conseil de relire le chapitre. L’appel entier constitue une seule étape
pour sandbox_undo_text, qui l’annule (redo: true le rétablit).
sandbox_write_text remplace un chapitre entier, à partir de markdown ou d’un fichier .md.
Pour vous montrer un endroit du texte, sandbox_select_text ouvre le panneau Texte
avec ce passage sélectionné (par text, line ou offset), comme le fait un clic sur
un résultat du panneau Vérifications.
#Organiser les chapitres
sandbox_manage_chapters ajoute, renomme, déplace, divise, fusionne et affiche des
chapitres :
// add a chapter in third place
{ "action": "add", "title": "Epilogue", "markdown": "# Epilogue\n\nThe end.\n", "position": 3 }
// split a chapter where a passage starts
{ "action": "split", "chapter": "Opening", "before": "## Second part" }
// one chapter per level-1 heading
{ "action": "split_at_headings", "chapter": 1 }sandbox_remove_chapter en supprime un, ce qui ne peut pas être annulé.
#Ajouter des images, des tableaux, des vidéos et des polices
sandbox_save_resource ajoute ou modifie une ressource, comme le fait le panneau Ressources.
Un fichier arrive par url (une adresse https: que la page peut récupérer, ou une URL
data:) ou en base64 :
// a picture with its caption and alternative text
{
"id": "harbour",
"image": { "url": "https://example.org/harbour.jpg" },
"caption": "The harbour at dawn",
"altText": "Fishing boats moored at a stone quay, mist over the water",
"placement": { "position": "top", "span": "page" }
}// a table from rows of text; the first row is the header
{
"id": "prices",
"caption": "Prices in 1850",
"table": { "rows": [["Item", "Price"], ["Bread", "2 d"], ["Ink", "6 d"]], "columnWidths": [2, 1] }
}// a YouTube video: its poster, frame size and title are fetched
{ "id": "interview", "video": { "url": "https://www.youtube.com/watch?v=…" }, "caption": "The author at work" }La réponse donne l’enregistrement stocké et la ligne qui le place,
::resource{id="prices"}, que l’agent écrit ensuite dans le texte avec
sandbox_edit_text. Sur un id existant, l’appel ne modifie que ce qu’il fournit :
une légende, les cellules d’un tableau, le placement, la zone de sécurité d’une image. newId
renomme une ressource et, par défaut, toutes les références à celle-ci dans le livre.
sandbox_list_resources les liste et, avec un id, en donne une en entier (les
cellules d’un tableau avec leur mise en forme, la source d’un SVG).
Les polices téléversées dans le livre passent par sandbox_save_font :
{ "action": "add", "family": "My Serif", "weight": 700, "style": "italic", "file": { "url": "https://example.org/MySerif-BoldItalic.woff2" } }#Vérifier le livre
// sandbox_get_warnings: every chapter
{ "scope": "book" }La réponse reprend ce que dit le panneau Vérifications, pour n’importe quel chapitre ou pour tout le livre, quoi qu’il y ait à l’écran : polices et images manquantes, balisage que le moteur n’a pas pu lire, éléments de maquette qui ne tiennent pas, texte trop pâle pour son fond, lignes lâches, veuves, encadrés qui débordent et contrôle avant impression. Chaque avertissement indique sa catégorie, son chapitre, sa ligne et ses positions, sa page, et le réglage ou la ressource qu’il désigne :
{
"ok": true,
"scope": "book",
"total": 3,
"byCategory": { "typesetting": 2, "design": 1 },
"warnings": [
{
"kind": "headerFooterMetadataMissing",
"category": "design",
"title": "Placeholder metadata missing",
"detail": "header · {title} — The metadata referenced by this placeholder is not set — it will render empty."
}
]
}À partir d’un avertissement, l’agent peut aller à son emplacement (sandbox_select_text avec
offset et toOffset, ou sandbox_go_to_page), regarder la page, et
modifier le texte ou le réglage. category restreint la liste ; sur un long livre,
scope: "book" met tous les chapitres en page et prend un certain temps.
#Montrer au lecteur
Ce que l’agent modifie, vous le voyez. Pour attirer votre attention sur quelque chose :
// sandbox_set_view: the Canvas with facing pages and loose lines highlighted
{ "viewer": "canvas", "pages": "spread", "fit": "height", "guides": { "looseLines": true, "baselineGrid": true } }// sandbox_go_to_page: where a figure is set
{ "anchor": "harbour" }sandbox_set_view choisit aussi la visionneuse (canvas, pdf, folio, html,
epub), le panneau latéral, chapitre ou livre entier, le zoom, la taille de caractère du lecteur,
l’aperçu d’impression et le groupe du panneau Maquette. sandbox_go_to_page tourne
les pages par step, page, position, un passage text, une anchor ou une
entrée contents d’un EPUB. sandbox_run_viewer actionne un bouton de barre d’outils :
regenerate écrit de nouveau le PDF ou l’EPUB et attend la fin, print ouvre la
boîte de dialogue d’impression pour que vous confirmiez, play_video lit une vidéo sur une page.
#Pages de bande dessinée
sandbox_inspect_comic donne les cases, les lignes de division et les bulles d’une page de bande dessinée
avec leurs positions ; sandbox_edit_comic fait les modifications qu’une personne fait
au pointeur, écrites dans la source :
// move a balloon's centre to a point of its panel's picture, in percent
{ "comic": 1, "action": "move_balloon", "balloon": 2, "at": { "x": 30, "y": 18 } }
// move the first split line to 45 % of its cell
{ "comic": 1, "action": "move_splitter", "splitter": 1, "start": 45 }La réponse prévient quand une bulle tombe sur un visage ou sort de sa case. Voir Bande dessinée pour le format.
#Livres, fichiers et Word
-
Ouvrir et conserver des livres.
sandbox_list_booksliste les exemples et vos projets ;sandbox_open_booken ouvre un ({ "kind": "sample", "id": "postext-guide", "language": "es" }) ;sandbox_save_bookavecaction: "copy_current"garde le livre à l’écran comme votre propre projet,new_blanken commence un vide. -
Exporter.
sandbox_exportécritpdf,epub,postext,docx,markdownouconfig. Par défaut, le navigateur télécharge le fichier ; avecdeliver: "data", un PDF ou un EPUB revient à l’agent encodé en base64 :{ "format": "pdf", "scope": "book", "deliver": "data" } -
Importer un fichier
.postextavecsandbox_import_book(inspect: trueindique quelles langues il contient sans l’importer). -
Faire entrer un manuscrit Word avec
sandbox_import_word. Lancez-le d’abord avecdryRun: true: il ne change rien et répond avec le rapport de qualité, chaque style Word avec ce qu’il deviendrait, et les chapitres et ressources qu’il créerait. Corrigez ensuite la correspondance et lancez-le pour de bon :{ "file": { "url": "https://example.org/manuscript.docx" }, "destination": "book", "mapping": { "paragraphs": { "Epigraph": { "kind": "quote" }, "Chapter Title": { "kind": "chapter" } } }, "saveTemplateAs": "My publisher" }sandbox_word_templatesliste, lit, enregistre et supprime les correspondances enregistrées, que l’export Word utilise aussi.
#Questions et messages
Quand un lien ouvre un livre dont vous avez déjà votre propre version, le Sandbox
demande s’il faut remplacer votre copie, et sandbox_get_state le signale par
question avec ready: false. sandbox_answer y répond : replaceCopy: false garde la vôtre, true la remplace par le livre publié et supprime
votre copie. dismissNotice: true efface le message du panneau Livres.
#Trois sessions du début à la fin
« Grossissez un peu le texte, mais gardez le livre sous les 220 pages. »
sandbox_get_state (212 pages) → sandbox_set_config avec
bodyText.fontSize à "10.5pt" (219 pages) → sandbox_render_page sur une
page dense pour en juger → sandbox_get_warnings avec category: "typesetting" pour repérer de nouvelles veuves → si quelque chose a mal tourné, sandbox_set_config
de nouveau avec les valeurs from de la première réponse.
« Corrigez ce que les vérifications ont trouvé dans le chapitre 4. » sandbox_get_warnings avec
chapter: 4 → pour chaque avertissement, sandbox_read_text autour de sa line et
sandbox_render_page de sa page → sandbox_edit_text ou
sandbox_set_config → de nouveau sandbox_get_warnings, jusqu’à ce qu’il revienne vide.
« Faites un livre à partir de ce fichier Word et donnez-moi le PDF. » sandbox_save_book
avec action: "new_blank" → sandbox_import_word avec dryRun: true →
mapping corrigé, puis l’import réel avec destination: "book" →
sandbox_get_warnings avec scope: "book" → sandbox_export avec format: "pdf" et scope: "book".
#Ce qui demande votre accord
Six outils font ce qui ne peut pas être défait et sont marqués comme ayant des conséquences
(consequentialHint), pour que le navigateur puisse vous demander votre accord avant leur exécution :
sandbox_remove_chapter, sandbox_delete_resource, sandbox_delete_book,
sandbox_reset_to_original, sandbox_import_word (il peut remplacer tout le
livre) et sandbox_answer (il peut supprimer votre copie d’un livre). En cas de doute, demandez
d’abord à l’agent d’exporter une copie .postext.
Les outils qui ne font que lire sont marqués readOnlyHint, et ceux dont la réponse contient
du texte que la page n’a pas écrit (le texte même du livre, un fichier récupéré) sont marqués
untrustedContentHint, pour que le navigateur puisse empêcher que ce texte soit pris pour
des instructions.
#Limites
- Tout reste dans votre navigateur. Les outils n’atteignent rien que le Sandbox
lui-même n’atteigne pas : vos livres sont dans le stockage de ce navigateur, et un fichier fourni
par
urlest récupéré par la page, si bien que son serveur doit l’autoriser (CORS). Une URLdata:ou dubase64fonctionne toujours. - Un long travail prend du temps. Un outil attend la mise en page avant de répondre ;
wait: falserépond immédiatement. Le PDF ou l’EPUB d’un long livre prend plusieurs minutes. - Ce que
sandbox_undo_textannule : les modifications de texte des outils (un appel à la fois) et les modifications faites sur les aperçus. Pas ce que vous tapez dans l’éditeur du panneau Texte (sa propre annulation s’en charge), ni les chapitres ajoutés ou déplacés, ni les modifications de la maquette et des ressources : pour celles-ci, il y a lefromde chaque réponse. La liste est perdue quand la page est rechargée. - Le livre à l’écran. Les outils agissent sur le livre ouvert. Seuls
sandbox_exportd’un fichier.postext,sandbox_save_bookavecduplicateetsandbox_reset_to_originalavecsampleatteignent un autre livre sans l’ouvrir.
#Les outils du site
Sur chaque page de postext.dev, Sandbox compris :
site_get_context: la page à l’écran, sa langue et son thème, les sections et toutes les pages de la documentation.site_search: la documentation et le livre de recettes, par mots, noms de réglages (bodyText.avoidOrphans) ou directives (::resource).site_read_page: une page du site en Markdown, sans quitter la page à l’écran.site_open_page: afficher une page, avec#headingpour arriver sur une section.site_list_recipesetsite_open_recipe_in_sandbox: trouver une recette du livre de recettes et l’ouvrir dans le Sandbox comme un livre modifiable.site_lookup_term: un terme du glossaire (veuve, crénage, kinsoku…).site_set_preferences: la langue et le thème du site.
Un agent qui démarre sur la page d’accueil peut donc chercher dans le livre de recettes, ouvrir
une recette dans le Sandbox et continuer là-bas avec les outils sandbox_*.
#Tous les outils
Regroupés comme le Sandbox les enregistre. La description complète et le schéma de
chacun s’obtiennent avec postextWebMcp.listTools().
- Ce qui est ouvert :
sandbox_get_state. - Les pages :
sandbox_render_page,sandbox_inspect_pages,sandbox_inspect_point. - Le texte :
sandbox_read_text,sandbox_write_text,sandbox_edit_text,sandbox_undo_text,sandbox_select_text,sandbox_search_text,sandbox_manage_chapters,sandbox_remove_chapter. - La maquette :
sandbox_get_config,sandbox_set_config,sandbox_find_setting,sandbox_reset_to_original. - L’affichage :
sandbox_set_view,sandbox_go_to_page,sandbox_run_viewer. - Ressources et polices :
sandbox_list_resources,sandbox_save_resource,sandbox_delete_resource,sandbox_list_fonts,sandbox_save_font. - Bande dessinée :
sandbox_inspect_comic,sandbox_edit_comic. - Livres et fichiers :
sandbox_list_books,sandbox_open_book,sandbox_save_book,sandbox_delete_book,sandbox_import_book,sandbox_export. - Word :
sandbox_import_word,sandbox_word_templates. - Questions :
sandbox_answer. - Les vérifications :
sandbox_get_warnings.
#Quand vous intégrez le Sandbox
<PostextSandbox> enregistre les outils tant qu’il est monté ; webmcp={false}
les laisse de côté (voir Props). Une page hôte peut ajouter
ses propres outils via le même module :
import { registerWebMcpTools } from 'postext-sandbox/webmcp';
const controller = new AbortController();
registerWebMcpTools([
{
name: 'shop_list_titles',
description: 'The titles of this shop, with the id of the Postext project of each one.',
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
annotations: { readOnlyHint: true },
execute: async () => ({ titles: await fetchTitles() }),
},
], controller.signal);
// controller.abort() takes them backIls sont enregistrés auprès de WebMCP là où le navigateur le propose, et toujours sur
window.postextWebMcp, avec leurs arguments vérifiés par rapport à inputSchema.