Crear una extensión de Chrome con IA (Manifest V3)

Crea una extensión de Chrome con IA paso a paso: Manifest V3, content scripts, service worker, permisos mínimos, claves de API ocultas y publicación en Chrome Web Store.

Solviera Teknoloji 9 min de lectura

Crear una extensión de Chrome con IA es una de las formas más fáciles de entrar en el vibe coding: una extensión son unos pocos archivos pequeños, la pruebas en tu propio navegador sin ningún servidor y agentes de código como Claude Code o Codex conocen bien la estructura de Manifest V3. Lo difícil no es el código; es elegir la pieza adecuada (content script, service worker, popup), pedir los mínimos permisos y no poner nunca claves de API dentro de la extensión. Este artículo recoge el camino que sigo desde una carpeta vacía hasta Chrome Web Store.

Como ejemplo construiremos algo pequeño pero real: una extensión que resume con una API de IA el artículo de la página actual. Con vibe coding puedes tener una primera versión en una tarde; la versión que publiques necesita unas cuantas reglas más.

Conoce primero las piezas

Para decirle al agente lo que quieres, solo necesitas conocer los cuatro bloques de una extensión de Chrome:

  • manifest.json: La identidad de la extensión. Nombre, versión, qué archivo hace qué y qué permisos pide. Las extensiones nuevas usan Manifest V3.
  • Content script: JavaScript que se ejecuta dentro de la página que visitas. Puede leer el texto de la página, añadir un botón, ocultar un elemento. No puede acceder directamente a las variables de JavaScript de la propia página; se ejecuta en un «mundo» aislado.
  • Service worker (segundo plano): Código que se ejecuta con independencia de cualquier página. Reacciona a eventos como un clic en el icono de la barra, cambios de pestaña o alarmas, y hace peticiones de red. Una propiedad importante: Chrome lo detiene cuando está inactivo, así que lo que guardes en una variable global puede desaparecer.
  • Popup y página de opciones: La ventana pequeña que se abre al hacer clic en el icono y una página aparte para los ajustes. Ambas son páginas HTML normales.

Estas piezas se comunican con chrome.runtime.sendMessage y chrome.tabs.sendMessage. Cuando algo que escribió el agente «no funciona», la causa suele ser código que se ejecuta en la pieza equivocada, por ejemplo intentar usar document en el service worker.

1. Configuración y estructura del proyecto

Lo que necesitas: Chrome (u otro navegador Chromium), Git, un editor de código y un agente de código. Para una primera extensión no hace falta una herramienta de compilación; basta con JavaScript puro. Si el proyecto crece, los frameworks de extensiones basados en Vite como WXT añaden TypeScript y recarga automática, pero yo me saltaría esa capa extra en la primera versión. Los errores del agente se ven mejor sin ella.

mkdir page-summarizer && cd page-summarizer
git init

Después pon en la raíz del proyecto un archivo corto de reglas que el agente lea en cada sesión (CLAUDE.md o AGENTS.md):

# Page Summarizer (Chrome extension)
- Manifest V3, plain JavaScript, no build step.
- Minimal permissions: activeTab, scripting, storage. No <all_urls>.
- No remote code; no eval, no remote <script>.
- No API key in the extension; requests go to our own server.
- Persistent state in chrome.storage, not in service worker globals.
- Ask before adding a permission or a package.

2. El primer prompt

En el primer mensaje pido al agente que explique qué va a construir y qué archivos creará, y luego que escriba el código:

Read CLAUDE.md. Build a Manifest V3 Chrome extension:
- Clicking the toolbar icon opens a popup with a "Summarize" button.
- Pressing it grabs the article text from the active tab (use activeTab +
  scripting and inject the content script only at that moment).
- The text goes to the service worker, which POSTs it to
  https://api.my-server.example/summarize.
- Show the summary in the popup; on error show a readable message.
- Keep the last 10 summaries in chrome.storage.local.
First list the files and what each one does, then create them.
Finish with step-by-step instructions to load and test it.

El manifest.json que produzca el agente debería parecerse a esto:

{
  "manifest_version": 3,
  "name": "Page Summarizer",
  "version": "0.1.0",
  "description": "Summarizes the article on the current page in one click.",
  "action": { "default_popup": "popup.html" },
  "background": { "service_worker": "background.js" },
  "permissions": ["activeTab", "scripting", "storage"],
  "host_permissions": ["https://api.my-server.example/*"]
}

Lo que reviso aquí es la lista de permisos. activeTab da acceso temporal solo a la pestaña actual cuando el usuario hace clic en el icono. Los agentes suelen añadir "<all_urls>" o "tabs" por comodidad; eso muestra a los usuarios una advertencia alarmante y ralentiza la revisión de la tienda.

3. Carga, prueba y depura

Antes de acercarte a la tienda, prueba la extensión en tu propio navegador:

  1. Abre chrome://extensions.
  2. Activa Developer mode arriba a la derecha.
  3. Haz clic en Load unpacked y elige la carpeta del proyecto.
  4. Fija el icono en la barra de herramientas y pruébalo con un artículo.

Después de cambiar código, pulsa el botón de recargar en la tarjeta de la extensión en chrome://extensions. Si cambió un content script, recarga también la página con la que pruebas.

Los tres lugares que más ayudan al depurar:

  • Service worker: El enlace «service worker» de la tarjeta de la extensión abre sus propias DevTools. Aquí aparecen las peticiones de red y los errores en segundo plano.
  • Popup: Con el popup abierto, haz clic derecho sobre él y elige Inspect.
  • Content script: Los registros aparecen en la consola de las DevTools de la propia página; puedes elegir tu extensión en el menú desplegable de contexto de la parte superior de la consola.

Si la tarjeta de la extensión muestra un botón Errors, copia su contenido tal cual y dáselo al agente:

I loaded the extension. Pressing "Summarize" in the popup shows this error:
[error text]
The service worker console also shows:
[log]
Explain the cause, fix it, and list what you changed in which file.

Decir dónde falló, qué pulsaste y qué muestra cada consola permite al agente arreglar el problema en lugar de adivinar.

4. Almacenamiento: elige el lugar adecuado

  • chrome.storage.local: Datos de este dispositivo, como el historial de resúmenes.
  • chrome.storage.sync: Se sincroniza entre dispositivos mediante el perfil de Chrome del usuario. La cuota es pequeña; úsalo solo para ajustes.
  • chrome.storage.session: Se borra al cerrar el navegador; sirve para el estado temporal que debe sobrevivir al reinicio del service worker.

En un service worker no existe localStorage. Si el agente intenta usarlo, por eso falla. Y no olvides el permiso storage en manifest.json.

5. Mantén las claves de API fuera de la extensión

Este es el error que más veo en extensiones hechas con IA. El agente escribe «pega aquí tu clave de OpenAI» y pone una constante en background.js. Una extensión publicada es un archivo ZIP; cualquiera puede descargarlo, descomprimirlo y leer tu clave. Minificar u ofuscar no cambia eso.

