Building plugins
Araç pluginleri
defineToolPlugin yalnızca ajanların çağırabileceği araçlar ekleyen bir plugin oluşturur: kanal,
model sağlayıcısı, kanca, hizmet veya kurulum arka ucu içermez. OpenClaw'un plugin
çalışma zamanı kodunu yüklemeden araçları keşfetmesi için gereken manifest meta verilerini
oluşturur.
Sağlayıcı, kanal, kanca, hizmet veya karma yetenekli pluginler için bunun yerine Plugin oluşturma, Kanal Pluginleri veya Sağlayıcı Pluginleri ile başlayın.
Gereksinimler
- Node 22.22.3+, Node 24.15+ veya Node 25.9+.
- TypeScript ESM paket çıktısı.
typebox,dependenciesiçinde olmalıdır (yalnızcadevDependenciesiçinde değil; oluşturulan plugin bunu çalışma zamanında içe aktarır).openclaw >=2026.5.17,openclaw/plugin-sdk/tool-plugindışa aktarımını yapan ilk sürüm.dist/,openclaw.plugin.jsonvepackage.jsondosyalarını dağıtan bir paket kökü.
Hızlı başlangıç
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm testplugins init şunları oluşturur:
| Dosya | Amaç |
|---|---|
src/index.ts |
Bir echo aracı içeren defineToolPlugin girişi |
src/index.test.ts |
Araç listesini doğrulayan meta veri testi |
tsconfig.json |
dist/ konumuna NodeNext TypeScript çıktısı |
vitest.config.ts |
src/**/*.test.ts için Vitest yapılandırması |
package.json |
Betikler, çalışma zamanı bağımlılıkları, openclaw.extensions: ["./dist/index.js"] |
openclaw.plugin.json |
İlk araç için oluşturulan manifest meta verileri |
npm run plugin:build, npm run build (tsc) ve ardından
openclaw plugins build --entry ./dist/index.js komutunu çalıştırır. npm run plugin:validate
yeniden oluşturur ve openclaw plugins validate --entry ./dist/index.js komutunu çalıştırır.
Başarılı doğrulama şu çıktıyı verir:
Plugin stock-quotes is valid.openclaw plugins init <id> seçenekleri:
| Bayrak | Varsayılan | Etki |
|---|---|---|
--directory <path> |
<id> |
Çıktı dizini |
--name <name> |
Başlık biçiminde <id> |
Görünen ad |
--type <type> |
tool |
Oluşturma türü: tool veya provider |
--force |
kapalı | Mevcut bir çıktı dizininin üzerine yaz |
Araç yazma
defineToolPlugin, plugin kimliğini, isteğe bağlı bir yapılandırma şemasını ve
statik bir araç listesini alır. Parametre ve yapılandırma türleri
TypeBox şemalarından çıkarılır.
export default defineToolPlugin({ id: "stock-quotes", name: "Stock Quotes", description: "Fetch stock quote snapshots.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "Quote API key." })), baseUrl: Type.Optional(Type.String({ description: "Quote API base URL." })), }), tools: (tool) => [ tool({ name: "stock_quote", label: "Stock Quote", description: "Fetch a stock quote snapshot.", parameters: Type.Object({ symbol: Type.String({ description: "Ticker symbol, for example OPEN." }), }), outputSchema: Type.Object( { symbol: Type.String(), configured: Type.Boolean(), baseUrl: Type.String(), }, { additionalProperties: false }, ), async execute({ symbol }, config, context) { context.signal?.throwIfAborted(); return { symbol: symbol.toUpperCase(), configured: Boolean(config.apiKey), baseUrl: config.baseUrl ?? "https://api.example.com", }; }, }), ],});Araç adları kararlı API'dir. Benzersiz, küçük harfli ve çekirdek araçlarla veya diğer pluginlerle çakışmayı önleyecek kadar belirgin adlar seçin.
İsteğe bağlı ve fabrika araçları
Kullanıcıların aracı bir modele gönderilmeden önce açıkça izin listesine alması
gerekiyorsa optional: true ayarlayın. openclaw plugins build, eşleşen
toolMetadata.<tool>.optional manifest girdisini yazar; böylece OpenClaw, plugin çalışma zamanı
kodunu yüklemeden aracın isteğe bağlı olduğunu görebilir.
tool({ name: "workflow_run", description: "Run an external workflow.", parameters: Type.Object({ goal: Type.String() }), optional: true, execute: ({ goal }) => ({ queued: true, goal }),});Bir aracın oluşturulabilmesi için önce çalışma zamanı araç bağlamına ihtiyacı olduğunda;
belirli bir çalıştırmada devre dışı kalmak, sandbox durumunu incelemek veya
çalışma zamanı yardımcılarını bağlamak için factory kullanın. Somut araç
çalışma zamanında oluşturulsa da meta veriler statik kalır.
tool({ name: "local_workflow", description: "Run a local workflow outside sandboxed sessions.", parameters: Type.Object({ goal: Type.String() }), optional: true, factory({ api, toolContext }) { if (toolContext.sandboxed) { return null; } return createLocalWorkflowTool(api); },});Fabrikalar yine de sabit bir araç adını önceden bildirir. Plugin araç adlarını
dinamik olarak hesapladığında veya araçları kancalar, hizmetler, sağlayıcılar
ya da komutlarla birleştirdiğinde doğrudan definePluginEntry kullanın.
Dönüş değerleri
defineToolPlugin, düz dönüş değerlerini OpenClaw araç sonucu
biçimine sarar:
- Modelin tam olarak bu metni görmesi gerektiğinde bir dize döndürün.
- Modelin biçimlendirilmiş JSON görmesini ve OpenClaw'un özgün değeri
detailsiçinde tutmasını istediğinizde JSON uyumlu bir değer döndürün.
tool({ name: "echo_text", description: "Echo input text.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => input,});tool({ name: "echo_json", description: "Echo input as structured JSON.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => ({ input, length: input.length }),});Özel bir AgentToolResult gerektiğinde veya mevcut bir
api.registerTool uygulamasını yeniden kullanmak istediğinizde fabrika aracı kullanın.
Çıktı sözleşmeleri
Bir araç kararlı, JSON uyumlu veriler döndürdüğünde outputSchema ekleyin. Bu,
content içindeki biçimlendirilmiş metni değil, AgentToolResult.details içinde
saklanan özgün değeri açıklar:
tool({ name: "shipment_list", description: "List shipments.", parameters: Type.Object({ buyer: Type.Optional(Type.String()), }), outputSchema: Type.Array( Type.Object( { id: Type.String(), buyer: Type.String(), paid: Type.Boolean(), tons: Type.Number(), }, { additionalProperties: false }, ), ), execute: ({ buyer }) => listShipments(buyer),});Code Mode ve Araç Arama, bu şemayı sınırlandırılmış TypeScript tarzı bir çıktı ipucuna dönüştürür. Bu sayede model, sonucun yapısını gözlemlemek için başka bir model turu harcamak yerine bilinen bir sonucu tek program içinde çağırıp dönüştürebilir.
OpenClaw, bir katalog çağrısını yürütmeden önce şemayı derler; ardından araç kancalarından
sonra nihai details değerini köprü üzerinden döndürmeden önce doğrular.
Geçersiz bir şema aracın çalışmasına izin vermez; sonuç uyuşmazlığı tamamlanan
çağrının başarısız olmasına neden olur. Yapılandırılmış hata varyantları da dahil olmak üzere
istisna oluşturmayan tüm sonuç varyantlarını ekleyin veya sonuç kararlı değilse şemayı
kullanmayın. Güvenilir çıktı meta verileri model tarafından görünür hâle gelebileceğinden
şema açıklamalarına gizli veya hassas değerler koymayın.
Eksiksiz ve kompakt bir çıktı ipucu istediğinizde nesne katmanlarında
{ additionalProperties: false } kullanın; açık veya kesilmiş şemalar tools.describe(...)
üzerinden kullanılabilir kalır ancak eksiksiz hızlı dizin sözleşmeleri olarak duyurulmaz.
Fabrika araçları, döndürdükleri somut AnyAgentTool üzerinde
outputSchema bildirir. Statik tool({ factory }) bildirimi, çalışma zamanı
aracıyla uyumsuz hâle gelebileceği için ayrı bir çıktı şeması kabul etmez.
Yapılandırma
configSchema isteğe bağlıdır. Bunu atladığınızda OpenClaw katı bir boş nesne
şeması uygular; oluşturulan manifest yine de configSchema içerir.
export default defineToolPlugin({ id: "no-config-tools", name: "No Config Tools", description: "Adds tools that do not need configuration.", tools: () => [],});Bir configSchema kullanıldığında ikinci execute bağımsız değişkeninin
türü bundan çıkarılır:
const configSchema = Type.Object({ apiKey: Type.String(),}); export default defineToolPlugin({ id: "configured-tools", name: "Configured Tools", description: "Adds configured tools.", configSchema, tools: (tool) => [ tool({ name: "configured_ping", description: "Check whether configuration is available.", parameters: Type.Object({}), execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }), }), ],});OpenClaw, plugin yapılandırmasını Gateway yapılandırmasındaki plugin girdisinden okur. Gizli değerleri kaynak koduna veya dokümantasyon örneklerine sabit kodlamayın; pluginin güvenlik modeline uygun olarak yapılandırma, ortam değişkenleri veya SecretRef'ler kullanın.
Oluşturulan meta veriler
OpenClaw, plugin çalışma zamanı kodunu içe aktarmadan önce plugin manifestini okumalıdır.
defineToolPlugin bunun için statik meta verileri sunar ve
openclaw plugins build bunları pakete yazar. Plugin kimliğini, adını, açıklamasını,
yapılandırma şemasını, etkinleştirmesini veya araç adlarını değiştirdikten sonra
oluşturucuyu yeniden çalıştırın:
npm run buildopenclaw plugins build --entry ./dist/index.jsTek araçlı bir plugin için oluşturulan manifest:
{ "id": "stock-quotes", "name": "Stock Quotes", "description": "Fetch stock quote snapshots.", "version": "0.1.0", "configSchema": { "type": "object", "additionalProperties": false, "properties": {} }, "activation": { "onStartup": true }, "contracts": { "tools": ["stock_quote"] }}contracts.tools önemli keşif sözleşmesidir: OpenClaw'a, kurulu her pluginin
çalışma zamanını yüklemeden her aracın hangi plugine ait olduğunu bildirir. Güncel olmayan
bir manifest, aracın keşifte bulunamamasına veya kayıt hatasının yanlış plugine
yüklenmesine neden olabilir.
Paket meta verileri
openclaw plugins build ayrıca package.json değerini seçilen çalışma zamanı
girdisiyle hizalar:
{ "type": "module", "files": ["dist", "openclaw.plugin.json", "README.md"], "dependencies": { "typebox": "^1.1.38" }, "peerDependencies": { "openclaw": ">=2026.5.17" }, "openclaw": { "extensions": ["./dist/index.js"] }}TypeScript kaynak girdisini değil, oluşturulmuş JavaScript'i (./dist/index.js) dağıtın.
Kaynak girdileri yalnızca çalışma alanı içindeki yerel geliştirmede çalışır.
CI'da doğrulama
Oluşturulan meta veriler güncel değilse plugins build --check, dosyaları yeniden
yazmadan başarısız olur:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testOpenClaw SDK uyumluluk alanları, düzenleyicilerin geçiş uyarıları olarak gösterdiği
TypeScript @deprecated ek açıklamalarını taşır. Bunları CI'da zorunlu kılmak için
@typescript-eslint/no-deprecated gibi
tür bilgisine duyarlı bir kuralı etkinleştirin.
Oxlint tür bilgisine duyarlı olmadığından bu ek açıklamaları zorunlu kılamaz. Bu nedenle
oluşturulan plugins init iskeleti bir kullanımdan kaldırma lint yapılandırması eklemez.
plugins validate şunları denetler:
openclaw.plugin.jsonmevcut ve normal manifest yükleyicisinden geçiyor.- Geçerli giriş,
defineToolPluginmeta verilerini dışa aktarıyor. - Oluşturulan manifest alanları giriş meta verileriyle eşleşiyor.
contracts.toolsbildirilen araç adlarıyla eşleşiyor.package.json,openclaw.extensionsöğesini seçilen çalışma zamanı girişine yönlendiriyor.
Yerel olarak yükleme ve inceleme
Ayrı bir OpenClaw çalışma kopyasından veya yüklü CLI'dan paket yolunu yükleyin:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimePaketlenmiş bir temel doğrulama testi için önce paketi oluşturun ve tarball dosyasını yükleyin:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --jsonYüklemeden sonra Gateway'i yeniden başlatın veya yeniden yükleyin ve ajandan aracı kullanmasını isteyin. Araç görünmüyorsa kodu değiştirmeden önce Plugin çalışma zamanını ve etkin araç kataloğunu inceleyin (bkz. Sorun giderme).
Yayımlama
Paket hazır olduğunda ClawHub aracılığıyla yayımlayın. clawhub package publish
bir kaynak alır: yerel klasör, GitHub deposu (owner/repo[@ref]) veya
tarball URL'si.
clawhub package publish ./stock-quotes --dry-runclawhub package publish ./stock-quotesAçık bir ClawHub konum belirleyicisiyle yükleyin:
openclaw plugins install clawhub:your-org/stock-quotesYalın npm paket belirtimleri, kullanıma geçiş sırasında npm'den yüklenmeye devam eder; ancak ClawHub, OpenClaw Plugin'leri için tercih edilen keşif ve dağıtım yüzeyidir. Sahip kapsamı ve sürüm incelemesi için ClawHub'da yayımlama bölümüne bakın.
Sorun giderme
plugin entry not found: ./dist/index.js
Seçilen giriş dosyası mevcut değil. npm run build komutunu çalıştırın,
ardından openclaw plugins build --entry ./dist/index.js veya
openclaw plugins validate --entry ./dist/index.js komutunu yeniden çalıştırın.
plugin entry does not expose defineToolPlugin metadata
Giriş, defineToolPlugin tarafından oluşturulan bir değeri dışa aktarmadı.
Modülün varsayılan dışa aktarımının defineToolPlugin(...) sonucu olduğunu
doğrulayın veya --entry ile doğru girişi iletin.
openclaw.plugin.json generated metadata is stale
Manifest artık giriş meta verileriyle eşleşmiyor. Şunları çalıştırın:
npm run buildopenclaw plugins build --entry ./dist/index.jsHem openclaw.plugin.json hem de package.json değişikliklerini kaydedin.
package.json openclaw.extensions must include ./dist/index.js
Paket meta verileri farklı bir çalışma zamanı girişine işaret ediyor.
Oluşturucunun paket meta verilerini yayımlamayı amaçladığınız girişle
hizalaması için openclaw plugins build --entry ./dist/index.js komutunu çalıştırın.
Cannot find package 'typebox'
Derlenen Plugin, çalışma zamanında typebox öğesini içe aktarıyor.
Bunu dependencies içinde tutun; yeniden yükleyin, yeniden derleyin ve
doğrulamayı tekrar çalıştırın.
Araç yüklemeden sonra görünmüyor
Şunları sırayla kontrol edin:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.json, beklenen araç adlarını içerencontracts.toolsöğesine sahip.package.json,openclaw.extensions: ["./dist/index.js"]öğesine sahip.- Plugin yüklendikten sonra Gateway yeniden başlatıldı veya yeniden yüklendi.