Claude

Mods en Claude Code: qué son y cómo crear el tuyo

Los mods son funciones de JavaScript o TypeScript que cambian cómo se ve y cómo se comporta Claude Code: reescriben prompts, bloquean comandos o dibujan paneles. Te explico qué son, en qué se diferencian de los hooks y cómo crear uno.

  • Javi Mata
  • 11 min de lectura
Tabla de contenido

Anthropic presentó los mods de Claude Code el 1 de octubre de 2026. Un mod es un conjunto de funciones en JavaScript o TypeScript que Claude Code ejecuta cuando ocurre un evento (una llamada a una herramienta, un prompt enviado o una parte de la interfaz que se dibuja) y que pueden observar el evento, cambiarlo o resolverlo por su cuenta. Con eso puedes añadir funciones propias, como un panel, un comando nuevo o una regla que filtre llamadas a herramientas.

Si todavía no usas Claude Code, empieza por la guía de inicio. Si ya conoces los hooks, los mods te van a sonar parecidos, pero hacen cosas que los hooks no pueden.

Mods y hooks: la diferencia

Los hooks de siempre son comandos de shell, peticiones HTTP o prompts que configuras en un archivo de ajustes. Los mods son funciones que corren dentro de Claude Code. La documentación oficial llama “hook” a ambos tipos, y para distinguirlos usa “settings hook” para el de siempre. Yo hago lo mismo en este artículo.

Según la documentación, un mod puede:

  • Dibujar una interfaz que puedes usar: un panel junto a la conversación o una banda sobre el prompt, con pestañas, botones y campos de texto.
  • Redibujar partes de la interfaz de Claude Code, como la fila de una llamada a herramienta, el spinner o el diálogo de preguntas.
  • Intervenir en una llamada a herramienta o en una petición: pausarla para preguntarte algo, responderla sin ejecutar la herramienta o enviar una petición a otro modelo.
  • Ejecutar tu código con un /comando propio, sin pasar por un turno de Claude.
  • Compartir datos entre hooks: lo que registra un hook lo puede mostrar otro.

Esta tabla resume la comparación que hace la documentación oficial:

ModSettings hookSkillServidor MCP
Qué esFunciones en un plugin que Claude Code llama en su propio procesoUn comando, petición HTTP o prompt que se ejecuta en un evento del ciclo de vidaUn archivo SKILL.md con instrucciones que Claude leeUn proceso o servicio externo que da herramientas a Claude
Puede dibujar en la interfazSíNoNoNo
Qué escribesJavaScript o TypeScriptUn script y una entrada en settings.jsonMarkdownUn servidor en cualquier lenguaje
Elígelo cuandoQuieres un panel, una banda sobre el prompt, un comando propio o reescribir un eventoQuieres bloquear, permitir o registrar un evento con un script que ya tienesPegas siempre las mismas instrucciones en el chatClaude necesita llegar a un sistema externo

Si un settings hook, un skill o un servidor MCP ya hacen lo que necesitas, la documentación recomienda compararlos antes de escribir un mod. Mi lectura: si lo tuyo es “ejecutar un script cuando pase X”, sigue con los hooks; si quieres cambiar o dibujar algo dentro de Claude Code, es un mod. Para dar instrucciones a Claude, un skill; para conectarlo a un sistema externo, un servidor MCP.

Requisitos y dónde funcionan

Los mods requieren Claude Code v2.1.287 o posterior y vienen activados por defecto. Revisa tu versión con:

claude --version

Los hooks de un mod se ejecutan en cualquier tipo de sesión que cargue el plugin, pero dibujar es más limitado: solo la terminal y la app de escritorio (pestaña Code) muestran los paneles, bandas y filas reemplazadas de un mod. En el panel de chat de la extensión de VS Code, en claude -p y en sesiones en la nube, los hooks corren pero lo que dibuja el mod no aparece.

Cómo es un mod por dentro

Un mod es un plugin con un archivo de entrada llamado hooks module. La versión más pequeña tiene tres archivos:

first-mod/
├── .claude-plugin/
│   └── plugin.json
└── hooks/
    ├── hooks.json
    └── register.js
  • plugin.json: el manifiesto del plugin.
  • hooks.json: apunta a tu archivo de código con la clave modules.
  • register.js: tu código. Exporta una función register.

No necesitas Node.js, un bundler ni un paso de compilación: Claude Code carga los archivos .js y .ts directamente.

