Gateway
설정 예시
아래 예시는 현재 구성 스키마에 맞춰져 있습니다. 전체 참조와 필드별 참고 사항은 구성을 참조하세요.
빠른 시작
절대 최소 구성
{ agents: { defaults: { workspace: "~/.openclaw/workspace" } }, channels: { whatsapp: { allowFrom: ["+15555550123"] } },}~/.openclaw/openclaw.json에 저장하면 해당 번호에서 봇에게 다이렉트 메시지를 보낼 수 있습니다.
권장 시작 구성
{ agents: { defaults: { workspace: "~/.openclaw/workspace", model: { primary: "anthropic/claude-sonnet-4-6" }, }, list: [ { id: "main", identity: { name: "Clawd", theme: "helpful assistant", emoji: "🦞", }, }, ], }, channels: { whatsapp: { allowFrom: ["+15555550123"], groups: { "*": { requireMention: true } }, }, }, messages: { visibleReplies: "automatic", groupChat: { visibleReplies: "message_tool", // default; use "automatic" for legacy room replies }, },}확장 예시(주요 옵션)
JSON5를 사용하면 주석과 후행 쉼표를 사용할 수 있습니다. 일반 JSON도 작동합니다.
{ // 환경 + 셸 env: { OPENROUTER_API_KEY: "sk-or-...", vars: { GROQ_API_KEY: "gsk-...", }, shellEnv: { enabled: true, timeoutMs: 15000, }, }, // 인증 프로필 메타데이터(시크릿은 auth-profiles.json에 있음) auth: { profiles: { "anthropic:default": { provider: "anthropic", mode: "api_key" }, "anthropic:work": { provider: "anthropic", mode: "api_key" }, "openai:default": { provider: "openai", mode: "api_key" }, "openai-codex:personal": { provider: "openai-codex", mode: "oauth" }, }, order: { anthropic: ["anthropic:default", "anthropic:work"], openai: ["openai:default"], "openai-codex": ["openai-codex:personal"], }, }, // Identity는 에이전트별 설정입니다. 아래 agents.list[].identity에서 설정하세요. // 로깅 logging: { level: "info", file: "/tmp/openclaw/openclaw.log", consoleLevel: "info", consoleStyle: "pretty", redactSensitive: "tools", }, // 메시지 형식 지정 messages: { messagePrefix: "[openclaw]", visibleReplies: "automatic", responsePrefix: ">", ackReaction: "👀", ackReactionScope: "group-mentions", groupChat: { historyLimit: 50, visibleReplies: "message_tool", // 일반 최종 답장은 그룹/채널에서 비공개로 유지됩니다 }, queue: { mode: "steer", debounceMs: 500, cap: 20, drop: "summarize", byChannel: { whatsapp: "steer", telegram: "steer", discord: "steer", slack: "steer", signal: "steer", imessage: "steer", webchat: "steer", }, }, }, // 도구 tools: { media: { audio: { enabled: true, maxBytes: 20971520, models: [ { provider: "openai", model: "gpt-4o-mini-transcribe" }, // 선택적 CLI 폴백(Whisper 바이너리): // { type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] } ], timeoutSeconds: 120, }, video: { enabled: true, maxBytes: 52428800, models: [{ provider: "google", model: "gemini-3-flash-preview" }], }, }, }, // 세션 동작 session: { scope: "per-sender", dmScope: "per-channel-peer", // 다중 사용자 받은 편지함에 권장 reset: { mode: "daily", atHour: 4, idleMinutes: 60, }, resetByChannel: { discord: { mode: "idle", idleMinutes: 10080 }, }, resetTriggers: ["/new", "/reset"], store: "~/.openclaw/agents/default/sessions/sessions.json", maintenance: { mode: "warn", pruneAfter: "30d", maxEntries: 500, resetArchiveRetention: "30d", // 기간 또는 false maxDiskBytes: "500mb", // 선택 사항 highWaterBytes: "400mb", // 선택 사항(maxDiskBytes의 80%가 기본값) }, typingIntervalSeconds: 5, sendPolicy: { default: "allow", rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }], }, }, // 채널 channels: { whatsapp: { dmPolicy: "pairing", allowFrom: ["+15555550123"], groupPolicy: "allowlist", groupAllowFrom: ["+15555550123"], groups: { "*": { requireMention: true } }, }, telegram: { enabled: true, botToken: "YOUR_TELEGRAM_BOT_TOKEN", allowFrom: ["123456789"], groupPolicy: "allowlist", groupAllowFrom: ["123456789"], groups: { "*": { requireMention: true } }, }, discord: { enabled: true, token: "YOUR_DISCORD_BOT_TOKEN", dm: { enabled: true, allowFrom: ["123456789012345678"] }, guilds: { "123456789012345678": { slug: "friends-of-openclaw", requireMention: false, channels: { general: { allow: true }, help: { allow: true, requireMention: true }, }, }, }, }, slack: { enabled: true, botToken: "xoxb-REPLACE_ME", appToken: "xapp-REPLACE_ME", channels: { "#general": { allow: true, requireMention: true }, }, dm: { enabled: true, allowFrom: ["U123"] }, slashCommand: { enabled: true, name: "openclaw", sessionPrefix: "slack:slash", ephemeral: true, }, }, }, // 에이전트 런타임 agents: { defaults: { workspace: "~/.openclaw/workspace", userTimezone: "America/Chicago", model: { primary: "anthropic/claude-sonnet-4-6", fallbacks: ["anthropic/claude-opus-4-6", "openai/gpt-5.4"], }, imageModel: { primary: "openrouter/anthropic/claude-sonnet-4-6", }, models: { "anthropic/claude-opus-4-6": { alias: "opus" }, "anthropic/claude-sonnet-4-6": { alias: "sonnet" }, "openai/gpt-5.4": { alias: "gpt" }, }, skills: ["github", "weather"], // list[].skills를 생략한 에이전트가 상속함 thinkingDefault: "low", verboseDefault: "off", toolProgressDetail: "explain", reasoningDefault: "off", elevatedDefault: "on", blockStreamingDefault: "off", blockStreamingBreak: "text_end", blockStreamingChunk: { minChars: 800, maxChars: 1200, breakPreference: "paragraph", }, blockStreamingCoalesce: { idleMs: 1000, }, humanDelay: { mode: "natural", }, timeoutSeconds: 600, mediaMaxMb: 5, typingIntervalSeconds: 5, maxConcurrent: 3, heartbeat: { every: "30m", model: "anthropic/claude-sonnet-4-6", target: "last", directPolicy: "allow", // allow(기본값) | block to: "+15555550123", prompt: "HEARTBEAT", ackMaxChars: 300, }, memorySearch: { provider: "gemini", model: "gemini-embedding-001", remote: { apiKey: "${GEMINI_API_KEY}", }, extraPaths: ["../team-docs", "/srv/shared-notes"], }, sandbox: { mode: "non-main", scope: "session", // 기존 perSession: true보다 선호 workspaceRoot: "~/.openclaw/sandboxes", docker: { image: "openclaw-sandbox:bookworm-slim", workdir: "/workspace", readOnlyRoot: true, tmpfs: ["/tmp", "/var/tmp", "/run"], network: "none", user: "1000:1000", }, browser: { enabled: false, }, }, }, list: [ { id: "main", default: true, identity: { name: "Samantha", theme: "helpful sloth", emoji: "🦥", }, // defaults.skills -> github, weather를 상속함 groupChat: { mentionPatterns: ["@openclaw", "openclaw"], }, thinkingDefault: "high", // 에이전트별 thinking 재정의 reasoningDefault: "on", // 에이전트별 reasoning 표시 여부 fastModeDefault: false, // 에이전트별 빠른 모드 }, { id: "quick", skills: [], // 이 에이전트에는 skills 없음 fastModeDefault: true, // 이 에이전트는 항상 빠르게 실행됨 thinkingDefault: "off", }, ], }, tools: { allow: ["exec", "process", "read", "write", "edit", "apply_patch"], deny: ["browser", "canvas"], exec: { backgroundMs: 10000, timeoutSec: 1800, cleanupMs: 1800000, }, elevated: { enabled: true, allowFrom: { whatsapp: ["+15555550123"], telegram: ["123456789"], discord: ["123456789012345678"], slack: ["U123"], signal: ["+15555550123"], imessage: ["[email protected]"], webchat: ["session:demo"], }, }, }, // 사용자 지정 모델 공급자 models: { mode: "merge", providers: { "custom-proxy": { baseUrl: "http://localhost:4000/v1", apiKey: "LITELLM_KEY", api: "openai-responses", authHeader: true, headers: { "X-Proxy-Region": "us-west" }, models: [ { id: "llama-3.1-8b", name: "Llama 3.1 8B", api: "openai-responses", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 32000, }, ], }, }, }, // Cron 작업 cron: { enabled: true, store: "~/.openclaw/cron/cron.json", maxConcurrentRuns: 2, // cron 디스패치 + 격리된 cron 에이전트 턴 실행 sessionRetention: "24h", runLog: { maxBytes: "2mb", keepLines: 2000, }, }, // Webhook hooks: { enabled: true, path: "/hooks", token: "shared-secret", presets: ["gmail"], transformsDir: "~/.openclaw/hooks/transforms", mappings: [ { id: "gmail-hook", match: { path: "gmail" }, action: "agent", wakeMode: "now", name: "Gmail", sessionKey: "hook:gmail:{{messages[0].id}}", messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}", textTemplate: "{{messages[0].snippet}}", deliver: true, channel: "last", to: "+15555550123", thinking: "low", timeoutSeconds: 300, transform: { module: "gmail.js", export: "transformGmail", }, }, ], gmail: { account: "[email protected]", label: "INBOX", 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" }, }, }, // Gateway + 네트워킹 gateway: { mode: "local", port: 18789, bind: "loopback", controlUi: { enabled: true, basePath: "/openclaw" }, auth: { mode: "token", token: "gateway-token", allowTailscale: true, }, tailscale: { mode: "serve", resetOnExit: false }, remote: { url: "ws://gateway.tailnet:18789", token: "remote-token" }, reload: { mode: "hybrid", debounceMs: 300 }, }, skills: { allowBundled: ["gemini", "peekaboo"], load: { extraDirs: ["~/Projects/agent-scripts/skills"], allowSymlinkTargets: ["~/Projects/agent-scripts/skills"], }, install: { preferBrew: true, nodeManager: "npm", // npm | pnpm | yarn | bun allowUploadedArchives: false, }, entries: { "image-lab": { enabled: true, apiKey: "GEMINI_KEY_HERE", env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" }, }, peekaboo: { enabled: true }, }, },}심볼릭 링크된 형제 skill 저장소
기본 제공 skill 루트에 형제 저장소로 연결되는 심볼릭 링크가 있을 때 사용합니다. 예:
~/.agents/skills/manager -> ~/Projects/manager/skills.
{ skills: { load: { extraDirs: ["~/Projects/manager/skills"], allowSymlinkTargets: ["~/Projects/manager/skills"], }, },}extraDirs는 형제 저장소를 명시적 skill 루트로 스캔합니다.allowSymlinkTargets는 심볼릭 링크된 skill 폴더가 임의의 심볼릭 링크 이탈을 허용하지 않고도 신뢰할 수 있는 실제 대상 루트로 해석되도록 합니다.
일반적인 패턴
하나의 재정의가 있는 공유 skill 기준선
{ agents: { defaults: { workspace: "~/.openclaw/workspace", skills: ["github", "weather"], }, list: [ { id: "main", default: true }, { id: "docs", workspace: "~/.openclaw/workspace-docs", skills: ["docs-search"] }, ], },}agents.defaults.skills는 공유 기준선입니다.agents.list[].skills는 한 에이전트에 대해 해당 기준선을 대체합니다.- 에이전트가 skills를 보지 않아야 할 때는
skills: []를 사용합니다.
다중 플랫폼 설정
{ agents: { defaults: { workspace: "~/.openclaw/workspace" } }, channels: { whatsapp: { allowFrom: ["+15555550123"] }, telegram: { enabled: true, botToken: "YOUR_TOKEN", allowFrom: ["123456789"], }, discord: { enabled: true, token: "YOUR_TOKEN", dm: { allowFrom: ["123456789012345678"] }, }, },}신뢰할 수 있는 Node 네트워크 자동 승인
네트워크 경로를 제어하지 않는 한 기기 페어링은 수동으로 유지하세요. 전용 랩 또는 tailnet 서브넷의 경우, 정확한 CIDR 또는 IP로 최초 Node 기기 자동 승인에 옵트인할 수 있습니다.
{ gateway: { nodes: { pairing: { autoApproveCidrs: ["192.168.1.0/24", "fd00:1234:5678::/64"], }, }, },}설정하지 않으면 계속 꺼진 상태입니다. 요청된 범위가 없는 새로운 role: node
페어링에만 적용됩니다. 운영자/브라우저 클라이언트와 역할, 범위, 메타데이터 또는
공개 키 업그레이드는 여전히 수동 승인이 필요합니다.
보안 DM 모드(공유 받은편지함 / 다중 사용자 DM)
두 명 이상이 봇에 DM을 보낼 수 있다면(allowFrom의 여러 항목, 여러 사람에 대한 페어링 승인 또는 dmPolicy: "open"), 보안 DM 모드를 활성화하여 서로 다른 발신자의 DM이 기본적으로 하나의 컨텍스트를 공유하지 않도록 하세요.
{ // Secure DM mode (recommended for multi-user or sensitive DM agents) session: { dmScope: "per-channel-peer" }, channels: { // Example: WhatsApp multi-user inbox whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15555550123", "+15555550124"], }, // Example: Discord multi-user inbox discord: { enabled: true, token: "YOUR_DISCORD_BOT_TOKEN", dm: { enabled: true, allowFrom: ["123456789012345678", "987654321098765432"] }, }, },}Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자 권한 부여는 기본적으로 ID 우선입니다.
그 위험을 명시적으로 수락하는 경우에만 각 채널의 dangerouslyAllowNameMatching: true로 직접 변경 가능한 이름/이메일/닉네임 매칭을 활성화하세요.
Anthropic API 키 + MiniMax 폴백
{ auth: { profiles: { "anthropic:api": { provider: "anthropic", mode: "api_key", }, }, order: { anthropic: ["anthropic:api"], }, }, models: { providers: { minimax: { baseUrl: "https://api.minimax.io/anthropic", api: "anthropic-messages", apiKey: "${MINIMAX_API_KEY}", }, }, }, agents: { defaults: { workspace: "~/.openclaw/workspace", model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["minimax/MiniMax-M2.7"], }, }, },}업무 봇(제한된 액세스)
{ agents: { defaults: { workspace: "~/work-openclaw", elevatedDefault: "off", }, list: [ { id: "main", identity: { name: "WorkBot", theme: "professional assistant", }, }, ], }, channels: { slack: { enabled: true, botToken: "xoxb-...", channels: { "#engineering": { allow: true, requireMention: true }, "#general": { allow: true, requireMention: true }, }, }, },}로컬 모델만 사용
{ agents: { defaults: { workspace: "~/.openclaw/workspace", model: { primary: "lmstudio/my-local-model" }, }, }, models: { mode: "merge", providers: { lmstudio: { baseUrl: "http://127.0.0.1:1234/v1", apiKey: "lmstudio", api: "openai-responses", models: [ { id: "my-local-model", name: "Local Model", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192, }, ], }, }, },}팁
dmPolicy: "open"을 설정하면, 일치하는allowFrom목록에"*"가 포함되어야 합니다.- 공급자 ID는 서로 다릅니다(전화번호, 사용자 ID, 채널 ID). 형식을 확인하려면 공급자 문서를 사용하세요.
- 나중에 추가할 선택적 섹션:
web,browser,ui,discovery,plugins,talk,signal,imessage. - 더 자세한 설정 참고 사항은 공급자 및 문제 해결을 참조하세요.