콘텐츠로 이동

OpenClaw Plugins 활용하기

개발을 하다 보면 코어 기능만으로는 부족할 때가 있죠. 특정 서비스와 연결하고 싶거나 우리 팀만의 독특한 워크플로우가 필요한 순간이 옵니다. 그렇다고 메인 코드를 직접 수정하는 건 부담스럽고 유지보수도 걱정되곤 해요.

OpenClaw Plugins는 이런 고민을 해결해 줍니다. 메인 코드를 건드리지 않고도 새로운 명령어나 도구, 채널을 추가할 수 있는 작은 코드 모듈이에요. 한 번 패턴을 익히고 나면 누구나 쉽게 필요한 기능을 붙여서 사용할 수 있습니다.

  • OpenClaw 설치 및 실행 중
  • 기본적인 TypeScript 지식 (커스텀 Plugin 제작 시)

현재 어떤 Plugin이 있는지 확인해 보세요.

Terminal window
openclaw plugins list

예를 들어 음성 통화 기능을 추가하고 싶다면 아래 명령어를 입력하세요.

Terminal window
openclaw plugins install @openclaw/voice-call

Gateway를 재시작하고, plugins.entries.<id>.config 경로에 설정을 추가하면 끝납니다.

{
plugins: {
entries: {
"voice-call": {
enabled: true,
config: {
provider: "twilio"
}
}
}
}
}
PluginPackageDescription
Voice Call@openclaw/voice-call전화 걸기 및 받기
Microsoft Teams@openclaw/msteamsTeams 채널 통합
Matrix@openclaw/matrixMatrix 채팅 프로토콜
Nostr@openclaw/nostrNostr 분산형 채팅
Zalo@openclaw/zalo베트남 메시징 앱

Bundled plugins (기본적으로 비활성화되어 있습니다):

  • Memory (Core) — 기본적인 메모리 검색
  • Memory (LanceDB) — 자동 회상 기능이 있는 장기 메모리
  • Google/Gemini/Qwen OAuth — 공급자 인증 흐름

Bundled Plugin은 아래 명령어로 활성화할 수 있어요.

Terminal window
openclaw plugins enable memory-lancedb