Crea tu primer mod

Este es el ejemplo de la documentación oficial. Cuenta las llamadas a herramientas que hace Claude, muestra el número junto al spinner y añade un comando /tally que lo imprime.

1. Crea las carpetas:

mkdir -p first-mod/.claude-plugin first-mod/hooks

2. Escribe el manifiesto en first-mod/.claude-plugin/plugin.json:

{
  "name": "first-mod",
  "version": "0.1.0",
  "description": "Counts Claude's tool calls, shows the count beside the spinner, and adds a /tally command",
  "author": { "name": "Your Name" }
}

3. Dile a Claude Code dónde está tu código en first-mod/hooks/hooks.json. Tener la clave modules es lo que convierte el plugin en un mod:

{
  "description": "The first-mod hooks module",
  "modules": ["./register.js"]
}

4. Escribe el código en first-mod/hooks/register.js:

// The count, shared by the hooks below
let calls = 0

// Claude Code calls this once when the mod loads
export function register(on) {
  // Runs when the session starts, before your first prompt
  on('session.start', async ($, e, next) => {
    // Add the /tally command
    await $.command.register({
      name: 'tally',
      description: 'Show how many tool calls Claude has made',
    })
    // Let the session start as usual
    return next(e)
  })

  // Runs each time Claude is about to use a tool
  on('tool.call', async ($, e, next) => {
    calls += 1
    // Ask Claude Code to draw the interface again, so the new count shows
    $.ui.invalidate('ui.render')
    // Let the tool run as usual
    return next(e)
  })

  // Runs when you type /tally, and only then, because of the matcher
  on('command.run', { command: 'tally' }, async () => {
    // The text to print in the transcript
    return { text: 'Claude has made ' + calls + ' tool calls since this mod loaded' }
  })

  // Runs each time Claude Code draws the spinner
  on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
    // Keep Claude Code's spinner, with the count added after its word
    return next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } })
  })
}

5. Cárgalo durante una sesión, sin instalarlo, con --plugin-dir:

claude --plugin-dir ./first-mod

Pídele a Claude algo que requiera varias herramientas, por ejemplo list the files here and read the README. El spinner mostrará algo como Thinking · tool calls: 2…, y al terminar puedes escribir /tally. Si cambias el código mientras la sesión está abierta, Claude Code recarga el módulo (al recargar, el contador vuelve a 0).

Los tres argumentos de cada hook

Cada función que pasas a on recibe los mismos tres argumentos:

  • $: la API de mods, con los métodos para salir de tu propio código ($.ui, $.command, etc.).
  • e: el evento, como datos planos (por ejemplo, el nombre de una herramienta y sus argumentos).
  • next: pasa el evento a los demás mods y luego al comportamiento de Claude Code, y devuelve el resultado.

Con eso, un hook puede hacer tres cosas: observar (llama a next(e) sin cambios), reescribir (llama a next con una copia modificada, como hace el hook del spinner) o responder (devuelve su propio resultado sin llamar a next, como hace el comando /tally).

Un caso práctico: bloquear un git push --force

La documentación incluye este ejemplo de un hook tool.call que rechaza un push forzado y le explica a Claude por qué. El segundo argumento de on, { tool: 'Bash' }, es un filtro: el hook solo corre para llamadas a Bash.

// The matcher limits the hook to Bash calls, so e.command is the shell command
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
  if (/git push .*--force/.test(e.command)) {
    // Returning without calling next answers the event, so the command never runs
    return { deny: 'Force pushes are not allowed in this repository. Push to a new branch instead.' }
  }
  // Every other command goes on to the permission check and then to Bash
  return next(e)
})

Claude lee el texto de deny como el resultado de la herramienta, así que conviene escribirlo como una instrucción que pueda seguir. Si quieres un ejemplo con pausa y botones, la documentación incluye uno que usa $.ui.ask para preguntarte antes de ejecutar comandos como rm -rf.

Para avisos, la API tiene $.ui.toast(text), que muestra una notificación arriba a la derecha durante 4 segundos por defecto, y $.ui.status(text), una línea bajo el prompt que se queda hasta que la cambies.

Pídele a Claude que escriba el mod

No tienes que escribirlo a mano. Según la documentación, puedes describir el mod en una sesión interactiva (por ejemplo, make a mod that shows the current git branch above the prompt) y Claude lo escribe usando un skill integrado llamado plugin-authoring. También puedes cargarlo tú con /plugin-authoring.

