Ir al contenido

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.

  • OpenClaw instalado y funcionando
  • Conocimientos básicos de TypeScript (para plugins personalizados)
Ventana de terminal
openclaw plugins list
Ventana de terminal
openclaw plugins install @openclaw/voice-call

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.

PluginPackageDescription
Voice Call@openclaw/voice-callHacer y recibir llamadas telefónicas
Microsoft Teams@openclaw/msteamsIntegración de canal de Teams
Matrix@openclaw/matrixProtocolo de chat Matrix
Nostr@openclaw/nostrChat descentralizado Nostr
Zalo@openclaw/zaloApp 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:

Ventana de terminal
openclaw plugins enable memory-lancedb

OpenClaw busca plugins en este orden:

  1. Rutas de configuración: plugins.load.paths
  2. Extensiones del workspace: .openclaw/extensions/*.ts
  3. Extensiones globales: ~/.openclaw/extensions/*.ts
  4. Integrados: vienen con OpenClaw (desactivados por defecto)

La primera coincidencia es la que manda. Las copias posteriores se ignoran.

{
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.

Algunas categorías permiten solo un plugin activo (como los proveedores de memoria):

{
plugins: {
slots: {
memory: "memory-lancedb" // o "memory-core" o "none"
}
}
}
Ventana de terminal
openclaw plugins list # Ver todos los plugins
openclaw plugins info <id> # Detalles del plugin
openclaw plugins install &lt;path|npm&gt; # Instalar plugin
openclaw plugins install -l <path> # Enlace para desarrollo
openclaw plugins enable <id> # Activar plugin
openclaw plugins disable <id> # Desactivar plugin
openclaw plugins update <id> # Actualizar plugin de npm
openclaw plugins update --all # Actualizar todos los plugins de npm
openclaw plugins doctor # Diagnosticar 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 doctor para 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.

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.

  • Node.js y un entorno para ejecutar TypeScript.
  • Acceso al directorio de extensiones en ~/.openclaw/extensions/.

Sigue estos pasos para tener un plugin funcional en menos de 5 minutos:

  1. Crea el archivo ~/.openclaw/extensions/my-plugin/index.ts:
export default function(api) {
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
respond(true, { status: "running" });
});
}
  1. Crea el archivo ~/.openclaw/extensions/my-plugin/openclaw.plugin.json:
{
"id": "my-plugin",
"name": "My Custom Plugin",
"version": "1.0.0"
}
  1. Reinicia el Gateway.
  2. Tu plugin ya está activo y listo para usarse.

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}` };
}
});
}

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.

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 });
}

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 list como plugin:<id>.
  • Puedes activar o desactivar el plugin para controlar sus hooks.

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.

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 run recibe un ProviderAuthContext con utilidades como prompter y openUrl.
  • Usa configPatch si necesitas añadir modelos por defecto.
  • Los usuarios pueden autenticarse con el comando:
Ventana de terminal
openclaw models auth login --provider acme --method oauth
  • 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 defaultModel para que --set-default pueda actualizar los agentes.

¿Necesitas ayuda con la configuración? Prueba nuestro AI Setup Assistant.

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.

  • Un entorno de desarrollo con Node.js.
  • El archivo openclaw.plugin.json configurado en tu proyecto.
  • Acceso a la API de OpenClaw.

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}`
})
});
}

Cuando se ejecuta el handler, recibes un objeto ctx con los siguientes datos:

CampoDescripción
senderIdID del remitente
channelCanal donde se envió el comando
isAuthorizedSenderSi el remitente está autorizado
argsArgumentos (si acceptsArgs: true)
commandBodyTexto completo del comando
configConfiguración actual de OpenClaw

Estas son las opciones disponibles para configurar el comportamiento del comando:

OpciónDescripción
nameNombre del comando (sin el prefijo /)
descriptionTexto de ayuda
acceptsArgsDefine si acepta argumentos (por defecto: false)
requireAuthRequiere un remitente autorizado (por defecto: true)
handlerFunció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, status o reset.

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"),
});
}

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"] });
}

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 }
}
}

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:

  1. Publicar: npm publish
  2. Instalación para usuarios:
Ventana de terminal
openclaw plugins install @yourscope/my-plugin
  • El comando no responde: Verifica que el nombre no coincida con un comando reservado (help, status, reset).
  • Error de autorización: Si requireAuth es 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.

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.

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.json o package.json en tus carpetas de extensiones.
  • Permisos para editar variables de entorno en tu sistema.

Si quieres configurar un plugin rápidamente, la mejor ruta es usar un Package Pack. Sigue estos pasos:

  1. Crea una carpeta para tu plugin en ~/.openclaw/extensions/my-pack.
  2. Crea un archivo package.json con la propiedad openclaw.extensions.
  3. Si usas dependencias externas, instálalas ahí mismo:
    Ventana de terminal
    cd ~/.openclaw/extensions/my-pack
    npm install
  4. Reinicia el Gateway para que detecte los cambios.

Si algo no funciona como esperas, revisa estos puntos basados en los errores más frecuentes:

Revisa lo siguiente:

  1. ¿Está plugins.enabled configurado como true?
  2. ¿Está el plugin en la lista deny?
  3. ¿Existe el archivo openclaw.plugin.json en la carpeta del plugin?

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.

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.


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:

Ventana de terminal
cd ~/.openclaw/extensions/my-pack
npm install

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.

¿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.

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.

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 }
}
}
}
}

Usa esta tabla para configurar los campos de meta:

FieldPurpose
meta.labelNombre a mostrar en CLI/UI
meta.selectionLabelTexto de selección más largo
meta.docsPathEnlace a la documentación (ej. /channels/acmechat)
meta.blurbDescripción corta
meta.aliasesIDs alternativos para el canal
meta.preferOverReemplaza a otro canal existente

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 })
}
};

Si necesitas funciones avanzadas, puedes implementar estos adapters:

AdapterPurpose
setupIntegración con el asistente (wizard)
securityPolítica de DM
statusDiagnóstico y salud del canal
gatewayStart/stop/login
mentionsManejo de menciones con @
threadingSoporte para hilos de conversación
streamingRespuestas en streaming
actionsAcciones en los mensajes
commandsComportamiento de comandos nativos

Exporta la función para que la API registre tu plugin:

export default function(api) {
api.registerChannel({ plugin });
}

Mantén la consistencia usando estas reglas:

TypeConventionExample
Gateway methodspluginId.actionvoicecall.status
Toolssnake_casevoice_call
CLI commandskebab-casevoicecall-start
Core collisionEvita chocar con comandos del coreN/A

Puedes incluir skills en tus plugins añadiendo un directorio skills/:

my-plugin/
├── index.ts
├── openclaw.plugin.json
└── skills/
└── my-skill/
└── SKILL.md

Para activarlo, usa plugins.entries.<id>.enabled y asegúrate de que esté en una de las ubicaciones de skills gestionadas.


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.

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.extensions apunte al entrypoint compilado.
Ventana de terminal
# Ejecutar tests del plugin
cd ~/.openclaw/extensions/my-plugin
npm test

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 deliveryMode en el adapter outbound coincida con la capacidad de tu plataforma de chat.

¿Necesitas ayuda personalizada? Prueba nuestro AI Setup Assistant.

OpenClaw

OpenClaw Expert

Sigues atascado?

Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.