margin-demo cómo funciona

← Volver al editor

Qué es esto

margin-demo es una prueba concreta de una idea: que un agente de IA use herramientas ejecutables publicadas en un sitio, sin instalar un cliente MCP — ni configuración, ni proceso local, ni handshake de protocolo. Todo el sitio (editor, tools, manifiesto) es HTML/JS estático servido por GitHub Pages, sin backend, sin base de datos.

La arquitectura: mcpwasm sin cliente

Esto usa el patrón llms-txt-skills: un origen publica un manifiesto (/llms.txt) que declara sus tools, la ruta de su código, y el hash SHA-256 de ese código. Un "skill" es literalmente un archivo .js que llama registerTool({ name, description, inputSchema, handler }) por cada tool que expone.

El loader (browser-eval-client.js) hace todo el trabajo, en 4 pasos, sin ningún cliente MCP de por medio:

  1. Hace fetch a /llms.txt y lee el manifiesto.
  2. Hace fetch al tool.js que el manifiesto declara.
  3. Calcula su SHA-256 y lo compara contra el hash pinneado en el manifiesto — si no coincide, se niega a ejecutar.
  4. Corre el código dentro de un Web Worker con fetch/XMLHttpRequest/WebSocket deshabilitados a mano — el código de la tool no tiene forma de alcanzar la red salvo un canal explícito y acotado (host.fetchOrigin, no usado por este skill en particular).

Una vez cargado, llamar una tool es una llamada local (skill.call('create_document', {...})) — sin protocolo, sin JSON-RPC, sin tools/list. El código corre en tu propio proceso (o en el del agente), no en un servidor.

Las tools de este skill

Definidas en tool.js, sin ninguna dependencia externa (ni siquiera atob/TextEncoder — el codec base64url+UTF-8 está escrito a mano para correr igual en cualquier sandbox):

No hay una tercera tool de "guardar". El documento nunca se persiste en ningún lado — la URL es el documento. Abrirla en cualquier navegador, en cualquier momento, reconstruye el contenido exacto, client-side, sin pedirle nada a ningún servidor.

El problema real que apareció: descubrimiento

Publicar el skill correctamente no alcanza para que un agente lo encuentre. En la primera prueba, le dimos la URL a Codex sin ninguna pista — la trató como una página web cualquiera. Recién al tercer mensaje, empujándolo explícitamente, hizo algo parecido a "usar el sitio" — y lo hizo manejando el DOM como un humano (tipeando en el textarea), no llamando a las tools reales.

Se agregaron tres capas para resolverlo, cada una más explícita que la anterior:

  1. Una sección visible en la propia página ("🤖 Para agentes") con instrucciones y el snippet de código.
  2. Un archivo /agent-setup/prompt.md — mismo patrón que usa Cloudflare en developers.cloudflare.com: instrucciones imperativas, pensadas para que un agente las ejecute, no las resuma.
  3. Un botón "Copiar para agente" que copia al portapapeles: "Fetch and execute the appropriate instructions to use margin-demo's tools from .../agent-setup/prompt.md" — el humano lo pega como su propio mensaje.

Con las tres capas puestas, se volvió a probar con Codex: a la primera, sin pistas adicionales, entendió el mecanismo, llamó create_document, y generó un documento real. En una prueba posterior le pedimos que editara ese documento — decodificó la URL con decode_document, modificó solo lo pedido, y re-codificó con create_document: un ciclo completo de lectura-modificación-escritura usando las tools, sin backend, sin cliente MCP, iniciado con un prompt de una línea.

Lo que esto no resuelve

Recursos