MCP y WebMCP
El paradigma 2 es el inverso de una caja de chat: en vez de que tu app llame a un modelo, un agente externo llama a tu app. Wu ofrece tres puertas, de menos a más fontanería.
1. La superficie en crudo
Sección titulada «1. La superficie en crudo»Cualquier cosa con acceso a la página — una consola de devtools, un script de Playwright, una extensión de navegador, un cliente CDP — puede usar wu.ai directamente:
window.wu.ai.tools();// [{ name: 'addToCart', description: '…', parameters: { … } }, …]
await window.wu.ai.execute('addToCart', { productId: 'SKU-42' });// { success: true, result: { added: 'SKU-42' } }execute() recorre el pipeline completo — comprobaciones de permisos, validación de parámetros, confirmación, registro de auditoría — con un trace ID nuevo a profundidad 0.
2. WebMCP — registro de tools dentro de la página
Sección titulada «2. WebMCP — registro de tools dentro de la página»WebMCP es una propuesta del W3C que permite a una página publicar tools al agente del propio navegador a través de navigator.modelContext.
const ok = wu.ai.expose();// true → todas las acciones registradas son ahora tools de navigator.modelContext// false → navigator.modelContext no está disponiblefunction expose(): boolean;Cada acción se registra con su nombre, su descripción y sus parameters como inputSchema, más un handler que reenvía a wu.ai.execute(), devolviendo result si tiene éxito o { error: reason } si falla. Los errores de registro individuales se registran y se omiten en vez de abortar el lote.
Si tiene éxito, wu emite ai:webmcp:exposed con el número de tools y sus nombres.
3. El servidor MCP — manejar una pestaña real
Sección titulada «3. El servidor MCP — manejar una pestaña real»El repositorio incluye un servidor MCP en mcp-server/. Es un relé:
Cliente MCP (Claude Code, …) ──stdio──► mcp-server ──WebSocket :19100──► puente wu.mcp (pestaña del navegador)El servidor habla MCP por stdio con el cliente y reenvía cada llamada a tool por un WebSocket a una página que haya conectado el puente del lado del navegador. Esa página ejecuta el comando con las APIs wu.* y devuelve el resultado.
Conectar la página
Sección titulada «Conectar la página»// Desarrollowu.mcp.connect();
// Con autenticaciónwu.mcp.connect('ws://localhost:19100', { token: 'my-secret' });
wu.mcp.isConnected(); // booleanwu.mcp.disconnect();El puente se carga de forma perezosa en el primer connect(). Reconecta automáticamente (hasta 10 intentos, con 2 s entre ellos), mantiene un log rodante de los últimos 200 eventos del bus para wu_list_events y reutiliza los mismos interceptores de red y consola que las browser actions: conectar el puente no envuelve fetch por duplicado.
El puerto es 19100 por defecto, sobrescribible con WU_MCP_PORT.
Las tools
Sección titulada «Las tools»18 tools, en cinco grupos:
| Grupo | Tools |
|---|---|
| Conexión y acciones | wu_conexion, wu_list_actions, wu_execute_action |
| Introspección | wu_status, wu_list_apps, wu_list_events |
| Estado y eventos | wu_get_state, wu_set_state, wu_emit_event, wu_navigate |
| Ver y manejar | wu_snapshot, wu_screenshot, wu_click, wu_type, wu_console, wu_network |
| Ciclo de vida de apps | wu_mount_app, wu_unmount_app |
wu_list_actions y wu_execute_action conectan directamente con el registro de acciones, así que toda acción que registres con wu.ai.action() es alcanzable desde el cliente MCP: el mismo handler, la misma API en sandbox, el mismo registro de auditoría.
Seguridad
Sección titulada «Seguridad»- El handshake acepta un token opcional; sin él, cualquier cosa que pueda abrir un WebSocket a
localhost:19100puede manejar la pestaña. Eso está bien en el portátil de quien desarrolla y es inaceptable en cualquier otro sitio. - Los comandos de solo lectura (
status,list_apps,snapshot,console,network) no tienen restricciones. Los que mutan consultanwu.ai.permissionsy emiten eventos de auditoría. - El puente emite como
wu-mcp-bridgecon un token interno del bus de eventos, así que una micro-app no puede suplantarlo en modo estricto. - Los screenshots se crean de forma exclusiva dentro del directorio real del driver. Traversal, rutas absolutas, escapes por symlink/junction y hardlinks preexistentes se rechazan antes de escribir bytes; una salida existente nunca se sobrescribe.
Elegir una puerta
Sección titulada «Elegir una puerta»| Lo que quieres | Usa |
|---|---|
| Que tu app llame a un modelo | send / stream |
| Que el agente propio de la página use tus tools | wu.ai.expose(), cuando los navegadores traigan WebMCP |
| Que un script o un test dentro de la página llame a tus tools | wu.ai.execute() |
| Que Claude Code u otro cliente MCP maneje una pestaña real | el relé mcp-server + wu.mcp.connect() |
Las cuatro comparten un mismo registro. Escribe una acción una vez y estará disponible por todas las puertas.
