Descubrimiento, resolución y carga por parte del cliente
Descubrimiento, resolución y carga por parte del cliente
Los cinco capítulos anteriores describieron el paquete: el manifiesto, los skills, el
mcp.json. Este capítulo describe la otra mitad del contrato: qué está obligado a
hacer el cliente cuando encuentra ese paquete en disco. Agent Plugins 1.0.0 fija
con lenguaje normativo dónde se busca el manifiesto, en qué momento se valida, dónde
se buscan los componentes, cómo se resuelven las rutas y —lo más importante para
quien escribe plugins— qué fallos son fatales y cuáles no.
También fija sus propios límites: hay decisiones que la especificación declara explícitamente fuera de su alcance, y confundirlas con parte del contrato es la forma más rápida de escribir un plugin que solo funciona en un cliente.
1. Lenguaje normativo y actores
La sección 2, Conformance language, dice que MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY y OPTIONAL se interpretan según RFC 2119 y RFC 8174 cuando y solo cuando aparecen en mayúsculas. Traduzco DEBE (MUST), NO DEBE (MUST NOT), DEBERÍA (SHOULD), NO DEBERÍA (SHOULD NOT) y PUEDE (MAY).
La misma sección advierte que el Apéndice A y las Design Decisions no son normativos; todas las demás secciones sí lo son. Cuando cite una decisión de diseño, la marco como contexto, no como regla.
Los tres términos de §3 que importan aquí, en su definición literal: el plugin
root es “The top-level directory of a plugin package”, el manifest es “A
plugin.json file at the plugin root”, y el client es “A tool that discovers,
installs, loads, and executes plugin components”. El cliente está definido por lo que
hace; todo lo que sigue son sus obligaciones.
2. Paso uno: localizar el manifiesto
La sección 5.1, Location and loading, es la frase más corta y más importante del
documento: “Clients MUST check for a manifest at plugin.json in the plugin root.”
Los clientes DEBEN buscar un manifiesto en plugin.json en la raíz del plugin. No en
.plugin/plugin.json, no en manifest.json, no en un archivo configurable: una sola
ruta fija. La misma sección añade dos aclaraciones normativas:
The Agent Plugins core specification defines exactly one portable manifest per plugin. No other file can replace, supplement, or override the core fields in root
plugin.json.
Un plugin tiene exactamente un manifiesto portable. Si un cliente inventa un
plugin.local.json que pisa el name, eso no es parte del formato portable.
A client loads and validates root
plugin.jsonbefore discovering components or applying client-specific behavior.
Este es el orden: primero manifiesto, después componentes, después comportamiento
específico del cliente. Nunca al revés. El bloque no normativo de Design Decisions
explica por qué bajo el título “Why root-level plugin.json is the conformance
floor”: da a quien escribe plugins un único manifiesto garantizado que funciona en
todos los clientes sin conocer rutas propietarias.
3. Paso dos: seleccionar las reglas de validación con $schema
Antes de validar el manifiesto, el cliente tiene que saber contra qué lo valida.
Eso lo decide $schema, y la §5.2 lo regula con cuatro obligaciones encadenadas:
- Para Agent Plugins 1.0.0, el valor de
$schemaDEBE ser el identificador canónicohttps://agent-plugins.org/schemas/1.0.0/plugin.schema.json. - Los clientes DEBEN usar un valor de
$schemareconocido para seleccionar las reglas de validación e interpretación soportadas localmente. - Un cliente PUEDE mapear varios identificadores canónicos a la misma implementación solo cuando reconoce explícitamente esas versiones de Agent Plugins como compatibles.
- Los clientes NO DEBEN recuperar un esquema mientras cargan un plugin.
La cuarta es la que más importa: “Clients MUST NOT retrieve a schema while loading a
plugin.” El identificador es un nombre, no una dirección para descargar. Cargar
un plugin no hace peticiones de red al dominio agent-plugins.org; un cliente que
hiciera fetch de ese URL en tiempo de carga estaría violando la especificación. Y
el desenlace cuando la versión no se soporta:
If a client does not support the declared Agent Plugins version or an explicitly recognized compatible version, it MUST reject the plugin and SHOULD report the unsupported version.
Rechazo del plugin completo, con reporte recomendado. Volveremos sobre esto en el capítulo 7, versionado y conformidad.
4. Paso tres: validar el manifiesto y decidir la fatalidad
Aquí está la asimetría clave del formato. El esquema de plugin.json es cerrado:
los únicos campos top-level permitidos son $schema, name, version,
description, author, homepage, repository, license, keywords y
extensions. Pero no todas las violaciones de ese esquema pesan igual.
4.1 Las dos excepciones no fatales
La §5.2 y la §8.1 definen exactamente dos desviaciones que no matan el plugin. Para un campo top-level desconocido:
Clients MUST report and ignore each unknown field and MUST continue loading the plugin if the manifest otherwise satisfies this section. Clients MUST NOT assign semantics to unknown fields.
Tres obligaciones en una frase: reportar, seguir cargando y no asignar semántica.
Para un extensions que no es objeto, la §8.1 impone el mismo tratamiento:
“the client MUST report and ignore the field and continue loading components.”
4.2 Todo lo demás es fatal
Any schema violation other than an unknown top-level field or a non-object
extensionsfield is fatal: the client MUST reject the plugin and MUST NOT discover or execute any of its components.
“Fatal” tiene un significado preciso: rechazar el plugin y no descubrir ni ejecutar ninguno de sus componentes. No es “carga lo que puedas”, es un cero absoluto. La §5.3 lo repite para los campos requeridos: si falta uno, tiene el tipo equivocado, está vacío o incumple sus restricciones, el cliente DEBE rechazar y DEBERÍA reportar cuál es.
La §5.4 añade el matiz que evita rechazos por celo: los clientes NO DEBEN rechazar un
manifiesto solo porque version no sea SemVer válido, homepage, repository o
author.url no sean URLs reconocidas, author.email no sea un email reconocido, o
license no sea un identificador SPDX. Salvo restricción explícita, los metadatos se
validan solo por su tipo JSON.
4.3 Tabla de fatalidad
| Situación en el manifiesto | Consecuencia normativa |
|---|---|
| Campo top-level desconocido | No fatal: reportar, ignorar, continuar |
extensions no es objeto | No fatal: reportar, ignorar, continuar |
Falta $schema o name | Fatal: rechazar el plugin |
name incumple las restricciones de §5.5 | Fatal: rechazar el plugin |
Campo desconocido dentro de author | Fatal: rechazar el plugin |
$schema de versión no soportada | Fatal: rechazar el plugin, reportar la versión |
plugin.json no resuelve dentro del plugin root | Fatal: rechazar el plugin |
version no es SemVer | No es motivo de rechazo |
license no es SPDX | No es motivo de rechazo |
El detalle campo por campo está en el capítulo 3 sobre el manifiesto.
5. Paso cuatro: descubrir los componentes en ubicaciones fijas
Con el manifiesto validado, el cliente busca componentes. La sección 6.1, Fixed locations, es tajante:
Clients MUST discover each supported component type from its fixed location.
plugin.jsoncannot override these locations or contain inline component configuration.
Las ubicaciones, literales de la tabla de §6.1:
| Tipo de componente | Ubicación fija | Patrón |
|---|---|---|
| Skills | skills/ | Subdirectorios que contienen SKILL.md |
| Servidores MCP | mcp.json | Configuración JSON |
Dos rutas. No hay campo en el manifiesto que las cambie, no hay configuración en línea, no hay fuentes alternativas con precedencia. El bloque no normativo de Design Decisions explica el motivo bajo “Why directory-based discovery?”: las ubicaciones fijas eliminan la indirección de descubrimiento, la precedencia entre fuentes y la configuración de manifiesto que si no todos los clientes tendrían que implementar.
5.1 Ausencia no es error
La sección 6.2, Missing locations, separa dos casos que suelen confundirse:
If a fixed component location is absent, the client MUST NOT treat that as an error.
Un plugin sin skills/ es válido, sin mcp.json también, y con solo plugin.json
también. Ausencia no es error y el cliente NO DEBE tratarla como tal.
If a fixed component location is present but does not resolve to the expected filesystem kind — for example,
skillsdoes not resolve to a directory ormcp.jsondoes not resolve to a regular file — the client MUST treat that component type as invalid and continue loading other supported component types.
Presencia con el tipo de archivo equivocado sí es un problema, pero acotado: ese
tipo queda inválido y el cliente sigue cargando los demás. Un skills que resultó ser
un archivo no impide que se cargue el mcp.json.
6. Cómo se resuelven las rutas: contención en el plugin root
La sección 4.1, General requirements, define la regla que atraviesa toda la carga, en tres piezas:
- Contención. Cuando un cliente descubre, lee o ejecuta un archivo o directorio suministrado por el paquete, la ruta resuelta en el sistema de archivos DEBE permanecer dentro del plugin root resuelto. Enlaces simbólicos, junctions, reparse points y mecanismos equivalentes PUEDEN resolver a destinos dentro del plugin root, pero los clientes DEBEN rechazar rutas del paquete que resuelvan fuera de él.
- Forma de las rutas relativas. Un campo que la especificación define como ruta
relativa al plugin DEBE empezar con
./, resolverse contra el plugin root y permanecer dentro del plugin root resuelto tras la resolución. - Opacidad de lo que no es ruta. Los valores no definidos como rutas —incluidos argumentos de comando y valores de variables de entorno— son cadenas opacas. Los clientes NO DEBEN interpretarlas como rutas del paquete a efectos de esta contención.
La especificación ilustra la diferencia con dos bloques. El válido:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"server": {
"type": "stdio",
"command": "./bin/server",
"cwd": "./data"
}
}
}
Y el inválido:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"server": {
"type": "stdio",
"command": "../bin/server",
"cwd": "data"
}
}
}
El texto de la especificación explica ambos: el primero es válido porque las dos
rutas empiezan con ./ y se quedan dentro del plugin root; el segundo es inválido
porque ../bin/server escapa del plugin root y data no es una ruta relativa al
plugin, le falta el ./. Esa segunda mitad es la que se olvida: data no es “casi
igual” que ./data, el prefijo es obligatorio, no cosmético.
La misma sección acota el alcance: estas reglas gobiernan el acceso a archivos del paquete. No aíslan un subproceso del plugin en una caja de arena ni restringen rutas suministradas en tiempo de ejecución.
7. La escalera de fallos: el límite más estrecho aplicable
Cuando una ruta incumple la contención, el cliente no rechaza el plugin entero: DEBE aplicar el límite de fallo más estrecho aplicable. La §4.1 lo enumera:
- Si
plugin.jsonno resuelve dentro del plugin root, el cliente DEBE rechazar el plugin. - Si la ubicación fija de un componente no resuelve dentro del plugin root, el cliente DEBE tratar ese tipo de componente como inválido bajo §6.2.
- Si un
SKILL.mddescubierto no resuelve dentro del plugin root, el cliente DEBE saltar ese skill bajo §7.1. - Si el
commando elcwdde un servidor MCP falla la contención, el cliente DEBE tratar esa entrada de servidor como inválida bajo §7.2.2. - Para cualquier otra ruta del paquete que resuelva fuera del plugin root, el cliente DEBE denegar el acceso a esa ruta.
Léase como una escalera de radios: el plugin entero, el tipo de componente, el skill individual, la entrada de servidor, la ruta suelta. El daño se contiene en el escalón más bajo posible.
flowchart TD
A["Ruta del paquete resuelve fuera del plugin root"] --> B{"Que ruta es"}
B -->|"plugin.json"| C["Rechazar el plugin completo"]
B -->|"Ubicacion fija de componente"| D["Tipo de componente invalido, seguir con los demas"]
B -->|"Un SKILL.md descubierto"| E["Saltar ese skill, seguir con los demas"]
B -->|"command o cwd de un servidor MCP"| F["Entrada de servidor invalida, seguir con las demas"]
B -->|"Cualquier otra ruta"| G["Denegar acceso a esa ruta"]
C --> H["Ningun componente se descubre ni ejecuta"]
D --> I["Carga parcial exitosa"]
E --> I
F --> I
G --> I
8. Descubrimiento de skills: una sola capa de profundidad
La sección 7.1 define el algoritmo exacto:
The fixed discovery location is
skills/. Each immediate child directory containing a path named exactlySKILL.mdthat resolves to a regular file is treated as one skill. Clients MUST NOT recursively search deeper descendants for additional skills.
Descomponiéndolo:
- Hijo inmediato: solo el primer nivel bajo
skills/. UnSKILL.mdenskills/grupo/deploy/SKILL.mdno se descubre. - Nombre exacto:
SKILL.md, con esas mayúsculas. Noskill.md, noSkill.md. - Archivo regular: un directorio llamado
SKILL.mdno cuenta. - NO DEBEN recursar: la prohibición es explícita, no una omisión.
Ese último punto tiene una consecuencia práctica agradable: los subdirectorios
scripts/, references/ y assets/ de un skill nunca se confunden con skills
nuevos, porque el cliente jamás mira ahí buscando SKILL.md. Ejemplo literal de la
especificación:
skills/
└── deploy/
├── SKILL.md # name: deploy
├── scripts/
│ └── rollback.sh
└── references/
└── runbook.md
Y el fallo acotado:
If a discovered skill does not conform to the Agent Skills specification, the client MUST skip that skill and continue loading other skills and component types. The client SHOULD report the invalid skill.
Un skill roto se salta; los demás skills y tipos de componente siguen cargando, y el reporte es DEBERÍA, no DEBE. Qué significa “conformar a la Agent Skills specification” está en el curso de Agent Skills, y cómo se empaqueta dentro del plugin en el capítulo 4.
9. Carga de MCP: cinco reglas de aislamiento
La sección 7.2.2, Loading rules, enumera cinco reglas. Las traduzco enteras porque cada una define un límite de fallo distinto:
- Los clientes que soportan servidores MCP DEBEN cargar la configuración
únicamente desde
mcp.jsonen la raíz del plugin. - Si
mcp.jsonno es JSON válido, apunta a una versión de Agent Plugins para la que el cliente no tiene soporte ni compatibilidad explícitamente reconocida, apunta a una versión distinta de la deplugin.json, o no satisface los demás requisitos top-level de §7.2.1, el cliente DEBE deshabilitar MCP para ese plugin y continuar cargando otros tipos de componente. DEBERÍA reportar la configuración inválida, no soportada o desajustada. - Si una entrada de servidor individual no satisface los requisitos de §7.2.1, el cliente DEBE saltar ese servidor y continuar con los demás servidores y tipos de componente. DEBERÍA reportar la entrada inválida.
- Si el cliente no soporta el transporte declarado por una entrada de servidor por lo demás válida, DEBE saltar ese servidor y continuar. DEBERÍA reportar el transporte no soportado.
- Si un servidor falla al arrancar, conectar, autenticar o completar el handshake MCP, el cliente DEBE continuar cargando los demás servidores y tipos de componente. DEBERÍA reportar el fallo de conexión.
Obsérvese la gradación: la regla 2 tumba todo el MCP del plugin; las reglas 3, 4 y 5 tumban una sola entrada. La diferencia está en si el problema es del archivo o de un servidor. La regla 5 tiene un corolario que la §7.2.1 hace explícito: “An authorization failure is a connection failure for that server, not invalid plugin configuration.” El detalle de las variantes de transporte está en el capítulo 5.
10. El ciclo de carga completo
Juntando todo, este es el ciclo que la especificación impone:
flowchart TD
A["Cliente recibe una ruta de directorio"] --> B["Buscar plugin.json en el plugin root"]
B --> C{"Existe y resuelve dentro del root"}
C -->|No| Z["Rechazar el plugin"]
C -->|Si| D["Leer $schema y seleccionar reglas locales"]
D --> E{"Version soportada o compatible reconocida"}
E -->|No| Z
E -->|Si| F["Validar el esquema cerrado del manifiesto"]
F --> G{"Tipo de violacion"}
G -->|"Campo top-level desconocido"| H["Reportar, ignorar y continuar"]
G -->|"extensions no es objeto"| H
G -->|"Cualquier otra violacion"| Z
G -->|Ninguna| I["Manifiesto valido"]
H --> I
I --> J["Descubrir componentes en ubicaciones fijas"]
J --> K["skills: hijos inmediatos con SKILL.md regular"]
J --> L["mcp.json: objeto con $schema y mcpServers"]
K --> M["Saltar skills no conformes, cargar el resto"]
L --> N{"mcp.json valido y de version coincidente"}
N -->|No| O["Deshabilitar MCP en este plugin, seguir"]
N -->|Si| P["Validar cada entrada de servidor por separado"]
P --> Q["Saltar entradas invalidas o de transporte no soportado"]
M --> R["Aplicar comportamiento especifico del cliente"]
O --> R
Q --> R
R --> S["Leer extensions y directorios de namespace implementados"]
S --> T["Plugin cargado, posiblemente de forma parcial"]
Un punto que conviene subrayar: la especificación fija el orden manifiesto → componentes → comportamiento específico del cliente, pero no fija un orden entre skills y MCP. Un plugin portable no puede asumir que sus skills están disponibles antes de que arranque su servidor MCP, ni al revés.
11. Qué ignora el cliente
Recopilando todas las obligaciones de ignorar que aparecen dispersas:
| Qué se ignora | Regla | Sección |
|---|---|---|
Campos top-level desconocidos en plugin.json | Reportar e ignorar; NO DEBE asignarles semántica | §5.2 |
extensions que no es objeto | Reportar e ignorar; continuar cargando componentes | §8.1 |
Namespaces de extensions no implementados | Ignorar sin validar el contenido de sus valores | §8.1, §11.1 |
| Tipos de componente no soportados | Los clientes DEBEN ignorarlos | §7, §11.3 |
| Texto que parece marcador pero no lo es | DEBE permanecer literal | §9.2 |
La tercera merece énfasis. La §8.1 dice: “A client MUST ignore manifest entries for
namespaces it does not implement without validating the contents of their values.”
Un cliente no puede quejarse de que el bloque de otro esté mal formado por dentro; ni
siquiera puede mirarlo. Solo verifica que el valor sea un objeto y sigue de largo. Lo
mismo con los directorios de extensión: un com.example.client/ en la raíz no es
basura ni error para otro cliente, es contenido ajeno que se ignora.
12. Qué rechaza el cliente
Solo cuatro situaciones producen rechazo del plugin completo:
plugin.jsonausente o que no resuelve dentro del plugin root.$schemaque declara una versión de Agent Plugins que el cliente no soporta ni reconoce explícitamente como compatible.- Falta un campo requerido, o tiene tipo incorrecto, o está vacío, o incumple sus restricciones —incluidas las de nombre de §5.5—.
- Cualquier otra violación del esquema cerrado que no sea campo top-level
desconocido ni
extensionsno objeto.
Todo lo demás se degrada. La sección 11.3 lo formula como principio general:
A failure isolated to a component type, component entry, or component process MUST NOT prevent the client from loading independently valid components.
Y remata con el matiz sobre soporte parcial: los clientes DEBERÍAN reportar configuración inválida y fallos de componente; PUEDEN reportar plugins parcialmente no soportados, pero la falta de soporte para un tipo de componente, un transporte MCP o una extensión de cliente no es en sí un error.
13. El piso de conformidad del cliente
La sección 11.1, Minimum client requirements, lista los ocho puntos que un cliente conformante DEBE poder hacer:
| # | Capacidad mínima |
|---|---|
| 1 | Cargar un plugin desde una ruta de directorio |
| 2 | Seleccionar un esquema de manifiesto soportado localmente a partir de $schema, y luego parsear y validar el esquema cerrado de plugin.json con las excepciones no fatales de §5.2 y §8.1 |
| 3 | Ignorar miembros no implementados de extensions sin validar el contenido de sus valores |
| 4 | Para cada tipo de componente que soporte, descubrir componentes en su ubicación fija |
| 5 | Si soporta MCP, seleccionar un esquema de configuración MCP soportado localmente a partir de $schema y soportar al menos stdio o streamable-http |
| 6 | Si lanza subprocesos del plugin, proveer PLUGIN_ROOT y PLUGIN_DATA y expandir ambas variables en args, env y cwd |
| 7 | Para servidores MCP stdio, resolver command como un único token ejecutable y usar el plugin root como directorio de trabajo por defecto |
| 8 | Soportar al menos un tipo de componente: skills o servidores MCP |
Y la sección 11.2, Incremental adoption, cierra la puerta a exigir lo demás: un cliente no está obligado a soportar todos los tipos de componente. El ejemplo es textual: un cliente solo-skills puede conformar sin soportar MCP, siempre que satisfaga todos los requisitos aplicables.
14. Qué queda explícitamente fuera del alcance
Esta es la sección que más debería leer quien escribe plugins, porque delimita lo que no puede asumir. Lo primero y lo más citable: cómo el cliente expone los skills al usuario o al modelo. La §7.1 lo dice literalmente:
This specification defines how Agent Skills are discovered within a plugin, not the skill format itself or how clients expose skills to users or models.
La especificación define el descubrimiento. No define el formato del skill —eso es
la Agent Skills specification, que la §7.1 declara “the source of truth for the
SKILL.md format, frontmatter fields, and directory layout”— ni cómo el cliente lo
presenta. Si un skill aparece como comando, como herramienta, como instrucción
inyectada en el contexto o como entrada de un menú, lo decide el cliente. Un plugin
portable no puede documentar “invoca este skill con /mi-skill”: esa sintaxis no
está en ningún lugar del contrato.
El resto de lo excluido:
| Fuera del alcance | Dónde lo dice | Cita o regla |
|---|---|---|
| Semántica de cable y ciclo de vida de MCP | §7.2 | La define la especificación de Model Context Protocol; Agent Plugins solo define mcp.json para localizar y conectar |
| Mapeo a la configuración nativa del cliente | §7.2 | ”its field names and values need not match a client-native format” |
| Reintento tras un fallo de transporte | §7.2.1 | ”Agent Plugins does not define fallback behavior if that attempt fails” |
| OAuth, credenciales y autorización | §7.2.1 | v1 no define configuración de OAuth ni campos portables de referencia a credenciales; todo es gestionado por el cliente |
Ubicación de PLUGIN_DATA y entorno base | §9.1 | El cliente elige ambos y PUEDE heredar, omitir o sanear variables del ambiente |
Si PATH resuelve un command sin ruta | §7.2.1 | ”is client-defined. Plugins claiming conformance MUST NOT depend on that behavior” |
| Contenido de cualquier namespace de extensión | §8 | Agent Plugins no asigna semántica portable de descubrimiento, validación, carga ni fallo |
| Aislamiento del subproceso | §4.1 | Las reglas de contención no ponen el subproceso en una caja de arena |
| Otros tipos de componente | §7 | ”Other component types are outside the v1 format and do not affect conformance” |
15. Implicaciones para quien escribe un plugin portable
El contrato traducido a decisiones concretas:
- Diseña para carga parcial. Tu plugin puede llegar al usuario con el MCP deshabilitado y los skills cargados, o con dos de tus tres servidores saltados por transporte no soportado. La especificación garantiza que eso ocurra en vez de un fallo total. Un skill que asume que su servidor MCP compañero está vivo fallará en silencio en algún cliente: documenta la degradación.
- Nunca dependas del orden entre skills y MCP. El contrato no lo fija.
- Empieza toda ruta relativa con
./../bin/serversí,bin/serverno. Es un error trivial de consecuencias acotadas pero reales: la entrada de servidor queda inválida y se salta. - Un solo nivel bajo
skills/. Si agrupas skills en subcarpetas temáticas, el cliente no los encontrará. La prohibición de recursar es normativa. - No inventes campos top-level en
plugin.json. No matan el plugin —se reportan y se ignoran— pero aparecerán como advertencias en cada cliente y nunca harán nada. Los datos propios van enextensionsbajo un namespace de dominio inverso. - No dependas del
PATH. La especificación es explícita: “A plugin that bundles an executable in the package MUST use a plugin-relativecommand.” - No escribas en el plugin root. Ahí van los archivos que envías. El estado que
debe sobrevivir a las actualizaciones va en
${PLUGIN_DATA}, que el cliente DEBE preservar entre actualizaciones y PUEDE borrar en la desinstalación. - Mantén
mcp.jsonyplugin.jsonen la misma versión. Un desajuste entre ambos$schemadeshabilita MCP para todo el plugin bajo la regla 2 de §7.2.2. Es de los pocos errores que apagan un tipo de componente entero. - No documentes la interfaz de usuario. Cómo se invoca tu skill lo decide el cliente. Documenta qué hace y cuándo es útil, no cómo se teclea.
- No pongas secretos en
envni enheaders. La especificación lo prohíbe en ambos sitios con la misma fórmula: son datos visibles del paquete, no un mecanismo portable de secretos.
Para ver cómo se ve esto en catálogos reales, el
curso de Google Skills recorre un
repositorio publicado con skills y plugins. Con un matiz que conviene no perder:
ese repositorio no declara conformidad con Agent Plugins 1.0.0 —no publica
plugin.json con el $schema canónico— y su carga la definen los clientes que lo
consumen, no esta especificación. Sirve como referencia de catálogo real, no como
ejemplo del contrato de carga descrito en este capítulo.
Resumen
- El cliente DEBE buscar el manifiesto en
plugin.jsonen el plugin root, y lo carga y valida antes de descubrir componentes o aplicar comportamiento propio. $schemaselecciona las reglas de validación locales. Los clientes NO DEBEN descargar el esquema durante la carga; una versión no soportada rechaza el plugin.- El esquema del manifiesto es cerrado, pero solo dos desviaciones son no fatales:
campo top-level desconocido y
extensionsque no es objeto. Ambas se reportan, se ignoran y la carga continúa; cualquier otra violación rechaza el plugin entero. - Los componentes se descubren en ubicaciones fijas —
skills/ymcp.json— que el manifiesto no puede sobrescribir. Ausencia no es error; presencia con el tipo de archivo equivocado invalida solo ese tipo de componente. - Las rutas relativas al plugin DEBEN empezar con
./y permanecer dentro del plugin root resuelto. Al fallar la contención, el cliente aplica el límite de fallo más estrecho aplicable, en una escalera de cinco escalones. - Los skills se descubren solo en hijos inmediatos de
skills/con unSKILL.mdque resuelva a archivo regular; los clientes NO DEBEN recursar más profundo. - En MCP, un
mcp.jsonroto o de versión desajustada deshabilita MCP para el plugin; una entrada rota, de transporte no soportado o que falla al conectar solo se salta a sí misma. - Un cliente conformante cumple ocho requisitos mínimos y soporta al menos un tipo de componente. La adopción incremental está permitida: un cliente solo-skills conforma.
- Queda fuera del alcance, entre otras cosas, cómo el cliente expone los skills al usuario o al modelo, el reintento tras un fallo de transporte, la autorización y las credenciales, y el contenido de cualquier namespace de extensión.
Siguiente: Versionado, compatibilidad y conformidad