Cap 15: Plugins
Qué son los Plugins
Los plugins extienden Claude Code con funcionalidad custom compartible entre proyectos y equipos. Pueden incluir skills, agents, hooks, MCP servers, LSP servers, monitors, settings y binarios.
Plugins vs configuración standalone
| Approach | Skill names | Best para |
|---|---|---|
Standalone (.claude/) | /hello | Workflows personales, customización por proyecto, experimentos |
Plugins (con .claude-plugin/plugin.json) | /plugin-name:hello | Compartir con el equipo, distribuir a la comunidad, versionado, reusable |
Usa standalone cuando customizás para un único proyecto y los nombres cortos importan.
Usa plugin cuando quieres compartir, versionar, distribuir via marketplace, o reusar en múltiples proyectos. Los plugin skills tienen namespace para evitar conflictos.
Empezá con standalone para iterar rápido y convertí a plugin cuando estés listo para compartir.
Por qué skills/ y no commands/
Los comandos personalizados y las skills se fusionaron en un mismo sistema: .claude/commands/deploy.md y .claude/skills/deploy/SKILL.md generan ambos /deploy y comparten el mismo frontmatter. Ante colisión de nombre, gana la skill. Esa es la razón de fondo por la que en plugins nuevos conviene escribir todo como skills. Ver Extend Claude with skills.
Quickstart
1. Crear directorio del plugin
mkdir my-first-plugin
mkdir my-first-plugin/.claude-plugin
2. Crear el manifest
my-first-plugin/.claude-plugin/plugin.json:
{
"name": "my-first-plugin",
"description": "A greeting plugin to learn the basics",
"version": "1.0.0",
"author": { "name": "Your Name" }
}
| Campo | Propósito |
|---|---|
name | Identificador único y namespace de skills. Los skills llevan prefix (/my-first-plugin:hello) |
description | Mostrado en el plugin manager |
version | Opcional. Si se setea, los users reciben updates solo cuando bumpés. Sin esto, el commit SHA se usa como versión |
author | Opcional. Atribución |
El manifiesto es opcional: si falta, los componentes se autodescubren y el nombre sale del directorio. Si existe, solo name es obligatorio.
Campos soportados por el schema vigente:
$schema, displayName (v2.1.143+), version, description, author, homepage, repository, license, keywords, defaultEnabled (v2.1.154+), skills, commands, agents, hooks, mcpServers, outputStyles, lspServers, userConfig, channels, dependencies y experimental.{themes,monitors}.
Los campos no reconocidos se ignoran con un warning; claude plugin validate --strict los convierte en error. Ver Plugin manifest schema.
Plugin de una sola skill (v2.1.142+): un plugin con
SKILL.mden la raíz se carga directamente como plugin de una skill, sin necesidad del directorioskills/ni del manifiesto.
3. Agregar un skill
mkdir -p my-first-plugin/skills/hello
my-first-plugin/skills/hello/SKILL.md:
---
description: Greet the user with a friendly message
disable-model-invocation: true
---
Greet the user warmly and ask how you can help them today.
4. Testear el plugin
claude --plugin-dir ./my-first-plugin
Y luego /my-first-plugin:hello. Run /help para ver el skill bajo el plugin namespace.
Plugin skills están siempre namespaced para evitar conflictos. Para cambiar el prefix, actualizá
nameenplugin.json.
5. Argumentos en skills
---
description: Greet the user with a personalized message
---
# Hello Skill
Greet the user named "$ARGUMENTS" warmly and ask how you can help them today.
Run /reload-plugins para recargar, luego /my-first-plugin:hello Alex.
Estructura de un plugin
Error común: NO pongas
commands/,agents/,skills/, nihooks/dentro de.claude-plugin/. Soloplugin.jsonva ahí. Las demás carpetas van en el plugin root.
| Directorio | Location | Propósito |
|---|---|---|
.claude-plugin/ | Plugin root | Contiene plugin.json (opcional si componentes usan locations default) |
skills/ | Plugin root | Skills como <name>/SKILL.md directorios |
commands/ | Plugin root | Commands como archivos Markdown planos. Usa skills/ para plugins nuevos |
agents/ | Plugin root | Agent definitions. Los subagentes de plugin ignoran por seguridad hooks, mcpServers y permissionMode |
hooks/ | Plugin root | Event handlers en hooks.json |
.mcp.json | Plugin root | MCP server configs |
.lsp.json | Plugin root | LSP server configs para code intelligence |
output-styles/ | Plugin root | Output styles del plugin (campo outputStyles del manifiesto) |
bin/ | Plugin root | Ejecutables agregados al PATH del Bash tool mientras el plugin esté enabled |
settings.json | Plugin root | Default settings aplicados cuando el plugin está enabled |
Monitors y themes ya no se declaran al nivel superior: viven bajo experimental.{themes,monitors} en el manifiesto (ver Background monitors).
Identidad de subagentes en plugins: a diferencia de los subagentes normales (donde la identidad viene solo del campo
name), en plugins el path cuenta:agents/review/security.mdse registra comomy-plugin:review:security.
Reglas de resolución de rutas
Todas las rutas del manifiesto son relativas a la raíz del plugin y empiezan por ./. Lo que hacen respecto del directorio por defecto:
| Campo | Comportamiento |
|---|---|
commands, agents, outputStyles, experimental.themes, experimental.monitors | Reemplazan el directorio por defecto |
skills | Se suma al escaneo por defecto de skills/ |
hooks, mcpServers, lspServers | Tienen reglas de fusión propias |
Variables disponibles en las rutas y comandos:
| Variable | Significado |
|---|---|
${CLAUDE_PLUGIN_ROOT} | Raíz del plugin instalado |
${CLAUDE_PLUGIN_DATA} | Directorio persistente del plugin, sobrevive a las actualizaciones |
${CLAUDE_PROJECT_DIR} | Raíz del proyecto donde corre la sesión |
Ver Path behavior rules.
Componentes avanzados
Skills
flowchart TD
A["my-plugin/"] --> B[".claude-plugin/"]
B --> C["plugin.json"]
A --> D["skills/"]
D --> E["code-review/"]
E --> F["SKILL.md"]
Después de instalar el plugin, /reload-plugins para cargar. Ver Skills para frontmatter completo.
LSP servers
Plugins LSP dan a Claude code intelligence en tiempo real. Para lenguajes comunes (TS, Python, Rust) usa los plugins oficiales. Para custom:
.lsp.json:
{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}
Los users instalando deben tener el binario instalado en su máquina.
Background monitors
Observan logs, files, o status externo y notifican a Claude.
Monitors y themes son campos experimentales del manifiesto: se declaran bajo experimental en plugin.json, y la ruta que indiques reemplaza el directorio por defecto.
{
"name": "my-plugin",
"experimental": {
"monitors": "./monitors/monitors.json",
"themes": "./themes"
}
}
Contenido del archivo de monitors:
[
{
"name": "error-log",
"command": "tail -F ./logs/error.log",
"description": "Application error log"
}
]
Cada stdout line del command se entrega a Claude como notificación durante la sesión.
Output styles
Los plugins pueden traer output styles vía el campo outputStyles del manifiesto (reemplaza el directorio por defecto). Frontmatter disponible: name, description, keep-coding-instructions (default false) y force-for-plugin (solo plugins, default false), que fuerza el estilo mientras el plugin esté habilitado.
/output-stylefue deprecado en v2.1.73 y eliminado en v2.1.91: hoy el estilo se cambia con/configo con el campooutputStyleen settings. Ver Output styles.
Default settings con settings.json
Plugins pueden incluir settings.json en el root con defaults aplicados al habilitarse. Actualmente solo agent y subagentStatusLine están soportados.
{
"agent": "security-reviewer"
}
Esto activa el agente security-reviewer definido en agents/ como main thread cuando el plugin se habilita.
MCP servers
.mcp.json en el plugin root. Los inline servers se conectan al startup del plugin y se desconectan al deshabilitarlo.
Naming de las herramientas de plugin (difiere del estándar mcp__<server>__<tool>):
| Elemento | Forma |
|---|---|
| Herramienta | mcp__plugin_<plugin>_<server>__<tool> |
| Registro del servidor | plugin:<plugin>:<server> |
Consecuencia práctica: un matcher de hook escrito contra la clave desnuda (mcp__database-tools__.*) nunca dispara para un servidor provisto por un plugin. Ver MCP.
Testing local
# Directorio
claude --plugin-dir ./my-plugin
# ZIP archive (v2.1.128+)
claude --plugin-dir ./my-plugin.zip
# Múltiples plugins
claude --plugin-dir ./plugin-one --plugin-dir ./plugin-two
# Desde URL
claude --plugin-url https://example.com/plugin.zip
Cuando un plugin con --plugin-dir tiene el mismo nombre que uno instalado del marketplace, la versión local tiene precedencia para esa sesión. Excepción: plugins force-enabled/disabled por managed settings no pueden ser overridden con --plugin-dir.
Claves managed-only que gobiernan plugins
Estas claves solo tienen efecto en los managed settings de la organización (no en user ni project):
| Clave | Efecto |
|---|---|
allowedChannelPlugins | Restringe qué plugins pueden venir por channels |
blockedMarketplaces | Lista de marketplaces bloqueados |
strictKnownMarketplaces | Solo permite marketplaces conocidos/declarados |
strictPluginOnlyCustomization | Bloquea skills, agents, hooks y MCP servers provenientes de fuentes de usuario y de proyecto |
channelsEnabled | Habilita o deshabilita el sistema de channels |
disableSideloadFlags | Desactiva --plugin-dir / --plugin-url |
pluginTrustMessage | Mensaje de confianza mostrado al instalar plugins |
allowManagedHooksOnly | Bloquea hooks de usuario, proyecto y plugin, salvo los de plugins force-enabled |
Ver Permissions y Settings.
/reload-plugins recarga sin reiniciar (incluye skills, agents, hooks, MCP servers, LSP servers del plugin).
Debugging
- Valida el manifiesto:
claude plugin validate ./my-plugin
claude plugin validate ./my-plugin --strict
Por defecto los campos no reconocidos de plugin.json solo generan un warning; con --strict se convierten en error. Es la primera herramienta a usar cuando un plugin “carga pero no hace nada”.
- Verifica la estructura: directorios en el plugin root, no dentro de
.claude-plugin/ - Test componentes individualmente: cada skill, agent, hook separado
- Ver Debugging tools para CLI commands
Distribución
Pasos para compartir:
- README.md con instrucciones de instalación y uso
- Versioning strategy: setear
versionexplícito o usar commit SHA del git - Marketplace: distribuir via plugin marketplaces o repositorio privado para uso interno
- Test con el equipo antes de publicar
Schema de .claude-plugin/marketplace.json
Un marketplace es un repositorio con .claude-plugin/marketplace.json en la raíz.
| Campo | Obligatoriedad |
|---|---|
name | Obligatorio |
owner | Obligatorio |
plugins | Obligatorio (array) |
$schema, description, version | Opcionales |
metadata.pluginRoot | Opcional. Raíz desde la que resuelven las rutas relativas |
allowCrossMarketplaceDependenciesOn | Opcional. Marketplaces cuyos plugins pueden usarse como dependencias |
renames (v2.1.193+) | Opcional. Mapea nombres viejos a nuevos |
Cada entrada de plugins requiere name y source. Tipos de source:
| Tipo | Forma |
|---|---|
| Ruta relativa | "./plugins/mi-plugin" |
| GitHub | { "source": "github", "repo": "org/repo", "ref"?: "...", "sha"?: "..." } |
| URL | { "source": "url", "url": "...", "ref"?: "...", "sha"?: "..." } |
| Subdirectorio git | { "source": "git-subdir", "url": "...", "path": "...", "ref"?: "...", "sha"?: "..." } |
| npm | { "source": "npm", "package": "...", "version"?: "...", "registry"?: "..." } |
Campos extra por plugin: category, tags, strict, relevance (v2.1.152+) y defaultEnabled (v2.1.154+).
{
"name": "mi-marketplace",
"owner": { "name": "Mi Equipo" },
"plugins": [
{ "name": "code-review", "source": "./plugins/code-review", "category": "quality" },
{ "name": "deploy-tools", "source": { "source": "github", "repo": "mi-org/deploy-tools" } }
]
}
Nombres reservados: Anthropic reserva nombres de marketplace como
claude-code-plugins,agent-skills,healthcareyfirst-party-plugins. Usar uno de ellos hace fallar la carga del marketplace.first-party-pluginsyhealthcarese reservaron en v2.1.205.
Ver Marketplace schema.
Submit al marketplace oficial
- Claude.ai: claude.ai/settings/plugins/submit
- Console: platform.claude.com/plugins/submit
Antes de enviar, verifica que el nombre del marketplace no colisione con los nombres reservados listados arriba.
Convertir standalone a plugin
mkdir -p my-plugin/.claude-plugin
my-plugin/.claude-plugin/plugin.json:
{
"name": "my-plugin",
"description": "Migrated from standalone configuration",
"version": "1.0.0"
}
Copiar configuraciones:
cp -r .claude/commands my-plugin/
cp -r .claude/agents my-plugin/
cp -r .claude/skills my-plugin/
Migrar hooks: crear my-plugin/hooks/hooks.json copiando el objeto hooks desde .claude/settings.json.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npm run lint:fix" }]
}
]
}
}
Testear:
claude --plugin-dir ./my-plugin
Después de migrar puedes borrar los archivos originales de .claude/ para evitar duplicados. La versión del plugin tendrá precedencia.
Diferencias estándar vs plugin
| Standalone | Plugin |
|---|---|
| Solo en un proyecto | Compartible via marketplaces |
Files en .claude/commands/ | Files en plugin-name/commands/ |
Hooks en settings.json | Hooks en hooks/hooks.json |
| Copiar manualmente para compartir | Install con /plugin install |
Instalación de plugins existentes
/plugin install code-review@claude-plugins-official
Marketplace de equipo: configurar plugin marketplaces en repos privados para distribución interna.
CLI commands
claude plugin install <plugin>@<marketplace>
claude plugin list
claude plugin remove <plugin>
Alias: claude plugins. Ver plugin reference CLI commands.
Recomendar tu plugin desde tu CLI
Una vez listado en el marketplace, puedes tener tu propio CLI que prompts a usuarios de Claude Code a instalarlo. Ver /en/plugin-hints en la doc oficial.
Siguiente: Checkpointing y Sesiones