Cómo extender OpenClaw con Plugins
¿Alguna vez has sentido que a tu herramienta le falta justo esa función específica para tu flujo de trabajo? A veces el núcleo de una aplicación no cubre todas las necesidades, y modificar el código base principal es un problema que genera fricción y errores difíciles de mantener.
Los plugins son la solución. Son módulos de código pequeños que añaden comandos, herramientas, canales o flujos de integración completos. Yo los uso para todo, desde llamadas de voz hasta integraciones con Slack. Una vez que entiendes el patrón, son fáciles de construir.
Requisitos previos
Sección titulada «Requisitos previos»- OpenClaw instalado y funcionando
- Conocimientos básicos de TypeScript (para plugins personalizados)
Quick Start (3 minutos)
Sección titulada «Quick Start (3 minutos)»Paso 1: Mira qué hay cargado
Sección titulada «Paso 1: Mira qué hay cargado»openclaw plugins listPaso 2: Instala un plugin oficial
Sección titulada «Paso 2: Instala un plugin oficial»openclaw plugins install @openclaw/voice-callPaso 3: Reinicia y configura
Sección titulada «Paso 3: Reinicia y configura»Reinicia tu Gateway y añade la configuración en plugins.entries.<id>.config:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio" } } } }}Listo. Tu nuevo plugin ya puede usarse.
Official Plugins
Sección titulada «Official Plugins»| Plugin | Package | Description |
|---|---|---|
| Voice Call | @openclaw/voice-call | Hacer y recibir llamadas telefónicas |
| Microsoft Teams | @openclaw/msteams | Integración de canal de Teams |
| Matrix | @openclaw/matrix | Protocolo de chat Matrix |
| Nostr | @openclaw/nostr | Chat descentralizado Nostr |
| Zalo | @openclaw/zalo | App de mensajería vietnamita |
Plugins integrados (desactivados por defecto):
- Memory (Core): búsqueda de memoria básica.
- Memory (LanceDB): memoria a largo plazo con recuperación automática.
- Google/Gemini/Qwen OAuth: flujos de autenticación de proveedores.
Activa los plugins integrados con:
openclaw plugins enable memory-lancedbPlugin Discovery
Sección titulada «Plugin Discovery»OpenClaw busca plugins en este orden:
- Rutas de configuración:
plugins.load.paths - Extensiones del workspace:
.openclaw/extensions/*.ts - Extensiones globales:
~/.openclaw/extensions/*.ts - Integrados: vienen con OpenClaw (desactivados por defecto)
La primera coincidencia es la que manda. Las copias posteriores se ignoran.
Configuration
Sección titulada «Configuration»{ plugins: { enabled: true, allow: ["voice-call"], // lista blanca (opcional) deny: ["untrusted-plugin"], // la lista negra tiene prioridad load: { paths: ["~/my-plugins/custom"] }, entries: { "voice-call": { enabled: true, config: { provider: "twilio" } } } }}Los cambios de configuración requieren reiniciar el Gateway.
Plugin Slots (Categorías exclusivas)
Sección titulada «Plugin Slots (Categorías exclusivas)»Algunas categorías permiten solo un plugin activo (como los proveedores de memoria):
{ plugins: { slots: { memory: "memory-lancedb" // o "memory-core" o "none" } }}CLI Commands
Sección titulada «CLI Commands»openclaw plugins list # Ver todos los pluginsopenclaw plugins info <id> # Detalles del pluginopenclaw plugins install <path|npm> # Instalar pluginopenclaw plugins install -l <path> # Enlace para desarrolloopenclaw plugins enable <id> # Activar pluginopenclaw plugins disable <id> # Desactivar pluginopenclaw plugins update <id> # Actualizar plugin de npmopenclaw plugins update --all # Actualizar todos los plugins de npmopenclaw plugins doctor # Diagnosticar problemasSolución de problemas
Sección titulada «Solución de problemas»- El plugin no aparece o no funciona: Los cambios en la configuración no son automáticos. Debes reiniciar el Gateway para que OpenClaw cargue los nuevos ajustes.
- Conflictos entre versiones: Si tienes el mismo plugin en varias rutas, OpenClaw usará el primero que encuentre según el orden de prioridad de descubrimiento.
- Errores desconocidos: Ejecuta
openclaw plugins doctorpara obtener un diagnóstico de posibles fallos en la carga o configuración.
Si necesitas ayuda personalizada para configurar tus plugins, usa el AI Setup Assistant.
Próximos pasos
Sección titulada «Próximos pasos»Si alguna vez has intentado añadir una función específica a tu flujo de trabajo y has terminado frustrado por la complejidad, este es tu sitio. No deberías perder horas configurando archivos solo para que una herramienta haga exactamente lo que tú quieres.
A veces, las soluciones estándar no son suficientes. Crear tus propios plugins te permite adaptar la plataforma a tus necesidades reales sin pelear con código innecesario.
Requisitos previos
Sección titulada «Requisitos previos»- Node.js y un entorno para ejecutar TypeScript.
- Acceso al directorio de extensiones en
~/.openclaw/extensions/.
Inicio rápido
Sección titulada «Inicio rápido»Sigue estos pasos para tener un plugin funcional en menos de 5 minutos:
- Crea el archivo
~/.openclaw/extensions/my-plugin/index.ts:
export default function(api) { api.registerGatewayMethod("myplugin.status", ({ respond }) => { respond(true, { status: "running" }); });}- Crea el archivo
~/.openclaw/extensions/my-plugin/openclaw.plugin.json:
{ "id": "my-plugin", "name": "My Custom Plugin", "version": "1.0.0"}- Reinicia el Gateway.
- Tu plugin ya está activo y listo para usarse.
Register a Tool
Sección titulada «Register a Tool»Para que el AI pueda ejecutar acciones específicas, usa registerTool. Define el nombre, la descripción y los parámetros que necesita:
export default function(api) { api.registerTool({ name: "my_tool", description: "Does something useful", parameters: { type: "object", properties: { input: { type: "string" } } }, handler: async ({ input }) => { return { result: `Processed: ${input}` }; } });}Register a Slash Command
Sección titulada «Register a Slash Command»Si necesitas ejecutar algo rápido sin llamar al AI, los comandos de barra son la mejor opción. Son ideales para comprobaciones de estado o ajustes rápidos:
export default function(api) { api.registerCommand({ name: "mystatus", description: "Show plugin status", handler: (ctx) => ({ text: `Plugin running on ${ctx.channel}` }) });}Este comando se ejecuta de forma directa, lo que ahorra tiempo y recursos.
Register a Channel
Sección titulada «Register a Channel»Puedes integrar nuevos servicios de mensajería definiendo un canal. Aquí tienes un ejemplo para un servicio ficticio llamado AcmeChat:
const plugin = { id: "acmechat", meta: { label: "AcmeChat", docsPath: "/channels/acmechat", blurb: "AcmeChat messaging." }, capabilities: { chatTypes: ["direct"] }, config: { listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}), resolveAccount: (cfg, id) => cfg.channels?.acmechat?.accounts?.[id ?? "default"] }, outbound: { deliveryMode: "direct", sendText: async ({ text }) => { // Send message return { ok: true }; } }};
export default function(api) { api.registerChannel({ plugin });}Plugin Hooks
Sección titulada «Plugin Hooks»Los plugins pueden incluir hooks y registrarlos en tiempo de ejecución. Esto permite agrupar automatizaciones basadas en eventos sin instalar paquetes de hooks por separado.
import { registerPluginHooksFromDir } from "openclaw/plugin-sdk";
export default function register(api) { registerPluginHooksFromDir(api, "./hooks");}Notas importantes:
- Los directorios de hooks deben seguir la estructura estándar (
HOOK.md+handler.ts). - Se aplican las reglas de elegibilidad habituales (requisitos de OS, binarios, env y config).
- Los hooks gestionados por plugins aparecen en
openclaw hooks listcomoplugin:<id>. - Puedes activar o desactivar el plugin para controlar sus hooks.
Runtime Helpers
Sección titulada «Runtime Helpers»Tu plugin puede acceder a funciones del núcleo mediante api.runtime. Por ejemplo, para usar el servicio de telefonía TTS:
const result = await api.runtime.tts.textToSpeechTelephony({ text: "Hello from OpenClaw", cfg: api.config,});Notas importantes:
- Utiliza la configuración de
messages.tts(OpenAI o ElevenLabs). - Devuelve un buffer de audio PCM y el sample rate.
Provider Plugins (Model Auth)
Sección titulada «Provider Plugins (Model Auth)»Si necesitas que los usuarios configuren sus propias llaves de API o flujos de OAuth, usa registerProvider:
api.registerProvider({ id: "acme", label: "AcmeAI", auth: [ { id: "oauth", label: "OAuth", kind: "oauth", run: async (ctx) => { // Run OAuth flow and return auth profiles return { profiles: [ { profileId: "acme:default", credential: { type: "oauth", provider: "acme", access: "...", refresh: "...", expires: Date.now() + 3600 * 1000, }, }, ], defaultModel: "acme/opus-1", }; }, }, ],});Notas importantes:
- La función
runrecibe unProviderAuthContextcon utilidades comoprompteryopenUrl. - Usa
configPatchsi necesitas añadir modelos por defecto. - Los usuarios pueden autenticarse con el comando:
openclaw models auth login --provider acme --method oauthSolución de problemas
Sección titulada «Solución de problemas»- El audio no funciona en telefonía: Recuerda que Edge TTS no es compatible con las funciones de telefonía.
- El plugin no procesa el audio correctamente: Los plugins deben encargarse de remuestrear o codificar el audio para sus propios proveedores.
- Los hooks no aparecen: Verifica que cumples con los requisitos de sistema operativo o variables de entorno definidos en el hook.
- Error en el modelo por defecto: Asegúrate de devolver
defaultModelpara que--set-defaultpueda actualizar los agentes.
¿Necesitas ayuda con la configuración? Prueba nuestro AI Setup Assistant.
Próximos pasos
Sección titulada «Próximos pasos»- Configuración de canales
- Referencia de la API del Gateway
- Guía de Hooks avanzados
- Publicación de Plugins
A veces necesitas que tu plugin responda al instante sin esperar a que el agente de AI procese la solicitud. Es frustrante intentar obtener un dato técnico simple, como el estado de un servicio, y tener que esperar el tiempo de respuesta de un modelo de lenguaje.
La mejor forma de resolver esto es registrando comandos que se ejecutan de forma local y directa. Esto ahorra tokens y reduce la latencia en tareas administrativas o de consulta rápida.
What You’ll Need
Sección titulada «What You’ll Need»- Un entorno de desarrollo con Node.js.
- El archivo
openclaw.plugin.jsonconfigurado en tu proyecto. - Acceso a la API de OpenClaw.
Quick Start
Sección titulada «Quick Start»Para registrar un comando que responda automáticamente sin invocar a la AI, usa el método api.registerCommand. Estos comandos tienen prioridad y se procesan antes que cualquier lógica del agente.
export default function(api) { api.registerCommand({ name: "mystatus", description: "Show plugin status", acceptsArgs: false, requireAuth: true, handler: (ctx) => ({ text: `Plugin running on ${ctx.channel}` }) });}Command Context
Sección titulada «Command Context»Cuando se ejecuta el handler, recibes un objeto ctx con los siguientes datos:
| Campo | Descripción |
|---|---|
senderId | ID del remitente |
channel | Canal donde se envió el comando |
isAuthorizedSender | Si el remitente está autorizado |
args | Argumentos (si acceptsArgs: true) |
commandBody | Texto completo del comando |
config | Configuración actual de OpenClaw |
Command Options
Sección titulada «Command Options»Estas son las opciones disponibles para configurar el comportamiento del comando:
| Opción | Descripción |
|---|---|
name | Nombre del comando (sin el prefijo /) |
description | Texto de ayuda |
acceptsArgs | Define si acepta argumentos (por defecto: false) |
requireAuth | Requiere un remitente autorizado (por defecto: true) |
handler | Función que devuelve { text: string } |
Notas importantes:
- Los comandos de los plugins se procesan antes que los comandos integrados y que el agente de AI.
- Los nombres de los comandos no distinguen entre mayúsculas y minúsculas.
- No puedes sobrescribir comandos reservados como
help,statusoreset.
Servicios en segundo plano
Sección titulada «Servicios en segundo plano»Si tu plugin requiere lógica persistente que no dependa de comandos del usuario, puedes registrar un servicio:
export default function(api) { api.registerService({ id: "my-service", start: () => api.logger.info("ready"), stop: () => api.logger.info("bye"), });}Comandos de CLI
Sección titulada «Comandos de CLI»Para extender la funcionalidad de la terminal, usa api.registerCli:
export default function(api) { api.registerCli(({ program }) => { program.command("mycmd").action(() => { console.log("Hello"); }); }, { commands: ["mycmd"] });}Plugin Manifest
Sección titulada «Plugin Manifest»Cada plugin debe incluir un archivo openclaw.plugin.json para definir su identidad y esquema de configuración:
{ "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "configSchema": { "type": "object", "properties": { "apiKey": { "type": "string" } } }, "uiHints": { "apiKey": { "label": "API Key", "sensitive": true } }}Publishing to npm
Sección titulada «Publishing to npm»Para compartir tu plugin, primero actualiza tu package.json:
{ "name": "@yourscope/my-plugin", "openclaw": { "extensions": ["./index.ts"] }}Luego, ejecuta los comandos estándar para publicar e instalar:
- Publicar:
npm publish - Instalación para usuarios:
openclaw plugins install @yourscope/my-pluginTroubleshooting
Sección titulada «Troubleshooting»- El comando no responde: Verifica que el nombre no coincida con un comando reservado (
help,status,reset). - Error de autorización: Si
requireAuthes true, asegúrate de que el usuario tenga los permisos necesarios en la configuración de Gateway.
¿Necesitas ayuda con la configuración? Prueba el AI Setup Assistant.
What’s Next
Sección titulada «What’s Next»Configurar plugins a veces se siente como buscar una aguja en un pajar. Instalas una extensión y, por alguna razón, no aparece o el sistema lanza un error críptico que te detiene en seco. No pierdas tiempo adivinando; aquí tienes cómo solucionar los problemas más comunes y dejar todo listo en pocos minutos.
Requisitos previos
Sección titulada «Requisitos previos»Para seguir esta guía, asegúrate de tener:
- Acceso al directorio de configuración de OpenClaw (
~/.openclaw/). - Node.js instalado para gestionar dependencias de plugins.
- Archivos de configuración
openclaw.plugin.jsonopackage.jsonen tus carpetas de extensiones. - Permisos para editar variables de entorno en tu sistema.
Inicio rápido
Sección titulada «Inicio rápido»Si quieres configurar un plugin rápidamente, la mejor ruta es usar un Package Pack. Sigue estos pasos:
- Crea una carpeta para tu plugin en
~/.openclaw/extensions/my-pack. - Crea un archivo
package.jsoncon la propiedadopenclaw.extensions. - Si usas dependencias externas, instálalas ahí mismo:
Ventana de terminal cd ~/.openclaw/extensions/my-packnpm install - Reinicia el Gateway para que detecte los cambios.
Solución de problemas
Sección titulada «Solución de problemas»Si algo no funciona como esperas, revisa estos puntos basados en los errores más frecuentes:
El plugin no carga
Sección titulada «El plugin no carga»Revisa lo siguiente:
- ¿Está
plugins.enabledconfigurado comotrue? - ¿Está el plugin en la lista
deny? - ¿Existe el archivo
openclaw.plugin.jsonen la carpeta del plugin?
Errores de validación de configuración
Sección titulada «Errores de validación de configuración»Causa: El sistema es estricto y lanza errores si encuentra IDs de plugins desconocidos en la configuración.
Solución: Elimina cualquier referencia a plugins desactivados o desinstalados de las secciones entries, allow y deny.
Conflictos de plugins
Sección titulada «Conflictos de plugins»Causa: Tienes varios plugins con el mismo ID. Solución: OpenClaw solo cargará el primer plugin que encuentre. Borra los duplicados de tus directorios de extensiones.
¿Sigues con problemas? Nuestro AI Setup Assistant puede ayudarte a depurar la configuración de tus plugins.
Package Packs
Sección titulada «Package Packs»Un directorio de plugin puede incluir un package.json con la propiedad openclaw.extensions. Esto permite agrupar varias funcionalidades en un solo paquete:
{ "name": "my-pack", "openclaw": { "extensions": ["./src/safety.ts", "./src/tools.ts"] }}Cada entrada se convierte en un plugin independiente. Si el paquete lista varias extensiones, el ID del plugin será name/<fileBase>.
Si tu plugin importa dependencias de npm, instálalas en ese mismo directorio:
cd ~/.openclaw/extensions/my-packnpm installChannel Catalog Metadata
Sección titulada «Channel Catalog Metadata»Los plugins de tipo Channel pueden anunciar metadatos de incorporación mediante openclaw.channel e instrucciones de instalación con openclaw.install:
{ "name": "@openclaw/nextcloud-talk", "openclaw": { "extensions": ["./index.ts"], "channel": { "id": "nextcloud-talk", "label": "Nextcloud Talk", "selectionLabel": "Nextcloud Talk (self-hosted)", "docsPath": "/channels/nextcloud-talk", "blurb": "Self-hosted chat via Nextcloud Talk webhook bots.", "order": 65, "aliases": ["nc-talk", "nc"] }, "install": { "npmSpec": "@openclaw/nextcloud-talk", "localPath": "extensions/nextcloud-talk", "defaultChoice": "npm" } }}Catálogos externos: Puedes añadir archivos JSON en las siguientes rutas para que OpenClaw los reconozca:
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
También puedes configurar la variable de entorno OPENCLAW_PLUGIN_CATALOG_PATHS para definir rutas personalizadas.
¿Necesitas ayuda específica con tu archivo de configuración? Usa el AI Setup Assistant.
Próximos pasos
Sección titulada «Próximos pasos»¿Alguna vez has intentado conectar una herramienta a una plataforma de chat específica y te has encontrado con que no hay una integración oficial? Es frustrante tener que lidiar con APIs incompatibles y configuraciones manuales cuando solo quieres que los mensajes lleguen a su destino. Si necesitas crear una superficie de chat nueva y no solo añadir un proveedor de modelos, esta guía es para ti.
Te recomiendo que sigas este proceso de forma lineal para asegurar que el Gateway reconozca tu canal correctamente desde el primer momento.
Requisitos previos
Sección titulada «Requisitos previos»Para empezar, asegúrate de tener lo siguiente:
- Un entorno de Node.js con TypeScript listo.
- Acceso a los archivos de configuración del Gateway.
Quick Start (5 minutos)
Sección titulada «Quick Start (5 minutos)»Sigue estos pasos para tener tu canal funcionando en tiempo récord.
Paso 1: Define el ID y la estructura de configuración
Sección titulada «Paso 1: Define el ID y la estructura de configuración»Toda la configuración de los canales vive bajo la propiedad channels.<id>. Define tu estructura en el archivo de configuración:
{ channels: { acmechat: { accounts: { default: { token: "TOKEN", enabled: true } } } }}Paso 2: Define los metadatos del canal
Sección titulada «Paso 2: Define los metadatos del canal»Usa esta tabla para configurar los campos de meta:
| Field | Purpose |
|---|---|
meta.label | Nombre a mostrar en CLI/UI |
meta.selectionLabel | Texto de selección más largo |
meta.docsPath | Enlace a la documentación (ej. /channels/acmechat) |
meta.blurb | Descripción corta |
meta.aliases | IDs alternativos para el canal |
meta.preferOver | Reemplaza a otro canal existente |
Paso 3: Implementa los Adapters requeridos
Sección titulada «Paso 3: Implementa los Adapters requeridos»Crea el objeto del plugin definiendo cómo se resuelven las cuentas y cómo se envían los mensajes:
const plugin = { id: "acmechat", meta: { /* ... */ }, capabilities: { chatTypes: ["direct"] }, config: { listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}), resolveAccount: (cfg, id) => cfg.channels?.acmechat?.accounts?.[id ?? "default"] }, outbound: { deliveryMode: "direct", sendText: async ({ text }) => ({ ok: true }) }};Paso 4: Añade Adapters opcionales
Sección titulada «Paso 4: Añade Adapters opcionales»Si necesitas funciones avanzadas, puedes implementar estos adapters:
| Adapter | Purpose |
|---|---|
setup | Integración con el asistente (wizard) |
security | Política de DM |
status | Diagnóstico y salud del canal |
gateway | Start/stop/login |
mentions | Manejo de menciones con @ |
threading | Soporte para hilos de conversación |
streaming | Respuestas en streaming |
actions | Acciones en los mensajes |
commands | Comportamiento de comandos nativos |
Paso 5: Registro del canal
Sección titulada «Paso 5: Registro del canal»Exporta la función para que la API registre tu plugin:
export default function(api) { api.registerChannel({ plugin });}Convenciones de nombres
Sección titulada «Convenciones de nombres»Mantén la consistencia usando estas reglas:
| Type | Convention | Example |
|---|---|---|
| Gateway methods | pluginId.action | voicecall.status |
| Tools | snake_case | voice_call |
| CLI commands | kebab-case | voicecall-start |
| Core collision | Evita chocar con comandos del core | N/A |
Skills en Plugins
Sección titulada «Skills en Plugins»Puedes incluir skills en tus plugins añadiendo un directorio skills/:
my-plugin/├── index.ts├── openclaw.plugin.json└── skills/ └── my-skill/ └── SKILL.mdPara activarlo, usa plugins.entries.<id>.enabled y asegúrate de que esté en una de las ubicaciones de skills gestionadas.
Notas de Seguridad
Sección titulada «Notas de Seguridad»Los plugins se ejecutan in-process con el Gateway. Trátalos como código de confianza:
- Instala solo plugins en los que confíes plenamente.
- Usa preferiblemente allowlists en
plugins.allow. - Reinicia el Gateway siempre después de realizar cambios.
- Revisa el código fuente del plugin antes de habilitarlo.
Testing de Plugins
Sección titulada «Testing de Plugins»Es fundamental que tus plugins incluyan tests:
- Plugins in-repo: Mantén los tests de Vitest bajo
src/**(ejemplo:src/plugins/voice-call.plugin.test.ts). - Plugins publicados: Ejecuta tu propia CI y valida que
openclaw.extensionsapunte al entrypoint compilado.
# Ejecutar tests del plugincd ~/.openclaw/extensions/my-pluginnpm testSolución de problemas
Sección titulada «Solución de problemas»Si encuentras problemas durante la implementación, revisa estos puntos basados en el comportamiento del Gateway:
- Los cambios no se aplican: El Gateway requiere un reinicio completo para cargar las modificaciones en el código del plugin.
- El plugin no carga: Verifica que el ID no colisione con comandos del core y que esté incluido en el allowlist si usas
plugins.allow. - Error de registro: Asegúrate de que la función de registro use la API correctamente y que los metadatos obligatorios estén presentes.
- Fallo en el envío: Revisa que el
deliveryModeen el adapteroutboundcoincida con la capacidad de tu plataforma de chat.
¿Necesitas ayuda personalizada? Prueba nuestro AI Setup Assistant.
Próximos pasos
Sección titulada «Próximos pasos»- Plugin Agent Tools → — Crea herramientas que la AI pueda invocar.
- Plugin Manifest → — Referencia completa del manifiesto.
- Voice Call Plugin → — Tutorial con un ejemplo real de plugin.
OpenClaw Expert
Sigues atascado?
Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.