Algunos detalles que conviene conocer:

  • Claude escribe el mod en ~/.claude/dev-mods/ seguido del ID de la sesión. En los modos de permiso default y acceptEdits te pide aprobar cada archivo, porque ~/.claude es una ruta protegida.
  • Al guardar el primer archivo, Claude Code pregunta si activas la recarga en caliente para esa sesión. Si aceptas, el mod carga al terminar el turno y se recarga en cada turno que lo cambie.
  • Ese mod solo carga en la sesión que lo creó, y Claude Code borra la carpeta cuando es más vieja que cleanupPeriodDays. Para conservarlo, copia su carpeta a otro lugar (por ejemplo ~/mods/git-branch) y cárgalo con claude --plugin-dir ~/mods/git-branch.

Si quieres entender mejor cómo se aprueban las acciones de Claude, mira el artículo de permisos y modos de permiso.

Valida y prueba tu mod

La documentación ofrece dos comandos para revisar un mod:

claude plugin validate ./first-mod

Revisa el manifiesto y analiza el código sin ejecutarlo. En su salida, la línea hooks: lista los eventos que maneja el mod y la línea calls: lista los métodos de la API que llama. También sirve para revisar un mod ajeno antes de instalarlo.

claude plugin test

Ejecuta, desde la carpeta del mod, los archivos que terminan en .test.ts o .test.tsx, sin sesión, sin iniciar sesión y sin red. El tutorial oficial incluye un test de ejemplo para first-mod.

Además, cada vez que cargas un mod desde --plugin-dir, Claude Code escribe archivos de tipos .d.ts en .claude-plugin/types/ con los eventos y métodos exactos de tu versión, para que tu editor autocomplete. La propia documentación advierte que los eventos y métodos pueden cambiar entre versiones, y que ante cualquier diferencia debes confiar en esos archivos antes que en la página.

Instalar mods de otros (y la advertencia de seguridad)

Un mod se instala como cualquier plugin, con el nombre del plugin, una @ y el nombre del marketplace:

/plugin install token-chart@your-org

Ese ejemplo es el de la documentación, con nombres de muestra. Para ver los mods activos de una sesión, ejecuta /plugin.

Un mod es código que corre con tus permisos. Puede leer y escribir tus archivos, lanzar procesos, hacer peticiones de red, leer variables de entorno (incluida una API key), ver cada prompt y cada llamada a herramienta, y aprobar una llamada antes de que te pregunten. No corre en un sandbox, y un proceso que lance un mod queda fuera del sandbox de Claude Code. Instala solo mods de autores y marketplaces en los que confíes.

Anthropic comparte tres mods de muestra, sin soporte, en el repositorio claude-code-playground:

  • token-weather: dibuja un pronóstico de tu ventana de contexto sobre el prompt.
  • blast-radius: detiene un comando de shell riesgoso, como rm -rf o un force push, y muestra qué cambiaría, con botones para continuar o cancelar.
  • replay-theater: añade un comando /replay que recorre las ediciones de archivos del último turno.

Para probar uno, clona el repositorio y cárgalo con --plugin-dir.

Mods integrados y uso en equipos

Algunas funciones de Claude Code ya son mods. El ejemplo que menciona Anthropic es /diff: como ahora es un mod, puedes desactivarlo en /plugin o reemplazarlo por tu propia versión. Anthropic indica que planea mover más funciones integradas a mods con el tiempo.

Para equipos, los mods viajan en plugins, así que aplican los controles de plugins que ya existen. En planes Team y Enterprise, y en cualquier máquina con managed settings, carga primero un mod integrado llamado sec-default que impide que los mods instalados por los usuarios hagan cosas riesgosas, como saltarse tus reglas deny. La administración detallada está en Manage mods for your organization.

Mi recomendación para empezar

Esto es opinión mía, no de la documentación:

  1. Actualiza Claude Code y confirma que tienes la v2.1.287 o posterior.
  2. Haz el tutorial de first-mod tal cual: toma pocos minutos y te enseña observar, reescribir y responder.
  3. Antes de instalar cualquier mod ajeno, corre claude plugin validate y lee las líneas hooks: y calls:.
  4. Si lo tuyo es solo “ejecutar un script cuando pase algo”, los hooks de siempre siguen siendo la opción más simple.

Fuentes