OpenClaw는 아래 순서대로 Plugin을 찾습니다. 먼저 발견된 것을 사용하고, 나중에 발견된 복사본은 무시해요.

  1. Config paths — plugins.load.paths
  2. Workspace extensions — .openclaw/extensions/*.ts
  3. Global extensions — ~/.openclaw/extensions/*.ts
  4. Bundled — OpenClaw와 함께 제공되는 기본 Plugin

설정 파일을 통해 Plugin의 권한과 경로를 관리할 수 있습니다.

{
plugins: {
enabled: true,
allow: ["voice-call"], // 허용 목록 (선택 사항)
deny: ["untrusted-plugin"], // 차단 목록이 우선권을 가짐
load: {
paths: ["~/my-plugins/custom"]
},
entries: {
"voice-call": {
enabled: true,
config: { provider: "twilio" }
}
}
}
}

주의하세요: 설정을 변경했다면 반드시 Gateway를 재시작해야 적용됩니다.

메모리 공급자처럼 한 번에 하나만 활성화해야 하는 카테고리가 있습니다.

{
plugins: {
slots: {
memory: "memory-lancedb" // 또는 "memory-core" 또는 "none"
}
}
}

자주 사용하는 CLI 명령어 모음입니다.

Terminal window
openclaw plugins list # 모든 Plugin 확인
openclaw plugins info <id> # Plugin 상세 정보 보기
openclaw plugins install &lt;path|npm&gt; # Plugin 설치
openclaw plugins install -l <path> # 개발을 위한 심볼릭 링크 연결
openclaw plugins enable <id> # Plugin 활성화
openclaw plugins disable <id> # Plugin 비활성화
openclaw plugins update <id> # 특정 npm Plugin 업데이트
openclaw plugins update --all # 모든 npm Plugin 업데이트
openclaw plugins doctor # 문제 진단하기
  • 설정을 바꿨는데 반응이 없어요: Gateway를 재시작했는지 확인해 보세요.
  • Plugin이 제대로 작동하지 않아요: openclaw plugins doctor 명령어를 실행해서 상태를 진단해 보세요.

더 궁금한 점이 있다면 AI Setup Assistant에게 물어보세요.

개발을 하다 보면 도구의 기본 기능만으로는 부족할 때가 있죠. 내 워크플로우에 딱 맞는 기능을 직접 추가하고 싶은데 어디서부터 시작해야 할지 막막한 경험, 다들 한 번쯤 있으실 거예요. OpenClaw는 여러분이 필요한 기능을 직접 구현할 수 있도록 유연한 플러그인 시스템을 제공해요.

시작하기 전에 다음 사항들이 준비되어 있는지 확인해 주세요.

  • ~/.openclaw/extensions/ 디렉토리 접근 권한
  • TypeScript 개발 환경
  • OpenClaw CLI 및 Gateway

5분 만에 첫 번째 플러그인을 만들어 볼게요.

  1. ~/.openclaw/extensions/my-plugin/index.ts 파일을 만들고 아래 코드를 복사해 넣으세요.
export default function(api) {
api.registerGatewayMethod("myplugin.status", ({ respond }) => {
respond(true, { status: "running" });
});
}
  1. 같은 위치에 ~/.openclaw/extensions/my-plugin/openclaw.plugin.json 파일을 만드세요.
{
"id": "my-plugin",
"name": "My Custom Plugin",
"version": "1.0.0"
}
  1. Gateway를 재시작하면 플러그인이 바로 활성화돼요.

플러그인을 통해 AI가 사용할 수 있는 도구를 등록할 수 있어요.

export default function(api) {
api.registerTool({
name: "my_tool",
description: "Does something useful",
parameters: {
type: "object",
properties: {
input: { type: "string" }
}
},
handler: async ({ input }) => {
return { result: `Processed: ${input}` };
}
});
}

AI를 거치지 않고 직접 실행되는 Slash Command를 만들 수도 있어요. 상태 확인이나 간단한 설정을 바꿀 때 아주 유용해요.

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

메시징 서비스를 연결하고 싶다면 Channel을 등록하면 돼요.

const plugin = {
id: "acmechat",
meta: {
label: "AcmeChat",
docsPath: "/channels/acmechat",
blurb: "AcmeChat messaging."
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: (cfg) =>
Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
resolveAccount: (cfg, id) =>
cfg.channels?.acmechat?.accounts?.[id ?? "default"]
},
outbound: {
deliveryMode: "direct",
sendText: async ({ text }) => {
// Send message
return { ok: true };
}
}
};
export default function(api) {
api.registerChannel({ plugin });
}

플러그인은 Hook을 포함해서 배포하거나 런타임에 등록할 수 있어요. 별도의 Hook 팩을 설치하지 않아도 이벤트 기반 자동화를 구현할 수 있죠.

import { registerPluginHooksFromDir } from "openclaw/plugin-sdk";
export default function register(api) {
registerPluginHooksFromDir(api, "./hooks");
}

참고 사항:

  • Hook 디렉토리는 일반적인 Hook 구조(HOOK.md + handler.ts)를 따라야 해요.
  • OS, 바이너리, 환경 변수, 설정 등 Hook 적격성 규칙이 동일하게 적용돼요.
  • 플러그인이 관리하는 Hook은 openclaw hooks list에서 plugin:<id> 형태로 표시돼요.
  • 플러그인을 활성화하거나 비활성화해서 Hook을 제어할 수 있어요.

api.runtime을 통해 코어 헬퍼 기능을 사용할 수 있어요. 예를 들어 전화 통신용 TTS 기능을 사용하는 방법이에요.

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

참고 사항:

  • 코어의 messages.tts 설정(OpenAI 또는 ElevenLabs)을 사용해요.
  • PCM 오디오 버퍼와 샘플 레이트를 반환해요.
  • 플러그인은 각 서비스 제공자에 맞게 리샘플링이나 인코딩을 직접 처리해야 해요.

플러그인으로 모델 제공자 인증(Model Provider Auth) 흐름을 등록하면, 사용자가 OpenClaw 안에서 OAuth나 API 키 설정을 진행할 수 있어요.

api.registerProvider({
id: "acme",
label: "AcmeAI",
auth: [
{
id: "oauth",
label: "OAuth",
kind: "oauth",
run: async (ctx) => {
// Run OAuth flow and return auth profiles
return {
profiles: [
{
profileId: "acme:default",
credential: {
type: "oauth",
provider: "acme",
access: "...",
refresh: "...",
expires: Date.now() + 3600 * 1000,
},
},
],
defaultModel: "acme/opus-1",
};
},
},
],
});

참고 사항:

  • run 함수는 prompter, runtime, openUrl 헬퍼가 포함된 ProviderAuthContext를 전달받아요.
  • 기본 모델을 추가해야 할 때는 configPatch를 반환하세요.
  • defaultModel을 반환하면 사용자가 --set-default 플래그를 썼을 때 에이전트 기본값을 업데이트할 수 있어요.

사용자는 터미널에서 아래 명령어로 인증을 진행하게 돼요.

Terminal window
openclaw models auth login --provider acme --method oauth

플러그인 개발 중에 문제가 생기면 다음 내용을 확인해 보세요.

  • 전화 통신용 TTS가 작동하지 않나요? Edge TTS는 해당 기능을 지원하지 않아요. OpenAI나 ElevenLabs 설정을 확인해 보세요.
  • Hook이 목록에 보이지 않나요? 해당 플러그인이 활성화되어 있는지 확인해 주세요.
  • Hook이 실행되지 않나요? OS 환경이나 필요한 바이너리 설치 여부 등 Hook 적격성 규칙을 만족하는지 확인이 필요해요.

더 궁금한 점이 있다면 AI Setup Assistant에게 물어보세요!

What’s Next?

봇을 개발하다 보면 모든 요청을 AI 에이전트가 처리할 필요는 없다는 걸 깨닫게 돼요. 단순한 상태 확인이나 고정된 응답이 필요한 상황에서도 AI가 매번 생각하고 토큰을 소비하는 건 비효율적이죠. 사용자의 의도를 즉각적으로 반영하면서도 리소스를 아낄 수 있는 직접적인 커맨드가 필요한 이유예요.

  • OpenClaw 플러그인 개발 환경
  • openclaw.plugin.json 매니페스트 파일
  • TypeScript 또는 JavaScript 프로젝트

플러그인에서 AI 에이전트를 호출하지 않고 즉시 실행되는 커스텀 Slash Command를 등록할 수 있어요. api.registerCommand를 사용하면 됩니다.

export default function(api) {
api.registerCommand({
name: "mystatus",
description: "Show plugin status",
acceptsArgs: false,
requireAuth: true,
handler: (ctx) => ({
text: `Plugin running on ${ctx.channel}`
})
});
}

handler 함수에서 사용할 수 있는 ctx 객체는 다음과 같은 정보를 담고 있어요.

FieldDescription
senderId보낸 사람의 ID
channel커맨드가 전송된 채널
isAuthorizedSender보낸 사람이 권한이 있는지 여부
args인자 값 (acceptsArgs: true인 경우)
commandBody커맨드 전체 텍스트
config현재 OpenClaw 설정(config)

커맨드를 등록할 때 설정할 수 있는 옵션들이에요.

OptionDescription
name커맨드 이름 (/ 제외)
description도움말 텍스트
acceptsArgs인자 수락 여부 (기본값: false)
requireAuth권한이 있는 사용자만 실행 가능 (기본값: true)
handler{ text: string }을 반환하는 실행 함수

참고 사항:

  • 플러그인 커맨드는 내장 커맨드나 AI 에이전트보다 먼저 처리돼요.
  • 커맨드 이름은 대소문자를 구분하지 않아요.
  • 예약된 커맨드(help, status, reset)는 덮어쓸 수 없어요.

커맨드 외에도 플러그인이 실행되는 동안 백그라운드에서 동작하는 서비스를 등록할 수 있어요.

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

터미널에서 직접 실행할 수 있는 CLI 커맨드가 필요하다면 api.registerCli를 사용하세요.

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

모든 플러그인은 openclaw.plugin.json 파일이 꼭 필요해요. 플러그인의 ID, 이름, 설정 스키마를 정의합니다.

{
"id": "my-plugin",
"name": "My Plugin",
"version": "1.0.0",
"configSchema": {
"type": "object",
"properties": {
"apiKey": { "type": "string" }
}
},
"uiHints": {
"apiKey": { "label": "API Key", "sensitive": true }
}
}

작성한 플러그인을 공유하거나 설치하려면 package.json에 다음 설정을 추가하세요.

{
"name": "@yourscope/my-plugin",
"openclaw": {
"extensions": ["./index.ts"]
}
}

이제 npm publish로 배포하면, 사용자는 아래 커맨드로 플러그인을 설치할 수 있어요.

Terminal window
openclaw plugins install @yourscope/my-plugin
  • 커맨드가 작동하지 않나요?: 예약된 커맨드 이름(help, status, reset)을 사용하고 있지는 않은지 확인해 보세요. 이 이름들은 시스템에서 보호됩니다.
  • 권한 문제: requireAuth가 true로 설정되어 있다면, 권한이 없는 사용자는 커맨드를 실행할 수 없어요. 테스트 시 이 설정을 확인해 보세요.

설정 과정에서 도움이 필요하다면 AI Setup Assistant에게 물어보세요.

---
title: OpenClaw 플러그인 문제 해결 및 패키지 구성 가이드
description: OpenClaw 플러그인 로딩 문제 해결 방법과 패키지 팩, 채널 카탈로그 메타데이터 설정법을 알아봅니다.
---
플러그인을 새로 추가했는데 리스트에 나타나지 않거나, 분명히 코드를 수정했는데 반영이 안 돼서 답답했던 적 있으신가요? 환경 설정 파일의 작은 오타 하나나 중복된 ID 때문에 개발 흐름이 끊기면 정말 번거롭죠.
이 가이드에서는 OpenClaw를 사용하면서 마주칠 수 있는 일반적인 플러그인 로딩 문제들을 해결하고, 여러 플러그인을 효율적으로 관리할 수 있는 패키지 구성 방법을 정리해 드릴게요.
## 필요한 것
시작하기 전에 다음 항목들이 준비되었는지 확인해 주세요.
- OpenClaw 설치 환경
- 설정 파일 (`openclaw.plugin.json` 또는 `package.json`)
- 확장 기능이 포함된 `~/.openclaw/extensions` 디렉토리
## 빠른 시작
문제를 빠르게 해결하고 싶다면 다음 4단계를 먼저 체크해 보세요.
1. `plugins.enabled` 설정이 `true`인지 확인합니다.
2. `package.json`의 `openclaw.extensions` 필드에 정확한 경로가 등록되어 있는지 봅니다.
3. 중복된 Plugin ID가 있다면 하나를 제거합니다.
4. 외부 카탈로그를 사용한다면 지정된 JSON 경로에 파일이 있는지 확인합니다.
## 문제 해결
### Plugin이 로드되지 않아요
**체크리스트:**
1. `plugins.enabled` 값이 `true`로 설정되어 있나요?
2. 해당 플러그인이 `deny` 리스트에 포함되어 있지는 않나요?
3. `openclaw.plugin.json` 파일이 해당 경로에 실제로 존재하나요?
### Config validation 에러가 발생해요
**원인:** 설정 파일에 등록된 Plugin ID가 시스템에서 인식할 수 없는 ID일 경우 엄격한 유효성 검사 에러가 발생합니다.
**해결 방법:** `entries`, `allow`, `deny` 섹션을 확인하여, 비활성화했거나 삭제한 플러그인에 대한 참조가 남아 있다면 모두 제거해 주세요.
### Plugin 충돌 문제
**원인:** 동일한 ID를 가진 플러그인이 여러 개 존재할 때 발생합니다.
**해결 방법:** OpenClaw는 가장 먼저 발견된 플러그인만 로드합니다. extension 디렉토리를 확인하여 중복된 플러그인을 삭제하세요.
> **여전히 해결되지 않나요?** [AI Setup Assistant](/docs/)가 플러그인 설정 디버깅을 도와드릴 수 있어요.
---
## Package Packs
여러 개의 확장 기능을 하나의 디렉토리에서 관리하고 싶다면 `package.json`에 `openclaw.extensions`를 정의하면 됩니다.
```json
{
"name": "my-pack",
"openclaw": {
"extensions": ["./src/safety.ts", "./src/tools.ts"]
}
}

이 설정에서 각 엔트리는 개별 플러그인으로 취급됩니다. 이렇게 팩 형태로 여러 확장 기능을 나열하면, Plugin ID는 name/<fileBase> (예: my-pack/safety) 형식이 됩니다.

만약 플러그인이 외부 npm 의존성을 사용한다면, 해당 디렉토리에서 직접 설치를 진행해 주세요.

Terminal window
cd ~/.openclaw/extensions/my-pack
npm install

Channel 플러그인은 openclaw.channel을 통해 온보딩 메타데이터를 제공하고, openclaw.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",
"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"
}
}
}

External catalogs 사용하기: 외부 카탈로그를 연동하려면 다음 위치에 JSON 파일을 저장하세요.

  • ~/.openclaw/mpm/plugins.json
  • ~/.openclaw/mpm/catalog.json
  • ~/.openclaw/plugins/catalog.json

환경 변수를 통해 직접 경로를 지정하고 싶다면 OPENCLAW_PLUGIN_CATALOG_PATHS를 설정하면 됩니다.


개발을 하다 보면 새로운 채팅 플랫폼을 연결해야 할 때가 많아요. 하지만 플랫폼마다 API 구조가 다르고 설정 방식도 제각각이라 매번 처음부터 다시 공부해야 하는 번거로움이 있죠.
이 가이드는 OpenClaw에서 새로운 Messaging Channel을 직접 만드는 과정을 도와드려요. 복잡한 과정 없이 핵심적인 단계만 따라오면 여러분만의 채널을 완성할 수 있어요.
## 필요한 것
- OpenClaw API
- Node.js 및 TypeScript 개발 환경
- 테스트를 위한 Vitest (선택 사항)
## 빠른 시작
새로운 채팅 인터페이스(모델 공급자가 아닌 경우)를 만들고 싶을 때 이 과정을 따라오세요. 5분이면 최소한의 경로로 채널을 구축할 수 있어요.
### Step 1: ID와 Config 형태 정하기
모든 채널 설정은 `channels.<id>` 아래에 위치해요.
```json
{
channels: {
acmechat: {
accounts: {
default: { token: "TOKEN", enabled: true }
}
}
}
}
필드용도
meta.labelCLI/UI에 표시될 이름
meta.selectionLabel더 길게 표시될 선택 텍스트
meta.docsPath문서 링크 (예: /channels/acmechat)
meta.blurb짧은 설명
meta.aliases대체 채널 ID
meta.preferOver다른 채널을 대체할 때 사용
const plugin = {
id: "acmechat",
meta: { /* ... */ },
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: (cfg) => Object.keys(cfg.channels?.acmechat?.accounts ?? {}),
resolveAccount: (cfg, id) => cfg.channels?.acmechat?.accounts?.[id ?? "default"]
},
outbound: {
deliveryMode: "direct",
sendText: async ({ text }) => ({ ok: true })
}
};

