Plugins
Membangun Plugin
Plugin memperluas OpenClaw dengan kapabilitas baru: kanal, penyedia model, ucapan, transkripsi realtime, suara realtime, pemahaman media, pembuatan gambar, pembuatan video, pengambilan web, pencarian web, alat agen, atau kombinasi apa pun.
Anda tidak perlu menambahkan Plugin Anda ke repositori OpenClaw. Publikasikan ke
ClawHub dan pengguna memasang dengan
openclaw plugins install clawhub:<package-name>. Spesifikasi paket polos tetap
dipasang dari npm selama peralihan peluncuran.
Prasyarat
- Node >= 22 dan manajer paket (npm atau pnpm)
- Familiar dengan TypeScript (ESM)
- Untuk Plugin dalam repo: repositori sudah dikloning dan
pnpm installsudah selesai. Pengembangan Plugin checkout sumber hanya mendukung pnpm karena OpenClaw memuat Plugin bundel dari paket workspaceextensions/*.
Jenis Plugin apa?
Hubungkan OpenClaw ke platform perpesanan (Discord, IRC, dll.)
Tambahkan penyedia model (LLM, proksi, atau endpoint kustom)
Daftarkan alat agen, kait peristiwa, atau layanan - lanjutkan di bawah
Untuk Plugin kanal yang tidak dijamin terpasang saat onboarding/penyiapan
berjalan, gunakan createOptionalChannelSetupSurface(...) dari
openclaw/plugin-sdk/channel-setup. Ini menghasilkan pasangan adaptor penyiapan + wizard
yang mengiklankan persyaratan pemasangan dan gagal secara tertutup pada penulisan konfigurasi nyata
hingga Plugin terpasang.
Mulai cepat: Plugin alat
Panduan ini membuat Plugin minimal yang mendaftarkan alat agen. Plugin kanal dan penyedia memiliki panduan khusus yang ditautkan di atas.
Buat paket dan manifes
{
"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
}
}
Setiap Plugin memerlukan manifes, bahkan tanpa konfigurasi. Alat yang didaftarkan runtime
harus dicantumkan dalam contracts.tools agar OpenClaw dapat menemukan
Plugin pemilik tanpa memuat runtime setiap Plugin. Plugin juga sebaiknya mendeklarasikan
activation.onStartup secara sengaja. Contoh ini menetapkannya ke true. Lihat
Manifes untuk skema lengkap. Cuplikan publikasi ClawHub kanonis
berada di docs/snippets/plugin-publish/.
Tulis entry point
// 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 digunakan untuk Plugin non-kanal. Untuk kanal, gunakan
defineChannelPluginEntry - lihat Plugin Kanal.
Untuk opsi entry point lengkap, lihat Entry Point.
Uji dan publikasikan
Plugin eksternal: validasi dan publikasikan dengan ClawHub, lalu pasang:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
openclaw plugins install clawhub:@myorg/openclaw-my-plugin
Spesifikasi paket polos seperti @myorg/openclaw-my-plugin dipasang dari npm selama
peralihan peluncuran. Gunakan clawhub: saat Anda menginginkan resolusi ClawHub.
Plugin dalam repo: letakkan di bawah pohon workspace Plugin bundel - ditemukan secara otomatis.
pnpm test -- <bundled-plugin-root>/my-plugin/
Kapabilitas Plugin
Satu Plugin dapat mendaftarkan sejumlah kapabilitas melalui objek api:
| Kapabilitas | Metode pendaftaran | Panduan terperinci |
|---|---|---|
| Inferensi teks (LLM) | api.registerProvider(...) |
Plugin Penyedia |
| Backend inferensi CLI | api.registerCliBackend(...) |
Backend CLI |
| Kanal / perpesanan | api.registerChannel(...) |
Plugin Kanal |
| Ucapan (TTS/STT) | api.registerSpeechProvider(...) |
Plugin Penyedia |
| Transkripsi realtime | api.registerRealtimeTranscriptionProvider(...) |
Plugin Penyedia |
| Suara realtime | api.registerRealtimeVoiceProvider(...) |
Plugin Penyedia |
| Pemahaman media | api.registerMediaUnderstandingProvider(...) |
Plugin Penyedia |
| Pembuatan gambar | api.registerImageGenerationProvider(...) |
Plugin Penyedia |
| Pembuatan musik | api.registerMusicGenerationProvider(...) |
Plugin Penyedia |
| Pembuatan video | api.registerVideoGenerationProvider(...) |
Plugin Penyedia |
| Pengambilan web | api.registerWebFetchProvider(...) |
Plugin Penyedia |
| Pencarian web | api.registerWebSearchProvider(...) |
Plugin Penyedia |
| Middleware hasil alat | api.registerAgentToolResultMiddleware(...) |
Ikhtisar SDK |
| Alat agen | api.registerTool(...) |
Di bawah |
| Perintah kustom | api.registerCommand(...) |
Entry Point |
| Kait Plugin | api.on(...) |
Kait Plugin |
| Kait peristiwa internal | api.registerHook(...) |
Entry Point |
| Rute HTTP | api.registerHttpRoute(...) |
Internal |
| Subperintah CLI | api.registerCli(...) |
Entry Point |
Untuk API pendaftaran lengkap, lihat Ikhtisar SDK.
Plugin bundel dapat menggunakan api.registerAgentToolResultMiddleware(...) saat mereka
membutuhkan penulisan ulang hasil alat secara async sebelum model melihat output. Deklarasikan
runtime target dalam contracts.agentToolResultMiddleware, misalnya
["pi", "codex"]. Ini adalah seam Plugin bundel tepercaya; Plugin eksternal
sebaiknya memilih kait Plugin OpenClaw biasa kecuali OpenClaw menumbuhkan
kebijakan kepercayaan eksplisit untuk kapabilitas ini.
Jika Plugin Anda mendaftarkan metode RPC gateway kustom, simpan metode tersebut pada prefiks
khusus Plugin. Namespace admin inti (config.*,
exec.approvals.*, wizard.*, update.*) tetap dicadangkan dan selalu diselesaikan ke
operator.admin, bahkan jika Plugin meminta cakupan yang lebih sempit.
Semantik guard kait yang perlu diingat:
before_tool_call:{ block: true }bersifat terminal dan menghentikan handler berprioritas lebih rendah.before_tool_call:{ block: false }diperlakukan sebagai tanpa keputusan.before_tool_call:{ requireApproval: true }menjeda eksekusi agen dan meminta persetujuan pengguna melalui overlay persetujuan exec, tombol Telegram, interaksi Discord, atau perintah/approvedi kanal apa pun.before_install:{ block: true }bersifat terminal dan menghentikan handler berprioritas lebih rendah.before_install:{ block: false }diperlakukan sebagai tanpa keputusan.message_sending:{ cancel: true }bersifat terminal dan menghentikan handler berprioritas lebih rendah.message_sending:{ cancel: false }diperlakukan sebagai tanpa keputusan.message_received: utamakan bidang bertipethreadIdsaat Anda memerlukan perutean thread/topik masuk. Simpanmetadatauntuk tambahan khusus kanal.message_sending: utamakan bidang perutean bertipereplyToId/threadIddaripada kunci metadata khusus kanal.
Perintah /approve menangani persetujuan exec dan Plugin dengan fallback terbatas: saat id persetujuan exec tidak ditemukan, OpenClaw mencoba ulang id yang sama melalui persetujuan Plugin. Penerusan persetujuan Plugin dapat dikonfigurasi secara independen melalui approvals.plugin dalam konfigurasi.
Jika plumbing persetujuan kustom perlu mendeteksi kasus fallback terbatas yang sama,
utamakan isApprovalNotFoundError dari openclaw/plugin-sdk/error-runtime
daripada mencocokkan string kedaluwarsa persetujuan secara manual.
Lihat Kait Plugin untuk contoh dan referensi kait.
Mendaftarkan alat agen
Alat adalah fungsi bertipe yang dapat dipanggil LLM. Alat dapat bersifat wajib (selalu tersedia) atau opsional (pilihan pengguna):
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 },
);
}
Setiap alat yang didaftarkan dengan api.registerTool(...) juga harus dideklarasikan dalam
manifes Plugin:
{
"contracts": {
"tools": ["my_tool", "workflow_tool"]
},
"toolMetadata": {
"workflow_tool": {
"optional": true
}
}
}
OpenClaw menangkap dan menyimpan cache descriptor tervalidasi dari tool terdaftar,
sehingga plugin tidak menduplikasi data description atau skema di manifest. Kontrak
manifest hanya mendeklarasikan kepemilikan dan discovery; eksekusi tetap memanggil
implementasi tool terdaftar yang live.
Tetapkan toolMetadata.<tool>.optional: true untuk tool yang didaftarkan dengan
api.registerTool(..., { optional: true }) agar OpenClaw dapat menghindari pemuatan
runtime plugin tersebut sampai tool secara eksplisit dimasukkan ke allowlist.
Pengguna mengaktifkan tool opsional dalam config:
{
tools: { allow: ["workflow_tool"] },
}
- Nama tool tidak boleh bentrok dengan tool core (konflik dilewati)
- Tool dengan objek pendaftaran yang tidak valid, termasuk
parametersyang hilang, dilewati dan dilaporkan dalam diagnostik plugin alih-alih menggagalkan jalannya agent - Gunakan
optional: trueuntuk tool dengan efek samping atau persyaratan binary tambahan - Pengguna dapat mengaktifkan semua tool dari sebuah plugin dengan menambahkan id plugin ke
tools.allow
Mendaftarkan perintah CLI
Plugin dapat menambahkan grup perintah root openclaw dengan api.registerCli. Sediakan
descriptors untuk setiap root perintah tingkat atas agar OpenClaw dapat menampilkan dan merutekan
perintah tanpa memuat setiap runtime plugin secara eager.
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,
},
],
},
);
}
Setelah install, verifikasi pendaftaran runtime dan jalankan perintah:
openclaw plugins inspect demo-plugin --runtime --json
openclaw demo-plugin ping
Konvensi impor
Selalu impor dari path openclaw/plugin-sdk/<subpath> yang terfokus:
// Wrong: monolithic root (deprecated, will be removed)
Untuk referensi subpath lengkap, lihat Ikhtisar SDK.
Di dalam plugin Anda, gunakan file barrel lokal (api.ts, runtime-api.ts) untuk
impor internal - jangan pernah mengimpor plugin Anda sendiri melalui path SDK-nya.
Untuk provider plugin, simpan helper khusus provider dalam barrel package-root tersebut kecuali seam benar-benar generik. Contoh bundled saat ini:
- Anthropic: wrapper stream Claude dan helper
service_tier/ beta - OpenAI: builder provider, helper model default, provider realtime
- OpenRouter: builder provider serta helper onboarding/config
Jika sebuah helper hanya berguna di dalam satu paket provider bundled, simpan di seam
package-root tersebut alih-alih mempromosikannya ke openclaw/plugin-sdk/*.
Beberapa seam helper openclaw/plugin-sdk/<bundled-id> yang dihasilkan masih ada untuk
pemeliharaan bundled-plugin ketika memiliki penggunaan owner yang terlacak. Perlakukan itu sebagai
permukaan yang dicadangkan, bukan sebagai pola default untuk plugin pihak ketiga baru.
Checklist prapengajuan
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
package.json memiliki metadata openclaw yang benar
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Manifest openclaw.plugin.json ada dan valid OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Entry point menggunakan defineChannelPluginEntry atau definePluginEntry
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Semua impor menggunakan path plugin-sdk/<subpath> yang terfokus
OPENCLAW_DOCS_MARKER:calloutClose: