OpenClaw 설정 가이드: 채널 및 DM 정책 완벽 구성
각 채널은 해당 설정 섹션이 존재하면 자동으로 시작돼요 (enabled: false인 경우는 제외).
DM 및 그룹 액세스
섹션 제목: “DM 및 그룹 액세스”모든 채널은 DM 정책과 그룹 정책을 지원해요.
| DM 정책 | 동작 |
|---|---|
pairing (기본값) | 알 수 없는 발신자에게 일회용 페어링 코드를 전송하며, 소유자가 승인해야 해요. |
allowlist | allowFrom에 포함된 발신자(또는 페어링된 허용 저장소)만 허용해요. |
open | 모든 인바운드 DM을 허용해요 (allowFrom: ["*"] 설정 필요). |
disabled | 모든 인바운드 DM을 무시해요. |
| 그룹 정책 | 동작 |
|---|---|
allowlist (기본값) | 설정된 allowlist와 일치하는 그룹만 허용해요. |
open | 그룹 allowlist를 우회해요 (mention-gating은 여전히 적용돼요). |
disabled | 모든 그룹/방 메시지를 차단해요. |
채널 모델 오버라이드
섹션 제목: “채널 모델 오버라이드”channels.modelByChannel을 사용하여 특정 채널 ID를 특정 모델에 고정할 수 있어요. 값은 provider/model 형식이나 설정된 모델 alias를 사용할 수 있어요. 이 채널 매핑은 세션에 모델 오버라이드(예: /model로 설정된 경우)가 없을 때 적용돼요.
{ channels: { modelByChannel: { discord: { "123456789012345678": "anthropic/claude-opus-4-6", }, slack: { C1234567890: "openai/gpt-4.1", }, telegram: { "-1001234567890": "openai/gpt-4.1-mini", "-1001234567890:topic:99": "anthropic/claude-sonnet-4-6", }, }, },}채널 기본값 및 heartbeat
섹션 제목: “채널 기본값 및 heartbeat”여러 프로바이더에 걸쳐 공유되는 그룹 정책 및 heartbeat 동작을 위해 channels.defaults를 사용하세요.
{ channels: { defaults: { groupPolicy: "allowlist", // open | allowlist | disabled heartbeat: { showOk: false, showAlerts: true, useIndicator: true, }, }, },}channels.defaults.groupPolicy: 프로바이더 레벨의groupPolicy가 설정되지 않았을 때의 폴백 그룹 정책이에요.channels.defaults.heartbeat.showOk: heartbeat 출력에 정상 상태인 채널 상태를 포함해요.channels.defaults.heartbeat.showAlerts: heartbeat 출력에 성능 저하/에러 상태를 포함해요.channels.defaults.heartbeat.useIndicator: 간결한 인디케이터 스타일로 heartbeat를 출력해요.
WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행돼요. 연결된 세션이 있으면 자동으로 시작돼요.
{ channels: { whatsapp: { dmPolicy: "pairing", // pairing | allowlist | open | disabled allowFrom: ["+15555550123", "+447700900123"], textChunkLimit: 4000, chunkMode: "length", // length | newline mediaMaxMb: 50, sendReadReceipts: true, // blue ticks (false in self-chat mode) groups: { "*": { requireMention: true }, }, groupPolicy: "allowlist", groupAllowFrom: ["+15551234567"], }, }, web: { enabled: true, heartbeatSeconds: 60, reconnect: { initialMs: 2000, maxMs: 120000, factor: 1.4, jitter: 0.2, maxAttempts: 0, }, },}다중 계정 WhatsApp
{ channels: { whatsapp: { accounts: { default: {}, personal: {}, biz: { // authDir: "~/.openclaw/credentials/whatsapp/biz", }, }, }, },}- 아웃바운드 명령은
default계정이 있으면 해당 계정을 기본으로 사용하며, 없으면 설정된 첫 번째 계정 ID(정렬 기준)를 사용해요. - 선택 사항인
channels.whatsapp.defaultAccount는 설정된 계정 ID와 일치할 때 해당 폴백 기본 계정 선택을 오버라이드해요. - 기존의 단일 계정 Baileys 인증 디렉토리는
openclaw doctor에 의해whatsapp/default로 마이그레이션돼요. - 계정별 오버라이드:
channels.whatsapp.accounts.<id>.sendReadReceipts,channels.whatsapp.accounts.<id>.dmPolicy,channels.whatsapp.accounts.<id>.allowFrom.
Telegram
섹션 제목: “Telegram”{ channels: { telegram: { enabled: true, botToken: "your-bot-token", dmPolicy: "pairing", allowFrom: ["tg:123456789"], groups: { "*": { requireMention: true }, "-1001234567890": { allowFrom: ["@admin"], systemPrompt: "Keep answers brief.", topics: { "99": { requireMention: false, skills: ["search"], systemPrompt: "Stay on topic.", }, }, }, }, customCommands: [ { command: "backup", description: "Git backup" }, { command: "generate", description: "Create an image" }, ], historyLimit: 50, replyToMode: "first", // off | first | all linkPreview: true, streaming: "partial", // off | partial | block | progress (default: off) actions: { reactions: true, sendMessage: true }, reactionNotifications: "own", // off | own | all mediaMaxMb: 100, retry: { attempts: 3, minDelayMs: 400, maxDelayMs: 30000, jitter: 0.1, }, network: { autoSelectFamily: true, dnsResultOrder: "ipv4first", }, proxy: "socks5://localhost:9050", webhookUrl: "https://example.com/telegram-webhook", webhookSecret: "secret", webhookPath: "/telegram-webhook", }, },}- Bot token:
channels.telegram.botToken또는channels.telegram.tokenFile(일반 파일만 가능, 심볼릭 링크는 거부됨)을 사용하며, 기본 계정에 대해TELEGRAM_BOT_TOKEN이 폴백으로 사용돼요. - 선택 사항인
channels.telegram.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요. - 다중 계정 설정(2개 이상의 계정 ID)에서는 폴백 라우팅을 피하기 위해 명시적인 기본값(
channels.telegram.defaultAccount또는channels.telegram.accounts.default)을 설정하세요. 설정이 누락되거나 유효하지 않으면openclaw doctor가 경고를 표시해요. configWrites: false는 Telegram에서 시작된 설정 쓰기(슈퍼그룹 ID 마이그레이션,/config set|unset)를 차단해요.- 최상위
bindings[]항목 중type: "acp"인 설정은 포럼 토픽에 대한 영구 ACP 바인딩을 구성해요 (match.peer.id에 정규화된chatId:topic:topicId사용). 필드 의미는 ACP 에이전트에서 공유돼요. - Telegram 스트림 미리보기는
sendMessage+editMessageText를 사용해요 (다이렉트 및 그룹 채팅에서 작동). - 재시도 정책: 재시도 정책을 참조하세요.
Discord
섹션 제목: “Discord”{ channels: { discord: { enabled: true, token: "your-bot-token", mediaMaxMb: 8, allowBots: false, actions: { reactions: true, stickers: true, polls: true, permissions: true, messages: true, threads: true, pins: true, search: true, memberInfo: true, roleInfo: true, roles: false, channelInfo: true, voiceStatus: true, events: true, moderation: false, }, replyToMode: "off", // off | first | all dmPolicy: "pairing", allowFrom: ["1234567890", "123456789012345678"], dm: { enabled: true, groupEnabled: false, groupChannels: ["openclaw-dm"] }, guilds: { "123456789012345678": { slug: "friends-of-openclaw", requireMention: false, ignoreOtherMentions: true, reactionNotifications: "own", users: ["987654321098765432"], channels: { general: { allow: true }, help: { allow: true, requireMention: true, users: ["987654321098765432"], skills: ["docs"], systemPrompt: "Short answers only.", }, }, }, }, historyLimit: 20, textChunkLimit: 2000, chunkMode: "length", // length | newline streaming: "off", // off | partial | block | progress (progress maps to partial on Discord) maxLinesPerMessage: 17, ui: { components: { accentColor: "#5865F2", }, }, threadBindings: { enabled: true, idleHours: 24, maxAgeHours: 0, spawnSubagentSessions: false, // opt-in for sessions_spawn({ thread: true }) }, voice: { enabled: true, autoJoin: [ { guildId: "123456789012345678", channelId: "234567890123456789", }, ], daveEncryption: true, decryptionFailureTolerance: 24, tts: { provider: "openai", openai: { voice: "alloy" }, }, }, retry: { attempts: 3, minDelayMs: 500, maxDelayMs: 30000, jitter: 0.1, }, }, },}- Token:
channels.discord.token을 사용하며, 기본 계정에 대해DISCORD_BOT_TOKEN이 폴백으로 사용돼요. - 명시적인 Discord
token을 제공하는 직접적인 아웃바운드 호출은 해당 토큰을 사용해요. 계정 재시도/정책 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정으로부터 가져와요. - 선택 사항인
channels.discord.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요. - 전달 대상으로
user:<id>(DM) 또는channel:<id>(길드 채널)를 사용하세요. 순수 숫자 ID는 거부돼요. - 길드 슬러그(slug)는 소문자이며 공백은
-로 대체돼요. 채널 키는 슬러그화된 이름을 사용해요 (#없음). 길드 ID 사용을 권장해요. - 봇이 작성한 메시지는 기본적으로 무시돼요.
allowBots: true로 설정하면 허용되며,allowBots: "mentions"를 사용하면 봇을 멘션하는 봇 메시지만 수락해요 (자신의 메시지는 여전히 필터링됨). channels.discord.guilds.<id>.ignoreOtherMentions(및 채널 오버라이드)는 다른 사용자나 역할을 멘션하지만 봇은 멘션하지 않는 메시지를 삭제해요 (@everyone/@here 제외).maxLinesPerMessage(기본값 17)는 2000자 미만이더라도 긴 메시지를 분할해요.channels.discord.threadBindings는 Discord 스레드 바인딩 라우팅을 제어해요:enabled: 스레드 바인딩 세션 기능(/focus,/unfocus,/agents,/session idle,/session max-age, 바인딩된 전달/라우팅)에 대한 Discord 오버라이드예요.idleHours: 비활성 자동 포커스 해제 시간(시간 단위)에 대한 Discord 오버라이드예요 (0은 비활성화).maxAgeHours: 하드 최대 수명(시간 단위)에 대한 Discord 오버라이드예요 (0은 비활성화).spawnSubagentSessions:sessions_spawn({ thread: true })자동 스레드 생성/바인딩을 위한 옵트인 스위치예요.
- 최상위
bindings[]항목 중type: "acp"인 설정은 채널 및 스레드에 대한 영구 ACP 바인딩을 구성해요 (match.peer.id에 채널/스레드 ID 사용). 필드 의미는 ACP 에이전트에서 공유돼요. channels.discord.ui.components.accentColor는 Discord components v2 컨테이너의 강조 색상을 설정해요.channels.discord.voice는 Discord 음성 채널 대화와 선택적인 자동 참여 + TTS 오버라이드를 활성화해요.channels.discord.voice.daveEncryption및channels.discord.voice.decryptionFailureTolerance는@discordjs/voiceDAVE 옵션으로 전달돼요 (기본값은 각각true및24).- OpenClaw는 복호화 실패가 반복될 때 음성 세션을 나갔다 다시 참여함으로써 음성 수신 복구를 추가로 시도해요.
channels.discord.streaming은 표준 스트림 모드 키예요. 기존의streamMode및 불리언streaming값은 자동으로 마이그레이션돼요.channels.discord.autoPresence는 런타임 가용성을 봇 상태에 매핑하며(healthy => online, degraded => idle, exhausted => dnd), 선택적인 상태 텍스트 오버라이드를 허용해요.channels.discord.dangerouslyAllowNameMatching은 변경 가능한 이름/태그 매칭을 다시 활성화해요 (긴급 호환성 모드).
반응 알림 모드: off (없음), own (봇의 메시지, 기본값), all (모든 메시지), allowlist (모든 메시지에 대해 guilds.<id>.users로부터의 반응).
Google Chat
섹션 제목: “Google Chat”{ channels: { googlechat: { enabled: true, serviceAccountFile: "/path/to/service-account.json", audienceType: "app-url", // app-url | project-number audience: "https://gateway.example.com/googlechat", webhookPath: "/googlechat", botUser: "users/1234567890", dm: { enabled: true, policy: "pairing", allowFrom: ["users/1234567890"], }, groupPolicy: "allowlist", groups: { "spaces/AAAA": { allow: true, requireMention: true }, }, actions: { reactions: true }, typingIndicator: "message", mediaMaxMb: 20, }, },}- 서비스 계정 JSON: 인라인(
serviceAccount) 또는 파일 기반(serviceAccountFile)으로 설정 가능해요. - 서비스 계정 SecretRef도 지원돼요 (
serviceAccountRef). - 환경 변수 폴백:
GOOGLE_CHAT_SERVICE_ACCOUNT또는GOOGLE_CHAT_SERVICE_ACCOUNT_FILE. - 전달 대상으로
spaces/<spaceId>또는users/<userId>를 사용하세요. channels.googlechat.dangerouslyAllowNameMatching은 변경 가능한 이메일 주체 매칭을 다시 활성화해요 (긴급 호환성 모드).
Slack
섹션 제목: “Slack”{ channels: { slack: { enabled: true, botToken: "xoxb-...", appToken: "xapp-...", dmPolicy: "pairing", allowFrom: ["U123", "U456", "*"], dm: { enabled: true, groupEnabled: false, groupChannels: ["G123"] }, channels: { C123: { allow: true, requireMention: true, allowBots: false }, "#general": { allow: true, requireMention: true, allowBots: false, users: ["U123"], skills: ["docs"], systemPrompt: "Short answers only.", }, }, historyLimit: 50, allowBots: false, reactionNotifications: "own", reactionAllowlist: ["U123"], replyToMode: "off", // off | first | all thread: { historyScope: "thread", // thread | channel inheritParent: false, }, actions: { reactions: true, messages: true, pins: true, memberInfo: true, emojiList: true, }, slashCommand: { enabled: true, name: "openclaw", sessionPrefix: "slack:slash", ephemeral: true, }, typingReaction: "hourglass_flowing_sand", textChunkLimit: 4000, chunkMode: "length", streaming: "partial", // off | partial | block | progress (preview mode) nativeStreaming: true, // use Slack native streaming API when streaming=partial mediaMaxMb: 20, }, },}- Socket mode는
botToken과appToken이 모두 필요해요 (기본 계정 환경 변수 폴백은SLACK_BOT_TOKEN+SLACK_APP_TOKEN). - HTTP mode는
botToken과signingSecret(루트 또는 계정별)이 필요해요. configWrites: false는 Slack에서 시작된 설정 쓰기를 차단해요.- 선택 사항인
channels.slack.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요. channels.slack.streaming은 표준 스트림 모드 키예요. 기존의streamMode및 불리언streaming값은 자동으로 마이그레이션돼요.- 전달 대상으로
user:<id>(DM) 또는channel:<id>를 사용하세요.
반응 알림 모드: off, own (기본값), all, allowlist (reactionAllowlist로부터의 반응).
스레드 세션 격리: thread.historyScope는 스레드별(기본값) 또는 채널 전체 공유로 설정할 수 있어요. thread.inheritParent는 부모 채널의 대화 기록을 새 스레드로 복사해요.
typingReaction은 답장이 진행되는 동안 인바운드 Slack 메시지에 임시 반응을 추가하고, 완료되면 제거해요."hourglass_flowing_sand"와 같은 Slack 이모지 숏코드를 사용하세요.
| 액션 그룹 | 기본값 | 참고 |
|---|---|---|
| reactions | 활성화 | 반응 추가 + 반응 목록 조회 |
| messages | 활성화 | 읽기/전송/수정/삭제 |
| pins | 활성화 | 고정/고정 해제/목록 조회 |
| memberInfo | 활성화 | 멤버 정보 |
| emojiList | 활성화 | 커스텀 이모지 목록 |
Mattermost
섹션 제목: “Mattermost”Mattermost는 플러그인으로 제공돼요: openclaw plugins install @openclaw/mattermost.
{ channels: { mattermost: { enabled: true, botToken: "mm-token", baseUrl: "https://chat.example.com", dmPolicy: "pairing", chatmode: "oncall", // oncall | onmessage | onchar oncharPrefixes: [">", "!"], commands: { native: true, // opt-in nativeSkills: true, callbackPath: "/api/channels/mattermost/command", // Optional explicit URL for reverse-proxy/public deployments callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, textChunkLimit: 4000, chunkMode: "length", }, },}채팅 모드: oncall (@-멘션 시 응답, 기본값), onmessage (모든 메시지), onchar (트리거 접두사로 시작하는 메시지).
Mattermost 네이티브 명령이 활성화된 경우:
commands.callbackPath는 전체 URL이 아닌 경로(예:/api/channels/mattermost/command)여야 해요.commands.callbackUrl은 OpenClaw Gateway 엔드포인트로 연결되어야 하며 Mattermost 서버에서 접근 가능해야 해요.- 프라이빗/tailnet/내부 콜백 호스트의 경우, Mattermost의
ServiceSettings.AllowedUntrustedInternalConnections에 콜백 호스트/도메인을 포함해야 할 수도 있어요. 전체 URL이 아닌 호스트/도메인 값을 사용하세요. channels.mattermost.configWrites: Mattermost에서 시작된 설정 쓰기를 허용하거나 거부해요.channels.mattermost.requireMention: 채널에서 답장하기 전에@mention을 요구해요.- 선택 사항인
channels.mattermost.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요.
Signal
섹션 제목: “Signal”{ channels: { signal: { enabled: true, account: "+15555550123", // optional account binding dmPolicy: "pairing", allowFrom: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"], configWrites: true, reactionNotifications: "own", // off | own | all | allowlist reactionAllowlist: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"], historyLimit: 50, }, },}반응 알림 모드: off, own (기본값), all, allowlist (reactionAllowlist로부터의 반응).
channels.signal.account: 채널 시작을 특정 Signal 계정 ID에 고정해요.channels.signal.configWrites: Signal에서 시작된 설정 쓰기를 허용하거나 거부해요.- 선택 사항인
channels.signal.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요.
BlueBubbles
섹션 제목: “BlueBubbles”BlueBubbles는 권장되는 iMessage 경로예요 (플러그인 기반, channels.bluebubbles에서 설정).
{ channels: { bluebubbles: { enabled: true, dmPolicy: "pairing", // serverUrl, password, webhookPath, group controls, and advanced actions: // see /channels/bluebubbles }, },}- 여기서 다루는 핵심 키 경로:
channels.bluebubbles,channels.bluebubbles.dmPolicy. - 선택 사항인
channels.bluebubbles.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요. - 전체 BlueBubbles 채널 설정은 BlueBubbles에 문서화되어 있어요.
iMessage
섹션 제목: “iMessage”OpenClaw는 imsg rpc (stdio를 통한 JSON-RPC)를 실행해요. 데몬이나 포트가 필요하지 않아요.
{ channels: { imessage: { enabled: true, cliPath: "imsg", dbPath: "~/Library/Messages/chat.db", remoteHost: "user@gateway-host", dmPolicy: "pairing", allowFrom: ["+15555550123", "user@example.com", "chat_id:123"], historyLimit: 50, includeAttachments: false, attachmentRoots: ["/Users/*/Library/Messages/Attachments"], remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"], mediaMaxMb: 16, service: "auto", region: "US", }, },}- 선택 사항인
channels.imessage.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요. - 메시지 DB에 대한 전체 디스크 접근 권한(Full Disk Access)이 필요해요.
chat_id:<id>대상을 권장해요.imsg chats --limit 20을 사용하여 채팅 목록을 확인할 수 있어요.cliPath는 SSH 래퍼를 가리킬 수 있어요. SCP 첨부 파일 가져오기를 위해remoteHost(host또는user@host)를 설정하세요.attachmentRoots및remoteAttachmentRoots는 인바운드 첨부 파일 경로를 제한해요 (기본값:/Users/*/Library/Messages/Attachments).- SCP는 엄격한 호스트 키 확인을 사용하므로 릴레이 호스트 키가
~/.ssh/known_hosts에 이미 존재하는지 확인하세요. channels.imessage.configWrites: iMessage에서 시작된 설정 쓰기를 허용하거나 거부해요.
iMessage SSH 래퍼 예시
#!/usr/bin/env bashexec ssh -T gateway-host imsg "$@"Microsoft Teams
섹션 제목: “Microsoft Teams”Microsoft Teams는 확장 기능 기반이며 channels.msteams에서 설정해요.
{ channels: { msteams: { enabled: true, configWrites: true, // appId, appPassword, tenantId, webhook, team/channel policies: // see /channels/msteams }, },}- 여기서 다루는 핵심 키 경로:
channels.msteams,channels.msteams.configWrites. - 전체 Teams 설정(자격 증명, 웹훅, DM/그룹 정책, 팀별/채널별 오버라이드)은 Microsoft Teams에 문서화되어 있어요.
IRC
섹션 제목: “IRC”IRC는 확장 기능 기반이며 channels.irc에서 설정해요.
{ channels: { irc: { enabled: true, dmPolicy: "pairing", configWrites: true, nickserv: { enabled: true, service: "NickServ", password: "${IRC_NICKSERV_PASSWORD}", register: false, registerEmail: "bot@example.com", }, }, },}- 여기서 다루는 핵심 키 경로:
channels.irc,channels.irc.dmPolicy,channels.irc.configWrites,channels.irc.nickserv.*. - 선택 사항인
channels.irc.defaultAccount는 설정된 계정 ID와 일치할 때 기본 계정 선택을 오버라이드해요. - 전체 IRC 채널 설정(호스트/포트/TLS/채널/allowlist/멘션 게이팅)은 IRC에 문서화되어 있어요.
다중 계정 (모든 채널)
섹션 제목: “다중 계정 (모든 채널)”채널당 여러 계정을 실행할 수 있어요 (각각 고유한 accountId 보유):
{ channels: { telegram: { accounts: { default: { name: "Primary bot", botToken: "123456:ABC...", }, alerts: { name: "Alerts bot", botToken: "987654:XYZ...", }, }, }, },}accountId가 생략된 경우(CLI + 라우팅)default가 사용돼요.- 환경 변수 토큰은 기본(default) 계정에만 적용돼요.
- 기본 채널 설정은 계정별로 오버라이드되지 않는 한 모든 계정에 적용돼요.
- 각 계정을 다른 에이전트로 라우팅하려면
bindings[].match.accountId를 사용하세요. - 단일 계정 최상위 채널 설정 상태에서
openclaw channels add(또는 채널 온보딩)를 통해 기본이 아닌 계정을 추가하면, OpenClaw는 기존 계정이 계속 작동하도록 계정 범위의 최상위 단일 계정 값을channels.<channel>.accounts.default로 먼저 이동시켜요. - 기존의 채널 전용 바인딩(
accountId없음)은 기본 계정과 계속 매칭돼요. 계정 범위 바인딩은 선택 사항으로 남아요. openclaw doctor --fix는 이름이 지정된 계정은 존재하지만default가 누락된 경우, 계정 범위의 최상위 단일 계정 값을accounts.default로 이동하여 혼합된 형태를 복구해요.
기타 확장 채널
섹션 제목: “기타 확장 채널”많은 확장 채널이 channels.<id>로 설정되며 전용 채널 페이지(예: Feishu, Matrix, LINE, Nostr, Zalo, Nextcloud Talk, Synology Chat, Twitch)에 문서화되어 있어요.
전체 채널 인덱스를 확인하세요: 채널.
그룹 채팅 멘션 게이팅
섹션 제목: “그룹 채팅 멘션 게이팅”그룹 메시지는 기본적으로 멘션 요구 (메타데이터 멘션 또는 정규식 패턴) 상태예요. WhatsApp, Telegram, Discord, Google Chat, iMessage 그룹 채팅에 적용돼요.
멘션 유형:
- 메타데이터 멘션: 플랫폼 네이티브 @-멘션이에요. WhatsApp 셀프 채팅 모드에서는 무시돼요.
- 텍스트 패턴:
agents.list[].groupChat.mentionPatterns에 정의된 정규식 패턴이에요. 항상 확인돼요. - 멘션 게이팅은 감지가 가능할 때만(네이티브 멘션 또는 하나 이상의 패턴이 있을 때) 강제 적용돼요.
{ messages: { groupChat: { historyLimit: 50 }, }, agents: { list: [{ id: "main", groupChat: { mentionPatterns: ["@openclaw", "openclaw"] } }], },}messages.groupChat.historyLimit은 글로벌 기본값을 설정해요. 채널별로 channels.<channel>.historyLimit(또는 계정별)을 통해 오버라이드할 수 있어요. 0으로 설정하면 비활성화돼요.
DM 히스토리 제한
섹션 제목: “DM 히스토리 제한”{ channels: { telegram: { dmHistoryLimit: 30, dms: { "123456789": { historyLimit: 50 }, }, }, },}해결 순서: DM별 오버라이드 → 프로바이더 기본값 → 제한 없음 (모두 유지).
지원 채널: telegram, whatsapp, discord, slack, signal, imessage, msteams.
셀프 채팅 모드
섹션 제목: “셀프 채팅 모드”자신의 번호를 allowFrom에 포함하여 셀프 채팅 모드를 활성화하세요 (네이티브 @-멘션은 무시하고 텍스트 패턴에만 응답함):
{ channels: { whatsapp: { allowFrom: ["+15555550123"], groups: { "*": { requireMention: true } }, }, }, agents: { list: [ { id: "main", groupChat: { mentionPatterns: ["reisponde", "@openclaw"] }, }, ], },}명령 (채팅 명령 처리)
섹션 제목: “명령 (채팅 명령 처리)”{ commands: { native: "auto", // register native commands when supported text: true, // parse /commands in chat messages bash: false, // allow ! (alias: /bash) bashForegroundMs: 2000, config: false, // allow /config debug: false, // allow /debug restart: false, // allow /restart + gateway restart tool allowFrom: { "*": ["user1"], discord: ["user:123"], }, useAccessGroups: true, },}명령 상세 정보
- 텍스트 명령은 맨 앞에
/가 붙은 독립된 메시지여야 해요. native: "auto"는 Discord/Telegram의 네이티브 명령을 켜고 Slack은 끈 상태로 둬요.- 채널별 오버라이드:
channels.discord.commands.native(불리언 또는"auto").false는 이전에 등록된 명령을 삭제해요. channels.telegram.customCommands는 Telegram 봇 메뉴 항목을 추가해요.bash: true는 호스트 쉘을 위한! <cmd>를 활성화해요.tools.elevated.enabled가 필요하며 발신자가tools.elevated.allowFrom.<channel>에 있어야 해요.config: true는/config(openclaw.json읽기/쓰기)를 활성화해요. Gatewaychat.send클라이언트의 경우, 영구적인/config set|unset쓰기에는operator.admin권한도 필요해요. 읽기 전용인/config show는 일반 쓰기 권한의 operator 클라이언트도 사용할 수 있어요.channels.<provider>.configWrites는 채널별 설정 변경을 제어해요 (기본값: true).- 다중 계정 채널의 경우,
channels.<provider>.accounts.<id>.configWrites는 해당 계정을 대상으로 하는 쓰기도 제어해요 (예:/allowlist --config --account <id>또는/config set channels.<provider>.accounts.<id>...). allowFrom은 프로바이더별로 설정돼요. 설정되면 이것이 유일한 인증 소스가 돼요 (채널 allowlist/페어링 및useAccessGroups는 무시됨).useAccessGroups: false는allowFrom이 설정되지 않았을 때 명령이 액세스 그룹 정책을 우회할 수 있게 해요.
에이전트 기본 설정
섹션 제목: “에이전트 기본 설정”agents.defaults.workspace
섹션 제목: “agents.defaults.workspace”기본값: ~/.openclaw/workspace.
{ agents: { defaults: { workspace: "~/.openclaw/workspace" } },}agents.defaults.repoRoot
섹션 제목: “agents.defaults.repoRoot”시스템 프롬프트의 Runtime 라인에 표시되는 선택적인 저장소 루트예요. 설정되지 않으면 OpenClaw가 워크스페이스에서 위로 올라가며 자동으로 감지해요.
{ agents: { defaults: { repoRoot: "~/Projects/openclaw" } },}agents.defaults.skipBootstrap
섹션 제목: “agents.defaults.skipBootstrap”워크스페이스 부트스트랩 파일(AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md)의 자동 생성을 비활성화해요.
{ agents: { defaults: { skipBootstrap: true } },}agents.defaults.bootstrapMaxChars
섹션 제목: “agents.defaults.bootstrapMaxChars”잘리기 전 워크스페이스 부트스트랩 파일당 최대 문자 수예요. 기본값: 20000.
{ agents: { defaults: { bootstrapMaxChars: 20000 } },}agents.defaults.bootstrapTotalMaxChars
섹션 제목: “agents.defaults.bootstrapTotalMaxChars”모든 워크스페이스 부트스트랩 파일에 걸쳐 주입되는 최대 총 문자 수예요. 기본값: 150000.
{ agents: { defaults: { bootstrapTotalMaxChars: 150000 } },}agents.defaults.bootstrapPromptTruncationWarning
섹션 제목: “agents.defaults.bootstrapPromptTruncationWarning”부트스트랩 컨텍스트가 잘렸을 때 에이전트에게 보이는 경고 텍스트를 제어해요.
기본값: "once".
"off": 시스템 프롬프트에 경고 텍스트를 주입하지 않아요."once": 고유한 절단 시그니처당 한 번만 경고를 주입해요 (권장)."always": 절단이 존재할 때마다 매 실행 시 경고를 주입해요.
{ agents: { defaults: { bootstrapPromptTruncationWarning: "once" } }, // off | once | always}agents.defaults.imageMaxDimensionPx
섹션 제목: “agents.defaults.imageMaxDimensionPx”프로바이더 호출 전 대화 기록/도구 이미지 블록에서 이미지의 가장 긴 변의 최대 픽셀 크기예요.
기본값: 1200.
낮은 값은 일반적으로 스크린샷이 많은 실행에서 vision-token 사용량과 요청 페이로드 크기를 줄여줘요. 높은 값은 더 많은 시각적 세부 사항을 보존해요.
{ agents: { defaults: { imageMaxDimensionPx: 1200 } },}agents.defaults.userTimezone
섹션 제목: “agents.defaults.userTimezone”시스템 프롬프트 컨텍스트를 위한 시간대예요 (메시지 타임스탬프가 아님). 호스트 시간대로 폴백돼요.
{ agents: { defaults: { userTimezone: "America/Chicago" } },}agents.defaults.timeFormat
섹션 제목: “agents.defaults.timeFormat”시스템 프롬프트의 시간 형식이에요. 기본값: auto (OS 설정 선호).
{ agents: { defaults: { timeFormat: "auto" } }, // auto | 12 | 24}agents.defaults.model
섹션 제목: “agents.defaults.model”{ agents: { defaults: { models: { "anthropic/claude-opus-4-6": { alias: "opus" }, "minimax/MiniMax-M2.5": { alias: "minimax" }, }, model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["minimax/MiniMax-M2.5"], }, imageModel: { primary: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free", fallbacks: ["openrouter/google/gemini-2.0-flash-vision:free"], }, pdfModel: { primary: "anthropic/claude-opus-4-6", fallbacks: ["openai/gpt-5-mini"], }, pdfMaxBytesMb: 10, pdfMaxPages: 20, thinkingDefault: "low", verboseDefault: "off", elevatedDefault: "on", timeoutSeconds: 600, mediaMaxMb: 5, contextTokens: 200000, maxConcurrent: 3, }, },}model: 문자열("provider/model") 또는 객체({ primary, fallbacks })를 받아요.- 문자열 형식은 기본 모델만 설정해요.
- 객체 형식은 기본 모델과 순서가 지정된 페일오버(failover) 모델들을 설정해요.
imageModel: 문자열("provider/model") 또는 객체({ primary, fallbacks })를 받아요.image도구 경로에서 vision-model 설정으로 사용돼요.- 선택된/기본 모델이 이미지 입력을 수락할 수 없을 때 폴백 라우팅으로도 사용돼요.
pdfModel: 문자열("provider/model") 또는 객체({ primary, fallbacks })를 받아요.pdf도구에서 모델 라우팅을 위해 사용돼요.- 생략하면 PDF 도구는
imageModel로 폴백하고, 그 다음 최선의 프로바이더 기본값으로 폴백해요.
pdfMaxBytesMb: 호출 시maxBytesMb가 전달되지 않았을 때pdf도구의 기본 PDF 크기 제한이에요.pdfMaxPages:pdf도구의 추출 폴백 모드에서 고려되는 기본 최대 페이지 수예요.model.primary:provider/model형식이에요 (예:anthropic/claude-opus-4-6). 프로바이더를 생략하면 OpenClaw는anthropic으로 간주해요 (권장되지 않음).models:/model을 위한 설정된 모델 카탈로그 및 allowlist예요. 각 항목은alias(단축키)와params(프로바이더별 설정, 예:temperature,maxTokens,cacheRetention,context1m)를 포함할 수 있어요.params병합 우선순위(설정):agents.defaults.models["provider/model"].params가 기본이며,agents.list[].params(일치하는 에이전트 ID)가 키별로 오버라이드해요.- 이 필드들을 변경하는 설정 작성기(예:
/models set,/models set-image, 폴백 추가/제거 명령)는 정규 객체 형식을 저장하고 가능한 경우 기존 폴백 목록을 보존해요. maxConcurrent: 세션 전체에 걸친 최대 병렬 에이전트 실행 수예요 (각 세션은 여전히 직렬화됨). 기본값: 1.
내장 alias 단축키 (모델이 agents.defaults.models에 있을 때만 적용됨):
| Alias | 모델 |
|---|---|
opus | anthropic/claude-opus-4-6 |
sonnet | anthropic/claude-sonnet-4-6 |
gpt | openai/gpt-5.4 |
gpt-mini | openai/gpt-5-mini |
gemini | google/gemini-3.1-pro-preview |
gemini-flash | google/gemini-3-flash-preview |
gemini-flash-lite | google/gemini-3.1-flash-lite-preview |
사용자가 설정한 alias는 항상 기본값보다 우선해요.
Z.AI GLM-4.x 모델은 --thinking off를 설정하거나 agents.defaults.models["zai/<model>"].params.thinking을 직접 정의하지 않는 한 자동으로 thinking 모드를 활성화해요.
Z.AI 모델은 도구 호출 스트리밍을 위해 기본적으로 tool_stream을 활성화해요. 비활성화하려면 agents.defaults.models["zai/<model>"].params.tool_stream을 false로 설정하세요.
Anthropic Claude 4.6 모델은 명시적인 thinking 레벨이 설정되지 않은 경우 기본적으로 adaptive thinking을 사용해요.
agents.defaults.cliBackends
섹션 제목: “agents.defaults.cliBackends”텍스트 전용 폴백 실행(도구 호출 없음)을 위한 선택적인 CLI 백엔드예요. API 프로바이더가 실패할 때 백업으로 유용해요.
{ agents: { defaults: { cliBackends: { "claude-cli": { command: "/opt/homebrew/bin/claude", }, "my-cli": { command: "my-cli", args: ["--json"], output: "json", modelArg: "--model", sessionArg: "--session", sessionMode: "existing", systemPromptArg: "--system", systemPromptWhen: "first", imageArg: "--image", imageMode: "repeat", }, }, }, },}- CLI 백엔드는 텍스트 우선이며, 도구는 항상 비활성화돼요.
sessionArg가 설정되면 세션이 지원돼요.imageArg가 파일 경로를 수락하면 이미지 패스스루(pass-through)가 지원돼요.
agents.defaults.heartbeat
섹션 제목: “agents.defaults.heartbeat”주기적인 heartbeat 실행 설정이에요.
{ agents: { defaults: { heartbeat: { every: "30m", // 0m disables model: "openai/gpt-5.2-mini", includeReasoning: false, lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files session: "main", to: "+15555550123", directPolicy: "allow", // allow (default) | block target: "none", // default: none | options: last | whatsapp | telegram | discord | ... prompt: "Read HEARTBEAT.md if it exists...", ackMaxChars: 300, suppressToolErrorWarnings: false, }, }, },}every: 기간 문자열(ms/s/m/h). 기본값:30m.suppressToolErrorWarnings: true일 때 heartbeat 실행 중 도구 에러 경고 페이로드를 억제해요.directPolicy: 다이렉트/DM 전달 정책이에요.allow(기본값)는 다이렉트 대상 전달을 허용해요.block은 다이렉트 대상 전달을 억제하고reason=dm-blocked를 내보내요.lightContext: true일 때 heartbeat 실행은 경량 부트스트랩 컨텍스트를 사용하며 워크스페이스 부트스트랩 파일 중HEARTBEAT.md만 유지해요.- 에이전트별 설정:
agents.list[].heartbeat를 설정하세요. 어떤 에이전트라도heartbeat를 정의하면 해당 에이전트들만 heartbeat를 실행해요. - Heartbeat는 전체 에이전트 턴(turn)을 실행하므로, 간격이 짧을수록 더 많은 토큰을 소모해요.
agents.defaults.compaction
섹션 제목: “agents.defaults.compaction”{ agents: { defaults: { compaction: { mode: "safeguard", // default | safeguard reserveTokensFloor: 24000, identifierPolicy: "strict", // strict | off | custom identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // used when identifierPolicy=custom postCompactionSections: ["Session Startup", "Red Lines"], // [] disables reinjection model: "openrouter/anthropic/claude-sonnet-4-5", // optional compaction-only model override memoryFlush: { enabled: true, softThresholdTokens: 6000, systemPrompt: "Session nearing compaction. Store durable memories now.", prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store.", }, }, }, },}mode:default또는safeguard(긴 히스토리를 위한 청크 단위 요약). Compaction을 참조하세요.identifierPolicy:strict(기본값),off, 또는custom.strict는 compaction 요약 중에 내장된 불투명 식별자 보존 가이드를 앞에 추가해요.identifierInstructions:identifierPolicy=custom일 때 사용되는 선택적인 커스텀 식별자 보존 텍스트예요.postCompactionSections: compaction 후 다시 주입할 선택적인 AGENTS.md H2/H3 섹션 이름들이에요. 기본값은["Session Startup", "Red Lines"]이며,[]로 설정하면 재주입을 비활성화해요. 설정되지 않았거나 기본값 쌍으로 명시적으로 설정된 경우, 이전의Every Session/Safety헤딩도 레거시 폴백으로 수락돼요.model: compaction 요약 전용의 선택적인provider/model-id오버라이드예요. 메인 세션은 한 모델을 유지하고 compaction 요약은 다른 모델에서 실행해야 할 때 사용하세요. 설정되지 않으면 세션의 기본 모델을 사용해요.memoryFlush: 자동 compaction 전에 영구 메모리를 저장하기 위한 조용한 에이전트 턴이에요. 워크스페이스가 읽기 전용이면 건너뛰어요.
agents.defaults.contextPruning
섹션 제목: “agents.defaults.contextPruning”LLM에 보내기 전에 메모리 내 컨텍스트에서 오래된 도구 결과를 정리해요. 디스크의 세션 히스토리는 수정하지 않아요.
{ agents: { defaults: { contextPruning: { mode: "cache-ttl", // off | cache-ttl ttl: "1h", // duration (ms/s/m/h), default unit: minutes keepLastAssistants: 3, softTrimRatio: 0.3, hardClearRatio: 0.5, minPrunableToolChars: 50000, softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 }, hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" }, tools: { deny: ["browser", "canvas"] }, }, }, },}cache-ttl 모드 동작
mode: "cache-ttl"은 정리 패스를 활성화해요.ttl은 정리가 다시 실행될 수 있는 빈도를 제어해요 (마지막 캐시 터치 이후).- 정리는 먼저 너무 큰 도구 결과를 soft-trim하고, 필요한 경우 오래된 도구 결과를 hard-clear해요.
Soft-trim은 시작 부분과 끝 부분을 유지하고 중간에 ...을 삽입해요.
Hard-clear는 전체 도구 결과를 플레이스홀더로 교체해요.
참고:
- 이미지 블록은 절대 트리밍되거나 삭제되지 않아요.
- 비율은 정확한 토큰 수가 아닌 문자 수 기준(근사치)이에요.
keepLastAssistants보다 적은 수의 assistant 메시지가 존재하면 정리를 건너뛰어요.
동작 상세 정보는 세션 정리를 참조하세요.
블록 스트리밍
섹션 제목: “블록 스트리밍”{ agents: { defaults: { blockStreamingDefault: "off", // on | off blockStreamingBreak: "text_end", // text_end | message_end blockStreamingChunk: { minChars: 800, maxChars: 1200 }, blockStreamingCoalesce: { idleMs: 1000 }, humanDelay: { mode: "natural" }, // off | natural | custom (use minMs/maxMs) }, },}- Telegram이 아닌 채널에서 블록 답장을 활성화하려면 명시적인
*.blockStreaming: true가 필요해요. - 채널 오버라이드:
channels.<channel>.blockStreamingCoalesce(및 계정별 변체). Signal/Slack/Discord/Google Chat의 기본값은minChars: 1500이에요. humanDelay: 블록 답장 사이의 무작위 일시 정지예요.natural= 800–2500ms. 에이전트별 오버라이드:agents.list[].humanDelay.
동작 및 청킹 상세 정보는 스트리밍을 참조하세요.
타이핑 인디케이터
섹션 제목: “타이핑 인디케이터”{ agents: { defaults: { typingMode: "instant", // never | instant | thinking | message typingIntervalSeconds: 6, }, },}- 기본값: 다이렉트 채팅/멘션 시
instant, 멘션되지 않은 그룹 채팅 시message. - 세션별 오버라이드:
session.typingMode,session.typingIntervalSeconds.
타이핑 인디케이터를 참조하세요.
agents.defaults.sandbox
섹션 제목: “agents.defaults.sandbox”내장 에이전트를 위한 선택적인 Docker 샌드박싱 설정이에요. 전체 가이드는 샌드박싱을 참조하세요.
{ agents: { defaults: { sandbox: { mode: "non-main", // off | non-main | all scope: "agent", // session | agent | shared workspaceAccess: "none", // none | ro | rw workspaceRoot: "~/.openclaw/sandboxes", docker: { image: "openclaw-sandbox:bookworm-slim", containerPrefix: "openclaw-sbx-", workdir: "/workspace", readOnlyRoot: true, tmpfs: ["/tmp", "/var/tmp", "/run"], network: "none", user: "1000:1000", capDrop: ["ALL"], env: { LANG: "C.UTF-8" }, setupCommand: "apt-get update && apt-get install -y git curl jq", pidsLimit: 256, memory: "1g", memorySwap: "2g", cpus: 1, ulimits: { nofile: { soft: 1024, hard: 2048 }, nproc: 256, }, seccompProfile: "/path/to/seccomp.json", apparmorProfile: "openclaw-sandbox", dns: ["1.1.1.1", "8.8.8.8"], extraHosts: ["internal.service:10.0.0.5"], binds: ["/home/user/source:/source:rw"], }, browser: { enabled: false, image: "openclaw-sandbox-browser:bookworm-slim", network: "openclaw-sandbox-browser", cdpPort: 9222, cdpSourceRange: "172.21.0.1/32", vncPort: 5900, noVncPort: 6080, headless: false, enableNoVnc: true, allowHostControl: false, autoStart: true, autoStartTimeoutMs: 12000, }, prune: { idleHours: 24, maxAgeDays: 7, }, }, }, }, tools: { sandbox: { tools: { allow: [ "exec", "process", "read", "write", "edit", "apply_patch", "sessions_list", "sessions_history", "sessions_send", "sessions_spawn", "session_status", ], deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"], }, }, },}샌드박스 상세 정보
워크스페이스 액세스:
none:~/.openclaw/sandboxes아래의 스코프별 샌드박스 워크스페이스ro:/workspace에 샌드박스 워크스페이스,/agent에 읽기 전용으로 마운트된 에이전트 워크스페이스rw:/workspace에 읽기/쓰기 가능하게 마운트된 에이전트 워크스페이스
스코프(Scope):
session: 세션별 컨테이너 + 워크스페이스agent: 에이전트당 하나의 컨테이너 + 워크스페이스 (기본값)shared: 공유 컨테이너 및 워크스페이스 (세션 간 격리 없음)
**setupCommand**는 컨테이너 생성 후 한 번 실행돼요 (sh -lc를 통해). 네트워크 아웃바운드, 쓰기 가능한 루트, 루트 사용자가 필요해요.
**컨테이너 기본값은 network: "none"**이에요. 에이전트에게 아웃바운드 액세스가 필요한 경우 "bridge"(또는 커스텀 브릿지 네트워크)로 설정하세요.
"host"는 차단돼요. "container:<id>"는 sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true를 명시적으로 설정하지 않는 한 기본적으로 차단돼요 (긴급용).
인바운드 첨부 파일은 활성 워크스페이스의 media/inbound/*에 스테이징돼요.
**docker.binds**는 추가적인 호스트 디렉토리를 마운트해요. 글로벌 및 에이전트별 바인딩이 병합돼요.
샌드박스 브라우저 (sandbox.browser.enabled): 컨테이너 내의 Chromium + CDP예요. noVNC URL이 시스템 프롬프트에 주입돼요. openclaw.json에 browser.enabled가 필요하지 않아요.
noVNC 관찰자 액세스는 기본적으로 VNC 인증을 사용하며 OpenClaw는 (공유 URL에 비밀번호를 노출하는 대신) 수명이 짧은 토큰 URL을 내보내요.
allowHostControl: false(기본값)는 샌드박스 세션이 호스트 브라우저를 대상으로 하는 것을 차단해요.network기본값은openclaw-sandbox-browser(전용 브릿지 네트워크)예요. 글로벌 브릿지 연결을 명시적으로 원하는 경우에만bridge로 설정하세요.cdpSourceRange는 선택적으로 컨테이너 에지에서의 CDP 인그레스를 CIDR 범위(예:172.21.0.1/32)로 제한해요.sandbox.browser.binds는 추가적인 호스트 디렉토리를 샌드박스 브라우저 컨테이너에만 마운트해요. 설정되면([]포함) 브라우저 컨테이너에 대해docker.binds를 대체해요.- 실행 기본값은
scripts/sandbox-browser-entrypoint.sh에 정의되어 있으며 컨테이너 호스트에 맞게 조정되어 있어요:--remote-debugging-address=127.0.0.1--remote-debugging-port=<OPENCLAW_BROWSER_CDP_PORT에서 파생됨>--user-data-dir=${HOME}/.chrome--no-first-run--no-default-browser-check--disable-3d-apis--disable-gpu--disable-software-rasterizer--disable-dev-shm-usage--disable-background-networking--disable-features=TranslateUI--disable-breakpad--disable-crash-reporter--renderer-process-limit=2--no-zygote--metrics-recording-only--disable-extensions(기본 활성화)--disable-3d-apis,--disable-software-rasterizer,--disable-gpu는 기본적으로 활성화되어 있으며, WebGL/3D 사용이 필요한 경우OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0으로 비활성화할 수 있어요.- 워크플로우가 확장에 의존하는 경우
OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0으로 확장을 다시 활성화할 수 있어요. --renderer-process-limit=2는OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>으로 변경할 수 있어요. Chromium의 기본 프로세스 제한을 사용하려면0으로 설정하세요.noSandbox가 활성화된 경우--no-sandbox및--disable-setuid-sandbox가 추가돼요.- 기본값은 컨테이너 이미지 베이스라인이에요. 컨테이너 기본값을 변경하려면 커스텀 엔트리포인트가 있는 커스텀 브라우저 이미지를 사용하세요.
이미지 빌드:
scripts/sandbox-setup.sh # main sandbox imagescripts/sandbox-browser-setup.sh # optional browser imageagents.list (에이전트별 오버라이드)
섹션 제목: “agents.list (에이전트별 오버라이드)”{ agents: { list: [ { id: "main", default: true, name: "Main Agent", workspace: "~/.openclaw/workspace", agentDir: "~/.openclaw/agents/main/agent", model: "anthropic/claude-opus-4-6", // or { primary, fallbacks } params: { cacheRetention: "none" }, // overrides matching defaults.models params by key identity: { name: "Samantha", theme: "helpful sloth", emoji: "🦥", avatar: "avatars/samantha.png", }, groupChat: { mentionPatterns: ["@openclaw"] }, sandbox: { mode: "off" }, runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent", cwd: "/workspace/openclaw", }, }, subagents: { allowAgents: ["*"] }, tools: { profile: "coding", allow: ["browser"], deny: ["canvas"], elevated: { enabled: true }, }, }, ], },}응답 접두사 (Response prefix)
섹션 제목: “응답 접두사 (Response prefix)”채널이나 계정별로 응답 접두사를 다르게 설정할 수 있어요. channels.<channel>.responsePrefix 또는 channels.<channel>.accounts.<id>.responsePrefix를 사용하면 돼요.
우선순위는 계정 → 채널 → 글로벌 순으로 적용돼요. ""로 설정하면 기능을 끄고 상위 설정을 무시해요. "auto"로 설정하면 [{identity.name}] 형식을 자동으로 사용해요.
템플릿 변수:
| 변수 | 설명 | 예시 |
|---|---|---|
{model} | 짧은 모델 이름 | claude-opus-4-6 |
{modelFull} | 전체 모델 식별자 | anthropic/claude-opus-4-6 |
{provider} | 프로바이더 이름 | anthropic |
{thinkingLevel} | 현재 사고(thinking) 수준 | high, low, off |
{identity.name} | 에이전트 식별 이름 | ("auto"와 동일) |
변수는 대소문자를 구분하지 않아요. {think}는 {thinkingLevel}의 별칭으로 쓸 수 있어요.
확인 반응 (Ack reaction)
섹션 제목: “확인 반응 (Ack reaction)”- 기본적으로 활성화된 에이전트의
identity.emoji를 사용하고, 없으면"👀"를 사용해요.""로 설정하면 끌 수 있어요. - 채널별 설정:
channels.<channel>.ackReaction,channels.<channel>.accounts.<id>.ackReaction. - 우선순위: 계정 → 채널 →
messages.ackReaction→ ID 기본값 순이에요. - 범위(Scope):
group-mentions(기본값),group-all,direct,all. removeAckAfterReply: 답장 후 확인 반응을 삭제해요 (Slack/Discord/Telegram/Google Chat만 지원).
인바운드 디바운스 (Inbound debounce)
섹션 제목: “인바운드 디바운스 (Inbound debounce)”동일한 발신자가 빠르게 보내는 여러 텍스트 메시지를 하나의 에이전트 턴으로 묶어줘요. 미디어나 첨부 파일은 즉시 처리되고, 제어 명령은 디바운싱을 거치지 않고 바로 실행돼요.
TTS (Text-to-speech)
섹션 제목: “TTS (Text-to-speech)”{ messages: { tts: { auto: "always", // off | always | inbound | tagged mode: "final", // final | all provider: "elevenlabs", summaryModel: "openai/gpt-4.1-mini", modelOverrides: { enabled: true }, maxTextLength: 4000, timeoutMs: 30000, prefsPath: "~/.openclaw/settings/tts.json", elevenlabs: { apiKey: "elevenlabs_api_key", baseUrl: "https://api.elevenlabs.io", voiceId: "voice_id", modelId: "eleven_multilingual_v2", seed: 42, applyTextNormalization: "auto", languageCode: "en", voiceSettings: { stability: 0.5, similarityBoost: 0.75, style: 0.0, useSpeakerBoost: true, speed: 1.0, }, }, openai: { apiKey: "openai_api_key", baseUrl: "https://api.openai.com/v1", model: "gpt-4o-mini-tts", voice: "alloy", }, }, },}auto는 자동 TTS를 제어해요. 세션별로/tts off|always|inbound|tagged명령어를 통해 설정을 바꿀 수 있어요.summaryModel은 자동 요약을 위해agents.defaults.model.primary설정을 덮어써요.modelOverrides는 기본적으로 활성화되어 있고,modelOverrides.allowProvider는 기본값이false예요.- API 키는
ELEVENLABS_API_KEY/XI_API_KEY및OPENAI_API_KEY환경 변수를 참조해요. openai.baseUrl로 OpenAI TTS 엔드포인트를 변경할 수 있어요. 설정 파일,OPENAI_TTS_BASE_URL,https://api.openai.com/v1순으로 확인해요.openai.baseUrl이 OpenAI가 아닌 엔드포인트를 가리키면, OpenClaw는 이를 OpenAI 호환 TTS 서버로 간주하고 모델이나 음성 검증을 유연하게 처리해요.
대화 (Talk)
섹션 제목: “대화 (Talk)”macOS/iOS/Android에서 사용하는 Talk 모드의 기본 설정이에요.
{ talk: { voiceId: "elevenlabs_voice_id", voiceAliases: { Clawd: "EXAVITQu4vr4xnSDxMaL", Roger: "CwhRBWXzGAHq8TQ4Fs17", }, modelId: "eleven_v3", outputFormat: "mp3_44100_128", apiKey: "elevenlabs_api_key", silenceTimeoutMs: 1500, interruptOnSpeech: true, },}- Voice ID는
ELEVENLABS_VOICE_ID또는SAG_VOICE_ID환경 변수를 사용해요. apiKey와providers.*.apiKey에는 일반 문자열이나 SecretRef 객체를 넣을 수 있어요.ELEVENLABS_API_KEY는 Talk API 키가 설정되지 않았을 때만 사용돼요.voiceAliases를 설정하면 Talk 명령에서 친숙한 이름을 사용할 수 있어요.silenceTimeoutMs는 사용자가 말을 멈춘 후 텍스트 변환 결과를 보낼 때까지 기다리는 시간이에요. 설정하지 않으면 플랫폼 기본값(macOS/Android 700ms, iOS 900ms)을 따라요.
도구 (Tools)
섹션 제목: “도구 (Tools)”도구 프로필 (Tool profiles)
섹션 제목: “도구 프로필 (Tool profiles)”tools.profile은 tools.allow/tools.deny를 적용하기 전의 기본 허용 목록을 설정해요.
로컬 온보딩 시 별도 설정이 없으면 새로운 로컬 설정은 tools.profile: "coding"으로 기본 지정돼요 (기존의 명시적인 프로필은 유지돼요).
| 프로필 | 포함 내용 |
|---|---|
minimal | session_status만 포함 |
coding | group:fs, group:runtime, group:sessions, group:memory, image |
messaging | group:messaging, sessions_list, sessions_history, sessions_send, session_status |
full | 제한 없음 (설정하지 않은 것과 동일) |
도구 그룹 (Tool groups)
섹션 제목: “도구 그룹 (Tool groups)”| 그룹 | 도구 |
|---|---|
group:runtime | exec, process (bash는 exec의 별칭으로 허용돼요) |
group:fs | read, write, edit, apply_patch |
group:sessions | sessions_list, sessions_history, sessions_send, sessions_spawn, session_status |
group:memory | memory_search, memory_get |
group:web | web_search, web_fetch |
group:ui | browser, canvas |
group:automation | cron, gateway |
group:messaging | message |
group:nodes | nodes |
group:openclaw | 모든 내장 도구 (프로바이더 플러그인 제외) |
tools.allow / tools.deny
섹션 제목: “tools.allow / tools.deny”글로벌 도구 허용/거부 정책이에요 (거부가 우선해요). 대소문자를 구분하지 않으며 * 와일드카드를 지원해요. Docker 샌드박스가 꺼져 있어도 적용돼요.
{ tools: { deny: ["browser", "canvas"] },}tools.byProvider
섹션 제목: “tools.byProvider”특정 프로바이더나 모델에 대해 도구를 더 제한할 수 있어요. 적용 순서는 기본 프로필 → 프로바이더 프로필 → 허용/거부 순이에요.
{ tools: { profile: "coding", byProvider: { "google-antigravity": { profile: "minimal" }, "openai/gpt-5.2": { allow: ["group:fs", "sessions_list"] }, }, },}tools.elevated
섹션 제목: “tools.elevated”호스트에 대한 승인된(elevated) 실행 권한을 제어해요.
{ tools: { elevated: { enabled: true, allowFrom: { whatsapp: ["+15555550123"], discord: ["1234567890123", "987654321098765432"], }, }, },}- 에이전트별 설정(
agents.list[].tools.elevated)은 권한을 더 축소하는 방향으로만 작동해요. /elevated on|off|ask|full명령어로 세션별 상태를 저장할 수 있고, 인라인 명령은 단일 메시지에만 적용돼요.- 승인된
exec는 호스트에서 직접 실행되며 샌드박스를 우회해요.
tools.exec
섹션 제목: “tools.exec”{ tools: { exec: { backgroundMs: 10000, timeoutSec: 1800, cleanupMs: 1800000, notifyOnExit: true, notifyOnExitEmptySuccess: false, applyPatch: { enabled: false, allowModels: ["gpt-5.2"], }, }, },}도구 루프 감지 (tools.loopDetection)
섹션 제목: “도구 루프 감지 (tools.loopDetection)”도구 루프 안전 점검은 기본적으로 비활성화되어 있어요. 감지 기능을 켜려면 enabled: true로 설정하세요.
글로벌 설정은 tools.loopDetection에서 하고, 에이전트별로 agents.list[].tools.loopDetection에서 덮어쓸 수 있어요.
{ tools: { loopDetection: { enabled: true, historySize: 30, warningThreshold: 10, criticalThreshold: 20, globalCircuitBreakerThreshold: 30, detectors: { genericRepeat: true, knownPollNoProgress: true, pingPong: true, }, }, },}historySize: 루프 분석을 위해 보관할 최대 도구 호출 기록 수예요.warningThreshold: 진전 없는 반복 패턴이 나타날 때 경고를 보내는 임계값이에요.criticalThreshold: 심각한 루프를 차단하기 위한 더 높은 임계값이에요.globalCircuitBreakerThreshold: 어떤 경우든 진전 없이 실행될 때 강제로 중단하는 임계값이에요.detectors.genericRepeat: 동일한 도구와 인자로 반복 호출할 때 경고해요.detectors.knownPollNoProgress: 알려진 폴링 도구(process.poll,command_status등)에서 경고하거나 차단해요.detectors.pingPong: 두 가지 도구가 진전 없이 번갈아 호출되는 패턴을 경고하거나 차단해요.warningThreshold >= criticalThreshold이거나criticalThreshold >= globalCircuitBreakerThreshold이면 유효성 검사에 실패해요.
tools.web
섹션 제목: “tools.web”{ tools: { web: { search: { enabled: true, apiKey: "brave_api_key", // or BRAVE_API_KEY env maxResults: 5, timeoutSeconds: 30, cacheTtlMinutes: 15, }, fetch: { enabled: true, maxChars: 50000, maxCharsCap: 50000, timeoutSeconds: 30, cacheTtlMinutes: 15, userAgent: "custom-ua", }, }, },}tools.media
섹션 제목: “tools.media”인바운드 미디어(이미지/오디오/비디오) 이해 기능을 설정해요.
{ tools: { media: { concurrency: 2, audio: { enabled: true, maxBytes: 20971520, scope: { default: "deny", rules: [{ action: "allow", match: { chatType: "direct" } }], }, models: [ { provider: "openai", model: "gpt-4o-mini-transcribe" }, { type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] }, ], }, video: { enabled: true, maxBytes: 52428800, models: [{ provider: "google", model: "gemini-3-flash-preview" }], }, }, },}미디어 모델 항목 필드
프로바이더 항목 (type: "provider" 또는 생략):
provider: API 프로바이더 ID (openai,anthropic,google/gemini,groq등)model: 모델 ID 덮어쓰기profile/preferredProfile:auth-profiles.json프로필 선택
CLI 항목 (type: "cli"):
command: 실행할 파일args: 템플릿 인자 ({{MediaPath}},{{Prompt}},{{MaxChars}}등 지원)
공통 필드:
capabilities: 선택적 목록 (image,audio,video). 기본값:openai/anthropic/minimax→ image,google→ image+audio+video,groq→ audio.prompt,maxChars,maxBytes,timeoutSeconds,language: 항목별 덮어쓰기.- 실패 시 다음 항목으로 넘어갑니다.
프로바이더 인증 순서: auth-profiles.json → 환경 변수 → models.providers.*.apiKey.
tools.agentToAgent
섹션 제목: “tools.agentToAgent”{ tools: { agentToAgent: { enabled: false, allow: ["home", "work"], }, },}tools.sessions
섹션 제목: “tools.sessions”세션 도구(sessions_list, sessions_history, sessions_send)가 접근할 수 있는 세션을 제어해요.
기본값은 tree (현재 세션 + 하위 에이전트 등 현재 세션에서 파생된 세션)예요.
{ tools: { sessions: { // "self" | "tree" | "agent" | "all" visibility: "tree", }, },}참고:
self: 현재 세션 키만 가능해요.tree: 현재 세션과 거기서 파생된 세션(서브 에이전트)만 가능해요.agent: 현재 에이전트 ID에 속한 모든 세션이 가능해요.all: 모든 세션이 가능해요. 다른 에이전트를 대상으로 하려면tools.agentToAgent설정이 여전히 필요해요.- 샌드박스 제한: 현재 세션이 샌드박스 상태이고
agents.defaults.sandbox.sessionToolsVisibility="spawned"인 경우,tools.sessions.visibility="all"로 설정해도tree로 강제 제한돼요.
tools.sessions_spawn
섹션 제목: “tools.sessions_spawn”sessions_spawn에 대한 인라인 첨부 파일 지원을 제어해요.
{ tools: { sessions_spawn: { attachments: { enabled: false, // opt-in: set true to allow inline file attachments maxTotalBytes: 5242880, // 5 MB total across all files maxFiles: 50, maxFileBytes: 1048576, // 1 MB per file retainOnSessionKeep: false, // keep attachments when cleanup="keep" }, }, },}참고:
- 첨부 파일은
runtime: "subagent"에서만 지원돼요. ACP 런타임은 이를 거부해요. - 파일은 자식 워크스페이스의
.openclaw/attachments/<uuid>/경로에 생성되며.manifest.json이 함께 생성돼요. - 첨부 파일 내용은 대화 기록 저장 시 자동으로 가려져요(redacted).
- Base64 입력은 엄격한 검증을 거치며 디코딩 전 크기 제한이 적용돼요.
- 파일 권한은 디렉토리
0700, 파일0600으로 설정돼요. - 정리는
cleanup정책을 따라요.delete는 항상 삭제하고,keep은retainOnSessionKeep: true일 때만 유지해요.
tools.subagents
섹션 제목: “tools.subagents”{ agents: { defaults: { subagents: { model: "minimax/MiniMax-M2.5", maxConcurrent: 1, runTimeoutSeconds: 900, archiveAfterMinutes: 60, }, }, },}model: 생성된 서브 에이전트의 기본 모델이에요. 생략하면 호출자의 모델을 상속받아요.runTimeoutSeconds: 도구 호출 시 지정하지 않았을 때의 기본 타임아웃(초)이에요.0은 타임아웃 없음을 의미해요.- 서브 에이전트별 도구 정책:
tools.subagents.tools.allow/tools.subagents.tools.deny.
커스텀 프로바이더 및 베이스 URL (Custom providers and base URLs)
섹션 제목: “커스텀 프로바이더 및 베이스 URL (Custom providers and base URLs)”OpenClaw는 pi-coding-agent 모델 카탈로그를 사용해요. 설정 파일의 models.providers나 ~/.openclaw/agents/<agentId>/agent/models.json을 통해 커스텀 프로바이더를 추가할 수 있어요.
{ models: { mode: "merge", // merge (기본값) | replace providers: { "custom-proxy": { baseUrl: "http://localhost:4000/v1", apiKey: "LITELLM_KEY", api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai models: [ { id: "llama-3.1-8b", name: "Llama 3.1 8B", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 32000, }, ], }, }, },}- 커스텀 인증이 필요한 경우
authHeader: true와headers를 사용하세요. OPENCLAW_AGENT_DIR(또는PI_CODING_AGENT_DIR) 환경 변수로 에이전트 설정 루트를 변경할 수 있어요.- 프로바이더 ID가 겹칠 때의 병합 우선순위:
- 에이전트
models.json의 비어 있지 않은baseUrl이 우선해요. - 해당 프로바이더가 SecretRef로 관리되지 않는 경우, 에이전트의 비어 있지 않은
apiKey가 우선해요. - SecretRef로 관리되는 프로바이더의
apiKey는 소스 마커(환경 변수는ENV_VAR_NAME, 파일/실행 참조는secretref-managed)에서 새로 고쳐져요. - SecretRef로 관리되는 프로바이더 헤더 값도 소스 마커에서 새로 고쳐져요.
- 에이전트의
apiKey/baseUrl이 비어 있으면 설정 파일의models.providers를 사용해요. - 모델의
contextWindow/maxTokens는 명시적 설정과 카탈로그 값 중 더 큰 값을 사용해요. - 설정을 통해
models.json을 완전히 새로 쓰려면models.mode: "replace"를 사용하세요. - 마커 유지는 소스 권한을 가져요. 마커는 런타임의 비밀값이 아니라 활성 소스 설정 스냅샷(해석 전)에서 작성돼요.
- 에이전트
프로바이더 필드 상세 정보
섹션 제목: “프로바이더 필드 상세 정보”models.mode: 프로바이더 카탈로그 동작 (merge또는replace).models.providers: 프로바이더 ID를 키로 하는 커스텀 프로바이더 맵.models.providers.*.api: 요청 어댑터 (openai-completions,openai-responses,anthropic-messages,google-generative-ai등).models.providers.*.apiKey: 프로바이더 인증 정보 (SecretRef/환경 변수 권장).models.providers.*.auth: 인증 전략 (api-key,token,oauth,aws-sdk).models.providers.*.injectNumCtxForOpenAICompat: Ollama +openai-completions사용 시 요청에options.num_ctx주입 여부 (기본값:true).models.providers.*.authHeader: 필요한 경우Authorization헤더에 인증 정보 강제 포함.models.providers.*.baseUrl: 업스트림 API 베이스 URL.models.providers.*.headers: 프록시/테넌트 라우팅을 위한 추가 정적 헤더.models.providers.*.models: 명시적인 프로바이더 모델 카탈로그 항목.models.providers.*.models.*.compat.supportsDeveloperRole: 선택적 호환성 힌트.api: "openai-completions"이면서baseUrl이 OpenAI 공식 주소가 아니면 OpenClaw는 런타임에 이를false로 강제해요.models.bedrockDiscovery: Bedrock 자동 감지 설정.models.bedrockDiscovery.enabled: 감지 폴링 활성화 여부.models.bedrockDiscovery.region: 감지할 AWS 리전.models.bedrockDiscovery.providerFilter: 특정 프로바이더 ID만 감지하도록 필터링.models.bedrockDiscovery.refreshInterval: 감지 새로고침 간격.models.bedrockDiscovery.defaultContextWindow: 감지된 모델의 기본 컨텍스트 창 크기.models.bedrockDiscovery.defaultMaxTokens: 감지된 모델의 기본 최대 출력 토큰 수.
프로바이더 예시
섹션 제목: “프로바이더 예시”Cerebras (GLM 4.6 / 4.7)
{ env: { CEREBRAS_API_KEY: "sk-..." }, agents: { defaults: { model: { primary: "cerebras/zai-glm-4.7", fallbacks: ["cerebras/zai-glm-4.6"], }, models: { "cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" }, "cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" }, }, }, }, models: { mode: "merge", providers: { cerebras: { baseUrl: "https://api.cerebras.ai/v1", apiKey: "${CEREBRAS_API_KEY}", api: "openai-completions", models: [ { id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" }, { id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" }, ], }, }, },}Cerebras를 사용하려면 cerebras/zai-glm-4.7을, Z.AI 직접 연결은 zai/glm-4.7을 사용하세요.
OpenCode
{ agents: { defaults: { model: { primary: "opencode/claude-opus-4-6" }, models: { "opencode/claude-opus-4-6": { alias: "Opus" } }, }, },}OPENCODE_API_KEY (또는 OPENCODE_ZEN_API_KEY)를 설정하세요. Zen 카탈로그는 opencode/...를, Go 카탈로그는 opencode-go/... 참조를 사용하세요. 단축 명령어: openclaw onboard --auth-choice opencode-zen 또는 openclaw onboard --auth-choice opencode-go.
Z.AI (GLM-4.7)
{ agents: { defaults: { model: { primary: "zai/glm-4.7" }, models: { "zai/glm-4.7": {} }, }, },}ZAI_API_KEY를 설정하세요. z.ai/*와 z-ai/* 모두 허용되는 별칭이에요. 단축 명령어: openclaw onboard --auth-choice zai-api-key.
- 일반 엔드포인트:
https://api.z.ai/api/paas/v4 - 코딩 엔드포인트 (기본값):
https://api.z.ai/api/coding/paas/v4 - 일반 엔드포인트를 쓰려면 베이스 URL을 덮어쓴 커스텀 프로바이더를 정의하세요.
Moonshot AI (Kimi)
{ env: { MOONSHOT_API_KEY: "sk-..." }, agents: { defaults: { model: { primary: "moonshot/kimi-k2.5" }, models: { "moonshot/kimi-k2.5": { alias: "Kimi K2.5" } }, }, }, models: { mode: "merge", providers: { moonshot: { baseUrl: "https://api.moonshot.ai/v1", apiKey: "${MOONSHOT_API_KEY}", api: "openai-completions", models: [ { id: "kimi-k2.5", name: "Kimi K2.5", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 256000, maxTokens: 8192, }, ], }, }, },}중국 엔드포인트의 경우: baseUrl: "https://api.moonshot.cn/v1" 또는 openclaw onboard --auth-choice moonshot-api-key-cn.
Kimi Coding
{ env: { KIMI_API_KEY: "sk-..." }, agents: { defaults: { model: { primary: "kimi-coding/k2p5" }, models: { "kimi-coding/k2p5": { alias: "Kimi K2.5" } }, }, },}Anthropic 호환 내장 프로바이더예요. 단축 명령어: openclaw onboard --auth-choice kimi-code-api-key.
Synthetic (Anthropic 호환)
{ env: { SYNTHETIC_API_KEY: "sk-..." }, agents: { defaults: { model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" }, models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } }, }, }, models: { mode: "merge", providers: { synthetic: { baseUrl: "https://api.synthetic.new/anthropic", apiKey: "${SYNTHETIC_API_KEY}", api: "anthropic-messages", models: [ { id: "hf:MiniMaxAI/MiniMax-M2.5", name: "MiniMax M2.5", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 192000, maxTokens: 65536, }, ], }, }, },}베이스 URL에서 /v1은 제외해야 해요 (Anthropic 클라이언트가 자동으로 붙여요). 단축 명령어: openclaw onboard --auth-choice synthetic-api-key.
MiniMax M2.5 (직접 연결)
{ agents: { defaults: { model: { primary: "minimax/MiniMax-M2.5" }, models: { "minimax/MiniMax-M2.5": { alias: "Minimax" }, }, }, }, models: { mode: "merge", providers: { minimax: { baseUrl: "https://api.minimax.io/anthropic", apiKey: "${MINIMAX_API_KEY}", api: "anthropic-messages", models: [ { id: "MiniMax-M2.5", name: "MiniMax M2.5", reasoning: false, input: ["text"], cost: { input: 15, output: 60, cacheRead: 2, cacheWrite: 10 }, contextWindow: 200000, maxTokens: 8192, }, ], }, }, },}MINIMAX_API_KEY를 설정하세요. 단축 명령어: openclaw onboard --auth-choice minimax-api.
로컬 모델 (LM Studio)
로컬 모델 문서를 참고하세요. 요약하자면, 고성능 하드웨어에서 LM Studio Responses API를 통해 MiniMax M2.5를 실행하고, 실패 시를 대비해 호스팅 모델을 병합해 두는 것이 좋아요.
스킬 (Skills)
섹션 제목: “스킬 (Skills)”{ skills: { allowBundled: ["gemini", "peekaboo"], load: { extraDirs: ["~/Projects/agent-scripts/skills"], }, install: { preferBrew: true, nodeManager: "npm", // npm | pnpm | yarn }, entries: { "nano-banana-pro": { apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" }, }, peekaboo: { enabled: true }, sag: { enabled: false }, }, },}allowBundled: 번들된 스킬에 대해서만 적용되는 선택적 허용 목록이에요 (관리형/워크스페이스 스킬은 영향을 받지 않아요).entries.<skillKey>.enabled: false: 스킬이 번들되어 있거나 설치되어 있더라도 비활성화할 수 있어요.entries.<skillKey>.apiKey: 주요 환경 변수를 선언하는 스킬을 위한 편의 필드예요 (일반 텍스트 문자열이나 SecretRef 객체를 사용할 수 있어요).
플러그인 (Plugins)
섹션 제목: “플러그인 (Plugins)”{ plugins: { enabled: true, allow: ["voice-call"], deny: [], load: { paths: ["~/Projects/oss/voice-call-extension"], }, entries: { "voice-call": { enabled: true, hooks: { allowPromptInjection: false, }, config: { provider: "twilio" }, }, }, },}~/.openclaw/extensions,<workspace>/.openclaw/extensions, 그리고plugins.load.paths에서 플러그인을 로드해요.- 설정 변경 사항을 적용하려면 Gateway를 다시 시작해야 해요.
allow: 선택적 허용 목록이에요 (목록에 있는 플러그인만 로드돼요).deny설정이 있는 경우 이 설정이 우선해요.plugins.entries.<id>.apiKey: 플러그인 수준에서 사용할 수 있는 API Key 편의 필드예요 (플러그인이 이를 지원하는 경우).plugins.entries.<id>.env: 플러그인 범위의 환경 변수 맵이에요.plugins.entries.<id>.hooks.allowPromptInjection: 이 값이false이면 코어에서before_prompt_build를 차단하고, 레거시before_agent_start에서 전달되는 프롬프트 변조 필드를 무시해요. 이때 레거시modelOverride와providerOverride는 그대로 유지돼요.plugins.entries.<id>.config: 플러그인에서 정의한 설정 객체예요 (플러그인 스키마에 의해 검증돼요).plugins.slots.memory: 활성화할 메모리 플러그인 ID를 선택하세요. 메모리 플러그인을 사용하지 않으려면"none"으로 설정하면 돼요.plugins.slots.contextEngine: 활성화할 컨텍스트 엔진 플러그인 ID를 선택하세요. 별도로 설치하고 선택하지 않으면 기본값은"legacy"로 설정돼요.plugins.installs:openclaw plugins update명령어가 사용하는 CLI 관리 설치 메타데이터예요.source,spec,sourcePath,installPath,version,resolvedName,resolvedVersion,resolvedSpec,integrity,shasum,resolvedAt,installedAt정보를 포함하고 있어요.plugins.installs.*영역은 관리되는 상태이므로 직접 수정하기보다는 CLI 명령어를 사용하는 것을 추천해요.
Plugins 문서를 확인해 보세요.
브라우저 (Browser)
섹션 제목: “브라우저 (Browser)”{ browser: { enabled: true, evaluateEnabled: true, defaultProfile: "chrome", ssrfPolicy: { dangerouslyAllowPrivateNetwork: true, // default trusted-network mode // allowPrivateNetwork: true, // legacy alias // hostnameAllowlist: ["*.example.com", "example.com"], // allowedHostnames: ["localhost"], }, profiles: { openclaw: { cdpPort: 18800, color: "#FF4500" }, work: { cdpPort: 18801, color: "#0066CC" }, remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" }, }, color: "#FF4500", // headless: false, // noSandbox: false, // extraArgs: [], // relayBindHost: "0.0.0.0", // only when the extension relay must be reachable across namespaces (for example WSL2) // executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser", // attachOnly: false, },}evaluateEnabled: false로 설정하면act:evaluate와wait --fn기능을 사용할 수 없어요.ssrfPolicy.dangerouslyAllowPrivateNetwork는 설정하지 않았을 때 기본값이true예요 (신뢰할 수 있는 네트워크 모델).- 엄격한 공용 네트워크 전용 브라우징이 필요하다면
ssrfPolicy.dangerouslyAllowPrivateNetwork: false로 설정하세요. ssrfPolicy.allowPrivateNetwork는 레거시 별칭으로 계속 지원돼요.- 엄격 모드에서는
ssrfPolicy.hostnameAllowlist와ssrfPolicy.allowedHostnames를 사용해 명시적으로 예외 대상을 지정할 수 있어요. - 원격 프로필은 attach-only 모드로 동작해요 (시작/중지/재설정 기능 비활성화).
- 자동 감지 순서: Chromium 기반 기본 브라우저 → Chrome → Brave → Edge → Chromium → Chrome Canary 순서로 감지해요.
- 제어 서비스: 루프백 전용이에요 (포트는
gateway.port에서 파생되며 기본값은18791이에요). extraArgs를 통해 로컬 Chromium 시작 시 추가적인 실행 플래그를 덧붙일 수 있어요 (예:--disable-gpu, 창 크기 지정, 디버그 플래그 등).relayBindHost는 Chrome 확장 프로그램 릴레이가 대기하는 주소를 변경해요. 루프백 전용 접근을 원한다면 비워두세요. WSL2와 같이 네임스페이스 경계를 넘어야 하고 호스트 네트워크를 이미 신뢰할 수 있는 경우에만0.0.0.0같은 명시적인 비-루프백 바인드 주소를 설정하세요.
{ ui: { seamColor: "#FF4500", assistant: { name: "OpenClaw", avatar: "CB", // emoji, short text, image URL, or data URI }, },}seamColor: 네이티브 앱 UI 크롬의 강조 색상이에요 (Talk Mode 버블 색상 등).assistant: UI 정체성 오버라이드를 제어해요. 설정하지 않으면 활성화된 에이전트의 정체성을 기본으로 사용해요.
게이트웨이 (Gateway)
섹션 제목: “게이트웨이 (Gateway)”{ gateway: { mode: "local", // local | remote port: 18789, bind: "loopback", auth: { mode: "token", // none | token | password | trusted-proxy token: "your-token", // password: "your-password", // or OPENCLAW_GATEWAY_PASSWORD // trustedProxy: { userHeader: "x-forwarded-user" }, // for mode=trusted-proxy; see /gateway/trusted-proxy-auth allowTailscale: true, rateLimit: { maxAttempts: 10, windowMs: 60000, lockoutMs: 300000, exemptLoopback: true, }, }, tailscale: { mode: "off", // off | serve | funnel resetOnExit: false, }, controlUi: { enabled: true, basePath: "/openclaw", // root: "dist/control-ui", // allowedOrigins: ["https://control.example.com"], // required for non-loopback Control UI // dangerouslyAllowHostHeaderOriginFallback: false, // dangerous Host-header origin fallback mode // allowInsecureAuth: false, // dangerouslyDisableDeviceAuth: false, }, remote: { url: "ws://gateway.tailnet:18789", transport: "ssh", // ssh | direct token: "your-token", // password: "your-password", }, trustedProxies: ["10.0.0.1"], // Optional. Default false. allowRealIpFallback: false, tools: { // Additional /tools/invoke HTTP denies deny: ["browser"], // Remove tools from the default HTTP deny list allow: ["gateway"], }, },}Gateway 필드 상세 정보
mode:local(Gateway 실행) 또는remote(원격 Gateway 연결)를 설정해요.local이 아니면 Gateway가 시작되지 않아요.port: WS와 HTTP를 위한 단일 멀티플렉싱 포트예요. 우선순위는--port>OPENCLAW_GATEWAY_PORT>gateway.port>18789순서예요.bind:auto,loopback(기본값),lan(0.0.0.0),tailnet(Tailscale IP 전용), 또는custom을 사용할 수 있어요.- 레거시 bind 별칭:
gateway.bind에는 호스트 별칭(0.0.0.0,127.0.0.1,localhost,::,::1) 대신 bind 모드 값(auto,loopback,lan,tailnet,custom)을 사용해 주세요. - Docker 참고: 기본값인
loopback은 컨테이너 내부의127.0.0.1에서 리스닝해요. Docker 브리지 네트워킹(-p 18789:18789)을 사용하면 트래픽이eth0으로 들어오기 때문에 Gateway에 접속할 수 없어요.--network host를 사용하거나, 모든 인터페이스에서 리스닝하도록bind: "lan"(또는bind: "custom"과customBindHost: "0.0.0.0")으로 설정하세요. - Auth: 기본적으로 인증이 필요해요. loopback이 아닌 bind의 경우 공유 token/password가 있어야 해요. 온보딩 마법사가 기본적으로 토큰을 생성해 줘요.
gateway.auth.token과gateway.auth.password가 모두 설정된 경우(SecretRefs 포함),gateway.auth.mode를token이나password로 명확히 지정해야 해요. 둘 다 설정되어 있는데 모드가 지정되지 않으면 시작이나 서비스 설치/복구 프로세스가 실패해요.gateway.auth.mode: "none": 인증을 사용하지 않는 모드예요. 신뢰할 수 있는 로컬 loopback 환경에서만 사용하세요. 온보딩 프롬프트에서는 이 옵션을 제공하지 않아요.gateway.auth.mode: "trusted-proxy": 인증을 ID 인식 리버스 프록시에 위임하고,gateway.trustedProxies에서 오는 ID 헤더를 신뢰해요 (Trusted Proxy Auth 참고).gateway.auth.allowTailscale:true로 설정하면 Tailscale Serve ID 헤더로 Control UI/WebSocket 인증을 통과할 수 있어요 (tailscale whois로 확인). 하지만 HTTP API 엔드포인트는 여전히 token/password 인증이 필요해요. 이 토큰 없는 흐름은 Gateway 호스트를 신뢰할 수 있다고 가정해요.tailscale.mode = "serve"일 때 기본값은true예요.gateway.auth.rateLimit: 선택 사항인 인증 실패 제한 기능이에요. 클라이언트 IP와 인증 범위(공유 비밀키와 디바이스 토큰은 독립적으로 추적됨)별로 적용돼요. 차단된 시도는429에러와Retry-After를 반환해요.gateway.auth.rateLimit.exemptLoopback은 기본값이true예요. 테스트 환경이나 엄격한 프록시 배포를 위해 localhost 트래픽도 제한하고 싶다면false로 설정하세요.
- 브라우저 기반의 WS 인증 시도는 loopback 예외 없이 항상 제한돼요 (브라우저를 통한 localhost 무차별 대입 공격 방어).
tailscale.mode:serve(tailnet 전용, loopback bind) 또는funnel(공개, 인증 필요) 중 선택해요.controlUi.allowedOrigins: Gateway WebSocket 연결을 위한 브라우저 오리진 허용 목록이에요. 브라우저 클라이언트가 loopback이 아닌 오리진에서 접속할 때 필요해요.controlUi.dangerouslyAllowHostHeaderOriginFallback: Host 헤더 오리진 정책에 의도적으로 의존하는 배포를 위한 위험한 모드예요. Host 헤더 오리진 폴백을 활성화해요.remote.transport:ssh(기본값) 또는direct(ws/wss)를 선택해요.direct의 경우remote.url은 반드시ws://나wss://여야 해요.OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1: 신뢰할 수 있는 사설 네트워크 IP에 대해 일반 텍스트ws://연결을 허용하는 클라이언트 측 강제 오버라이드 설정이에요. 기본적으로 일반 텍스트는 loopback만 허용돼요.gateway.remote.token/.password는 원격 클라이언트의 자격 증명 필드예요. 이것만으로는 Gateway 인증이 구성되지 않아요.- 로컬 Gateway 호출 경로는
gateway.auth.*가 설정되지 않았을 때만gateway.remote.*를 폴백으로 사용할 수 있어요. gateway.auth.token/gateway.auth.password가 SecretRef를 통해 명시적으로 설정되었지만 해결되지 않은 경우, 보안을 위해 원격 폴백 없이 실패 처리돼요.trustedProxies: TLS를 종료하는 리버스 프록시 IP 목록이에요. 직접 제어하는 프록시만 등록하세요.allowRealIpFallback:true인 경우,X-Forwarded-For가 없으면 Gateway가X-Real-IP를 수락해요. 기본값은 안전을 위해false예요.gateway.tools.deny: HTTPPOST /tools/invoke에서 차단할 추가 도구 이름 목록이에요 (기본 차단 목록에 추가됨).gateway.tools.allow: 기본 HTTP 차단 목록에서 제거할 도구 이름 목록이에요.
OpenAI 호환 엔드포인트
섹션 제목: “OpenAI 호환 엔드포인트”- Chat Completions: 기본적으로 비활성화되어 있어요.
gateway.http.endpoints.chatCompletions.enabled: true로 활성화할 수 있어요. - Responses API:
gateway.http.endpoints.responses.enabled로 설정해요. - Responses URL 입력 강화 설정:
gateway.http.endpoints.responses.maxUrlPartsgateway.http.endpoints.responses.files.urlAllowlistgateway.http.endpoints.responses.images.urlAllowlist
- 선택 사항인 응답 보안 헤더:
gateway.http.securityHeaders.strictTransportSecurity(직접 제어하는 HTTPS 오리진에만 설정하세요. Trusted Proxy Auth 참고)
멀티 인스턴스 격리
섹션 제목: “멀티 인스턴스 격리”고유한 포트와 상태 디렉토리를 사용하여 한 호스트에서 여러 Gateway를 실행할 수 있어요.
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \OPENCLAW_STATE_DIR=~/.openclaw-a \openclaw gateway --port 19001편의를 위한 플래그: --dev (~/.openclaw-dev와 포트 19001 사용), --profile <name> (~/.openclaw-<name> 사용).
자세한 내용은 Multiple Gateways를 확인해 보세요.
훅 (Hooks)
섹션 제목: “훅 (Hooks)”{ hooks: { enabled: true, token: "shared-secret", path: "/hooks", maxBodyBytes: 262144, defaultSessionKey: "hook:ingress", allowRequestSessionKey: false, allowedSessionKeyPrefixes: ["hook:"], allowedAgentIds: ["hooks", "main"], presets: ["gmail"], transformsDir: "~/.openclaw/hooks/transforms", mappings: [ { match: { path: "gmail" }, action: "agent", agentId: "hooks", wakeMode: "now", name: "Gmail", sessionKey: "hook:gmail:{{messages[0].id}}", messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}", deliver: true, channel: "last", model: "openai/gpt-5.2-mini", }, ], },}인증 방법: Authorization: Bearer <token> 또는 x-openclaw-token: <token>.
엔드포인트:
POST /hooks/wake→{ text, mode?: "now"|"next-heartbeat" }POST /hooks/agent→{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }- 요청 페이로드의
sessionKey는hooks.allowRequestSessionKey=true일 때만 수락돼요 (기본값:false).
- 요청 페이로드의
POST /hooks/<name>→hooks.mappings를 통해 해결돼요.
매핑 상세 정보
match.path:/hooks이후의 하위 경로와 매칭돼요 (예:/hooks/gmail→gmail).match.source: 일반 경로에 대해 페이로드 필드와 매칭돼요.{{messages[0].subject}}와 같은 템플릿은 페이로드에서 데이터를 읽어와요.transform: 훅 액션을 반환하는 JS/TS 모듈을 가리킬 수 있어요.transform.module은 반드시 상대 경로여야 하며hooks.transformsDir내부에 있어야 해요 (절대 경로 및 상위 디렉토리 접근은 거부됨).
agentId: 특정 에이전트로 라우팅해요. 알 수 없는 ID는 기본값으로 폴백돼요.allowedAgentIds: 명시적 라우팅을 제한해요 (*또는 생략 시 모두 허용,[]시 모두 거부).defaultSessionKey: 명시적인sessionKey없이 실행되는 훅 에이전트를 위한 선택 사항인 고정 세션 키예요.allowRequestSessionKey:/hooks/agent호출자가sessionKey를 설정할 수 있게 허용해요 (기본값:false).allowedSessionKeyPrefixes: 명시적sessionKey값(요청 + 매핑)에 대한 선택 사항인 접두사 허용 목록이에요 (예:["hook:"]).deliver: true: 최종 응답을 채널로 전송해요.channel기본값은last예요.model: 이 훅 실행에 대해 LLM을 오버라이드해요 (모델 카탈로그가 설정된 경우 허용된 모델이어야 함).
Gmail 연동
섹션 제목: “Gmail 연동”{ hooks: { gmail: { account: "openclaw@gmail.com", topic: "projects/<project-id>/topics/gog-gmail-watch", subscription: "gog-gmail-watch-push", pushToken: "shared-push-token", hookUrl: "http://127.0.0.1:18789/hooks/gmail", includeBody: true, maxBytes: 20000, renewEveryMinutes: 720, serve: { bind: "127.0.0.1", port: 8788, path: "/" }, tailscale: { mode: "funnel", path: "/gmail-pubsub" }, model: "openrouter/meta-llama/llama-3.3-70b-instruct:free", thinking: "off", }, },}- 설정이 완료되면 Gateway 부팅 시
gog gmail watch serve가 자동으로 시작돼요. 비활성화하려면OPENCLAW_SKIP_GMAIL_WATCHER=1을 설정하세요. - Gateway와 별도로
gog gmail watch serve를 실행하지 마세요.
캔버스 호스트 (Canvas host)
섹션 제목: “캔버스 호스트 (Canvas host)”{ canvasHost: { root: "~/.openclaw/workspace/canvas", liveReload: true, // enabled: false, // or OPENCLAW_SKIP_CANVAS_HOST=1 },}- 에이전트가 편집 가능한 HTML/CSS/JS 및 A2UI를 Gateway 포트의 HTTP를 통해 제공해요.
http://<gateway-host>:<gateway.port>/__openclaw__/canvas/http://<gateway-host>:<gateway.port>/__openclaw__/a2ui/
- 로컬 전용:
gateway.bind: "loopback"(기본값)을 유지하세요. - loopback이 아닌 bind: 캔버스 경로는 다른 Gateway HTTP 서비스와 마찬가지로 Gateway 인증(token/password/trusted-proxy)이 필요해요.
- Node WebViews는 보통 인증 헤더를 보내지 않아요. 노드가 페어링되고 연결된 후, Gateway는 캔버스/A2UI 접근을 위한 노드 범위의 기능(capability) URL을 광고해요.
- 기능 URL은 활성 노드 WS 세션에 바인딩되며 빠르게 만료돼요. IP 기반 폴백은 사용되지 않아요.
- 제공되는 HTML에 live-reload 클라이언트를 삽입해요.
- 디렉토리가 비어 있으면 시작용
index.html을 자동으로 생성해요. /__openclaw__/a2ui/에서 A2UI도 함께 제공해요.- 변경 사항을 적용하려면 Gateway를 재시작해야 해요.
- 디렉토리가 너무 크거나
EMFILE에러가 발생하면 live reload를 비활성화하세요.
디스커버리 (Discovery)
섹션 제목: “디스커버리 (Discovery)”mDNS (Bonjour)
섹션 제목: “mDNS (Bonjour)”{ discovery: { mdns: { mode: "minimal", // minimal | full | off }, },}minimal(기본값): TXT 레코드에서cliPath와sshPort를 제외해요.full:cliPath와sshPort를 포함해요.- 호스트네임 기본값은
openclaw예요.OPENCLAW_MDNS_HOSTNAME으로 변경할 수 있어요.
광역 네트워크 (DNS-SD)
섹션 제목: “광역 네트워크 (DNS-SD)”{ discovery: { wideArea: { enabled: true }, },}~/.openclaw/dns/ 아래에 유니캐스트 DNS-SD 존을 작성해요. 네트워크 간 디스커버리를 위해 DNS 서버(CoreDNS 권장) 및 Tailscale split DNS와 함께 사용하세요.
설정 방법: openclaw dns setup --apply.
환경 설정 (Environment)
섹션 제목: “환경 설정 (Environment)”env (인라인 환경 변수)
섹션 제목: “env (인라인 환경 변수)”{ env: { OPENROUTER_API_KEY: "sk-or-...", vars: { GROQ_API_KEY: "gsk-...", }, shellEnv: { enabled: true, timeoutMs: 15000, }, },}- 인라인 환경 변수는 프로세스 환경에 해당 키가 없을 때만 적용돼요.
.env파일: 현재 작업 디렉토리(CWD)의.env와~/.openclaw/.env를 불러오며, 두 파일 모두 기존 변수를 덮어쓰지 않아요.shellEnv: 로그인 쉘 프로필에서 누락된 예상 키들을 가져와요.- 전체 우선순위는 Environment 문서에서 확인할 수 있어요.
환경 변수 치환 (Env var substitution)
섹션 제목: “환경 변수 치환 (Env var substitution)”설정 문자열 어디서든 ${VAR_NAME} 형식을 사용해 환경 변수를 참조할 수 있어요.
{ gateway: { auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" }, },}[A-Z_][A-Z0-9_]*패턴과 일치하는 대문자 이름만 매칭돼요.- 변수가 없거나 비어 있으면 설정 로드 시 에러가 발생해요.
- 문자 그대로의
${VAR}를 표현하고 싶다면$${VAR}로 이스케이프 하세요. $include와 함께 사용할 수 있어요.
시크릿 (Secrets)
섹션 제목: “시크릿 (Secrets)”시크릿 참조는 추가적인 방식이며, 일반 텍스트 값도 여전히 사용할 수 있어요.
SecretRef
섹션 제목: “SecretRef”다음과 같은 객체 형태를 사용해요.
{ source: "env" | "file" | "exec", provider: "default", id: "..." }유효성 검사 규칙은 다음과 같아요.
provider패턴:^[a-z][a-z0-9_-]{0,63}$source: "env"id 패턴:^[A-Z][A-Z0-9_]{0,127}$source: "file"id: 절대 경로 JSON 포인터 (예:"/providers/openai/apiKey")source: "exec"id 패턴:^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$source: "exec"id에는.또는..과 같이 슬래시로 구분된 경로 세그먼트가 포함될 수 없어요 (예:a/../b는 거부돼요).
지원되는 자격 증명 범위 (Supported credential surface)
섹션 제목: “지원되는 자격 증명 범위 (Supported credential surface)”- 표준 매트릭스: SecretRef Credential Surface
secrets apply는 지원되는openclaw.json자격 증명 경로를 대상으로 해요.auth-profiles.json참조는 런타임 확인 및 감사 범위에 포함돼요.
시크릿 프로바이더 설정 (Secret providers config)
섹션 제목: “시크릿 프로바이더 설정 (Secret providers config)”{ secrets: { providers: { default: { source: "env" }, // 선택 사항인 명시적 env 프로바이더 filemain: { source: "file", path: "~/.openclaw/secrets.json", mode: "json", timeoutMs: 5000, }, vault: { source: "exec", command: "/usr/local/bin/openclaw-vault-resolver", passEnv: ["PATH", "VAULT_ADDR"], }, }, defaults: { env: "default", file: "filemain", exec: "vault", }, },}참고 사항:
file프로바이더는mode: "json"과mode: "singleValue"를 지원해요 (singleValue모드에서id는 반드시"value"여야 해요).exec프로바이더는 절대 경로로 된command가 필요하며, stdin/stdout을 통한 프로토콜 페이로드를 사용해요.- 기본적으로 심볼릭 링크로 된 커맨드 경로는 거부돼요.
allowSymlinkCommand: true를 설정하면 심볼릭 링크를 허용하면서 최종 타겟 경로를 검증할 수 있어요. trustedDirs가 설정된 경우, 신뢰할 수 있는 디렉토리 체크가 최종 타겟 경로에 적용돼요.exec자식 프로세스 환경은 기본적으로 최소화되어 있어요. 필요한 변수는passEnv를 통해 명시적으로 전달해 주세요.- 시크릿 참조는 활성화 시점에 메모리 내 스냅샷으로 확인(resolve)되며, 이후 요청 경로는 이 스냅샷만 읽게 돼요.
- 활성화 중에 활성 범위 필터링이 적용돼요. 활성화된 범위에서 확인되지 않은 참조가 있으면 시작 또는 재로드가 실패하며, 비활성 범위는 진단 정보와 함께 건너뛰게 돼요.
인증 저장소 (Auth storage)
섹션 제목: “인증 저장소 (Auth storage)”{ auth: { profiles: { "anthropic:me@example.com": { provider: "anthropic", mode: "oauth", email: "me@example.com" }, "anthropic:work": { provider: "anthropic", mode: "api_key" }, }, order: { anthropic: ["anthropic:me@example.com", "anthropic:work"], }, },}- 에이전트별 프로필은
<agentDir>/auth-profiles.json에 저장돼요. auth-profiles.json은 값 수준의 참조(value-level refs)를 지원해요 (api_key를 위한keyRef,token을 위한tokenRef).- 정적 런타임 자격 증명은 메모리 내에서 해결된 스냅샷에서 가져오며, 기존의 레거시 정적
auth.json항목은 발견 시 삭제돼요. - 레거시 OAuth 임포트는
~/.openclaw/credentials/oauth.json에서 이루어져요. - OAuth 문서를 참고해 주세요.
- Secrets 런타임 동작과
audit/configure/apply도구에 대해서는 Secrets Management에서 확인할 수 있어요.
로깅 (Logging)
섹션 제목: “로깅 (Logging)”{ logging: { level: "info", file: "/tmp/openclaw/openclaw.log", consoleLevel: "info", consoleStyle: "pretty", // pretty | compact | json redactSensitive: "tools", // off | tools redactPatterns: ["\\bTOKEN\\b\\s*[=:]\\s*([\"']?)([^\\s\"']+)\\1"], },}- 기본 로그 파일 경로는
/tmp/openclaw/openclaw-YYYY-MM-DD.log예요. - 고정된 경로를 사용하려면
logging.file을 설정하세요. --verbose플래그를 사용하면consoleLevel이debug로 올라가요.
CLI
섹션 제목: “CLI”{ cli: { banner: { taglineMode: "off", // random | default | off }, },}cli.banner.taglineMode 설정을 통해 배너의 태그라인 스타일을 관리할 수 있어요.
"random"(기본값): 재미있거나 시즌에 어울리는 태그라인이 무작위로 돌아가며 나타나요."default": 고정된 중립적인 태그라인(All your chats, one OpenClaw.)이 표시돼요."off": 태그라인 텍스트가 나오지 않아요 (배너 제목과 버전은 여전히 표시돼요).
태그라인뿐만 아니라 배너 전체를 숨기고 싶다면, 환경 변수 OPENCLAW_HIDE_BANNER=1을 설정해 주세요.
Wizard
섹션 제목: “Wizard”onboard, configure, doctor와 같은 CLI Wizard가 작성하는 메타데이터예요.
{ wizard: { lastRunAt: "2026-01-01T00:00:00.000Z", lastRunVersion: "2026.1.4", lastRunCommit: "abc1234", lastRunCommand: "configure", lastRunMode: "local", },}아이덴티티
섹션 제목: “아이덴티티”{ agents: { list: [ { id: "main", identity: { name: "Samantha", theme: "helpful sloth", emoji: "🦥", avatar: "avatars/samantha.png", }, }, ], },}이 설정은 macOS onboarding assistant가 작성해요. 다음과 같은 기본값들을 자동으로 가져오죠:
identity.emoji를 기반으로messages.ackReaction을 설정해요 (값이 없으면 👀를 사용해요).identity.name이나identity.emoji를 사용해mentionPatterns를 생성해요.avatar항목에는 워크스페이스 상대 경로,http(s)URL, 또는data:URI를 사용할 수 있어요.
브릿지 (레거시, 삭제됨)
섹션 제목: “브릿지 (레거시, 삭제됨)”최신 빌드에는 더 이상 TCP bridge가 포함되지 않아요. 이제 Node는 Gateway WebSocket을 통해 연결되거든요. bridge.* 키는 더 이상 설정 스키마의 일부가 아니에요. 이 키들을 제거하기 전까지는 유효성 검사에 실패하게 되는데, openclaw doctor --fix를 사용하면 알 수 없는 키들을 자동으로 제거할 수 있어요.
Legacy bridge config (historical reference)
{ "bridge": { "enabled": true, "port": 18790, "bind": "tailnet", "tls": { "enabled": true, "autoGenerate": true } }}Cron
섹션 제목: “Cron”{ cron: { enabled: true, maxConcurrentRuns: 2, webhook: "https://example.invalid/legacy", // deprecated fallback for stored notify:true jobs webhookToken: "replace-with-dedicated-token", // optional bearer token for outbound webhook auth sessionRetention: "24h", // duration string or false runLog: { maxBytes: "2mb", // default 2_000_000 bytes keepLines: 2000, // default 2000 }, },}sessionRetention: 완료된 개별 Cron 실행 세션을sessions.json에서 삭제하기 전까지 보관하는 기간이에요. 보관 기간이 지난 삭제된 Cron 기록의 정리 작업도 함께 제어해요. 기본값은24h이며, 기능을 끄려면false로 설정하세요.runLog.maxBytes: 실행 로그 파일(cron/runs/<jobId>.jsonl)이 정리되기 전까지의 최대 크기예요. 기본값은2,000,000바이트예요.runLog.keepLines: 로그 정리가 시작될 때 유지할 최신 줄 수예요. 기본값은2000줄이에요.webhookToken: Cron Webhook POST 전송(delivery.mode = "webhook") 시 사용하는 Bearer 토큰이에요. 이 설정을 생략하면 인증 헤더를 보내지 않아요.webhook: 더 이상 권장되지 않는(deprecated) 레거시 Webhook URL(http/https)이에요. 여전히notify: true설정이 남아 있는 저장된 작업에만 사용돼요.
Cron Jobs 문서도 함께 확인해 보세요.
Media 모델 템플릿 변수
섹션 제목: “Media 모델 템플릿 변수”tools.media.models[].args에서 사용할 수 있는 템플릿 변수들이에요.
| 변수 | 설명 |
|---|---|
{{Body}} | 수신된 메시지 본문 전체 |
{{RawBody}} | 원본 본문 (히스토리나 발신자 정보 제외) |
{{BodyStripped}} | 그룹 멘션이 제거된 본문 |
{{From}} | 발신자 식별자 |
{{To}} | 수신처 식별자 |
{{MessageSid}} | 채널 메시지 ID |
{{SessionId}} | 현재 세션 UUID |
{{IsNewSession}} | 새 세션이 생성되었을 때 "true" |
{{MediaUrl}} | 수신 미디어 가상 URL |
{{MediaPath}} | 로컬 미디어 경로 |
{{MediaType}} | 미디어 타입 (image/audio/document 등) |
{{Transcript}} | 오디오 텍스트 변환 결과 |
{{Prompt}} | CLI 항목에 대해 확인된 미디어 프롬프트 |
{{MaxChars}} | CLI 항목에 대해 확인된 최대 출력 글자 수 |
{{ChatType}} | "direct" 또는 "group" |
{{GroupSubject}} | 그룹 주제 (최대한 확인된 정보) |
{{GroupMembers}} | 그룹 멤버 미리보기 (최대한 확인된 정보) |
{{SenderName}} | 발신자 표시 이름 (최대한 확인된 정보) |
{{SenderE164}} | 발신자 전화번호 (최대한 확인된 정보) |
{{Provider}} | 공급자 힌트 (whatsapp, telegram, discord 등) |
설정 포함하기 ($include)
섹션 제목: “설정 포함하기 ($include)”설정 파일을 여러 개로 나누어 관리할 수 있어요.
{ gateway: { port: 18789 }, agents: { $include: "./agents.json5" }, broadcast: { $include: ["./clients/mueller.json5", "./clients/schmidt.json5"], },}병합 동작 방식:
- 단일 파일: 해당 객체를 통째로 대체해요.
- 파일 배열: 순서대로 Deep-merge 되며, 나중에 나오는 파일이 이전 파일의 설정을 덮어써요.
- 형제 키(Sibling keys): include가 처리된 후 병합되며, 포함된 값을 덮어써요.
- 중첩 include: 최대 10단계 깊이까지 사용할 수 있어요.
- 경로: include를 사용하는 파일을 기준으로 상대 경로를 계산해요. 단, 반드시 최상위 설정 디렉토리(
openclaw.json이 있는 위치) 내에 있어야 해요. 절대 경로 나../형식은 이 경계 안에서 해석될 때만 허용돼요. - 에러: 파일 누락, 파싱 에러, 순환 참조가 발생하면 명확한 에러 메시지를 보여줘요.
관련 문서: Configuration · Configuration Examples · Doctor
{ agents: { list: [ { id: "home", default: true, workspace: "~/.openclaw/workspace-home" }, { id: "work", workspace: "~/.openclaw/workspace-work" }, ], }, bindings: [ { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } }, { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } }, ],}{ agents: { list: [ { id: "personal", workspace: "~/.openclaw/workspace-personal", sandbox: { mode: "off" }, }, ], },}{ agents: { list: [ { id: "family", workspace: "~/.openclaw/workspace-family", sandbox: { mode: "all", scope: "agent", workspaceAccess: "ro" }, tools: { allow: [ "read", "sessions_list", "sessions_history", "sessions_send", "sessions_spawn", "session_status", ], deny: ["write", "edit", "apply_patch", "exec", "process", "browser"], }, }, ], },}{ agents: { list: [ { id: "public", workspace: "~/.openclaw/workspace-public", sandbox: { mode: "all", scope: "agent", workspaceAccess: "none" }, tools: { allow: [ "sessions_list", "sessions_history", "sessions_send", "sessions_spawn", "session_status", "whatsapp", "telegram", "slack", "discord", "gateway", ], deny: [ "read", "write", "edit", "apply_patch", "exec", "process", "browser", "canvas", "nodes", "cron", "gateway", "image", ], }, }, ], },}{ session: { scope: "per-sender", dmScope: "main", // main | per-peer | per-channel-peer | per-account-channel-peer identityLinks: { alice: ["telegram:123456789", "discord:987654321012345678"], }, reset: { mode: "daily", // daily | idle atHour: 4, idleMinutes: 60, }, resetByType: { thread: { mode: "daily", atHour: 4 }, direct: { mode: "idle", idleMinutes: 240 }, group: { mode: "idle", idleMinutes: 120 }, }, resetTriggers: ["/new", "/reset"], store: "~/.openclaw/agents/{agentId}/sessions/sessions.json", parentForkMaxTokens: 100000, // skip parent-thread fork above this token count (0 disables) maintenance: { mode: "warn", // warn | enforce pruneAfter: "30d", maxEntries: 500, rotateBytes: "10mb", resetArchiveRetention: "30d", // duration or false maxDiskBytes: "500mb", // optional hard budget highWaterBytes: "400mb", // optional cleanup target }, threadBindings: { enabled: true, idleHours: 24, // default inactivity auto-unfocus in hours (`0` disables) maxAgeHours: 0, // default hard max age in hours (`0` disables) }, mainKey: "main", // legacy (runtime always uses "main") agentToAgent: { maxPingPongTurns: 5 }, sendPolicy: { rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }], default: "allow", }, },}{ messages: { responsePrefix: "🦞", // or "auto" ackReaction: "👀", ackReactionScope: "group-mentions", // group-mentions | group-all | direct | all removeAckAfterReply: false, queue: { mode: "collect", // steer | followup | collect | steer-backlog | steer+backlog | queue | interrupt debounceMs: 1000, cap: 20, drop: "summarize", // old | new | summarize byChannel: { whatsapp: "collect", telegram: "collect", }, }, inbound: { debounceMs: 2000, // 0 disables byChannel: { whatsapp: 5000, slack: 1500, }, }, },}OpenClaw Expert
아직 막혀 있나요?
이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.