Plugins

Creación de plugins

Los plugins extienden OpenClaw con nuevas capacidades: canales, proveedores de modelos, voz, transcripción en tiempo real, voz en tiempo real, comprensión de medios, generación de imágenes, generación de video, obtención web, búsqueda web, herramientas de agente o cualquier combinación.

No necesitas agregar tu plugin al repositorio de OpenClaw. Publícalo en ClawHub y los usuarios lo instalan con openclaw plugins install clawhub:<package-name>. Las especificaciones de paquete simples aún se instalan desde npm durante la transición de lanzamiento.

Requisitos previos

  • Node >= 22 y un gestor de paquetes (npm o pnpm)
  • Familiaridad con TypeScript (ESM)
  • Para plugins dentro del repositorio: repositorio clonado y pnpm install ejecutado. El desarrollo de plugins desde el checkout de código fuente es solo con pnpm porque OpenClaw carga los plugins incluidos desde los paquetes de workspace extensions/*.

¿Qué tipo de plugin?

Para un plugin de canal cuya instalación no esté garantizada cuando se ejecuta el onboarding/la configuración, usa createOptionalChannelSetupSurface(...) desde openclaw/plugin-sdk/channel-setup. Produce un par de adaptador de configuración + asistente que anuncia el requisito de instalación y falla de forma cerrada en escrituras reales de configuración hasta que el plugin esté instalado.

Inicio rápido: plugin de herramienta

Este recorrido crea un plugin mínimo que registra una herramienta de agente. Los plugins de canal y de proveedor tienen guías dedicadas enlazadas arriba.

  • Crea el paquete y el manifiesto

    {
    "name": "@myorg/openclaw-my-plugin",
    "version": "1.0.0",
    "type": "module",
    "openclaw": {
      "extensions": ["./index.ts"],
      "compat": {
        "pluginApi": ">=2026.3.24-beta.2",
        "minGatewayVersion": "2026.3.24-beta.2"
      },
      "build": {
        "openclawVersion": "2026.3.24-beta.2",
        "pluginSdkVersion": "2026.3.24-beta.2"
      }
    }
    }
    
    {
    "id": "my-plugin",
    "name": "My Plugin",
    "description": "Adds a custom tool to OpenClaw",
    "contracts": {
      "tools": ["my_tool"]
    },
    "activation": {
      "onStartup": true
    },
    "configSchema": {
      "type": "object",
      "additionalProperties": false
    }
    }
    

    Todo plugin necesita un manifiesto, incluso sin configuración. Las herramientas registradas en tiempo de ejecución deben aparecer en contracts.tools para que OpenClaw pueda descubrir el plugin propietario sin cargar todos los runtimes de plugins. Los plugins también deberían declarar activation.onStartup de forma intencional. Este ejemplo lo establece en true. Consulta Manifiesto para ver el esquema completo. Los fragmentos canónicos de publicación en ClawHub viven en docs/snippets/plugin-publish/.

  • Escribe el punto de entrada

    // index.ts
    import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
    import { Type } from "@sinclair/typebox";
    
    export default definePluginEntry({
      id: "my-plugin",
      name: "My Plugin",
      description: "Adds a custom tool to OpenClaw",
      register(api) {
        api.registerTool({
          name: "my_tool",
          description: "Do a thing",
          parameters: Type.Object({ input: Type.String() }),
          async execute(_id, params) {
            return { content: [{ type: "text", text: `Got: ${params.input}` }] };
          },
        });
      },
    });
    

    definePluginEntry es para plugins que no son de canal. Para canales, usa defineChannelPluginEntry; consulta Plugins de canal. Para ver todas las opciones del punto de entrada, consulta Puntos de entrada.

  • Prueba y publica

    Plugins externos: valida y publica con ClawHub, luego instala:

    clawhub package publish your-org/your-plugin --dry-run
    clawhub package publish your-org/your-plugin
    openclaw plugins install clawhub:@myorg/openclaw-my-plugin
    

    Las especificaciones de paquete simples como @myorg/openclaw-my-plugin se instalan desde npm durante la transición de lanzamiento. Usa clawhub: cuando quieras resolución de ClawHub.

    Plugins dentro del repositorio: colócalos bajo el árbol de workspace de plugins incluidos; se descubren automáticamente.

    pnpm test -- <bundled-plugin-root>/my-plugin/
    
  • Capacidades de plugin

    Un solo plugin puede registrar cualquier número de capacidades mediante el objeto api:

    Capacidad Método de registro Guía detallada
    Inferencia de texto (LLM) api.registerProvider(...) Plugins de proveedor
    Backend de inferencia de CLI api.registerCliBackend(...) Backends de CLI
    Canal / mensajería api.registerChannel(...) Plugins de canal
    Voz (TTS/STT) api.registerSpeechProvider(...) Plugins de proveedor
    Transcripción en tiempo real api.registerRealtimeTranscriptionProvider(...) Plugins de proveedor
    Voz en tiempo real api.registerRealtimeVoiceProvider(...) Plugins de proveedor
    Comprensión de medios api.registerMediaUnderstandingProvider(...) Plugins de proveedor
    Generación de imágenes api.registerImageGenerationProvider(...) Plugins de proveedor
    Generación de música api.registerMusicGenerationProvider(...) Plugins de proveedor
    Generación de video api.registerVideoGenerationProvider(...) Plugins de proveedor
    Obtención web api.registerWebFetchProvider(...) Plugins de proveedor
    Búsqueda web api.registerWebSearchProvider(...) Plugins de proveedor
    Middleware de resultados de herramientas api.registerAgentToolResultMiddleware(...) Descripción general del SDK
    Herramientas de agente api.registerTool(...) Abajo
    Comandos personalizados api.registerCommand(...) Puntos de entrada
    Hooks de plugin api.on(...) Hooks de plugin
    Hooks de eventos internos api.registerHook(...) Puntos de entrada
    Rutas HTTP api.registerHttpRoute(...) Internos
    Subcomandos de CLI api.registerCli(...) Puntos de entrada

    Para ver la API de registro completa, consulta Descripción general del SDK.

    Los plugins incluidos pueden usar api.registerAgentToolResultMiddleware(...) cuando necesitan reescritura asíncrona de resultados de herramientas antes de que el modelo vea la salida. Declara los runtimes objetivo en contracts.agentToolResultMiddleware, por ejemplo ["pi", "codex"]. Esta es una interfaz de plugin incluido de confianza; los plugins externos deberían preferir los hooks habituales de plugin de OpenClaw salvo que OpenClaw desarrolle una política de confianza explícita para esta capacidad.

    Si tu plugin registra métodos RPC personalizados de Gateway, mantenlos con un prefijo específico del plugin. Los espacios de nombres administrativos del núcleo (config.*, exec.approvals.*, wizard.*, update.*) permanecen reservados y siempre se resuelven a operator.admin, aunque un plugin solicite un alcance más estrecho.

    Semántica de protección de hooks que conviene tener presente:

    • before_tool_call: { block: true } es terminal y detiene los manejadores de menor prioridad.
    • before_tool_call: { block: false } se trata como ausencia de decisión.
    • before_tool_call: { requireApproval: true } pausa la ejecución del agente y solicita aprobación al usuario mediante la superposición de aprobación de ejecución, botones de Telegram, interacciones de Discord o el comando /approve en cualquier canal.
    • before_install: { block: true } es terminal y detiene los manejadores de menor prioridad.
    • before_install: { block: false } se trata como ausencia de decisión.
    • message_sending: { cancel: true } es terminal y detiene los manejadores de menor prioridad.
    • message_sending: { cancel: false } se trata como ausencia de decisión.
    • message_received: prefiere el campo tipado threadId cuando necesites enrutamiento de hilo/tema entrante. Mantén metadata para extras específicos del canal.
    • message_sending: prefiere los campos de enrutamiento tipados replyToId / threadId sobre claves de metadatos específicas del canal.

    El comando /approve maneja aprobaciones de ejecución y de plugin con fallback acotado: cuando no se encuentra un id de aprobación de ejecución, OpenClaw reintenta el mismo id mediante aprobaciones de plugin. El reenvío de aprobaciones de plugin puede configurarse de forma independiente mediante approvals.plugin en la configuración.

    Si la canalización personalizada de aprobaciones necesita detectar ese mismo caso de fallback acotado, prefiere isApprovalNotFoundError de openclaw/plugin-sdk/error-runtime en lugar de comparar manualmente cadenas de expiración de aprobación.

    Consulta Hooks de plugin para ver ejemplos y la referencia de hooks.

    Registrar herramientas de agente

    Las herramientas son funciones tipadas que el LLM puede llamar. Pueden ser obligatorias (siempre disponibles) u opcionales (el usuario las habilita):

    register(api) {
      // Required tool - always available
      api.registerTool({
        name: "my_tool",
        description: "Do a thing",
        parameters: Type.Object({ input: Type.String() }),
        async execute(_id, params) {
          return { content: [{ type: "text", text: params.input }] };
        },
      });
    
      // Optional tool - user must add to allowlist
      api.registerTool(
        {
          name: "workflow_tool",
          description: "Run a workflow",
          parameters: Type.Object({ pipeline: Type.String() }),
          async execute(_id, params) {
            return { content: [{ type: "text", text: params.pipeline }] };
          },
        },
        { optional: true },
      );
    }
    

    Toda herramienta registrada con api.registerTool(...) también debe declararse en el manifiesto del plugin:

    {
      "contracts": {
        "tools": ["my_tool", "workflow_tool"]
      },
      "toolMetadata": {
        "workflow_tool": {
          "optional": true
        }
      }
    }
    

    OpenClaw captura y almacena en caché el descriptor validado de la herramienta registrada, por lo que los plugins no duplican description ni los datos de esquema en el manifiesto. El contrato del manifiesto solo declara la propiedad y el descubrimiento; la ejecución sigue llamando a la implementación activa de la herramienta registrada. Define toolMetadata.<tool>.optional: true para herramientas registradas con api.registerTool(..., { optional: true }) para que OpenClaw pueda evitar cargar ese runtime del plugin hasta que la herramienta se incluya explícitamente en la lista de permitidos.

    Los usuarios habilitan herramientas opcionales en la configuración:

    {
      tools: { allow: ["workflow_tool"] },
    }
    
    • Los nombres de herramientas no deben entrar en conflicto con las herramientas del núcleo (los conflictos se omiten)
    • Las herramientas con objetos de registro mal formados, incluido parameters faltante, se omiten y se informan en los diagnósticos del plugin en lugar de interrumpir las ejecuciones del agente
    • Usa optional: true para herramientas con efectos secundarios o requisitos binarios adicionales
    • Los usuarios pueden habilitar todas las herramientas de un plugin agregando el id del plugin a tools.allow

    Registrar comandos de CLI

    Los plugins pueden agregar grupos de comandos raíz de openclaw con api.registerCli. Proporciona descriptors para cada raíz de comando de nivel superior para que OpenClaw pueda mostrar y enrutar el comando sin cargar ansiosamente cada runtime de plugin.

    register(api) {
      api.registerCli(
        ({ program }) => {
          const demo = program
            .command("demo-plugin")
            .description("Run demo plugin commands");
    
          demo
            .command("ping")
            .description("Check that the plugin CLI is executable")
            .action(() => {
              console.log("demo-plugin:pong");
            });
        },
        {
          descriptors: [
            {
              name: "demo-plugin",
              description: "Run demo plugin commands",
              hasSubcommands: true,
            },
          ],
        },
      );
    }
    

    Después de la instalación, verifica el registro en runtime y ejecuta el comando:

    openclaw plugins inspect demo-plugin --runtime --json
    openclaw demo-plugin ping
    

    Convenciones de importación

    Importa siempre desde rutas enfocadas openclaw/plugin-sdk/<subpath>:

    
    
    // Wrong: monolithic root (deprecated, will be removed)
    
    

    Para la referencia completa de subrutas, consulta Descripción general del SDK.

    Dentro de tu plugin, usa archivos barril locales (api.ts, runtime-api.ts) para importaciones internas; nunca importes tu propio plugin a través de su ruta de SDK.

    Para plugins de proveedor, conserva los helpers específicos del proveedor en esos barriles de raíz del paquete, salvo que la interfaz sea realmente genérica. Ejemplos empaquetados actuales:

    • Anthropic: wrappers de flujo de Claude y helpers de service_tier / beta
    • OpenAI: constructores de proveedor, helpers de modelo predeterminado, proveedores en tiempo real
    • OpenRouter: constructor de proveedor más helpers de incorporación/configuración

    Si un helper solo es útil dentro de un paquete de proveedor empaquetado, mantenlo en esa interfaz de raíz de paquete en lugar de promoverlo a openclaw/plugin-sdk/*.

    Algunas interfaces helper generadas openclaw/plugin-sdk/<bundled-id> aún existen para mantenimiento de plugins empaquetados cuando tienen uso rastreado por el propietario. Trátalas como superficies reservadas, no como el patrón predeterminado para nuevos plugins de terceros.

    Lista de comprobación previa al envío

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s package.json tiene los metadatos openclaw correctos OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s El manifiesto openclaw.plugin.json está presente y es válido OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s El punto de entrada usa defineChannelPluginEntry o definePluginEntry OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Todas las importaciones usan rutas enfocadas plugin-sdk/<subpath> OPENCLAW_DOCS_MARKER:calloutClose: