En junio de 2026 convertimos dribba.com en una de las primeras webs de España operables por agentes de IA vía WebMCP. No como experimento de laboratorio: en producción, con leads reales entrando por ella. Este es el caso técnico completo — decisiones, código, errores incluidos — para que puedas replicarlo en tu stack.
Si el contexto de qué es WebMCP te pilla de nuevas, empieza por nuestra introducción al estándar y vuelve. Te esperamos.
El punto de partida
dribba.com ya tenía la capa de lectura resuelta: llms.txt y llms-full.txt publicados, versiones markdown de cada página servidas por content negotiation (cabecera Accept: text/markdown), schema.org en JSON-LD y política explícita para crawlers de IA. Lo que faltaba era la capa de acción: que un agente pudiera hacer cosas, no solo leer.
Stack: Next.js 16 con App Router, APIs propias en route handlers, despliegue en Cloud Run. Lo que sigue aplica casi literal a cualquier React moderno, y conceptualmente a cualquier stack.
Decisión 1: qué herramientas exponer
La tentación es exponerlo todo. La decisión correcta es empezar por el embudo de valor real. Elegimos cuatro:
list_services— catálogo de servicios con descripciones y URLs. Lectura pura, riesgo cero.get_project_estimate— estimación orientativa de presupuesto a partir de una descripción del proyecto. Envuelve la API de nuestro estimador (que ya existía).book_meeting— devuelve el enlace de Calendly. Trivial, pero es la conversión que más nos importa.submit_contact_request— deja un lead real. La única herramienta de escritura, y la que más diseño necesitó.
El criterio: cada herramienta mapea a algo que un visitante humano ya puede hacer. Ninguna da al agente capacidades nuevas — le da una interfaz mejor a las existentes.
Decisión 2: el registro, defensivo
El componente que registra las herramientas es un client component montado en el layout raíz. Renderiza null; su único trabajo es el registro. Las decisiones defensivas:
// Chrome 150+ expone la API en document; el origin trial de
// Chrome 149 usaba navigator. Soportamos ambas superficies.
const mc = document.modelContext ?? navigator.modelContext;
if (!mc) return; // navegador sin WebMCP — no-op silencioso
try {
if (typeof mc.registerTool === "function") {
for (const tool of tools) mc.registerTool(tool);
} else if (typeof mc.provideContext === "function") {
mc.provideContext({ tools }); // forma anterior del explainer
}
} catch (err) {
// API experimental: el registro JAMÁS debe romper la página
console.warn("[webmcp] registration failed:", err);
}
Feature detection en ambas superficies, soporte de las dos formas de la API (la especificación se mueve rápido) y try/catch global: si algo cambia en Chrome mañana, lo peor que pasa es que las herramientas no se registran. La web nunca se entera.
Decisión 3: el agente es un cliente no confiable (como todos)
Aquí está el 80% del valor de diseño. Cada execute llama a nuestras APIs por la puerta normal: mismo endpoint, misma validación de origen, mismo rate limiting que el formulario web. El agente no tiene carril VIP.
El caso interesante fue submit_contact_request, porque nuestra API de contacto tiene defensas anti-spam: un honeypot y una regla que descarta silenciosamente envíos hechos a menos de 3 segundos de cargar el formulario (ningún humano rellena 4 campos en 3 segundos). Un agente sí puede — legítimamente. ¿Saltarse la regla? No: la herramienta reporta el tiempo real desde la carga de página y, si el agente fue más rápido que el umbral, espera la diferencia. La defensa anti-bots tontos sigue intacta; el cliente legítimo no choca con ella.
Dos decisiones más en esa herramienta:
- Confirmación humana explícita. La descripción de la herramienta instruye al agente: "solo llama a esto después de que el usuario haya confirmado nombre, email y mensaje exactos". La acción de escritura queda gated por la conversación humano-agente.
- Atribución desde el día uno. Los leads entran con
source: "webmcp-agent". Cuando dentro de seis meses alguien pregunte "¿esto del WebMCP nos trae negocio?", habrá un número, no una opinión.
Decisión 4: el origin trial
Para que la API exista en los Chrome de visitantes reales, el origen debe estar registrado en el origin trial de Chrome y servir el token. Dos detalles que nos costaron tiempo real:
El token tiene variantes. La primera vez lo generamos con "third-party matching" activado — esa variante está pensada para scripts de terceros y puede no validar servida en cabecera first-party. Regenerado sin esa opción, listo. Revisa los flags antes de copiar el token.
Cuidado con dónde lees la variable de entorno. En Next.js, las cabeceras declaradas en next.config.ts se evalúan en build time; en Cloud Run, las variables de entorno llegan en runtime. Si sirves el token desde la config, no llegará nunca. Lo movimos al middleware, que se ejecuta por petición:
const otToken = process.env.ORIGIN_TRIAL_WEBMCP;
if (otToken) res.headers.append("Origin-Trial", otToken);
Y apunta la caducidad. Los tokens expiran con el ciclo del trial. El nuestro muere el 17 de noviembre de 2026 y hay un recordatorio en el calendario. Un token caducado falla en silencio absoluto — la clase de bug que nadie detecta hasta que alguien pregunta por qué ya no funciona la demo.
Lo que encontramos por el camino: la capa de navegación
Auditando con Lighthouse (categoría Agentic Browsing) descubrimos que nuestro chat widget ocultaba su panel con aria-hidden + opacity: 0... dejando sus inputs alcanzables por teclado. Para un agente que navega por el árbol de accesibilidad, eso es un elemento fantasma: declarado inexistente, operativamente presente. Se arregla con el atributo inert de React 19 — el detalle completo está aquí.
La lección general: la capa de acción (WebMCP) no vive sola. Sin árbol de accesibilidad honesto y sin capa de lectura eficiente, le estás dando herramientas a un agente que ni te entiende ni puede navegarte.
Resultados y qué haríamos distinto
Lo medible a fecha de publicación: las cuatro herramientas registradas y validando, el audit de Agent Accessibility en verde, los mirrors markdown sirviendo a crawlers de IA a diario, y la demo con Gemini in Chrome funcionando — que en reuniones comerciales vale más que cualquier slide.
¿Qué haríamos distinto? Empezar antes por las descripciones de las herramientas. Escribimos las primeras versiones como documentación para desarrolladores; las reescribimos como instrucciones para un agente (qué hace, cuándo usarla, qué confirmar antes). La calidad de la descripción determina la calidad del uso que el agente hace de la herramienta — es prompt engineering, no javadoc.
El detalle completo del servicio — auditoría, capas y tiempos — está en dribba.com/web-agentica. Y si quieres ver la implementación en vivo: abre dribba.com en un Chrome con Gemini y pídele un presupuesto. Te atenderá nuestra web.




