플러그인(확장)
빠른 시작(플러그인이 처음인가요?)
플러그인은 추가 기능(명령, 도구, Gateway RPC)으로 OpenClaw를 확장하는 작은 코드 모듈일 뿐입니다. 대부분의 경우, 아직 OpenClaw 코어에 내장되지 않은 기능이 필요할 때 (또는 선택적 기능을 주 설치본과 분리해 두고 싶을 때) 플러그인을 사용합니다. 빠른 경로:- 무엇이 이미 로드되어 있는지 확인합니다:
- 공식 플러그인을 설치합니다(예: Voice Call):
@latest는 안정 트랙에 머뭅니다. npm이 둘 중 하나를 prerelease로
해석하면 OpenClaw는 중지하고 @beta/@rc 같은 prerelease 태그나 정확한
prerelease 버전으로 명시적으로 opt-in 하라고 요청합니다.
- Gateway를 재시작한 다음
plugins.entries.<id>.config아래에서 구성합니다.
사용 가능한 플러그인(공식)
- Microsoft Teams는 2026.1.15부터 플러그인 전용입니다. Teams를 사용한다면
@openclaw/msteams를 설치하세요. - Memory (Core) — 번들된 memory search 플러그인(
plugins.slots.memory를 통해 기본 활성화) - Memory (LanceDB) — 번들된 장기 메모리 플러그인(auto-recall/capture,
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) —
google-antigravity-auth로 번들 제공(기본 비활성화) - Gemini CLI OAuth (provider auth) —
google-gemini-cli-auth로 번들 제공(기본 비활성화) - Qwen OAuth (provider auth) —
qwen-portal-auth로 번들 제공(기본 비활성화) - Copilot Proxy (provider auth) — 로컬 VS Code Copilot Proxy 브리지, 내장
github-copilotdevice login과는 별개(번들 제공, 기본 비활성화)
- Gateway RPC 메서드
- Gateway HTTP 라우트
- 에이전트 도구
- CLI 명령
- 백그라운드 서비스
- 컨텍스트 엔진
- 선택적 config validation
- Skills (
skills디렉터리를 플러그인 manifest에 나열하여) - 자동 응답 명령 (AI 에이전트를 호출하지 않고 실행)
런타임 헬퍼
플러그인은api.runtime를 통해 선택된 코어 헬퍼에 접근할 수 있습니다.
전화용 TTS 예시:
- 코어
messages.tts구성(OpenAI 또는 ElevenLabs)을 사용합니다. - PCM 오디오 버퍼 + 샘플 레이트를 반환합니다. 플러그인은 provider에 맞게 resample/encode해야 합니다.
- Edge TTS는 전화용으로 지원되지 않습니다.
- 코어 media-understanding 오디오 구성(
tools.media.audio)과 provider fallback 순서를 사용합니다. - transcription 출력이 생성되지 않으면
{ text: undefined }를 반환합니다(예: 입력이 건너뛰어졌거나 지원되지 않는 경우).
Gateway HTTP 라우트
플러그인은api.registerHttpRoute(...)로 HTTP endpoint를 노출할 수 있습니다.
path: gateway HTTP 서버 아래의 라우트 경로auth: 필수. 일반 gateway auth가 필요하면"gateway"를, 플러그인 관리 auth/webhook verification에는"plugin"을 사용합니다.match: 선택 사항."exact"(기본값) 또는"prefix"replaceExisting: 선택 사항. 같은 플러그인이 기존에 등록한 자신의 라우트를 교체할 수 있게 합니다.handler: 라우트가 요청을 처리했으면true를 반환합니다.
api.registerHttpHandler(...)는 더 이상 사용되지 않습니다.api.registerHttpRoute(...)를 사용하세요.- 플러그인 라우트는
auth를 명시적으로 선언해야 합니다. - 정확히 같은
path + match충돌은replaceExisting: true가 아닌 한 거부되며, 한 플러그인이 다른 플러그인의 라우트를 교체할 수는 없습니다. auth수준이 다른 중첩 라우트는 거부됩니다.exact/prefixfallthrough 체인은 같은 auth 수준에서만 유지하세요.
Plugin SDK import 경로
플러그인을 작성할 때는 단일openclaw/plugin-sdk import 대신 SDK 서브패스를
사용하세요:
- 범용 플러그인 API, provider auth 타입, 공유 헬퍼에는
openclaw/plugin-sdk/core core보다 더 넓은 공유 런타임 헬퍼가 필요한 번들/내부 플러그인 코드에는openclaw/plugin-sdk/compat- Telegram 채널 플러그인에는
openclaw/plugin-sdk/telegram - Discord 채널 플러그인에는
openclaw/plugin-sdk/discord - Slack 채널 플러그인에는
openclaw/plugin-sdk/slack - Signal 채널 플러그인에는
openclaw/plugin-sdk/signal - iMessage 채널 플러그인에는
openclaw/plugin-sdk/imessage - WhatsApp 채널 플러그인에는
openclaw/plugin-sdk/whatsapp - LINE 채널 플러그인에는
openclaw/plugin-sdk/line - 번들된 Microsoft Teams 플러그인 표면에는
openclaw/plugin-sdk/msteams - 번들된 확장 전용 서브패스도 사용할 수 있습니다:
openclaw/plugin-sdk/acpx,openclaw/plugin-sdk/bluebubbles,openclaw/plugin-sdk/copilot-proxy,openclaw/plugin-sdk/device-pair,openclaw/plugin-sdk/diagnostics-otel,openclaw/plugin-sdk/diffs,openclaw/plugin-sdk/feishu,openclaw/plugin-sdk/google-gemini-cli-auth,openclaw/plugin-sdk/googlechat,openclaw/plugin-sdk/irc,openclaw/plugin-sdk/llm-task,openclaw/plugin-sdk/lobster,openclaw/plugin-sdk/matrix,openclaw/plugin-sdk/mattermost,openclaw/plugin-sdk/memory-core,openclaw/plugin-sdk/memory-lancedb,openclaw/plugin-sdk/minimax-portal-auth,openclaw/plugin-sdk/nextcloud-talk,openclaw/plugin-sdk/nostr,openclaw/plugin-sdk/open-prose,openclaw/plugin-sdk/phone-control,openclaw/plugin-sdk/qwen-portal-auth,openclaw/plugin-sdk/synology-chat,openclaw/plugin-sdk/talk-voice,openclaw/plugin-sdk/test-utils,openclaw/plugin-sdk/thread-ownership,openclaw/plugin-sdk/tlon,openclaw/plugin-sdk/twitch,openclaw/plugin-sdk/voice-call,openclaw/plugin-sdk/zalo,openclaw/plugin-sdk/zalouser.
openclaw/plugin-sdk는 기존 외부 플러그인에 대해 계속 지원됩니다.- 신규 및 마이그레이션된 번들 플러그인은 채널 또는 확장 전용 서브패스를
사용해야 합니다. 범용 표면에는
core, 더 넓은 공유 헬퍼가 필요할 때만compat를 사용하세요.
읽기 전용 채널 검사
플러그인이 채널을 등록한다면resolveAccount(...)와 함께
plugin.config.inspectAccount(cfg, accountId) 구현을 우선 고려하세요.
이유:
resolveAccount(...)는 런타임 경로입니다. 자격 증명이 완전히 materialize되었다고 가정해도 되며, 필요한 secret이 없으면 빠르게 실패해도 됩니다.openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolve, doctor/config repair 흐름 같은 읽기 전용 명령 경로는 구성 설명만 하기 위해 런타임 자격 증명을 materialize할 필요가 없어야 합니다.
inspectAccount(...) 동작:
- 설명용 계정 상태만 반환합니다.
enabled와configured를 유지합니다.- 관련이 있다면 다음과 같은 credential source/status 필드를 포함합니다:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- 읽기 전용 가용성 보고를 위해 raw token 값을 반환할 필요는 없습니다. 상태형 명령에는
tokenStatus: "available"(및 그에 대응하는 source 필드)만으로 충분합니다. - SecretRef를 통해 credential이 구성되어 있지만 현재 명령 경로에서는 사용할 수 없다면
configured_unavailable을 사용하세요.
- 플러그인 discovery와 manifest 메타데이터는 burst성 startup/reload 작업을 줄이기 위해 짧은 in-process cache를 사용합니다.
- 이 cache를 끄려면
OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1또는OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1을 설정하세요. - cache window는
OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS와OPENCLAW_PLUGIN_MANIFEST_CACHE_MS로 조정합니다.
Discovery 및 precedence
OpenClaw는 다음 순서로 스캔합니다:- Config 경로
plugins.load.paths(file 또는 directory)
- 워크스페이스 확장
<workspace>/.openclaw/extensions/*.ts<workspace>/.openclaw/extensions/*/index.ts
- 전역 확장
~/.openclaw/extensions/*.ts~/.openclaw/extensions/*/index.ts
- 번들 확장(OpenClaw와 함께 제공되며 대부분 기본 비활성화)
<openclaw>/extensions/*
plugins.entries.<id>.enabled 또는
openclaw plugins enable <id>를 통해 명시적으로 활성화해야 합니다.
기본 활성화되는 번들 플러그인 예외:
device-pairphone-controltalk-voice- 활성 메모리 슬롯 플러그인(기본 슬롯:
memory-core)
plugins.allow가 비어 있고 번들이 아닌 플러그인이 discovery 가능하면 OpenClaw는 startup warning에 플러그인 id와 source를 기록합니다.- 후보 경로는 discovery 허용 전에 safety-check를 거칩니다. OpenClaw는 다음 경우 후보를 차단합니다:
- 확장 엔트리가 플러그인 루트 밖으로 resolve되는 경우(심볼릭 링크/경로 순회 escape 포함)
- 플러그인 루트/source 경로가 world-writable인 경우
- 번들이 아닌 플러그인의 path ownership이 의심스러운 경우(POSIX owner가 현재 uid도 root도 아님)
- install/load-path provenance가 없는 로드된 비번들 플러그인은 trust pin(
plugins.allow) 또는 install tracking(plugins.installs)을 설정할 수 있도록 warning을 출력합니다.
openclaw.plugin.json 파일을 포함해야 합니다. 경로가 파일을
가리키면 플러그인 루트는 그 파일의 디렉터리가 되며, 그 디렉터리에 manifest가
있어야 합니다.
여러 플러그인이 같은 id로 resolve되면 위 순서에서 먼저 일치한 것이 우선하며,
더 낮은 우선순위의 복사본은 무시됩니다.
Package pack
플러그인 디렉터리는openclaw.extensions가 있는 package.json을 포함할 수 있습니다:
name/<fileBase>가 됩니다.
플러그인이 npm dependency를 import한다면 해당 디렉터리에 dependency를 설치해
node_modules를 사용할 수 있게 하세요(npm install / pnpm install).
보안 가드레일: 모든 openclaw.extensions 항목은 심볼릭 링크 해석 후에도 플러그인
디렉터리 내부에 있어야 합니다. 패키지 디렉터리 밖으로 벗어나는 항목은 거부됩니다.
보안 참고: openclaw plugins install은 플러그인 dependency를
npm install --ignore-scripts(lifecycle script 없음)로 설치합니다. 플러그인
dependency 트리는 “pure JS/TS”로 유지하고 postinstall 빌드가 필요한 패키지는
피하세요.
채널 카탈로그 메타데이터
채널 플러그인은openclaw.channel을 통해 onboarding metadata를,
openclaw.install을 통해 설치 힌트를 광고할 수 있습니다. 이렇게 하면 코어에
카탈로그 데이터를 넣지 않아도 됩니다.
예시:
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS(또는 OPENCLAW_MPM_CATALOG_PATHS)를 하나
이상의 JSON 파일(쉼표/세미콜론/PATH 구분)로 지정하세요. 각 파일은
{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }
형태를 포함해야 합니다.
Plugin ID
기본 plugin id:- Package pack:
package.json의name - 독립 파일: 파일 기본 이름(
~/.../voice-call.ts→voice-call)
id를 export하면 OpenClaw는 그것을 사용하지만, 구성된 id와 일치하지
않으면 warning을 출력합니다.
Config
enabled: 마스터 토글(기본값: true)allow: allowlist(선택 사항)deny: denylist(선택 사항, deny가 우선)load.paths: 추가 plugin file/dirslots:memory,contextEngine같은 배타적 slot selectorentries.<id>: 플러그인별 토글 + config
entries,allow,deny,slots의 알 수 없는 plugin id는 오류입니다.- plugin manifest가 채널 id를 선언하지 않은 한, 알 수 없는
channels.<id>키는 오류입니다. - plugin config는
openclaw.plugin.json에 내장된 JSON Schema(configSchema)를 사용해 validation됩니다. - 플러그인이 비활성화되어 있으면 해당 config는 보존되고 warning이 출력됩니다.
Plugin slot(배타적 카테고리)
일부 plugin 카테고리는 배타적입니다(한 번에 하나만 활성). 어떤 plugin이 그 slot을 소유할지plugins.slots로 선택합니다:
memory: 활성 memory plugin("none"이면 memory plugin 비활성화)contextEngine: 활성 context engine plugin("legacy"는 내장 기본값)
kind: "memory" 또는 kind: "context-engine"을 선언하면, 해당
slot에 선택된 plugin만 로드됩니다. 나머지는 diagnostics와 함께 비활성화됩니다.
Context engine 플러그인
Context engine 플러그인은 ingest, assembly, compaction에 대한 세션 컨텍스트 오케스트레이션을 담당합니다. 플러그인에서api.registerContextEngine(id, factory)로 등록한 다음, 활성 엔진을
plugins.slots.contextEngine으로 선택하세요.
메모리 search나 hook만 추가하는 것이 아니라 기본 context pipeline을 교체하거나
확장해야 할 때 사용합니다.
Control UI(schema + label)
Control UI는 더 나은 폼 렌더링을 위해config.schema(JSON Schema + uiHints)를
사용합니다.
OpenClaw는 discovery된 plugin에 따라 런타임에 uiHints를 보강합니다:
plugins.entries.<id>/.enabled/.config에 plugin별 label 추가- 선택적인 plugin 제공 config field hint를 다음 아래로 병합:
plugins.entries.<id>.config.<field>
uiHints를 제공하세요.
예시:
CLI
plugins update는 plugins.installs 아래에서 추적되는 npm 설치에 대해서만
동작합니다. 업데이트 사이에 저장된 integrity metadata가 바뀌면 OpenClaw는
warning을 표시하고 확인을 요청합니다(프롬프트를 건너뛰려면 전역 --yes 사용).
플러그인은 자신만의 최상위 명령도 등록할 수 있습니다(예: openclaw voicecall).
Plugin API(개요)
플러그인은 다음 중 하나를 export합니다:- 함수:
(api) => { ... } - 객체:
{ id, name, configSchema, register(api) { ... } }
Plugin hook
플러그인은 런타임에 hook을 등록할 수 있습니다. 이를 통해 별도의 hook pack 설치 없이 플러그인이 이벤트 기반 automation을 번들로 제공할 수 있습니다.예시
api.registerHook(...)로 hook을 명시적으로 등록하세요.- hook eligibility 규칙은 계속 적용됩니다(OS/bins/env/config 요구 사항).
- plugin 관리 hook은
openclaw hooks list에plugin:<id>로 표시됩니다. - plugin 관리 hook은
openclaw hooks로 enable/disable할 수 없습니다. 대신 plugin 자체를 enable/disable하세요.
에이전트 lifecycle hook (api.on)
타입이 지정된 런타임 lifecycle hook에는 api.on(...)을 사용하세요:
before_model_resolve: 세션 로드 전에 실행됩니다(messages사용 불가).modelOverride또는providerOverride를 결정적으로 덮어쓸 때 사용하세요.before_prompt_build: 세션 로드 후에 실행됩니다(messages사용 가능). 프롬프트 입력을 조정할 때 사용하세요.before_agent_start: 레거시 호환용 hook입니다. 가능하면 위 두 개의 명시적 hook을 우선 사용하세요.
- 운영자는
plugins.entries.<id>.hooks.allowPromptInjection: false로 플러그인별 프롬프트 변형 hook을 비활성화할 수 있습니다. - 비활성화되면 OpenClaw는
before_prompt_build를 차단하고, 레거시before_agent_start가 반환한 프롬프트 변경 필드는 무시하되 레거시modelOverride와providerOverride는 유지합니다.
before_prompt_build 결과 필드:
prependContext: 이번 실행의 user prompt 앞에 텍스트를 추가합니다. turn별 또는 동적 콘텐츠에 가장 적합합니다.systemPrompt: 전체 system prompt를 덮어씁니다.prependSystemContext: 현재 system prompt 앞에 텍스트를 추가합니다.appendSystemContext: 현재 system prompt 뒤에 텍스트를 추가합니다.
- user prompt에
prependContext를 적용합니다. - 제공되면
systemPromptoverride를 적용합니다. prependSystemContext + current system prompt + appendSystemContext를 적용합니다.
- hook handler는 priority 순으로 실행됩니다(높을수록 먼저).
- 병합되는 context 필드는 실행 순서대로 값을 이어 붙입니다.
before_prompt_build값은 레거시before_agent_startfallback 값보다 먼저 적용됩니다.
- provider가 안정적인 system-prefix 콘텐츠를 캐시할 수 있도록, 정적인 가이드는
prependContext에서prependSystemContext(또는appendSystemContext)로 옮기세요. - user message에 결합된 상태로 유지되어야 하는 turn별 동적 컨텍스트에는
prependContext를 유지하세요.
Provider 플러그인(model auth)
플러그인은 모델 provider auth 흐름을 등록할 수 있으므로 사용자가 OpenClaw 내부에서 OAuth 또는 API key 설정을 수행할 수 있습니다(외부 스크립트 불필요).api.registerProvider(...)로 provider를 등록하세요. 각 provider는 하나 이상의
auth method(OAuth, API key, device code 등)를 노출합니다. 이 method는 다음을
구동합니다:
openclaw models auth login --provider <id> [--method <id>]
run은prompter,runtime,openUrl,oauth.createVpsAwareHandlers헬퍼가 포함된ProviderAuthContext를 받습니다.- 기본 모델 또는 provider config를 추가해야 한다면
configPatch를 반환하세요. --set-default가 에이전트 기본값을 업데이트할 수 있도록defaultModel을 반환하세요.
메시징 채널 등록
플러그인은 내장 채널(WhatsApp, Telegram 등)처럼 동작하는 채널 플러그인을 등록할 수 있습니다. 채널 config는channels.<id> 아래에 위치하며, 여러분의
채널 플러그인 코드로 validation됩니다.
- config는
plugins.entries가 아니라channels.<id>아래에 두세요. meta.label은 CLI/UI 목록의 label로 사용됩니다.meta.aliases는 정규화와 CLI 입력을 위한 대체 id를 추가합니다.meta.preferOver는 두 채널이 모두 구성되어 있을 때 자동 활성화에서 건너뛸 채널 id를 나열합니다.meta.detailLabel과meta.systemImage는 UI가 더 풍부한 채널 label/icon을 표시할 수 있게 합니다.
채널 onboarding hook
채널 플러그인은plugin.onboarding에 선택적 onboarding hook을 정의할 수 있습니다:
configure(ctx)는 기본 설정 흐름입니다.configureInteractive(ctx)는 구성됨/미구성 상태 모두에 대해 대화형 설정을 완전히 직접 제어할 수 있습니다.configureWhenConfigured(ctx)는 이미 구성된 채널에 대해서만 동작을 재정의할 수 있습니다.
configureInteractive(존재하는 경우)configureWhenConfigured(채널 상태가 이미 configured일 때만)- 그렇지 않으면
configure로 fallback
configureInteractive와configureWhenConfigured는 다음을 받습니다:configured(true또는false)label(프롬프트에 사용되는 사용자 대상 채널 이름)- 그리고 공유되는 config/runtime/prompter/options 필드
"skip"을 반환하면 selection과 account tracking은 변경되지 않습니다.{ cfg, accountId? }를 반환하면 config 업데이트가 적용되고 account selection이 기록됩니다.
새 메시징 채널 작성(step-by-step)
모델 provider가 아니라 새 채팅 표면(즉, “messaging channel”)이 필요할 때 사용하세요. 모델 provider 문서는/providers/* 아래에 있습니다.
- id와 config shape를 정합니다
- 모든 채널 config는
channels.<id>아래에 위치합니다. - 멀티 계정 설정에는
channels.<id>.accounts.<accountId>를 우선 고려하세요.
- 채널 metadata를 정의합니다
meta.label,meta.selectionLabel,meta.docsPath,meta.blurb가 CLI/UI 목록을 제어합니다.meta.docsPath는/channels/<id>같은 docs 페이지를 가리켜야 합니다.meta.preferOver를 사용하면 플러그인이 다른 채널을 대체할 수 있습니다(자동 활성화가 이를 우선합니다).meta.detailLabel과meta.systemImage는 UI에서 상세 텍스트/icon에 사용됩니다.
- 필수 adapter를 구현합니다
config.listAccountIds+config.resolveAccountcapabilities(채팅 타입, 미디어, 스레드 등)outbound.deliveryMode+outbound.sendText(기본 전송용)
- 필요에 따라 선택적 adapter를 추가합니다
setup(wizard),security(DM 정책),status(상태/진단)gateway(start/stop/login),mentions,threading,streamingactions(message action),commands(네이티브 명령 동작)
- 플러그인에서 채널을 등록합니다
api.registerChannel({ plugin })
plugins.load.paths), Gateway를
재시작한 다음 config에서 channels.<id>를 구성하세요.
Agent tool
전용 가이드를 참고하세요: Plugin agent tools.Gateway RPC 메서드 등록
CLI 명령 등록
자동 응답 명령 등록
플러그인은 AI 에이전트를 호출하지 않고 실행되는 사용자 지정 슬래시 명령을 등록할 수 있습니다. 이는 LLM 처리가 필요 없는 토글 명령, 상태 확인, 빠른 동작에 유용합니다.senderId: 발신자 ID(가능한 경우)channel: 명령이 전송된 채널isAuthorizedSender: 발신자가 권한 있는 사용자인지 여부args: 명령 뒤에 전달된 인수(acceptsArgs: true인 경우)commandBody: 전체 명령 텍스트config: 현재 OpenClaw config
name: 명령 이름(앞의/제외)nativeNames: 슬래시/메뉴 표면용 선택적 native-command 별칭. 모든 native provider에는default, provider별 키에는discord같은 값을 사용합니다.description: 명령 목록에 표시되는 도움말 텍스트acceptsArgs: 명령이 인수를 받을지 여부(기본값: false). false인데 인수가 제공되면 명령은 일치하지 않고 메시지는 다른 handler로 fall through됩니다.requireAuth: 권한 있는 발신자를 요구할지 여부(기본값: true)handler:{ text: string }을 반환하는 함수(async 가능)
- plugin 명령은 내장 명령과 AI 에이전트보다 먼저 처리됩니다
- 명령은 전역으로 등록되며 모든 채널에서 동작합니다
- 명령 이름은 대소문자를 구분하지 않습니다(
/MyStatus는/mystatus와 일치) - 명령 이름은 문자로 시작해야 하며 문자, 숫자, 하이픈, 밑줄만 포함할 수 있습니다
- 예약된 명령 이름(
help,status,reset등)은 plugin이 재정의할 수 없습니다 - 플러그인 간 중복 명령 등록은 diagnostic error로 실패합니다
백그라운드 서비스 등록
네이밍 규칙
- Gateway 메서드:
pluginId.action(예:voicecall.status) - 도구:
snake_case(예:voice_call) - CLI 명령: kebab 또는 camel, 단 코어 명령과 충돌은 피하세요
Skills
플러그인은 저장소에 skill(skills/<name>/SKILL.md)을 포함해 배포할 수 있습니다.
plugins.entries.<id>.enabled(또는 다른 config gate)로 활성화하고,
워크스페이스/관리형 skills 위치에 존재하도록 하세요.
배포(npm)
권장 패키징:- 메인 패키지:
openclaw(이 저장소) - 플러그인:
@openclaw/*아래의 별도 npm 패키지(예:@openclaw/voice-call)
- 플러그인
package.json에는 하나 이상의 엔트리 파일이 들어 있는openclaw.extensions가 포함되어야 합니다. - 엔트리 파일은
.js또는.ts일 수 있습니다(jiti가 런타임에 TS를 로드). openclaw plugins install <npm-spec>는npm pack을 사용하고,~/.openclaw/extensions/<id>/에 압축 해제한 뒤 config에서 활성화합니다.- Config 키 안정성: scoped package는
plugins.entries.*에 대해 unscoped id로 정규화됩니다.
예시 플러그인: Voice Call
이 저장소에는 voice-call 플러그인(Twilio 또는 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(선택적statusCallbackUrl,twimlUrl) - Config (dev):
provider: "log"(네트워크 없음)
extensions/voice-call/README.md를 참고하세요.
안전성 참고
플러그인은 Gateway와 같은 프로세스 안에서 실행됩니다. 신뢰할 수 있는 코드로 취급하세요:- 신뢰하는 플러그인만 설치하세요.
- 가능하면
plugins.allowallowlist를 우선 사용하세요. - 변경 후 Gateway를 재시작하세요.
플러그인 테스트
플러그인은 테스트를 포함할 수 있으며, 포함해야 합니다:- 저장소 내부 플러그인은
src/**아래에 Vitest 테스트를 둘 수 있습니다(예:src/plugins/voice-call.plugin.test.ts). - 별도로 퍼블리시되는 플러그인은 자체 CI(lint/build/test)를 실행하고
openclaw.extensions가 빌드된 엔트리포인트(dist/index.js)를 가리키는지 검증해야 합니다.