Step 4: 선택 사항 Adapter 추가하기

섹션 제목: “Step 4: 선택 사항 Adapter 추가하기”
Adapter용도
setupWizard 통합
securityDM 정책
status상태 및 진단
gateway시작/중지/로그인
mentions@mention 처리
threading스레드 지원
streaming스트리밍 응답
actions메시지 액션
commands네이티브 명령어 동작
export default function(api) {
api.registerChannel({ plugin });
}

플러그인을 만들 때는 아래의 명명 규칙을 지켜주세요. 코어 명령어와 충돌하지 않도록 주의해야 해요.

유형규칙예시
Gateway 메서드pluginId.actionvoicecall.status
Toolssnake_casevoice_call
CLI 명령어kebab-casevoicecall-start

플러그인에 skills/ 디렉토리를 추가하면 스킬을 함께 배포할 수 있어요.

my-plugin/
├── index.ts
├── openclaw.plugin.json
└── skills/
└── my-skill/
└── SKILL.md

plugins.entries.<id>.enabled 설정을 통해 활성화하고, 관리되는 스킬 경로에 해당 파일이 있는지 확인하세요.


플러그인은 Gateway와 동일한 프로세스에서 실행돼요. 신뢰할 수 있는 코드만 다루어야 합니다.

  • 직접 신뢰하는 플러그인만 설치하세요.
  • plugins.allow 허용 목록을 사용하는 것을 권장해요.
  • 코드를 변경한 후에는 반드시 Gateway를 재시작하세요.
  • 활성화하기 전에 플러그인 소스 코드를 검토하세요.

플러그인은 테스트 코드를 포함해야 해요.

  • In-repo 플러그인: Vitest 테스트를 src/** 아래에 유지하세요. (예: src/plugins/voice-call.plugin.test.ts)
  • 배포된 플러그인: 자체 CI를 실행하고 openclaw.extensions가 빌드된 엔트리포인트를 가리키는지 확인하세요.
Terminal window
# 플러그인 테스트 실행
cd ~/.openclaw/extensions/my-plugin
npm test
  • 문제: CLI 명령어가 제대로 작동하지 않거나 이름이 충돌해요.
    • 해결: pluginId.action 형식을 사용하고 있는지 확인하고, 코어 명령어와 겹치지 않는지 체크하세요.
  • 문제: 플러그인 설정을 바꿨는데 적용이 안 돼요.
    • 해결: 플러그인은 Gateway와 함께 실행되므로, 변경 사항을 적용하려면 Gateway를 재시작해야 해요.

설정 중에 도움이 필요하신가요? AI Setup Assistant에게 물어보세요!

OpenClaw

OpenClaw Expert

아직 막혀 있나요?

이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.