プラグイン(拡張機能)

クイックスタート(プラグインが初めての方へ)

プラグインとは、OpenClawに追加機能(コマンド、ツール、Gateway RPC)を提供する小さなコードモジュールです。

ほとんどの場合、コアOpenClawにまだ組み込まれていない機能が必要なとき(またはオプション機能をメインインストールから分離したいとき)にプラグインを使います。

導入手順:

  1. ロード済みのプラグインを確認:
openclaw plugins list
  1. 公式プラグインをインストール(例: Voice Call):
openclaw plugins install @openclaw/voice-call

npm仕様はレジストリのみ(パッケージ名+オプションの正確なバージョンまたはdist-tag)。Git/URL/file仕様やsemver範囲は拒否されます。

ベアの仕様と@latestは安定トラックに留まります。npmがこれらをプレリリースに解決した場合、OpenClawは停止し、@beta/@rcなどのプレリリースタグまたは正確なプレリリースバージョンでの明示的なオプトインを求めます。

  1. Gatewayを再起動し、plugins.entries.<id>.configで設定。

具体的なプラグイン例はVoice Callを参照。 サードパーティの一覧はコミュニティプラグインを参照。

アーキテクチャ

OpenClawのプラグインシステムは4つのレイヤーで構成されています:

  1. マニフェスト+検出 OpenClawは設定されたパス、ワークスペースルート、グローバル拡張ルート、バンドル拡張から候補プラグインを検出。まずopenclaw.plugin.jsonとパッケージメタデータを読み取ります。
  2. 有効化+バリデーション 検出されたプラグインが有効、無効、ブロック、またはmemoryなどの排他スロットに選択されるかをコアが決定。
  3. ランタイムロード 有効化されたプラグインはjiti経由でインプロセスにロードされ、セントラルレジストリに機能を登録。
  4. サーフェス消費 OpenClawの他の部分がレジストリを読み取り、ツール、チャンネル、プロバイダー設定、フック、HTTPルート、CLIコマンド、サービスを公開。

重要な設計境界:

  • 検出+設定バリデーションはプラグインコードを実行せずにマニフェスト/スキーマメタデータから動作すべき
  • ランタイム動作はプラグインモジュールのregister(api)パスから生じる

この分離により、完全なランタイムがアクティブになる前に、OpenClawが設定のバリデーション、不足/無効プラグインの説明、UI/スキーマヒントの構築が可能です。

実行モデル

プラグインはGatewayとインプロセスで実行されます。サンドボックス化はされません。ロードされたプラグインはコアコードと同じプロセスレベルの信頼境界を持ちます。

意味するところ:

  • プラグインはツール、ネットワークハンドラ、フック、サービスを登録できる
  • プラグインのバグによりGatewayがクラッシュまたは不安定になる可能性がある
  • 悪意のあるプラグインはOpenClawプロセス内での任意コード実行と同等

非バンドルプラグインには許可リストと明示的なインストール/ロードパスを使用してください。ワークスペースプラグインは開発時のコードとして扱い、本番デフォルトにはしないでください。

信頼に関する重要な注意:

  • plugins.allowプラグインIDを信頼するもので、ソースの出所ではありません。
  • バンドルプラグインと同じIDを持つワークスペースプラグインは、そのワークスペースプラグインが有効化/許可リスト登録されている場合、意図的にバンドルコピーをシャドウします。
  • これはローカル開発、パッチテスト、ホットフィックスにとって正常かつ有用な動作です。

