Qué es Agent Plugins, el estándar que unifica skills y MCP
Tienes una skill que funciona bien. La quieres usar en Claude Code, en Codex y en Copilot.
Enhorabuena: acabas de firmar un contrato de mantenimiento a tres bandas.
Porque el SKILL.md es el mismo, sí, pero el manifiesto va en .claude-plugin/plugin.json para uno, en plugin.json a secas para otro y en .plugin/plugin.json para el de más allá. El MCP se declara en .mcp.json aquí y en mcp.json allá. La variable para apuntar a la carpeta del plugin es ${CLAUDE_PLUGIN_ROOT} en un sitio y ${PLUGIN_ROOT} en otro. Cambias una línea del contenido y tienes que tocar tres repositorios.
Eso es exactamente lo que Agent Plugins 1.0.0 viene a matar: un estándar abierto y neutral para empaquetar Agent Skills y servidores MCP en un formato que cualquier cliente compatible sepa leer.
Lo impulsó Vercel, pero lo firma medio sector: Amazon Web Services, Anysphere (los de Cursor), GitHub, Microsoft y OpenAI. Y hay una ausencia que canta y de la que vamos a hablar sin rodeos.
En este post vas a encontrar:
- Qué es Agent Plugins y qué problema resuelve de verdad (spoiler: menos del que parece)
- La estructura exacta de un plugin conforme, con los campos del manifiesto uno a uno
- Cómo se declaran los MCP en
mcp.jsony qué hacen${PLUGIN_ROOT}y${PLUGIN_DATA} - Qué se queda FUERA de la versión 1.0 y por qué eso importa más que lo que entra
- Cómo migrar tu plugin de Claude Code al estándar, paso a paso
- Mi lectura honesta: si te conviene adoptarlo hoy o esperar
Vamos al lío.
¿Qué es exactamente Agent Plugins? ¶
Agent Plugins es una especificación abierta que define un directorio con un manifiesto plugin.json en la raíz y ubicaciones fijas para sus componentes. Nada más. No es un runtime, no es un gestor de paquetes, no es un marketplace. Es un contrato de dónde van los ficheros.
La versión publicada es la 1.0.0 y vive en el repositorio agentplugins/agent-plugins-spec, con el texto normativo bajo licencia Creative Commons Attribution 4.0 y los esquemas JSON bajo Apache 2.0.
El plugin más pequeño que puedes escribir cabe en tres ficheros:
hello-plugin/
├── plugin.json
└── skills/
└── greet/
└── SKILL.md
Y el manifiesto, en su versión mínima, son dos campos:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "hello-plugin"
}
Eso es un plugin conforme. Un cliente que soporte skills lo carga leyendo plugin.json y descubriendo skills/greet/SKILL.md. Cómo te enseñe después esa skill (en un menú, en un /comando, invocada por el modelo) ya es asunto suyo: la especificación se corta ahí a propósito.
🔑 El estándar solo define qué necesita un cliente para descubrir y cargar lo que hay dentro. No define cómo se instala, cómo se distribuye, ni cómo se ejecuta. Es un formato de empaquetado, no una plataforma.
Si andas perdido con el vocabulario, tienes el mapa completo en el post sobre en qué se diferencian las Agent Skills de los prompts, los MCP y los subagentes. Aquí doy por sabido qué es un SKILL.md.
¿Qué problema resuelve y cuál no resuelve? ¶
El problema es la fragmentación del empaquetado, no la del contenido.
Fíjate en el matiz, porque es la clave para no llevarte una decepción. Tu SKILL.md ya era portable: es markdown con frontmatter que sigue la especificación de Agent Skills, y la mitad de los agentes del mercado ya lo entienden. Tu servidor MCP también era portable: habla el mismo protocolo en todas partes.
Lo que no era portable era la caja. Los clientes esperaban metadatos distintos en la raíz, rutas de descubrimiento distintas y formatos de configuración MCP incompatibles entre sí. El mismo componente, cuatro envoltorios.
Agent Plugins estandariza la caja. Y punto.
| Qué se estandariza | Qué NO se estandariza |
|---|---|
Ubicación del manifiesto (plugin.json en la raíz) |
Cómo se instala el plugin |
| Campos permitidos del manifiesto (lista cerrada) | Cómo se distribuye (no hay registro oficial) |
Dónde viven las skills (skills/) |
Cómo el cliente expone la skill al usuario |
Formato de configuración MCP (mcp.json) |
Permisos, sandboxing y modelo de confianza |
Variables ${PLUGIN_ROOT} y ${PLUGIN_DATA} |
Firmas, procedencia y verificación |
Esa segunda columna da para un post entero. La retomamos más abajo, que tiene tela.
Una especificación no solo sirve para empaquetar plugins
La misma idea aplicada a tu código se llama Spec Driven Development. En el curso recorres el ciclo completo de OpenSpec sobre un proyecto de juguete, del proposal al archivado, y lo ves funcionar entero antes de coger tú el volante.
Entra en el curso gratis →¿Quién está detrás del estándar y quién brilla por su ausencia? ¶
La propuesta la arrancó Vercel y la refinaron representantes de Amazon Web Services, Anysphere, GitHub, Microsoft, OpenAI y la propia Vercel hasta convertirla en la 1.0.0.
El gobierno del proyecto no se deja al azar. Hay una Technical Steering Committee con cinco Core Maintainers, y la carta técnica es explícita en dos puntos que me parecen los más importantes del documento: los roles los ostentan personas, no organizaciones, y ningún fabricante puede controlar la mayoría de los asientos.
Estos son los cinco, con la organización a la que representan en las discusiones:
| Core Maintainer | Organización |
|---|---|
| Clare Liguori | Amazon |
| Roshan Sadanani | Cursor |
| Harald Kirschner | Microsoft |
| Gav Verma | OpenAI |
| Jonathan Hefner | Vercel (Lead Core Maintainer) |
¿Y Anthropic?
No está. Ni en la lista de colaboradores del anuncio, ni en el comité técnico, ni entre los clientes que soportan el formato en el lanzamiento. Los clientes que sí lo soportan de salida son ChatGPT, Codex, Cursor, GitHub Copilot, Kiro y VS Code.
Que la empresa que popularizó el formato de plugins con skills, agentes y hooks se quede fuera del estándar que unifica los plugins con skills no es un detalle menor. Volvemos a ello en la sección de convivencia, porque tiene consecuencias prácticas para ti.
⚠️ El estándar es neutral por diseño y por gobernanza, pero “neutral” no significa “universal”. A día de hoy hay un ecosistema grande de plugins que no sigue este formato y sus autores no tienen ninguna obligación de migrar.
Hay un detalle arqueológico que explica de dónde sale todo esto: el repositorio de la especificación arranca el 2 de abril de 2026 con un commit llamado “Add Open Plugin Specification v1.0.0”, bajo la organización vercel-labs. Empezó siendo un experimento de un fabricante. Cuatro meses y 79 commits después, es un estándar con comité. La documentación de VS Code todavía llama “Legacy OpenPlugin” al formato de aquella primera versión, con manifiesto en .plugin/plugin.json.
¿Cómo es la estructura de un plugin conforme? ¶
Un plugin es un directorio en el sistema de ficheros. Sin .zip, sin .tar.gz, sin bundles descargados de un registro. Esta es la razón que da la propia especificación: así los plugins se inspeccionan con ls y cat, se editan en caliente mientras los desarrollas y funcionan con control de versiones sin herramientas especiales.
El diseño completo, con todas las piezas puestas, tiene esta pinta:
my-plugin/
├── plugin.json
├── skills/
│ └── summarize/
│ ├── SKILL.md
│ ├── scripts/
│ │ └── analyze.sh
│ └── references/
│ └── checklist.md
├── mcp.json
├── com.example.client/
│ └── hooks/
├── LICENSE
└── CHANGELOG.md
Las ubicaciones son fijas y no negociables. El manifiesto no puede redefinirlas ni meter configuración de componentes en línea. Solo hay dos tipos de componente en la versión 1:
| Tipo de componente | Ubicación fija | Patrón |
|---|---|---|
| Skills | skills/ |
Subdirectorios que contengan un SKILL.md |
| Servidores MCP | mcp.json |
Configuración JSON |
Un par de reglas con las que te vas a topar seguro:
- El cliente no busca en profundidad. Solo mira los hijos directos de
skills/. Si escondes una skill enskills/categoria/mi-skill/SKILL.md, no existe. - Si falta una ubicación, no es un error. Un plugin sin
mcp.jsones válido; un plugin sinskills/también. - Todo lo que el cliente lea debe resolverse dentro de la raíz del plugin. Un
../en una ruta invalida esa entrada. Los enlaces simbólicos valen, siempre que apunten dentro.
Y hay una regla de resiliencia que me parece de las mejores decisiones de diseño de toda la especificación: los fallos son locales. Si un servidor MCP no arranca, las skills siguen cargando. Si una skill está mal formada, el cliente la salta y sigue con las demás. Un plugin no se cae entero porque una pieza falle.
Los formatos de todo esto cambian cada trimestre y no da tiempo a leérselo entero. Cada domingo seleccionamos 12 recursos sobre IA, herramientas y carrera para developers. Gratis desde 2018, ya somos +6.700.
Suscríbete gratis →¿Qué campos admite el manifiesto plugin.json? ¶
Aquí viene la parte que más te va a afectar si vienes de otro formato: el esquema es cerrado. Solo se admiten diez campos de primer nivel, ni uno más.
| Campo | Tipo | Obligatorio | Para qué sirve |
|---|---|---|---|
$schema |
string | Sí | Identificador canónico de la versión del estándar |
name |
string | Sí | Nombre del plugin |
version |
string | No | Versión (se recomienda SemVer) |
description |
string | No | Descripción breve |
author |
object | No | Solo admite name, email y url |
homepage |
string | No | URL de documentación |
repository |
string | No | URL del repositorio |
license |
string | No | Identificador de licencia (se recomienda SPDX) |
keywords |
string[] | No | Etiquetas de búsqueda |
extensions |
object | No | Datos específicos de cliente por espacio de nombres |
El manifiesto completo, con todo puesto:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "plugin-name",
"version": "1.2.0",
"description": "Brief plugin description",
"author": {
"name": "Author Name",
"email": "author@example.com",
"url": "https://example.com"
},
"homepage": "https://docs.example.com/plugin",
"repository": "https://github.com/example/plugin",
"license": "MIT",
"keywords": ["keyword1", "keyword2"],
"extensions": {
"com.example.client": {
"setting": true
}
}
}
El campo $schema no es decorativo: es el discriminador de formato. VS Code, por ejemplo, detecta que un plugin.json en la raíz es Agent Plugins 1.0 precisamente porque declara ese identificador canónico. Si no lo declara, lo trata como formato Copilot. Y los clientes tienen prohibido descargar el esquema durante la carga del plugin: usan el identificador para elegir sus reglas locales de validación, no para ir a buscarlas a internet.
Las reglas del nombre que te van a hacer perder media hora ¶
El campo name tiene cuatro restricciones y la validación es implacable:
- Entre 1 y 64 caracteres
- Solo
a-z,0-9, guiones y puntos - El primer y el último carácter deben ser alfanuméricos
- Prohibidos los guiones dobles (
--) y los puntos dobles (..)
Válidos: my-plugin, acme.tools, lint3r, a. Inválidos: My-Plugin (mayúsculas), -start (guion inicial), has--double, too.many..dots.
Si el nombre falla, el plugin entero se rechaza. No se carga a medias: se rechaza.
Qué pasa con los campos desconocidos ¶
Esta es la única concesión elegante del esquema cerrado. Si metes un campo de primer nivel que no está en la lista, el cliente debe reportarlo e ignorarlo, pero debe seguir cargando el plugin si el resto es válido. Lo mismo si extensions no es un objeto.
Cualquier otra violación del esquema es fatal: el cliente rechaza el plugin y no ejecuta ninguno de sus componentes.
¿Por qué cerrarlo así? La especificación lo justifica en su sección de decisiones de diseño: un esquema cerrado permite validación estricta, detección de erratas y autocompletado en el editor. Los experimentos de cada fabricante no pueden apropiarse de campos de primer nivel arbitrarios; se meten bajo extensions con un identificador de dominio invertido.
👉 ¿Y cómo se declaran los MCP en todo esto?
¿Cómo se configuran los servidores MCP en mcp.json? ¶
En un fichero mcp.json en la raíz del plugin. No en plugin.json, no en ninguna ruta alternativa. El fichero tiene exactamente dos campos de primer nivel, $schema y mcpServers, y ningún otro.
Si tienes servidores MCP dando vueltas por tu máquina y quieres refrescar cómo funcionan por debajo, ahí tienes la guía para instalar MCP en los 16 agentes más populares. Lo que cambia aquí es el envoltorio, no el protocolo.
Cada servidor declara su transporte con type y cae en una de tres variantes cerradas: stdio, streamable-http o sse (el HTTP+SSE antiguo, marcado como heredado).
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"local-validator": {
"type": "stdio",
"command": "./bin/validator",
"args": ["--data", "${PLUGIN_DATA}/validator"],
"env": {
"CONFIG": "${PLUGIN_ROOT}/config.json"
},
"cwd": "${PLUGIN_ROOT}"
},
"deployment-api": {
"type": "streamable-http",
"url": "https://deploy.example.com/mcp",
"headers": {
"X-Tenant": "public-tenant"
}
},
"legacy-events": {
"type": "sse",
"url": "https://legacy.example.com/sse"
}
}
}
Cuatro detalles de la letra pequeña que te van a ahorrar dolores de cabeza:
commandes UN token, no una línea de shell. O un nombre de ejecutable pelado (npx) o una ruta relativa al plugin que empiece por./. Nada desh -c "algo && otra cosa". La especificación lo justifica: así los clientes no tienen que parsear ni escapar cadenas de shell escritas por terceros.- En
commandno hay expansión de variables. Las rutas relativas se resuelven contra la raíz del plugin de forma directa. - Un cliente conforme puede soportar solo un transporte. Debe soportar al menos
stdioostreamable-http(y debería soportar ambos);ssees opcional. Si no soporta el transporte que declaras, salta ese servidor y sigue con los demás. - Las URLs no loopback tienen que ser HTTPS. HTTP solo se permite si el host es exactamente
localhosto una IP de loopback.
🛡️ Ni las cabeceras HTTP ni el objeto
envson un mecanismo para secretos. La especificación es tajante: son datos visibles del paquete. Si metes ahí una API key, la estás publicando en el repositorio del plugin. La versión 1.0 no define ningún mecanismo portable de credenciales.
¿Para qué sirven ${PLUGIN_ROOT} y ${PLUGIN_DATA}? ¶
Para resolver el problema de siempre: tu servidor MCP necesita rutas absolutas en tiempo de ejecución, pero tú no sabes dónde va a instalar el cliente tu plugin.
El estándar define dos variables que el cliente está obligado a proporcionar en el entorno de cada subproceso que lance:
PLUGIN_ROOT: la ruta absoluta a la raíz del plugin. Para referenciar scripts, binarios y ficheros de configuración que vienen dentro del paquete.PLUGIN_DATA: la ruta absoluta a un directorio de datos persistente que gestiona el cliente, dedicado a esa instalación concreta. Paranode_modules, entornos virtuales, código generado, cachés y cualquier estado que deba sobrevivir a una actualización.
Ese segundo punto es el que marca la diferencia frente a soluciones anteriores. El cliente debe crear el directorio antes de lanzar el subproceso, debe hacerlo escribible y debe preservar su contenido entre actualizaciones. Cuando el plugin se actualiza y se reemplaza el contenido del paquete, tus dependencias instaladas siguen ahí.
Un ejemplo de lo que ve un plugin llamado devtools:
PLUGIN_ROOT=/home/alex/.agents/plugins/devtools
PLUGIN_DATA=/home/alex/.agents/plugins/data/devtools
La expansión de los marcadores tiene reglas estrictas y conviene conocerlas:
- Se expanden solo en cada elemento de
args, en cada valor deenvy encwd. - No se expanden en las claves de
env, ni encommand, ni en las ubicaciones fijas. - Es un reemplazo textual único y no recursivo: lo que introduce una sustitución no se vuelve a escanear.
- Cualquier otro texto con pinta de marcador se queda literal. No hay expansión de variables de entorno arbitrarias.
- Tu
envno puede contener entradas llamadasPLUGIN_ROOToPLUGIN_DATA. Si lo intentas, esa configuración de servidor es inválida. Las pone el cliente, no tú.
¿Cómo creo un plugin conforme desde cero? ¶
Con mkdir y un editor. En serio: no hay CLI oficial, no hay init, no hay scaffolding. El estándar es un contrato de rutas, así que crear un plugin es crear carpetas.
Vamos a montar uno con una skill y un servidor MCP en cinco minutos.
Paso 1. La estructura. Un directorio con la carpeta de la skill dentro:
mkdir -p mi-plugin/skills/revisa-pr
cd mi-plugin
Paso 2. El manifiesto. Crea plugin.json en la raíz. El $schema es obligatorio y el nombre tiene que respetar las reglas que vimos antes:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "mi-plugin",
"version": "0.1.0",
"description": "Revisiones de pull request con criterio propio",
"license": "MIT"
}
Paso 3. La skill. En skills/revisa-pr/SKILL.md, markdown con frontmatter. El name del frontmatter debe ir en kebab-case plano y coincidir con el nombre del directorio:
---
name: revisa-pr
description: Revisa una pull request buscando fugas de secretos, tests que faltan y cambios de API no documentados. Úsala al preparar o revisar una PR.
---
Cuando revises una pull request:
1. Busca credenciales, tokens y ficheros .env en el diff.
2. Comprueba que cada función nueva tiene su test.
3. Señala los cambios de firma pública sin entrada en el CHANGELOG.
Si la skill necesita scripts o documentación de apoyo, van en scripts/ y references/ dentro de la propia carpeta de la skill. Eso ya lo define la especificación de Agent Skills, no esta.
Paso 4 (opcional). El servidor MCP. Si tu plugin trae herramientas, añade mcp.json en la raíz. Ojo con la versión: tiene que ser la misma que declaraste en plugin.json.
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"github-tools": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"CACHE_DIR": "${PLUGIN_DATA}/cache"
}
}
}
}
Paso 5. El resultado. Tu plugin conforme tiene esta pinta y ya se puede cargar:
mi-plugin/
├── plugin.json
├── mcp.json
└── skills/
└── revisa-pr/
└── SKILL.md
Ya está. Súbelo a un repositorio Git y cualquier cliente compatible puede instalarlo desde la URL.
⚠️ No existe validador oficial del estándar. La suite de conformidad para clientes y el linter para plugins están en la lista de consideraciones futuras, así que hasta que lleguen tu única red de seguridad es el propio cliente reportando errores al cargar.
Y el error número uno con diferencia: si una skill no aparece, mira el name del frontmatter. Un nombre con prefijo de espacio de nombres (miorg/revisa-pr) o que no coincida con el directorio hace que el cliente la salte en silencio, sin avisar de nada.
¿Qué se queda fuera de la versión 1.0? ¶
Todo lo demás. Y esta es la parte que más gente se va a saltar y más quebraderos de cabeza va a dar.
Agent Plugins 1.0 define exactamente dos tipos de componente: skills y servidores MCP. La especificación lo argumenta con honestidad: ambos tienen especificaciones establecidas fuera de este proyecto y adopción real entre clientes. El resto sigue siendo demasiado específico de cada fabricante.
Lo que queda fuera del contrato portable:
- Hooks (comandos que se ejecutan en eventos del ciclo de vida)
- Comandos slash
- Agentes y subagentes con sus personalidades y restricciones de herramientas
- Reglas de contexto
- Servidores LSP
Si tu plugin de Claude Code vive de sus hooks y sus subagentes, migrarlo al estándar significa que la mitad de tu plugin viaja como extensión específica de cliente, en un directorio de dominio invertido tipo com.example.client/. Y los clientes que no implementen ese espacio de nombres lo van a ignorar sin decir nada.
VS Code, sin ir más lejos, lo declara por escrito en su documentación: soporta el estándar, pero ignora los datos y directorios de extensión de cliente en los paquetes Agent Plugins 1.0. Carga las skills y los MCP portables, y nada más.
💡 La pregunta que te tienes que hacer antes de migrar no es “¿puedo?”, es “¿qué porcentaje de mi plugin es portable?”. Si son skills y MCP, casi todo. Si son hooks, agentes y comandos, estás empaquetando una cáscara.
El contenido lo pones tú
Un plugin sin skills dentro es una caja vacía
El estándar te resuelve el empaquetado, no el relleno. Vas a montar Agent Skills reutilizables en un SKILL.md que tu agente carga solo cuando hacen falta, y que funcionan igual en Claude Code, Copilot, OpenCode y 25+ agentes más.
Abrir la guía →Acceso con suscripción Web Reactiva Premium · 15€/mes · Plantillas SKILL.md descargables
¿Cómo conviven Agent Plugins y el formato de Claude Code? ¶
Conviven porque los clientes multiformato hacen de traductores. Y ahí VS Code es el caso de estudio perfecto, porque soporta cuatro formatos a la vez y autodetecta cuál es cuál:
| Formato | Manifiesto | Variable de raíz |
|---|---|---|
| Agent Plugins 1.0 | plugin.json con el $schema canónico |
${PLUGIN_ROOT} y ${PLUGIN_DATA} |
| Copilot | plugin.json |
${PLUGIN_ROOT} o ${CLAUDE_PLUGIN_ROOT} |
| Claude | .claude-plugin/plugin.json |
${CLAUDE_PLUGIN_ROOT} |
| Legacy OpenPlugin | .plugin/plugin.json |
${PLUGIN_ROOT} |
Aquí está la buena noticia, y es más grande de lo que parece: la carpeta skills/ es idéntica en los cuatro formatos. Claude Code busca las skills en skills/<nombre>/SKILL.md, exactamente igual que el estándar. La incompatibilidad no está en el contenido, está en el manifiesto y en el fichero de MCP.
Las diferencias concretas entre el formato de Claude Code y el estándar:
| Pieza | Claude Code | Agent Plugins 1.0 |
|---|---|---|
| Manifiesto | .claude-plugin/plugin.json |
plugin.json en la raíz |
Campo $schema |
No lo usa | Obligatorio |
| Configuración MCP | .mcp.json |
mcp.json |
| Skills | skills/<nombre>/SKILL.md |
Igual |
| Hooks, agentes, LSP, monitores | Soportados de forma nativa | Fuera del estándar |
| Datos persistentes | Sin equivalente definido | ${PLUGIN_DATA} |
Si quieres ver ecosistema real, mira awslabs/agent-plugins: nueve plugins de AWS (serverless, Amplify, bases de datos, SageMaker y compañía) que se instalan en Claude Code desde su marketplace, en Cursor desde su tienda, en Codex clonando el repositorio y en Kiro con un conversor de terceros. Un mismo repositorio, cuatro caminos de instalación. Es justo el escenario que el estándar quiere volver innecesario.
Y mientras tanto existe el parche: @every-env/compound-plugin, un CLI que convierte plugins de formato Claude Code a los formatos nativos de una docena de agentes que aún no hablan el estándar. Funciona, pero es un síntoma, no una cura.
Si andas comparando ecosistemas de extensiones, el repaso a los mejores plugins para OpenCode te da una foto de lo diverso que está esto ahora mismo.
¿Qué clientes lo soportan y cómo se instala un plugin? ¶
En el lanzamiento son seis: ChatGPT, Codex, Cursor, GitHub Copilot, Kiro y VS Code. Y aquí viene el matiz que nadie cuenta: el estándar no define cómo se instala nada. Define cómo se lee el paquete. La instalación se la inventa cada cliente.
Eso significa que no hay registro central, no hay npm install universal y no hay un comando que funcione en todas partes. Lo que hay es esto:
| Cliente | Cómo llegan los plugins |
|---|---|
| VS Code | Marketplaces configurables, instalación desde URL de Git o rutas locales |
| GitHub Copilot CLI | Instalación propia, con los plugins en ~/.copilot/installed-plugins/ |
| Cursor | Marketplace propio y ajustes de la aplicación |
| Codex | Descubrimiento en el sistema de ficheros del proyecto |
| Kiro | Soporte marcado como experimental por los propios autores de plugins |
| ChatGPT | Soporte del formato en la aplicación |
VS Code es el que tiene la historia más completa y sirve como referencia de lo que se puede esperar del resto. Lo primero: el soporte se activa con el ajuste chat.plugins.enabled. Si tienes plugins instalados y no aparecen por ningún lado, empieza por ahí antes de volverte loco.
Para buscar e instalar tienes tres caminos:
- Desde un marketplace: abre la vista de extensiones y escribe
@agentPlugins. Por defecto trae configurados los repositoriosgithub/copilot-pluginsygithub/awesome-copilot; puedes añadir los tuyos con el ajustechat.plugins.marketplaces, que acepta desde el atajoowner/repohasta una URL SSH o unfile:///local. - Directo desde un repositorio Git: ejecuta Chat: Install Plugin From Source desde la paleta de comandos y pega la URL. VS Code clona e instala. Este es el camino para probar el plugin que acabas de escribir.
- Desde una carpeta local: el ajuste
chat.pluginLocationsmapea rutas de tu disco atrueofalse. Un plugin registrado confalsese queda instalado pero desactivado.
// settings.json
"chat.pluginLocations": {
"/Users/tu-usuario/dev/mi-plugin": true
}
Un detalle que agradecerás en equipo: un proyecto puede recomendar plugins a quien lo abra. Se configura con los campos extraKnownMarketplaces y enabledPlugins en los ajustes del workspace, y VS Code enseña una notificación la primera vez que alguien manda un mensaje al chat.
¿Y las actualizaciones? Se comprueban con Extensions: Check for Extension Updates o de forma automática cada 24 horas si tienes activado extensions.autoUpdate. La excepción son los plugins que vienen de npm o PyPI: esos nunca se actualizan solos, te sale un botón y decides tú.
🔑 Si publicas, recuerda subir el campo
versiondeplugin.jsonen cada cambio. Sin ese incremento, los clientes que usan la versión para decidir si hay actualización no se enteran de que has publicado nada.
Para ver todo esto junto en un caso real, mira awslabs/agent-plugins. Nueve plugins de AWS y cuatro rutas de instalación distintas según el cliente: en Claude Code con /plugin marketplace add awslabs/agent-plugins y luego /plugin install; en Cursor desde su marketplace buscando “AWS”; en Codex clonando el repositorio; y en Kiro con un conversor de terceros. Un solo repositorio, cuatro maneras de meterlo en tu máquina.
Esa tabla de arriba es, en el fondo, la mejor prueba de qué resuelve el estándar y qué no: el formato del paquete ya es uno, la puerta de entrada sigue siendo seis.
¿Cómo migro mi plugin actual al estándar? ¶
Si tu plugin es de skills y MCP, la migración es de tarde de viernes. Estos son los pasos.
1. Saca el manifiesto de su escondite. Mueve .claude-plugin/plugin.json a plugin.json en la raíz del plugin.
2. Añade el $schema y limpia lo que sobre. Recuerda que el esquema es cerrado: si tenías campos propios de Claude Code de primer nivel, o los tiras o los metes bajo extensions con un espacio de nombres de dominio invertido.
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "mi-plugin",
"version": "1.0.0",
"description": "Lo que hace mi plugin",
"license": "MIT"
}
3. Revisa el nombre. Minúsculas, sin guiones dobles, sin puntos dobles, empezando y acabando en alfanumérico. Si tu plugin se llamaba Mi-Plugin, ya no vale.
4. Renombra .mcp.json a mcp.json y añádele su $schema correspondiente. Ojo: la versión declarada en mcp.json debe coincidir con la de plugin.json. Si no coinciden, la configuración MCP se invalida entera (aunque las skills siguen cargando).
5. Cambia las variables. Todos los ${CLAUDE_PLUGIN_ROOT} pasan a ${PLUGIN_ROOT}. Y aprovecha para mover a ${PLUGIN_DATA} lo que sea estado que deba sobrevivir a una actualización: cachés, dependencias instaladas, código generado.
6. Comprueba que command es un token. Si tenías una línea de shell con pipes o &&, sácala a un script dentro del plugin y apunta a ./scripts/loquesea.sh.
7. Las skills se quedan como están. En serio. Si ya cumplen la especificación de Agent Skills y viven en skills/<nombre>/SKILL.md, no toques nada.
8. Decide qué haces con lo no portable. Hooks, agentes y comandos: o se quedan en un directorio de extensión con tu dominio invertido, o mantienes dos ramas. No hay tercera opción.
Un detalle que vas a agradecer si depuras esto en VS Code: si una skill no aparece, casi siempre es que el campo name del frontmatter del SKILL.md no está en kebab-case plano o no coincide con el nombre del directorio. Las skills con nombre inválido se saltan en silencio.
Migrar formatos, probar agentes nuevos, romper cosas y contarlo: eso es lo que compartimos cada domingo los +6.700 developers que estamos metiendo IA en el día a día del desarrollo. Gratis, desde 2018.
Apúntate gratis →¿Qué le falta al estándar para ser serio en producción? ¶
Todo lo relacionado con la seguridad. Y lo dicen ellos, no yo: el documento de consideraciones futuras del repositorio lista siete áreas pendientes, y las cuatro primeras dan bastante respeto.
La versión 1.0.0 no define modelo de confianza, sistema de permisos ni requisitos de sandboxing. Tampoco define cómo verificar el origen o la integridad de un plugin: no hay firmas criptográficas, no hay cadenas de atestación que conecten un plugin publicado con su repositorio y su build. Tampoco hay manejo de secretos: ya vimos que env y headers son datos visibles del paquete. Ni controles de empresa: nada de listas de permitidos, registros con aprobación o configuración centralizada.
Ah, y tampoco hay dependencias entre plugins, ni linter oficial, ni suite de conformidad para clientes.
Traduzco: instalar un plugin conforme sigue siendo un acto de fe. El estándar te garantiza que el cliente sabrá leer la caja, no que lo que hay dentro sea inofensivo. Un mcp.json perfectamente conforme puede lanzar un binario que se lleve tus variables de entorno a un servidor ajeno, y la especificación no tiene nada que decir al respecto.
Y este no es un miedo teórico. Según el estudio “Agent Skills in the Wild” (Liu et al., 2026), que analizó 42.447 skills de los principales marketplaces, el 26,1% contiene al menos una vulnerabilidad y el 5,2% muestra indicios de intención maliciosa. Una de cada cuatro. Ese es el material que ahora vamos a empaquetar de forma más cómoda y a distribuir a más clientes.
Por eso escanear antes de instalar deja de ser paranoia: si te tomas en serio esto, SkillSpector y el escaneo de seguridad de skills es lectura obligatoria antes de meterte plugins ajenos en la máquina.
⚠️ Un formato portable multiplica el alcance de lo bueno y de lo malo por igual. La misma propiedad que hace que tu skill funcione en seis clientes hace que una skill maliciosa funcione en seis clientes.
Hay algo que sí resuelve bien y merece reconocimiento: VS Code marca los servidores MCP de plugins como confiados de forma implícita al instalar el plugin, sin pedir confirmación aparte al arrancar. Es cómodo. También significa que toda la decisión de seguridad se concentra en un único momento: el de instalar. Elige bien ese momento.
¿Merece la pena adoptarlo hoy? ¶
Mi respuesta corta: sí, si publicas; con calma, si consumes.
Si escribes plugins para que otros los usen, la 1.0.0 es la mejor apuesta disponible ahora mismo. Un manifiesto en la raíz, un mcp.json y tus skills sin tocar te abren ChatGPT, Codex, Cursor, Copilot, Kiro y VS Code. Cinco de los seis clientes con más tracción del mercado, con un cambio que te cuesta una tarde. La relación esfuerzo-alcance no tiene discusión.
Si solo consumes plugins, no vas a notar nada durante un tiempo. Tu cliente ya lee el formato que lee, y los buenos (VS Code es el ejemplo) soportan cuatro formatos a la vez precisamente para que a ti te dé igual.
Lo que sí me parece que ha cambiado de verdad es otra cosa, y no es técnica: por primera vez hay una mesa donde AWS, Cursor, Microsoft, OpenAI y Vercel se sientan a acordar cómo se empaqueta una extensión de agente, con una carta técnica que prohíbe que uno solo controle la mayoría. Eso, en un sector que lleva dos años inventando formatos incompatibles cada trimestre, es más noticia que el plugin.json.
Falta el que falta. Y mientras falte, “escribe una vez, ejecuta en todas partes” seguirá teniendo un asterisco.
¿Tú qué vas a hacer con el plugin que tienes a medias en el cajón?
TL;DR ¶
- 🧩 Agent Plugins 1.0.0 es un estándar abierto para empaquetar Agent Skills y servidores MCP: un directorio con
plugin.jsonen la raíz, skills enskills/y MCP enmcp.json. - 🤝 Lo impulsó Vercel y lo refinaron AWS, Anysphere (Cursor), GitHub, Microsoft y OpenAI. Cinco Core Maintainers, ningún fabricante con mayoría. Anthropic no está.
- 🔌 Soportado en el lanzamiento por ChatGPT, Codex, Cursor, GitHub Copilot, Kiro y VS Code.
- 📦 Solo estandariza dos tipos de componente: skills y MCP. Hooks, comandos, agentes y LSP quedan fuera y viajan como extensiones de cliente.
- 🔐 La 1.0 no define permisos, sandboxing, firmas ni secretos: instalar un plugin sigue siendo un acto de confianza.
- 🛠️ Crear uno es
mkdiry dos ficheros: no hay CLI oficial, ni scaffolding, ni validador. Instalarlo sí cambia en cada cliente, porque el estándar no define la instalación. - 🚚 Si vienes de Claude Code, migrar es mover el manifiesto a la raíz, renombrar
.mcp.json, cambiar${CLAUDE_PLUGIN_ROOT}por${PLUGIN_ROOT}y no tocar las skills.
Preguntas frecuentes sobre Agent Plugins ¶
¿Qué es Agent Plugins? ¶
Agent Plugins es una especificación abierta y neutral que define un formato portable para empaquetar Agent Skills y servidores MCP en plugins distribuibles. Un plugin conforme es un directorio con un manifiesto plugin.json en la raíz, las skills en skills/ y la configuración MCP en mcp.json.
¿Quién ha creado el estándar Agent Plugins? ¶
La propuesta la inició Vercel y la refinaron representantes de Amazon Web Services, Anysphere (Cursor), GitHub, Microsoft y OpenAI hasta publicar la versión 1.0.0. El comité técnico lo forman cinco Core Maintainers, con Jonathan Hefner (Vercel) como Lead Core Maintainer.
¿Qué clientes soportan Agent Plugins? ¶
En el lanzamiento lo soportan ChatGPT, Codex, Cursor, GitHub Copilot, Kiro y VS Code. Claude Code no figura entre los clientes compatibles y Anthropic no participa en el comité técnico del estándar.
¿Cómo creo un plugin conforme al estándar? ¶
Creando un directorio con un plugin.json en la raíz que declare el $schema canónico y un name válido, y poniendo tus skills en skills/<nombre>/SKILL.md. Si el plugin trae servidores MCP, añades un mcp.json en la raíz con la misma versión de esquema. No hay CLI oficial ni scaffolding: el estándar es un contrato de rutas.
¿Cómo instalo un plugin de Agent Plugins? ¶
Depende del cliente, porque el estándar no define la instalación. En VS Code puedes buscar @agentPlugins en la vista de extensiones, ejecutar Chat: Install Plugin From Source con una URL de repositorio Git, o registrar una carpeta local con el ajuste chat.pluginLocations. Antes de nada, comprueba que chat.plugins.enabled está activado.
¿Qué campos son obligatorios en plugin.json? ¶
Solo dos: $schema, que debe contener el identificador canónico https://agent-plugins.org/schemas/1.0.0/plugin.schema.json, y name. El resto (version, description, author, homepage, repository, license, keywords y extensions) es opcional, y no se admite ningún otro campo de primer nivel.
¿Agent Plugins soporta hooks y comandos slash? ¶
No. La versión 1.0 define solo dos tipos de componente portables: skills y servidores MCP. Los hooks, comandos, agentes, reglas y servidores LSP se consideran demasiado específicos de cada cliente y deben viajar bajo un directorio de extensión con espacio de nombres de dominio invertido.
¿Cuál es la diferencia entre PLUGIN_ROOT y PLUGIN_DATA? ¶
PLUGIN_ROOT apunta a la carpeta del plugin y sirve para referenciar scripts, binarios y ficheros que vienen en el paquete. PLUGIN_DATA apunta a un directorio escribible que gestiona el cliente y cuyo contenido se preserva entre actualizaciones: úsalo para dependencias instaladas, cachés y estado generado.
¿Puedo migrar un plugin de Claude Code a Agent Plugins? ¶
Sí, si tu plugin se basa en skills y MCP. Hay que mover .claude-plugin/plugin.json a plugin.json en la raíz, añadir el campo $schema, renombrar .mcp.json a mcp.json y sustituir ${CLAUDE_PLUGIN_ROOT} por ${PLUGIN_ROOT}. La carpeta skills/ no cambia. Los hooks y agentes no son portables.
¿Qué transportes MCP admite el estándar? ¶
Tres: stdio para procesos locales, streamable-http para el transporte HTTP actual de MCP y sse para el HTTP+SSE heredado de la especificación de 2024-11-05. Un cliente conforme debe soportar al menos stdio o streamable-http; el soporte de sse es opcional.
¿Es seguro instalar un plugin conforme al estándar? ¶
El estándar no lo garantiza. La versión 1.0.0 no define modelo de confianza, permisos, sandboxing, firmas criptográficas ni manejo de secretos: todas esas áreas figuran como consideraciones futuras. Conformidad significa que el cliente sabrá leer el paquete, no que su contenido sea inofensivo.
¿Puedo poner claves de API en el mcp.json de mi plugin? ¶
No deberías. La especificación es explícita: los valores de env y las cabeceras HTTP son datos visibles del paquete y los plugins tienen prohibido embeber credenciales en ellos. La versión 1.0 no define ningún mecanismo portable de secretos, así que la gestión de credenciales queda en manos del cliente.
Fuentes ¶
- Especificación Agent Plugins 1.0.0 (texto normativo completo)
- Carta técnica y gobernanza del proyecto
- Consideraciones futuras: lo que no entra en la 1.0
- Esquema del manifiesto plugin.json
- Documentación de agent plugins en VS Code
- Documentación de plugins de Claude Code
- Agent Plugins for AWS (awslabs/agent-plugins)
- Sitio oficial del estándar
🧨 Última oprtunidad para recibir la dinamita que mereces sobre programación con IA el próximo domingo: Suscríbete gratis a Web Reactiva en https://webreactiva.com/newsletter
12 recursos para developers cada domingo en tu bandeja de entrada
Además de una skill práctica bien explicada, trucos para mejorar tu futuro profesional y una pizquita de humor útil para el resto de la semana. Gratis.