Plugins (Extensions)
Bắt đầu nhanh (mới làm quen với plugins?)
Plugin chỉ là một module code nhỏ mở rộng OpenClaw với các tính năng bổ sung (lệnh, công cụ và Gateway RPC).
Hầu hết thời gian, các bạn sẽ dùng plugins khi muốn một tính năng chưa được tích hợp sẵn trong OpenClaw core (hoặc muốn giữ các tính năng tùy chọn tách khỏi bản cài đặt chính).
Cách nhanh:
- Xem những gì đã được tải:
openclaw plugins list
- Cài đặt một plugin chính thức (ví dụ: Voice Call):
openclaw plugins install @openclaw/voice-call
- Khởi động lại Gateway, sau đó cấu hình trong
plugins.entries.<id>.config.
Xem Voice Call để tham khảo ví dụ plugin cụ thể.
Các plugin có sẵn (chính thức)
- Microsoft Teams chỉ có dạng plugin từ 2026.1.15; cài
@openclaw/msteamsnếu các bạn dùng Teams. - Memory (Core) — plugin tìm kiếm bộ nhớ đi kèm (bật mặc định qua
plugins.slots.memory) - Memory (LanceDB) — plugin bộ nhớ dài hạn đi kèm (tự động ghi nhớ/lưu trữ; đặt
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 (provider auth) — đi kèm dưới tên
google-antigravity-auth(tắt mặc định) - Gemini CLI OAuth (provider auth) — đi kèm dưới tên
google-gemini-cli-auth(tắt mặc định) - Qwen OAuth (provider auth) — đi kèm dưới tên
qwen-portal-auth(tắt mặc định) - Copilot Proxy (provider auth) — cầu nối VS Code Copilot Proxy cục bộ; khác với đăng nhập thiết bị
github-copilottích hợp sẵn (đi kèm, tắt mặc định)
OpenClaw plugins là TypeScript modules được tải lúc runtime qua jiti. Xác thực config không thực thi code plugin; nó dùng plugin manifest và JSON Schema thay thế. Xem Plugin manifest.
Plugins có thể đăng ký:
- Gateway RPC methods
- Gateway HTTP handlers
- Agent tools
- CLI commands
- Background services
- Xác thực config tùy chọn
- Skills (bằng cách liệt kê thư mục
skillstrong plugin manifest) - Auto-reply commands (thực thi mà không cần gọi AI agent)
Plugins chạy in-process với Gateway, nên hãy coi chúng như code đáng tin cậy. Hướng dẫn viết công cụ: Plugin agent tools.
Runtime helpers
Plugins có thể truy cập các helper core đã chọn qua api.runtime. Cho telephony TTS:
const result = await api.runtime.tts.textToSpeechTelephony({
text: "Hello from OpenClaw",
cfg: api.config,
});
Lưu ý:
- Dùng cấu hình
messages.ttscore (OpenAI hoặc ElevenLabs). - Trả về PCM audio buffer + sample rate. Plugins phải resample/encode cho providers.
- Edge TTS không được hỗ trợ cho telephony.
Discovery & precedence
OpenClaw quét theo thứ tự:
- Config paths
plugins.load.paths(file hoặc thư mục)
- Workspace extensions
<workspace>/.openclaw/extensions/*.ts<workspace>/.openclaw/extensions/*/index.ts
- Global extensions
~/.openclaw/extensions/*.ts~/.openclaw/extensions/*/index.ts
- Bundled extensions (đi kèm với OpenClaw, tắt mặc định)
<openclaw>/extensions/*
Bundled plugins phải được bật rõ ràng qua plugins.entries.<id>.enabled hoặc openclaw plugins enable <id>. Installed plugins được bật mặc định, nhưng có thể tắt theo cách tương tự.
Mỗi plugin phải có file openclaw.plugin.json trong thư mục gốc của nó. Nếu đường dẫn trỏ đến một file, thư mục gốc plugin là thư mục chứa file đó và phải có manifest.
Nếu nhiều plugins cùng resolve về một id, kết quả khớp đầu tiên theo thứ tự trên sẽ thắng và các bản sao ưu tiên thấp hơn bị bỏ qua.
Package packs
Một thư mục plugin có thể bao gồm package.json với openclaw.extensions:
{
"name": "my-pack",
"openclaw": {
"extensions": ["./src/safety.ts", "./src/tools.ts"]
}
}
Mỗi entry trở thành một plugin. Nếu pack liệt kê nhiều extensions, plugin id sẽ trở thành name/<fileBase>.
Nếu plugin của các bạn import npm deps, hãy cài chúng trong thư mục đó để node_modules có sẵn (npm install / pnpm install).
Channel catalog metadata
Channel plugins có thể quảng cáo metadata onboarding qua openclaw.channel và gợi ý cài đặt qua openclaw.install. Điều này giữ cho core catalog không có dữ liệu.
Ví dụ:
{
"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"
}
}
}
OpenClaw cũng có thể merge external channel catalogs (ví dụ, một MPM registry export). Đặt file JSON tại một trong các vị trí:
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
Hoặc trỏ OPENCLAW_PLUGIN_CATALOG_PATHS (hoặc OPENCLAW_MPM_CATALOG_PATHS) đến một hoặc nhiều file JSON (phân cách bằng dấu phẩy/chấm phẩy/PATH). Mỗi file nên chứa { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }.
Plugin IDs
Plugin ids mặc định:
- Package packs:
nametrongpackage.json - Standalone file: tên base của file (
~/.../voice-call.ts→voice-call)
Nếu plugin export id, OpenClaw sẽ dùng nó nhưng cảnh báo khi nó không khớp với id đã cấu hình.
Config
{
plugins: {
enabled: true,
allow: ["voice-call"],
deny: ["untrusted-plugin"],
load: { paths: ["~/Projects/oss/voice-call-extension"] },
entries: {
"voice-call": { enabled: true, config: { provider: "twilio" } },
},
},
}
Các trường:
enabled: công tắc chính (mặc định: true)allow: danh sách cho phép (tùy chọn)deny: danh sách từ chối (tùy chọn; deny thắng)load.paths: file/thư mục plugin bổ sungentries.<id>: công tắc + config cho từng plugin
Thay đổi config yêu cầu khởi động lại gateway.
Quy tắc xác thực (nghiêm ngặt):
- Plugin ids không xác định trong
entries,allow,deny, hoặcslotslà lỗi. - Các key
channels.<id>không xác định là lỗi trừ khi plugin manifest khai báo channel id đó. - Config plugin được xác thực bằng JSON Schema nhúng trong
openclaw.plugin.json(configSchema). - Nếu plugin bị tắt, config của nó được giữ lại và một cảnh báo được phát ra.
Plugin slots (exclusive categories)
Một số danh mục plugin là exclusive (chỉ một plugin hoạt động tại một thời điểm). Dùng plugins.slots để chọn plugin nào sở hữu slot:
{
plugins: {
slots: {
memory: "memory-core", // hoặc "none" để tắt memory plugins
},
},
}
Nếu nhiều plugins khai báo kind: "memory", chỉ plugin được chọn mới tải. Các plugin khác bị tắt với diagnostics.
Control UI (schema + labels)
Control UI dùng config.schema (JSON Schema + uiHints) để render form tốt hơn.
OpenClaw bổ sung uiHints lúc runtime dựa trên các plugin đã khám phá:
- Thêm labels cho từng plugin cho
plugins.entries.<id>/.enabled/.config - Merge các gợi ý trường config tùy chọn do plugin cung cấp dưới:
plugins.entries.<id>.config.<field>
Nếu các bạn muốn các trường config plugin hiển thị labels/placeholders tốt (và đánh dấu secrets là sensitive), hãy cung cấp uiHints cùng với JSON Schema trong plugin manifest.
Ví dụ:
{
"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> # copy file/thư mục cục bộ vào ~/.openclaw/extensions/<id>
openclaw plugins install ./extensions/voice-call # đường dẫn tương đối ok
openclaw plugins install ./plugin.tgz # cài từ tarball cục bộ
openclaw plugins install ./plugin.zip # cài từ zip cục bộ
openclaw plugins install -l ./extensions/voice-call # link (không copy) cho dev
openclaw plugins install @openclaw/voice-call # cài từ npm
openclaw plugins update <id>
openclaw plugins update --all
openclaw plugins enable <id>
openclaw plugins disable <id>
openclaw plugins doctor
plugins update chỉ hoạt động cho các bản cài npm được theo dõi trong plugins.installs.
Plugins cũng có thể đăng ký các lệnh top-level riêng (ví dụ: openclaw voicecall).
Plugin API (tổng quan)
Plugins export một trong hai:
- Một function:
(api) => { ... } - Một object:
{ id, name, configSchema, register(api) { ... } }
Plugin hooks
Plugins có thể đi kèm hooks và đăng ký chúng lúc runtime. Điều này cho phép plugin đóng gói automation hướng sự kiện mà không cần cài đặt hook pack riêng.
Ví dụ
import { registerPluginHooksFromDir } from "openclaw/plugin-sdk";
export default function register(api) {
registerPluginHooksFromDir(api, "./hooks");
}
Lưu ý:
- Thư mục hooks tuân theo cấu trúc hook thông thường (
HOOK.md+handler.ts). - Quy tắc điều kiện hook vẫn áp dụng (yêu cầu OS/bins/env/config).
- Hooks do plugin quản lý hiển thị trong
openclaw hooks listvớiplugin:<id>. - Các bạn không thể bật/tắt hooks do plugin quản lý qua
openclaw hooks; thay vào đó hãy bật/tắt plugin.
Provider plugins (model auth)
Plugins có thể đăng ký model provider auth flows để người dùng có thể chạy OAuth hoặc thiết lập API-key bên trong OpenClaw (không cần script bên ngoài).
Đăng ký provider qua api.registerProvider(...). Mỗi provider cung cấp một hoặc nhiều phương thức auth (OAuth, API key, device code, v.v.). Các phương thức này hỗ trợ:
openclaw models auth login --provider <id> [--method <id>]
Ví dụ:
api.registerProvider({
id: "acme",
label: "AcmeAI",
auth: [
{
id: "oauth",
label: "OAuth",
kind: "oauth",
run: async (ctx) => {
// Chạy OAuth flow và trả về auth profiles.
return {
profiles: [
{
profileId: "acme:default",
credential: {
type: "oauth",
provider: "acme",
access: "...",
refresh: "...",
expires: Date.now() + 3600 * 1000,
},
},
],
defaultModel: "acme/opus-1",
};
},
},
],
});
Lưu ý:
runnhậnProviderAuthContextvới các helperprompter,runtime,openUrl, vàoauth.createVpsAwareHandlers.- Trả về
configPatchkhi các bạn cần thêm models mặc định hoặc provider config. - Trả về
defaultModelđể--set-defaultcó thể cập nhật agent defaults.
Đăng ký messaging channel
Plugins có thể đăng ký channel plugins hoạt động như các channels tích hợp sẵn (WhatsApp, Telegram, v.v.). Config channel nằm dưới channels.<id> và được xác thực bởi code channel plugin của các bạn.
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 });
}
Lưu ý:
- Đặt config dưới
channels.<id>(không phảiplugins.entries). meta.labelđược dùng cho labels trong danh sách CLI/UI.meta.aliasesthêm các id thay thế cho normalization và CLI inputs.meta.preferOverliệt kê các channel ids để bỏ qua auto-enable khi cả hai được cấu hình.meta.detailLabelvàmeta.systemImagecho phép UIs hiển thị labels/icons channel phong phú hơn.
Viết messaging channel mới (từng bước)
Dùng cái này khi các bạn muốn một chat surface mới (một “messaging channel”), không phải model provider. Tài liệu model provider nằm dưới /providers/*.
- Chọn id + hình dạng config
- Tất cả config channel nằm dưới
channels.<id>. - Ưu tiên
channels.<id>.accounts.<accountId>cho thiết lập multi-account.
- Định nghĩa metadata channel
meta.label,meta.selectionLabel,meta.docsPath,meta.blurbđiều khiển danh sách CLI/UI.meta.docsPathnên trỏ đến trang docs như/channels/<id>.meta.preferOvercho phép plugin thay thế channel khác (auto-enable ưu tiên nó).meta.detailLabelvàmeta.systemImageđược UIs dùng cho text/icons chi tiết.
- Implement các adapters bắt buộc
config.listAccountIds+config.resolveAccountcapabilities(chat types, media, threads, v.v.)outbound.deliveryMode+outbound.sendText(cho gửi cơ bản)
- Thêm adapters tùy chọn khi cần
setup(wizard),security(DM policy),status(health/diagnostics)gateway(start/stop/login),mentions,threading,streamingactions(message actions),commands(native command behavior)
- Đăng ký channel trong plugin của các bạn
api.registerChannel({ plugin })
Ví dụ config tối thiểu:
{
channels: {
acmechat: {
accounts: {
default: { token: "ACME_TOKEN", enabled: true },
},
},
},
}
Channel plugin tối thiểu (chỉ outbound):
const plugin = {
id: "acmechat",
meta: {
id: "acmechat",
label: "AcmeChat",
selectionLabel: "AcmeChat (API)",
docsPath: "/channels/acmechat",
blurb: "AcmeChat messaging channel.",
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 ({ text }) => {
// gửi `text` đến channel của các bạn ở đây
return { ok: true };
},
},
};
export default function (api) {
api.registerChannel({ plugin });
}
Tải plugin (thư mục extensions hoặc plugins.load.paths), khởi động lại gateway, sau đó cấu hình channels.<id> trong config của các bạn.
Agent tools
Xem hướng dẫn chuyên biệt: Plugin agent tools.
Đăng ký gateway RPC method
export default function (api) {
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
respond(true, { ok: true });
});
}
Đăng ký CLI commands
export default function (api) {
api.registerCli(
({ program }) => {
program.command("mycmd").action(() => {
console.log("Hello");
});
},
{ commands: ["mycmd"] },
);
}
Đăng ký auto-reply commands
Plugins có thể đăng ký các slash commands tùy chỉnh thực thi mà không cần gọi AI agent. Điều này hữu ích cho các lệnh toggle, kiểm tra trạng thái, hoặc hành động nhanh không cần xử lý LLM.
export default function (api) {
api.registerCommand({
name: "mystatus",
description: "Show plugin status",
handler: (ctx) => ({
text: `Plugin is running! Channel: ${ctx.channel}`,
}),
});
}
Command handler context:
senderId: ID của người gửi (nếu có)channel: Channel nơi lệnh được gửiisAuthorizedSender: Người gửi có phải là người dùng được ủy quyền khôngargs: Các đối số được truyền sau lệnh (nếuacceptsArgs: true)commandBody: Toàn bộ text lệnhconfig: Config OpenClaw hiện tại
Command options:
name: Tên lệnh (không có dấu/đầu)description: Text trợ giúp hiển thị trong danh sách lệnhacceptsArgs: Lệnh có chấp nhận đối số không (mặc định: false). Nếu false và có đối số được cung cấp, lệnh sẽ không khớp và message rơi vào các handlers khácrequireAuth: Có yêu cầu người gửi được ủy quyền không (mặc định: true)handler: Function trả về{ text: string }(có thể async)
Ví dụ với authorization và arguments:
api.registerCommand({
name: "setmode",
description: "Set plugin mode",
acceptsArgs: true,
requireAuth: true,
handler: async (ctx) => {
const mode = ctx.args?.trim() || "default";
await saveMode(mode);
return { text: `Mode set to: ${mode}` };
},
});
Lưu ý:
- Plugin commands được xử lý trước built-in commands và AI agent
- Commands được đăng ký globally và hoạt động trên tất cả channels
- Tên lệnh không phân biệt chữ hoa chữ thường (
/MyStatuskhớp với/mystatus) - Tên lệnh phải bắt đầu bằng chữ cái và chỉ chứa chữ cái, số, dấu gạch ngang và gạch dưới
- Tên lệnh dành riêng (như
help,status,reset, v.v.) không thể bị plugins ghi đè - Đăng ký lệnh trùng lặp giữa các plugins sẽ thất bại với lỗi diagnostic
Đăng ký background services
export default function (api) {
api.registerService({
id: "my-service",
start: () => api.logger.info("ready"),
stop: () => api.logger.info("bye"),
});
}
Naming conventions
- Gateway methods:
pluginId.action(ví dụ:voicecall.status) - Tools:
snake_case(ví dụ:voice_call) - CLI commands: kebab hoặc camel, nhưng tránh xung đột với core commands
Skills
Plugins có thể đi kèm skill trong repo (skills/<name>/SKILL.md).
Bật nó với plugins.entries.<id>.enabled (hoặc các cổng config khác) và đảm bảo nó có mặt trong workspace/managed skills locations của các bạn.
Distribution (npm)
Packaging được khuyến nghị:
- Package chính:
openclaw(repo này) - Plugins: các npm packages riêng dưới
@openclaw/*(ví dụ:@openclaw/voice-call)
Publishing contract:
package.jsoncủa plugin phải bao gồmopenclaw.extensionsvới một hoặc nhiều entry files.- Entry files có thể là
.jshoặc.ts(jiti tải TS lúc runtime). openclaw plugins install <npm-spec>dùngnpm pack, giải nén vào~/.openclaw/extensions/<id>/, và bật nó trong config.- Tính ổn định config key: scoped packages được normalize thành id không có scope cho
plugins.entries.*.
Ví dụ plugin: Voice Call
Repo này bao gồm một voice-call plugin (Twilio hoặc log fallback):
- Source:
extensions/voice-call - Skill:
skills/voice-call - CLI:
openclaw voicecall start|status - Tool:
voice_call - RPC:
voicecall.start,voicecall.status - Config (twilio):
provider: "twilio"+twilio.accountSid/authToken/from(tùy chọnstatusCallbackUrl,twimlUrl) - Config (dev):
provider: "log"(không có network)
Xem Voice Call và extensions/voice-call/README.md để biết cách thiết lập và sử dụng.
Lưu ý bảo mật
Plugins chạy in-process với Gateway. Hãy coi chúng như code đáng tin cậy:
- Chỉ cài plugins mà các bạn tin tưởng.
- Ưu tiên dùng allowlists
plugins.allow. - Khởi động lại Gateway sau khi thay đổi.
Testing plugins
Plugins có thể (và nên) đi kèm tests:
- In-repo plugins có thể giữ Vitest tests dưới
src/**(ví dụ:src/plugins/voice-call.plugin.test.ts). - Plugins được publish riêng nên chạy CI riêng (lint/build/test) và xác thực
openclaw.extensionstrỏ đến built entrypoint (dist/index.js).