利用可能なプラグイン(公式)

  • Microsoft Teamsは2026.1.15以降プラグインのみ。Teamsを使用する場合は@openclaw/msteamsをインストール。
  • Memory (Core) — バンドルメモリ検索プラグイン(デフォルトでplugins.slots.memory経由で有効)
  • Memory (LanceDB) — バンドル長期メモリプラグイン(自動リコール/キャプチャ、plugins.slots.memory = "memory-lancedb"で設定)
  • Voice Call@openclaw/voice-call
  • Zalo Personal@openclaw/zalouser
  • Matrix@openclaw/matrix
  • Nostr@openclaw/nostr
  • Zalo@openclaw/zalo
  • Microsoft Teams@openclaw/msteams
  • Google Antigravity OAuth(プロバイダー認証)— google-antigravity-authとしてバンドル(デフォルト無効)
  • Gemini CLI OAuth(プロバイダー認証)— google-gemini-cli-authとしてバンドル(デフォルト無効)
  • Qwen OAuth(プロバイダー認証)— qwen-portal-authとしてバンドル(デフォルト無効)
  • Copilot Proxy(プロバイダー認証)— ローカルVS Code Copilot Proxyブリッジ。組み込みgithub-copilotデバイスログインとは別物(バンドル、デフォルト無効)

OpenClawプラグインはjiti経由でランタイムにロードされるTypeScriptモジュールです。設定バリデーションはプラグインコードを実行しません。プラグインマニフェストとJSON Schemaを使用します。プラグインマニフェストを参照。

プラグインが登録できるもの:

  • Gateway RPCメソッド
  • Gateway HTTPルート
  • エージェントツール
  • CLIコマンド
  • バックグラウンドサービス
  • コンテキストエンジン
  • オプションの設定バリデーション
  • スキル(プラグインマニフェストにskillsディレクトリを記載)
  • 自動返信コマンド(AIエージェントを呼び出さずに実行)

プラグインはGatewayとインプロセスで実行されるため、信頼できるコードとして扱ってください。 ツール作成ガイド: プラグインエージェントツール

ロードパイプライン