La estructura correcta es un pequeño proxy:

  1. La extensión llama a tu propio servidor (https://api.my-server.example/summarize).
  2. El servidor guarda la clave en su entorno y llama a la API de IA real.
  3. El servidor limita la frecuencia de las peticiones (por usuario o IP) y rechaza textos demasiado grandes.

Abre un proyecto aparte para este servidor y dile al agente:

Write a small HTTP service: POST /summarize takes { text } in the body.
Cap the text at 20,000 characters, call the AI API with the key from an
environment variable, return { summary }. Allow CORS only for the
chrome-extension://<EXTENSION_ID> origin. Add a simple rate limit.
Never log the key. Create a .env.example file.

El ID de la extensión aparece en chrome://extensions cuando la cargas sin empaquetar; una vez publicada en la tienda puede ser distinto. Actualiza la configuración de CORS antes de publicar. Si los usuarios traen su propia clave (habitual en herramientas para desarrolladores), pídela en la página de opciones y guárdala en chrome.storage.local; nunca incluyas la tuya.

Lo que la IA hace mal

  • Escribir código de Manifest V2. background.page, chrome.browserAction, una página en segundo plano persistente o webRequestBlocking vienen de ejemplos antiguos. Dile al agente «usa el equivalente de Manifest V3».
  • Suponer que el service worker siempre está en marcha. Un contador en una variable global o un setInterval se detiene pasado un tiempo. Usa chrome.alarms para el trabajo programado y chrome.storage para el estado.
  • Pedir demasiados permisos. <all_urls>, tabs, history suelen ser innecesarios. Pide al agente que justifique cada permiso en una frase; quita los que no pueda justificar.
  • Cargar código remoto. Traer una biblioteca de un CDN con <script> o usar eval no está permitido en Manifest V3. Incluye la biblioteca en el paquete.
  • Intentar alcanzar variables de la página desde un content script. Como se ejecuta en un mundo aislado, no puede ver window.someApp; tiene que trabajar a través del DOM.
  • Olvidar las respuestas asíncronas en la mensajería. Si un listener de onMessage responde de forma asíncrona, tiene que hacer return true; si no, el popup recibe una respuesta vacía.
  • Suponer que todos los sitios tienen el mismo HTML. Para obtener el texto de un artículo, busca primero un elemento article o main y usa una alternativa razonable. Prueba en tres sitios distintos.

Seguridad

  • Los secretos viven en .env, en el servidor. Nada de .env en la carpeta de la extensión; acabaría en el ZIP.
  • Nunca pegues claves de API en el chat. El agente necesita el nombre de la variable, no la clave.
  • Lee los comandos que ejecuta el agente. Sobre todo las instalaciones de paquetes y cualquier cosa como curl … | sh.
  • No te fíes de los datos de la página. No muestres con innerHTML en el popup el texto que leyó el content script; usa textContent. Si no, una página maliciosa puede inyectar código en tu extensión.
  • Comprueba de quién viene un mensaje. Si no necesitas mensajes del exterior, no añadas externally_connectable; si lo necesitas, mantén estrechos los orígenes permitidos.
  • Recoge solo lo necesario. Si el texto de la página va a tu servidor, dilo con claridad y no lo guardes allí.

6. Publicar en Chrome Web Store

A grandes rasgos, la publicación sigue estos pasos:

  1. Crea una cuenta de desarrollador. Regístrate en el panel de desarrolladores de Chrome Web Store; hay una tarifa de registro única.
  2. Empaquétala. Comprime en ZIP la carpeta del proyecto con el manifest en la raíz. Deja fuera .git, node_modules, los archivos de prueba y .env.
  3. Rellena la ficha. Descripción, capturas de pantalla, iconos, categoría.
  4. Rellena la sección de privacidad. Indica la finalidad única de la extensión, justifica cada permiso y declara qué datos de usuario recoges. Si recoges datos, necesitas una URL de política de privacidad accesible públicamente.
  5. Envíala a revisión. El tiempo varía. Los permisos de host amplios y el código difícil de leer pueden ralentizarla; si te la rechazan, el correo indica qué política incumpliste.

El agente también ayuda aquí:

I'm submitting this extension to the Chrome Web Store. For each
permission in manifest.json, write a one-sentence justification for the
store form, write the single-purpose description and list the user data
we collect. Tell me if any permission looks unnecessary. Give me a command
that builds the release ZIP without .git, .env and test files.

Para las actualizaciones, sube version en manifest.json. Añadir un permiso nuevo puede desactivar la extensión para los usuarios existentes hasta que lo aprueben, así que piénsalo dos veces antes de añadir uno.

Cómo lo hago con AgentVera

Puedes crear una extensión con una terminal y un navegador. Yo uso AgentVera cuando construyo a la vez la extensión y el servidor proxy:

  • Dos agentes, dos tareas. En el espacio de trabajo abro un agente Claude Code para la extensión y un agente Codex para el servidor proxy, cada uno en su propia carpeta o git worktree.
  • Probar el servidor. El cliente de API puede encontrar los endpoints del servidor a partir de su código; pruebo /summarize ahí antes de conectarlo a la extensión.
  • Enviar errores al agente. Envío la salida de error de una terminal al agente elegido con Send to agent en lugar de copiar y pegar.
  • Revisar antes de fusionar. La revisión de código comprueba cada turno terminado y el panel de Git muestra el diff. Un permiso extra o una clave incrustada suele detectarse aquí.
  • Seguimiento de tokens. Cada panel muestra el tamaño de contexto en vivo; una extensión pequeña no necesita una sesión hinchada.

Cargar la extensión en Chrome y probarla sigue siendo cosa tuya; AgentVera no lo hace por ti.

Para terminar

Para crear una extensión de Chrome con IA, aprende las piezas (manifest, content script, service worker, popup), da al agente reglas por escrito, empieza con permisos mínimos, cárgala sin empaquetar y depura desde la consola correcta, y mantén las claves de API detrás de un servidor proxy. Antes de enviarla a la tienda, asegúrate de poder justificar cada permiso. Para saber más sobre cómo comprobar lo que producen los agentes, lee revisión de código con IA, y para elegir herramientas, las mejores herramientas de código con IA.

Preguntas frecuentes

¿Puedo crear una extensión de Chrome con IA sin saber programar?

Una extensión sencilla, sí; la mayoría son un puñado de archivos pequeños que un agente de código puede escribir. Aprender lo básico, como el manifest, los permisos y cómo se envían mensajes las piezas entre sí, sigue ayudando a describir los errores al agente con precisión.

¿Cuál es la diferencia entre un content script y un service worker?

Un content script se ejecuta dentro de la página que visitas y puede leer y modificar su DOM. El service worker se ejecuta en segundo plano, independiente de cualquier página; reacciona a eventos, hace peticiones de red y Chrome lo detiene cuando está inactivo.

¿Cómo oculto una clave de API en una extensión de Chrome?

No puedes; todo lo que incluyas en una extensión puede leerlo el usuario. Guarda la clave en tu propio servidor, haz que la extensión llame a tu servidor y que el servidor llame a la API real.

¿Cuánto tarda la revisión de Chrome Web Store?

No hay un plazo fijo; puede tardar desde unas horas hasta varios días, a veces más. Las extensiones que piden permisos amplios o incluyen código minificado difícil de leer suelen recibir una revisión más detallada.

¿Puede la IA convertir una extensión Manifest V2 a Manifest V3?

Sí, los agentes hacen bien esta migración: de la página en segundo plano al service worker, del código remoto al paquete, de las variables persistentes a chrome.storage. Después prueba a mano cada función, porque el cierre del service worker cambia el comportamiento.

Reúne a tus agentes en un mismo escritorio.

Descarga AgentVera gratis; tus CLI instaladas ya están listas.

Más artículos