Capítulo 23 · Parte III · La práctica
WebMCP: un agente trabajando en el Sandbox
Lo que un agente de IA en el navegador puede hacer con el Sandbox mediante sus 36 herramientas WebMCP (mirar las páginas, cambiar cualquier ajuste, editar el texto, añadir imágenes, tablas y fuentes, pasar la revisión, exportar) y cómo se llama cada una, con argumentos y respuestas reales
En pocas palabras
Esta página es para quien quiere que un asistente de inteligencia artificial trabaje por él en un libro del Sandbox. Mientras el Sandbox está abierto, le da al asistente un juego de herramientas: mirar cualquier página, cambiar el diseño, editar el texto, añadir imágenes y tablas, encontrar problemas y guardar archivos. Tú se lo pides con tus palabras, por ejemplo «sube un poco la letra y comprueba que el libro sigue cabiendo en 40 páginas», y el asistente usa las herramientas y te enseña las páginas. Todo se queda en tu navegador. La página explica cómo conectar un asistente, qué puede hacer y cómo se llama cada herramienta.
Un agente en tu navegador trabaja sobre el libro abierto en el Sandbox: mira las páginas, las cambia y vuelve a mirarlas.
El Sandbox da a un agente sus propias herramientas mediante
WebMCP, un borrador de estándar
web que permite a una página ofrecer herramientas al modelo de IA con el que
habla el navegador. Con ellas el agente no va pulsando por la interfaz: lee el
libro, pide una imagen de la página 12, pone bodyText.fontSize a 10,5 pt, ve
que el capítulo ha pasado de 18 a 19 páginas y lo deja como estaba. Hace lo
mismo que tú haces a ojo, con tu libro y en tu navegador.
Hay 36 herramientas cuyo nombre empieza por sandbox_, registradas mientras el
Sandbox está en pantalla, y 8 herramientas del sitio, site_*, en todas las
páginas de postext.dev. Esta página las ordena según lo que le pedirías a un
agente y da la llamada de cada una.
#Conectar un agente
#En un navegador con WebMCP
Las herramientas se registran en document.modelContext al montarse el Sandbox
y se retiran al salir de él. Un agente al que el navegador entrega las
herramientas de la página las encuentra ahí. En Postext no hay nada que
instalar ni configurar.
WebMCP sigue siendo un borrador. Chrome lo ofrece como prueba de origen y tras
la opción chrome://flags/#enable-webmcp-testing. Las herramientas dependen de
la página: en la portada o en la documentación el agente tiene las herramientas
site_*; cuando el Sandbox está en pantalla aparecen además las 36
herramientas sandbox_*.
#En cualquier otro navegador: window.postextWebMcp
La página pone también las mismas herramientas en window.postextWebMcp, haya
WebMCP o no. Las puede usar cualquier agente capaz de ejecutar código en la
página: una herramienta de automatización como Puppeteer o Playwright, un
servidor MCP que maneja el navegador y evalúa código (Chrome DevTools MCP), una
extensión del navegador o tú mismo, en la consola de desarrollo:
// Qué hay en esta página
postextWebMcp.listTools().map((t) => t.name);
// Ejecutar una herramienta: el nombre y un objeto con sus argumentos
await postextWebMcp.executeTool('sandbox_get_state', {});
await postextWebMcp.executeTool('sandbox_set_config', {
changes: [{ path: 'bodyText.fontSize', value: '10.5pt' }],
});Lo mismo desde un script de Puppeteer, que guarda una página como imagen:
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/es/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 perfil de navegador nuevo tiene su propio almacenamiento, así que empieza con las muestras y no con tus proyectos. Para trabajar con tus libros, usa el navegador en el que los creaste.
#Cómo es cada respuesta
Una herramienta responde con un objeto JSON: ok: true y lo que se pidió, o
ok: false y un error que dice qué estaba mal y qué pedir en su lugar:
{
"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."
}Los argumentos se comprueban contra el esquema de la herramienta antes de
ejecutar nada, de modo que un parámetro mal escrito se rechaza con la lista de
los correctos. Una herramienta que devuelve imágenes (sandbox_render_page)
responde con la forma de MCP, { content: [...] }: una parte de texto con un
JSON que describe las páginas y después una parte de imagen por página,
codificada en base64.
#El ciclo de trabajo
Toda herramienta que cambia el libro espera a que la maquetación se ponga al día antes de responder, y dice cuántas páginas ocupa cada capítulo. Así, la siguiente mirada es siempre a las páginas nuevas, y el agente puede trabajar como lo hace un diseñador:
- Ver cómo está todo:
sandbox_get_stateda el libro, sus capítulos con sus páginas, el capítulo y la página en pantalla y el panel abierto. - Mirar:
sandbox_render_pagepinta una página,sandbox_inspect_pagesla describe como datos ysandbox_get_warningsenumera lo que ha encontrado la revisión. - Cambiar:
sandbox_set_config,sandbox_edit_text,sandbox_save_resource… - Volver a mirar, y quedarse con el cambio o deshacerlo.
La página se maqueta y se pinta para la herramienta sea cual sea el visor en pantalla, así que el agente puede mirar el capítulo 7 mientras tú lees el 2.
#Qué puedes pedir y cómo se hace
#Saber qué está abierto
// sandbox_get_state
{}{
"ok": true,
"ready": true,
"book": { "kind": "sample", "id": "postext-guide", "name": "Guía" },
"pages": 3,
"chapters": [
{ "chapter": 1, "id": "a", "title": "Apertura", "onScreen": true, "words": 1007, "pages": 2 },
{ "chapter": 2, "id": "b", "title": "Segundo", "words": 101, "pages": 1 }
],
"view": { "viewer": "canvas", "panel": "none", "scope": "chapter", "chapter": 1 },
"resources": 0,
"warnings": 0
}ready: false viene con waitingFor, que dice por qué (un libro que aún se
está cargando). question y notice aparecen cuando el Sandbox está esperando
algo de ti; consulta Preguntas y avisos.
Toda herramienta que recibe un chapter acepta su posición en el libro
(empezando por 1), su título o su id. Si se omite, es el capítulo en pantalla.
#Mirar una página
Una imagen. «Enséñame el arranque del capítulo 3», «¿cómo queda la doble página 24-25?»:
// sandbox_render_page: una doble página, 1200 px de ancho por página
{ "chapter": 3, "page": 24, "count": 2, "width": 1200 }page es el número impreso en la página; position es el lugar de la página
entre las del capítulo (empezando por 1), para las páginas sin número. Sin
ninguno de los dos, es la página en pantalla. crop amplía una parte de la
página, en fracciones de su ancho y su alto desde la esquina superior
izquierda, para juzgar de cerca la letra y los espacios:
// sandbox_render_page: el cuarto inferior derecho, ampliado
{ "chapter": 3, "page": 24, "crop": { "x": 0.5, "y": 0.5, "width": 0.5, "height": 0.5 }, "width": 1600 }printPreview: true pinta la prueba en pantalla del perfil de impresión con
las guías de corte, sangre y zona de seguridad; trimmed: true deja fuera el
margen con las marcas de corte.
La misma página como datos. «¿Qué líneas de esta página quedan flojas?», «¿está llena la segunda columna?»:
// sandbox_inspect_pages: sin página, una línea por cada página del capítulo
{ "chapter": 1 }{
"chapter": 1, "title": "Apertura", "chapterPages": 2, "converged": true,
"pages": [
{ "position": 1, "label": "1", "role": "opener", "blank": false, "lines": 45, "figures": 0, "starts": "Apertura" },
{ "position": 2, "label": "2", "role": "body", "blank": false, "lines": 37, "figures": 0, "starts": "décadas. La tipografía impresa pasó cinco siglos…" }
]
}Con page o position enumera todos los bloques de la página: su tipo, su
columna, su texto, su número de líneas, las líneas que terminan en guion y las
líneas justificadas flojas con el ancho de sus espacios, su caja en la página,
y además cuánto se llena cada columna (fill: 0.99).
Qué hay en un punto. Cuando el agente ve algo en una imagen, pregunta qué es con las mismas fracciones que usó para el recorte:
// sandbox_inspect_point
{ "chapter": 3, "page": 24, "x": 0.71, "y": 0.42 }La respuesta da el bloque, la línea y la columna del Markdown fuente en ese
punto (y la palabra), un enlace y la página a la que lleva, o la celda de
tabla o el pie de un recurso. Con select: true hace además lo que hace un
clic: se abre el panel Texto con el cursor en ese lugar (word: true
selecciona la palabra y to selecciona hasta un segundo punto).
#Cambiar el diseño
Cualquier ajuste de la configuración se puede cambiar por su ruta. Un agente casi nunca conoce la ruta de entrada, así que la busca:
// 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 lee un ajuste o una sección entera: set es lo que guarda
el libro y effective lo que resulta al completar con los valores por
defecto, que muestra también todos los ajustes que tiene la sección.
// sandbox_get_config
{ "path": "headings.levels[level=2]" }Las rutas nombran un elemento de una lista por lo que lo distingue:
headings.levels[level=2].fontSize, header.elements[id=titleOdd].italic,
calloutStyles[id=note].title. Después, sandbox_set_config cambia tantos
ajustes como quieras en una sola llamada:
// 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 }
]
}Una longitud es "2.5cm", { "value": 2.5, "unit": "cm" } o un número en la
unidad del ajuste; un color es "#1f3a5f". Un valor null quita el ajuste y
vuelve el valor del diseño. La respuesta sirve para juzgar el cambio y para
deshacerlo:
{
"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": "Apertura", "pages": 19, "pagesBefore": 18 }]
}from es el valor guardado antes (aquí null: el libro no lo fijaba), así que
la misma llamada con from como valor lo deshace. followed enumera los
ajustes que dependen de este y se han movido con él. Aparece una note cuando
el motor ha resuelto algo distinto de lo pedido (un límite, un ajuste que
depende de otro), y un valor con una forma equivocada, o una configuración que
el motor no puede resolver, se rechaza sin cambiar nada.
Para cambios más grandes, patch combina un objeto con la configuración (los
objetos se combinan, null quita y las listas se sustituyen enteras) y
replace pone una configuración completa en lugar de la del libro, como la de
un postext-config.json exportado. sandbox_reset_to_original con
part: "config" restaura el diseño con el que empezó el libro.
Las fuentes también son ajustes: sandbox_list_fonts con search: "Garamond"
busca familias en el catálogo abierto, y escribir el nombre en un ajuste
fontFamily la carga.
#Editar el texto
El texto de cada capítulo es Markdown con las extensiones de Postext (consulta Formato del documento). El agente lo lee con números de línea, localiza un pasaje y sustituye pasajes exactos:
// sandbox_read_text: las líneas 40 a 80 del capítulo 2
{ "chapter": 2, "fromLine": 40, "toLine": 80 }// sandbox_search_text: dónde aparece un pasaje y en qué página
{ "query": "retícula base", "pages": true }// sandbox_edit_text
{
"chapter": 2,
"edits": [
{ "find": "Las últimas palabras de la apertura.", "replace": "Las palabras con que se cierra la apertura." },
{ "find": "obscuro", "replace": "oscuro", "all": true }
]
}Cada find tiene que coincidir exactamente con el texto fuente y aparecer una
sola vez, salvo que se indique all. O se aplican todas las ediciones o
ninguna: un pasaje que no está se rechaza con el consejo de volver a leer el
capítulo. La llamada entera es un solo paso para sandbox_undo_text, que la
deshace (redo: true la rehace). sandbox_write_text sustituye un capítulo
entero, a partir de markdown o de un archivo .md.
Para enseñarte un lugar del texto, sandbox_select_text abre el panel Texto
con ese pasaje seleccionado (por text, line u offset), igual que un clic
en un hallazgo del panel Revisión.
#Organizar los capítulos
sandbox_manage_chapters añade, renombra, mueve, divide, fusiona y muestra
capítulos:
// añadir un capítulo en tercer lugar
{ "action": "add", "title": "Epílogo", "markdown": "# Epílogo\n\nFin.\n", "position": 3 }
// dividir un capítulo donde empieza un pasaje
{ "action": "split", "chapter": "Apertura", "before": "## Segunda parte" }
// un capítulo por cada título de nivel 1
{ "action": "split_at_headings", "chapter": 1 }sandbox_remove_chapter borra uno, y eso no se puede deshacer.
#Añadir imágenes, tablas, vídeos y fuentes
sandbox_save_resource añade un recurso o cambia uno, como el panel Recursos.
Un archivo llega por url (una dirección https: que la página pueda
descargar, o una URL data:) o en base64:
// una imagen con su pie y su texto alternativo
{
"id": "harbour",
"image": { "url": "https://example.org/harbour.jpg" },
"caption": "El puerto al amanecer",
"altText": "Barcas de pesca amarradas a un muelle de piedra, con niebla sobre el agua",
"placement": { "position": "top", "span": "page" }
}// una tabla a partir de filas de texto; la primera fila es la cabecera
{
"id": "prices",
"caption": "Precios en 1850",
"table": { "rows": [["Artículo", "Precio"], ["Pan", "2 d"], ["Tinta", "6 d"]], "columnWidths": [2, 1] }
}// un vídeo de YouTube: su portada, el tamaño del fotograma y el título se descargan
{ "id": "interview", "video": { "url": "https://www.youtube.com/watch?v=…" }, "caption": "El autor trabajando" }La respuesta da el registro guardado y la línea que lo coloca,
::resource{id="prices"}, que el agente escribe después en el texto con
sandbox_edit_text. Sobre un id que ya existe, la llamada cambia solo lo que
indica: un pie, las celdas de una tabla, la colocación, la zona segura de una
imagen. newId renombra un recurso y, por defecto, todas sus referencias en
el libro. sandbox_list_resources los enumera y, con un id, da uno completo
(las celdas de una tabla con su formato, el código de un SVG).
Las fuentes que se suben al libro pasan por sandbox_save_font:
{ "action": "add", "family": "My Serif", "weight": 700, "style": "italic", "file": { "url": "https://example.org/MySerif-BoldItalic.woff2" } }#Revisar el libro
// sandbox_get_warnings: todos los capítulos
{ "scope": "book" }La respuesta es lo que dice el panel Revisión, para cualquier capítulo o para el libro entero, esté lo que esté en pantalla: fuentes e imágenes que faltan, marcado que el motor no ha podido leer, elementos de diseño que no caben, texto demasiado pálido para su fondo, líneas flojas, viudas, cajas que desbordan y el preflight de impresión. Cada aviso trae su categoría, su capítulo, su línea y sus desplazamientos, su página y el ajuste o el recurso que nombra:
{
"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."
}
]
}Desde un aviso el agente puede ir a su lugar (sandbox_select_text con
offset y toOffset, o sandbox_go_to_page), mirar la página y cambiar el
texto o el ajuste. category acota la lista; en un libro largo,
scope: "book" maqueta todos los capítulos y tarda un rato.
#Mostrar al lector
Lo que cambia el agente, lo ves tú. Para señalarte algo:
// sandbox_set_view: el Canvas con páginas enfrentadas y las líneas flojas resaltadas
{ "viewer": "canvas", "pages": "spread", "fit": "height", "guides": { "looseLines": true, "baselineGrid": true } }// sandbox_go_to_page: donde está colocada una figura
{ "anchor": "harbour" }sandbox_set_view elige además el visor (canvas, pdf, folio, html,
epub), el panel lateral, capítulo o libro entero, el zoom, el tamaño de
letra del lector, la vista previa de impresión y el grupo del panel Diseño.
sandbox_go_to_page pasa páginas por step, page, position, un pasaje
text, un anchor o una entrada contents de un EPUB. sandbox_run_viewer
pulsa un botón de la barra de herramientas: regenerate vuelve a escribir el
PDF o el EPUB y espera a que termine, print abre el diálogo de impresión
para que lo confirmes tú y play_video reproduce un vídeo de una página.
#Páginas de cómic
sandbox_inspect_comic da las viñetas, las líneas de división y los bocadillos
de una página de cómic con sus posiciones; sandbox_edit_comic hace las
ediciones que una persona hace con el puntero y las escribe en el texto
fuente:
// mover el centro de un bocadillo a un punto de la imagen de su viñeta, en porcentaje
{ "comic": 1, "action": "move_balloon", "balloon": 2, "at": { "x": 30, "y": 18 } }
// mover la primera línea de división al 45 % de su celda
{ "comic": 1, "action": "move_splitter", "splitter": 1, "start": 45 }La respuesta avisa cuando un bocadillo cae sobre una cara o se sale de su viñeta. El formato está en Cómics.
#Libros, archivos y Word
-
Abrir y guardar libros.
sandbox_list_booksenumera las muestras y tus proyectos;sandbox_open_bookabre uno ({ "kind": "sample", "id": "postext-guide", "language": "es" });sandbox_save_bookconaction: "copy_current"guarda el libro en pantalla como proyecto tuyo, ynew_blankempieza uno vacío. -
Exportar.
sandbox_exportescribepdf,epub,postext,docx,markdownoconfig. Por defecto el navegador descarga el archivo; condeliver: "data", un PDF o un EPUB vuelve al agente codificado en base64:{ "format": "pdf", "scope": "book", "deliver": "data" } -
Importar un archivo
.postextconsandbox_import_book(inspect: truedice qué idiomas trae sin importarlo). -
Traer un manuscrito de Word con
sandbox_import_word. Ejecútalo primero condryRun: true: no cambia nada y responde con el informe de calidad, cada estilo de Word con aquello en lo que se convertiría y los capítulos y recursos que crearía. Después corrige la asignación y ejecútalo de verdad:{ "file": { "url": "https://example.org/manuscript.docx" }, "destination": "book", "mapping": { "paragraphs": { "Epígrafe": { "kind": "quote" }, "Título de capítulo": { "kind": "chapter" } } }, "saveTemplateAs": "Mi editorial" }sandbox_word_templatesenumera, lee, guarda y borra las asignaciones guardadas, que también usa la exportación a Word.
#Preguntas y avisos
Cuando un enlace abre un libro del que ya tienes tu propia versión, el Sandbox
pregunta si sustituir tu copia, y sandbox_get_state lo indica como
question con ready: false. sandbox_answer responde: replaceCopy: false
conserva la tuya y true la sustituye por el libro publicado y borra tu copia.
dismissNotice: true cierra el mensaje del panel Libros.
#Tres sesiones de principio a fin
«Sube un poco la letra, pero que el libro no pase de 220 páginas.»
sandbox_get_state (212 páginas) → sandbox_set_config con
bodyText.fontSize a "10.5pt" (219 páginas) → sandbox_render_page de una
página densa para juzgarla → sandbox_get_warnings con
category: "typesetting" por si hay viudas nuevas → si algo ha salido mal,
sandbox_set_config otra vez con los valores from de la primera respuesta.
«Corrige lo que ha encontrado la revisión en el capítulo 4.»
sandbox_get_warnings con chapter: 4 → para cada aviso, sandbox_read_text
alrededor de su line y sandbox_render_page de su page →
sandbox_edit_text o sandbox_set_config → sandbox_get_warnings de nuevo,
hasta que vuelva vacío.
«Haz un libro con este archivo de Word y dame el PDF.» sandbox_save_book
con action: "new_blank" → sandbox_import_word con dryRun: true →
mapping corregido y la importación real con destination: "book" →
sandbox_get_warnings con scope: "book" → sandbox_export con
format: "pdf" y scope: "book".
#Qué pide tu consentimiento
Seis herramientas hacen cosas que no se pueden deshacer y van marcadas como
consecuentes (consequentialHint), para que el navegador pueda preguntarte
antes de ejecutarlas: sandbox_remove_chapter, sandbox_delete_resource,
sandbox_delete_book, sandbox_reset_to_original, sandbox_import_word
(puede sustituir el libro entero) y sandbox_answer (puede borrar tu copia de
un libro). Si tienes dudas, pide antes al agente que exporte una copia
.postext.
Las herramientas que solo leen van marcadas con readOnlyHint, y las que
devuelven texto que no ha escrito la página (el propio texto del libro, un
archivo descargado), con untrustedContentHint, para que el navegador pueda
evitar que ese texto se tome por instrucciones.
#Límites
- Todo se queda en tu navegador. Las herramientas no alcanzan nada que no
alcance el propio Sandbox: tus libros están en el almacenamiento de este
navegador, y un archivo indicado por
urllo descarga la página, así que su servidor tiene que permitirlo (CORS). Una URLdata:obase64funciona siempre. - El trabajo largo lleva tiempo. Una herramienta espera a la maquetación
antes de responder;
wait: falseresponde enseguida. El PDF o el EPUB de un libro largo tarda minutos. - Lo que deshace
sandbox_undo_text: las ediciones de texto de las herramientas (una llamada cada vez) y las ediciones hechas sobre las vistas previas. No deshace lo que escribes en el editor del panel Texto (eso lo hace su propio deshacer), los capítulos añadidos o movidos ni los cambios en el diseño y en los recursos: para eso está elfromde cada respuesta. La lista se pierde al recargar la página. - El libro en pantalla. Las herramientas trabajan sobre el libro abierto.
Solo
sandbox_exportde un archivo.postext,sandbox_save_bookconduplicateysandbox_reset_to_originalconsamplellegan a otro libro sin abrirlo.
#Las herramientas del sitio
En todas las páginas de postext.dev, también en el Sandbox:
site_get_context: la página en pantalla, su idioma y su tema, las secciones y todas las páginas de la documentación.site_search: la documentación y el Recetario, por palabras, por nombres de ajustes (bodyText.avoidOrphans) o por directivas (::resource).site_read_page: una página del sitio como Markdown, sin salir de la página en pantalla.site_open_page: mostrar una página, con#títulopara llegar a una sección.site_list_recipesysite_open_recipe_in_sandbox: encontrar una receta del Recetario y abrirla en el Sandbox como un libro que puedes editar.site_lookup_term: un término del glosario (viuda, kerning, kinsoku…).site_set_preferences: el idioma y el tema del sitio.
Un agente que empieza en la portada puede, por tanto, buscar en el Recetario,
abrir una receta en el Sandbox y seguir allí con las herramientas sandbox_*.
#Todas las herramientas
Agrupadas como las registra el Sandbox. La descripción completa y el esquema
de cada una se obtienen con postextWebMcp.listTools().
- Lo que está abierto:
sandbox_get_state. - Las páginas:
sandbox_render_page,sandbox_inspect_pages,sandbox_inspect_point. - El texto:
sandbox_read_text,sandbox_write_text,sandbox_edit_text,sandbox_undo_text,sandbox_select_text,sandbox_search_text,sandbox_manage_chapters,sandbox_remove_chapter. - El diseño:
sandbox_get_config,sandbox_set_config,sandbox_find_setting,sandbox_reset_to_original. - Cómo se muestra:
sandbox_set_view,sandbox_go_to_page,sandbox_run_viewer. - Recursos y fuentes:
sandbox_list_resources,sandbox_save_resource,sandbox_delete_resource,sandbox_list_fonts,sandbox_save_font. - Cómics:
sandbox_inspect_comic,sandbox_edit_comic. - Libros y archivos:
sandbox_list_books,sandbox_open_book,sandbox_save_book,sandbox_delete_book,sandbox_import_book,sandbox_export. - Word:
sandbox_import_word,sandbox_word_templates. - Preguntas:
sandbox_answer. - La revisión:
sandbox_get_warnings.
#Al incrustar el Sandbox
<PostextSandbox> registra las herramientas mientras está montado;
webmcp={false} las deja fuera (consulta Props).
Una página anfitriona puede añadir herramientas propias con el mismo módulo:
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() las retiraSe registran en WebMCP donde el navegador lo ofrece y siempre en
window.postextWebMcp, con sus argumentos comprobados contra inputSchema.