起動時にOpenClawはおおむね以下を実行:

  1. 候補プラグインルートを検出
  2. openclaw.plugin.jsonとパッケージメタデータを読み取り
  3. 安全でない候補を拒否
  4. プラグイン設定を正規化(plugins.enabledallowdenyentriesslotsload.paths
  5. 各候補の有効化を決定
  6. 有効なモジュールをjiti経由でロード
  7. register(api)を呼び出し、登録をプラグインレジストリに収集
  8. レジストリをコマンド/ランタイムサーフェスに公開

安全ゲートはランタイム実行のに処理されます。エントリがプラグインルートから逸脱する場合、パスがワールドライタブルな場合、非バンドルプラグインでパスの所有権が怪しい場合、候補はブロックされます。

マニフェストファーストの動作

マニフェストはコントロールプレーンの信頼できる情報源です。OpenClawはマニフェストを以下に使用:

  • プラグインの識別
  • 宣言されたチャンネル/スキル/設定スキーマの検出
  • plugins.entries.<id>.configのバリデーション
  • Control UIのラベル/プレースホルダーの補強
  • インストール/カタログメタデータの表示

ランタイムモジュールはデータプレーン部分です。フック、ツール、コマンド、プロバイダーフローなどの実際の動作を登録します。

ローダーがキャッシュするもの

OpenClawは短いインプロセスキャッシュを以下に保持:

  • 検出結果
  • マニフェストレジストリデータ
  • ロード済みプラグインレジストリ

これらのキャッシュはバースト的な起動と繰り返しのコマンドオーバーヘッドを削減します。短寿命のパフォーマンスキャッシュと考えてください。永続化ではありません。

ランタイムヘルパー

プラグインはapi.runtime経由で選択されたコアヘルパーにアクセスできます。テレフォニーTTSの場合:

const result = await api.runtime.tts.textToSpeechTelephony({
  text: "Hello from OpenClaw",
  cfg: api.config,
});

注意事項:

  • コアのmessages.tts設定(OpenAIまたはElevenLabs)を使用。
  • PCMオーディオバッファ+サンプルレートを返します。プラグインはプロバイダー向けにリサンプル/エンコードが必要。
  • Edge TTSはテレフォニーには非対応。

STT/文字起こしの場合:

const { text } = await api.runtime.stt.transcribeAudioFile({
  filePath: "/tmp/inbound-audio.ogg",
  cfg: api.config,
  mime: "audio/ogg",
});

Gateway HTTPルート

プラグインはapi.registerHttpRoute(...)でHTTPエンドポイントを公開できます。

api.registerHttpRoute({
  path: "/acme/webhook",
  auth: "plugin",
  match: "exact",
  handler: async (_req, res) => {
    res.statusCode = 200;
    res.end("ok");
    return true;
  },
});

注意事項:

  • api.registerHttpHandler(...)は非推奨。api.registerHttpRoute(...)を使用してください。
  • プラグインルートはauthを明示的に宣言する必要があります。

プラグインSDKインポートパス

プラグイン作成時はモノリシックなopenclaw/plugin-sdkインポートの代わりにSDKサブパスを使用:

  • openclaw/plugin-sdk/core — 汎用プラグインAPI、プロバイダー認証型、共有ヘルパー。
  • openclaw/plugin-sdk/compatcoreより広範な共有ランタイムヘルパーが必要なバンドル/内部プラグインコード。
  • openclaw/plugin-sdk/telegram — Telegramチャンネルプラグイン。
  • openclaw/plugin-sdk/discord — Discordチャンネルプラグイン。
  • openclaw/plugin-sdk/slack — Slackチャンネルプラグイン。
  • openclaw/plugin-sdk/signal — Signalチャンネルプラグイン。
  • openclaw/plugin-sdk/imessage — iMessageチャンネルプラグイン。
  • openclaw/plugin-sdk/whatsapp — WhatsAppチャンネルプラグイン。
  • openclaw/plugin-sdk/line — LINEチャンネルプラグイン。
  • openclaw/plugin-sdk/msteams — バンドルMicrosoft Teamsプラグインサーフェス。
  • バンドル拡張固有のサブパスも利用可能(openclaw/plugin-sdk/acpxopenclaw/plugin-sdk/lobsteropenclaw/plugin-sdk/voice-callなど)。

互換性に関する注意:

  • openclaw/plugin-sdkは既存の外部プラグイン向けに引き続きサポート。
  • 新規およびマイグレーション済みのバンドルプラグインはチャンネルまたは拡張固有のサブパスを使用すべき。

読み取り専用チャンネルインスペクション

プラグインがチャンネルを登録する場合、resolveAccount(...)と合わせてplugin.config.inspectAccount(cfg, accountId)の実装を推奨します。読み取り専用コマンド(openclaw status等)がランタイム認証情報を実体化せずに設定状態を報告できるようにするためです。

パフォーマンスに関する注意:

  • プラグイン検出とマニフェストメタデータは短いインプロセスキャッシュを使用。
  • OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1またはOPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1でキャッシュを無効化。

検出と優先順位

OpenClawは以下の順序でスキャン:

  1. 設定パス — plugins.load.paths
  2. ワークスペース拡張 — <workspace>/.openclaw/extensions/*.ts
  3. グローバル拡張 — ~/.openclaw/extensions/*.ts
  4. バンドル拡張 — <openclaw>/extensions/*

ほとんどのバンドルプラグインは明示的に有効化する必要があります。

デフォルト有効のバンドルプラグイン例外: device-pairphone-controltalk-voice、アクティブメモリスロットプラグイン。

ワークスペースプラグインは明示的に有効化または許可リスト登録しない限りデフォルトで無効です。

有効化ルール

  • plugins.enabled: falseはすべてのプラグインを無効化
  • plugins.denyは常に優先
  • plugins.entries.<id>.enabled: falseはそのプラグインを無効化
  • ワークスペース起源のプラグインはデフォルトで無効
  • 許可リストはIDベース

パッケージパック

{
  "name": "my-pack",
  "openclaw": {
    "extensions": ["./src/safety.ts", "./src/tools.ts"]
  }
}

各エントリがプラグインになります。パックが複数の拡張をリストする場合、プラグインIDはname/<fileBase>になります。

セキュリティに関する注意: openclaw plugins installはプラグインの依存関係をnpm install --ignore-scriptsでインストールします。

チャンネルカタログメタデータ

チャンネルプラグインはopenclaw.channelopenclaw.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",
      "docsLabel": "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"
    }
  }
}

プラグインID

  • パッケージパック: package.jsonname
  • スタンドアロンファイル: ファイルのベース名(~/.../voice-call.tsvoice-call

レジストリモデル

ロードされたプラグインはセントラルプラグインレジストリに登録します。コア機能はレジストリから読み取ります。

設定

{
  plugins: {
    enabled: true,
    allow: ["voice-call"],
    deny: ["untrusted-plugin"],
    load: { paths: ["~/Projects/oss/voice-call-extension"] },
    entries: {
      "voice-call": { enabled: true, config: { provider: "twilio" } },
    },
  },
}

フィールド:

  • enabled: マスタートグル(デフォルト: true)
  • allow: 許可リスト(オプション)
  • deny: 拒否リスト(denyが優先)
  • load.paths: 追加プラグインファイル/ディレクトリ
  • slots: 排他スロットセレクター(memorycontextEngine
  • entries.<id>: プラグイン単位のトグル+設定

設定変更にはGatewayの再起動が必要です。

プラグインスロット(排他カテゴリ)

{
  plugins: {
    slots: {
      memory: "memory-core",
      contextEngine: "legacy",
    },
  },
}
  • memory: アクティブメモリプラグイン("none"で無効化)
  • contextEngine: アクティブコンテキストエンジンプラグイン("legacy"は組み込みデフォルト)

Control UI(スキーマ+ラベル)

{
  "id": "my-plugin",
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "apiKey": { "type": "string" },
      "region": { "type": "string" }
    }
  },
  "uiHints": {
    "apiKey": { "label": "API Key", "sensitive": true },
    "region": { "label": "Region", "placeholder": "us-east-1" }
  }
}

CLI

openclaw plugins list
openclaw plugins info <id>
openclaw plugins install <path>                 # ローカルファイル/ディレクトリをコピー
openclaw plugins install @openclaw/voice-call # npmからインストール
openclaw plugins install @openclaw/voice-call --pin # 正確なバージョンを保存
openclaw plugins update <id>
openclaw plugins update --all
openclaw plugins enable <id>
openclaw plugins disable <id>
openclaw plugins doctor

プラグインAPI(概要)

プラグインは以下のいずれかをエクスポート:

  • 関数: (api) => { ... }
  • オブジェクト: { id, name, configSchema, register(api) { ... } }

一般的な登録: registerToolregisterHookon(...)registerChannelregisterProviderregisterHttpRouteregisterCommandregisterCliregisterContextEngineregisterService

プラグインフック

export default function register(api) {
  api.registerHook(
    "command:new",
    async () => {
      // フックロジック
    },
    {
      name: "my-plugin.command-new",
      description: "Runs when /new is invoked",
    },
  );
}

エージェントライフサイクルフック(api.on

export default function register(api) {
  api.on(
    "before_prompt_build",
    (event, ctx) => {
      return {
        prependSystemContext: "Follow company style guide.",
      };
    },
    { priority: 10 },
  );
}

プロンプト構築に重要なフック:

  • before_model_resolve: セッションロード前に実行。modelOverrideproviderOverrideの決定的オーバーライドに使用。
  • before_prompt_build: セッションロード後に実行。プロンプト入力の整形に使用。
  • before_agent_start: レガシー互換性フック。

before_prompt_buildの結果フィールド:

  • prependContext: ユーザープロンプトにテキストを先頭追加。
  • systemPrompt: フルシステムプロンプトオーバーライド。
  • prependSystemContext: システムプロンプトにテキストを先頭追加。
  • appendSystemContext: システムプロンプトにテキストを末尾追加。

プロバイダープラグイン(モデル認証)

プラグインはモデルプロバイダーを登録できます。5つのフェーズに参加:

  1. 認証auth[].run(ctx)
  2. 非対話的設定auth[].runNonInteractive(ctx)
  3. ウィザード統合wizard.onboardingwizard.modelPicker
  4. 暗黙的検出discovery.run(ctx)
  5. 選択後フォローアップonModelSelected(ctx)
api.registerProvider({
  id: "acme",
  label: "AcmeAI",
  auth: [
    {
      id: "oauth",
      label: "OAuth",
      kind: "oauth",
      run: async (ctx) => {
        return {
          profiles: [
            {
              profileId: "acme:default",
              credential: {
                type: "oauth",
                provider: "acme",
                access: "...",
                refresh: "...",
                expires: Date.now() + 3600 * 1000,
              },
            },
          ],
          defaultModel: "acme/opus-1",
        };
      },
    },
  ],
  wizard: {
    onboarding: {
      choiceId: "acme",
      choiceLabel: "AcmeAI",
      groupId: "acme",
      groupLabel: "AcmeAI",
      methodId: "oauth",
    },
    modelPicker: {
      label: "AcmeAI (custom)",
      hint: "Connect a self-hosted AcmeAI endpoint",
      methodId: "oauth",
    },
  },
  discovery: {
    order: "late",
    run: async () => ({
      provider: {
        baseUrl: "https://acme.example/v1",
        api: "openai-completions",
        apiKey: "${ACME_API_KEY}",
        models: [],
      },
    }),
  },
});

メッセージングチャンネルの登録

const myChannel = {
  id: "acmechat",
  meta: {
    id: "acmechat",
    label: "AcmeChat",
    selectionLabel: "AcmeChat (API)",
    docsPath: "/channels/acmechat",
    blurb: "demo channel plugin.",
    aliases: ["acme"],
  },
  capabilities: { chatTypes: ["direct"] },
  config: {
    listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
    resolveAccount: (cfg, accountId) =>
      cfg.channels?.acmechat?.accounts?.[accountId ?? "default"] ?? {
        accountId,
      },
  },
  outbound: {
    deliveryMode: "direct",
    sendText: async () => ({ ok: true }),
  },
};

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

エージェントツール

専用ガイドを参照: プラグインエージェントツール

Gateway RPCメソッドの登録

export default function (api) {
  api.registerGatewayMethod("myplugin.status", ({ respond }) => {
    respond(true, { ok: true });
  });
}

CLIコマンドの登録

export default function (api) {
  api.registerCli(
    ({ program }) => {
      program.command("mycmd").action(() => {
        console.log("Hello");
      });
    },
    { commands: ["mycmd"] },
  );
}

自動返信コマンドの登録

export default function (api) {
  api.registerCommand({
    name: "mystatus",
    description: "Show plugin status",
    handler: (ctx) => ({
      text: `Plugin is running! Channel: ${ctx.channel}`,
    }),
  });
}

バックグラウンドサービスの登録

export default function (api) {
  api.registerService({
    id: "my-service",
    start: () => api.logger.info("ready"),
    stop: () => api.logger.info("bye"),
  });
}

命名規則

  • Gatewayメソッド: pluginId.action(例: voicecall.status
  • ツール: snake_case(例: voice_call
  • CLIコマンド: ケバブケースまたはキャメルケース

スキル

プラグインはリポジトリ内にスキルを同梱可能(skills/<name>/SKILL.md)。

配布(npm)

  • メインパッケージ: openclaw
  • プラグイン: @openclaw/*配下の個別npmパッケージ
  • スコープ付きパッケージはplugins.entries.*用にアンスコープIDに正規化

プラグイン例: Voice Call

  • ソース: extensions/voice-call
  • スキル: skills/voice-call
  • CLI: openclaw voicecall start|status
  • ツール: voice_call
  • RPC: voicecall.startvoicecall.status

セットアップと使用方法はVoice Callextensions/voice-call/README.mdを参照。

セーフティに関する注意

プラグインはGatewayとインプロセスで実行されます。信頼できるコードとして扱ってください:

  • 信頼できるプラグインのみインストール。
  • plugins.allow許可リストを推奨。
  • 変更後にGatewayを再起動。

プラグインのテスト

プラグインはテストを同梱すべきです:

  • リポジトリ内プラグインはVitestテストをsrc/**配下に配置可能。
  • 個別に公開するプラグインは独自のCI(lint/build/test)を実行すべき。