Gateway

구성 참조

Core config reference for ~/.openclaw/openclaw.json. For a task-oriented overview, see Configuration.

Covers the main OpenClaw config surfaces and links out when a subsystem has its own deeper reference. Channel- and plugin-owned command catalogs and deep memory/QMD knobs live on their own pages rather than on this one.

Code truth:

  • openclaw config schema prints the live JSON Schema used for validation and Control UI, with bundled/plugin/channel metadata merged in when available
  • config.schema.lookup returns one path-scoped schema node for drill-down tooling
  • pnpm config:docs:check / pnpm config:docs:gen validate the config-doc baseline hash against the current schema surface

Agent lookup path: use the gateway tool action config.schema.lookup for exact field-level docs and constraints before edits. Use Configuration for task-oriented guidance and this page for the broader field map, defaults, and links to subsystem references.

Dedicated deep references:

  • Memory configuration reference for agents.defaults.memorySearch.*, memory.qmd.*, memory.citations, and dreaming config under plugins.entries.memory-core.config.dreaming
  • Slash commands for the current built-in + bundled command catalog
  • owning channel/plugin pages for channel-specific command surfaces

Config format is JSON5 (comments + trailing commas allowed). All fields are optional - OpenClaw uses safe defaults when omitted.


Channels

Per-channel config keys moved to a dedicated page - see Configuration - channels for channels.*, including Slack, Discord, Telegram, WhatsApp, Matrix, iMessage, and other bundled channels (auth, access control, multi-account, mention gating).

Agent defaults, multi-agent, sessions, and messages

Moved to a dedicated page - see Configuration - agents for:

  • agents.defaults.* (workspace, model, thinking, heartbeat, memory, media, skills, sandbox)
  • multiAgent.* (multi-agent routing and bindings)
  • session.* (session lifecycle, compaction, pruning)
  • messages.* (message delivery, TTS, markdown rendering)
  • talk.* (Talk mode)
    • talk.speechLocale: optional BCP 47 locale id for Talk speech recognition on iOS/macOS
    • talk.silenceTimeoutMs: when unset, Talk keeps the platform default pause window before sending the transcript (700 ms on macOS and Android, 900 ms on iOS)

Tools and custom providers

Tool policy, experimental toggles, provider-backed tool config, and custom provider / base-URL setup moved to a dedicated page - see Configuration - tools and custom providers.

Models

Provider definitions, model allowlists, and custom provider setup live in Configuration - tools and custom providers. The models root also owns global model-catalog behavior.

{
  models: {
    // Optional. Default: true. Requires a Gateway restart when changed.
    pricing: { enabled: false },
  },
}
  • models.mode: provider catalog behavior (merge or replace).
  • models.providers: custom provider map keyed by provider id.
  • models.pricing.enabled: controls the background pricing bootstrap that starts after sidecars and channels reach the Gateway ready path. When false, the Gateway skips OpenRouter and LiteLLM pricing-catalog fetches; configured models.providers.*.models[].cost values still work for local cost estimates.

MCP

OpenClaw-managed MCP server definitions live under mcp.servers and are consumed by embedded Pi and other runtime adapters. The openclaw mcp list, show, set, and unset commands manage this block without connecting to the target server during config edits.

{
  mcp: {
    // Optional. Default: 600000 ms (10 minutes). Set 0 to disable idle eviction.
    sessionIdleTtlMs: 600000,
    servers: {
      docs: {
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-fetch"],
      },
      remote: {
        url: "https://example.com/mcp",
        transport: "streamable-http", // streamable-http | sse
        headers: {
          Authorization: "Bearer ${MCP_REMOTE_TOKEN}",
        },
      },
    },
  },
}
  • mcp.servers: named stdio or remote MCP server definitions for runtimes that expose configured MCP tools. Remote entries use transport: "streamable-http" or transport: "sse"; type: "http" is a CLI-native alias that openclaw mcp set and openclaw doctor --fix normalize into the canonical transport field.
  • mcp.sessionIdleTtlMs: idle TTL for session-scoped bundled MCP runtimes. One-shot embedded runs request run-end cleanup; this TTL is the backstop for long-lived sessions and future callers.
  • Changes under mcp.* hot-apply by disposing cached session MCP runtimes. The next tool discovery/use recreates them from the new config, so removed mcp.servers entries are reaped immediately instead of waiting for idle TTL.

See MCP and CLI backends for runtime behavior.

Skills

{
  skills: {
    allowBundled: ["gemini", "peekaboo"],
    load: {
      extraDirs: ["~/Projects/agent-scripts/skills"],
    },
    install: {
      preferBrew: true,
      nodeManager: "npm", // npm | pnpm | yarn | bun
    },
    entries: {
      "image-lab": {
        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: optional allowlist for bundled skills only (managed/workspace skills unaffected).
  • load.extraDirs: extra shared skill roots (lowest precedence).
  • install.preferBrew: when true, prefer Homebrew installers when brew is available before falling back to other installer kinds.
  • install.nodeManager: node installer preference for metadata.openclaw.install specs (npm | pnpm | yarn | bun).
  • entries.<skillKey>.enabled: false disables a skill even if bundled/installed.
  • entries.<skillKey>.apiKey: convenience for skills declaring a primary env var (plaintext string or SecretRef object).

Plugins

{
  plugins: {
    enabled: true,
    allow: ["voice-call"],
    bundledDiscovery: "allowlist",
    deny: [],
    load: {
      paths: ["~/Projects/oss/voice-call-plugin"],
    },
    entries: {
      "voice-call": {
        enabled: true,
        hooks: {
          allowPromptInjection: false,
        },
        config: { provider: "twilio" },
      },
    },
  },
}
  • Loaded from ~/.openclaw/extensions, <workspace>/.openclaw/extensions, plus plugins.load.paths.
  • Discovery accepts native OpenClaw plugins plus compatible Codex bundles and Claude bundles, including manifestless Claude default-layout bundles.
  • Config changes require a gateway restart.
  • allow: optional allowlist (only listed plugins load). deny wins.
  • bundledDiscovery: defaults to "allowlist" for new configs, so a non-empty plugins.allow also gates bundled provider plugins, including web-search runtime providers. Doctor writes "compat" for migrated legacy allowlist configs to preserve existing bundled provider behavior until you opt in.
  • plugins.entries.<id>.apiKey: plugin-level API key convenience field (when supported by the plugin).
  • plugins.entries.<id>.env: plugin-scoped env var map.
  • plugins.entries.<id>.hooks.allowPromptInjection: when false, core blocks before_prompt_build and ignores prompt-mutating fields from legacy before_agent_start, while preserving legacy modelOverride and providerOverride. Applies to native plugin hooks and supported bundle-provided hook directories.
  • plugins.entries.<id>.hooks.allowConversationAccess: when true, trusted non-bundled plugins may read raw conversation content from typed hooks such as llm_input, llm_output, before_model_resolve, before_agent_reply, before_agent_run, before_agent_finalize, and agent_end.
  • plugins.entries.<id>.subagent.allowModelOverride: explicitly trust this plugin to request per-run provider and model overrides for background subagent runs.
  • plugins.entries.<id>.subagent.allowedModels: optional allowlist of canonical provider/model targets for trusted subagent overrides. Use "*" only when you intentionally want to allow any model.
  • plugins.entries.<id>.config: plugin-defined config object (validated by native OpenClaw plugin schema when available).
  • Channel plugin account/runtime settings live under channels.<id> and should be described by the owning plugin's manifest channelConfigs metadata, not by a central OpenClaw option registry.
  • plugins.entries.firecrawl.config.webFetch: Firecrawl web-fetch provider settings.
    • apiKey: Firecrawl API key (accepts SecretRef). Falls back to plugins.entries.firecrawl.config.webSearch.apiKey, legacy tools.web.fetch.firecrawl.apiKey, or FIRECRAWL_API_KEY env var.
    • baseUrl: Firecrawl API base URL (default: https://api.firecrawl.dev; self-hosted overrides must target private/internal endpoints).
    • onlyMainContent: extract only the main content from pages (default: true).
    • maxAgeMs: maximum cache age in milliseconds (default: 172800000 / 2 days).
    • timeoutSeconds: scrape request timeout in seconds (default: 60).
  • plugins.entries.xai.config.xSearch: xAI X Search (Grok web search) settings.
    • enabled: enable the X Search provider.
    • model: Grok model to use for search (e.g. "grok-4-1-fast").
  • plugins.entries.memory-core.config.dreaming: memory dreaming settings. See Dreaming for phases and thresholds.
    • enabled: master dreaming switch (default false).
    • frequency: cron cadence for each full dreaming sweep ("0 3 * * *" by default).
    • model: optional Dream Diary subagent model override. Requires plugins.entries.memory-core.subagent.allowModelOverride: true; pair with allowedModels to restrict targets. Model-unavailable errors retry once with the session default model; trust or allowlist failures do not fall back silently.
    • phase policy and thresholds are implementation details (not user-facing config keys).
  • Full memory config lives in Memory configuration reference:
    • agents.defaults.memorySearch.*
    • memory.backend
    • memory.citations
    • memory.qmd.*
    • plugins.entries.memory-core.config.dreaming
  • Enabled Claude bundle plugins can also contribute embedded Pi defaults from settings.json; OpenClaw applies those as sanitized agent settings, not as raw OpenClaw config patches.
  • plugins.slots.memory: pick the active memory plugin id, or "none" to disable memory plugins.
  • plugins.slots.contextEngine: pick the active context engine plugin id; defaults to "legacy" unless you install and select another engine.

See Plugins.


Commitments

commitments controls inferred follow-up memory: OpenClaw can detect check-ins from conversation turns and deliver them through heartbeat runs.

  • commitments.enabled: enable hidden LLM extraction, storage, and heartbeat delivery for inferred follow-up commitments. Default: false.
  • commitments.maxPerDay: maximum inferred follow-up commitments delivered per agent session in a rolling day. Default: 3.

See Inferred commitments.


Browser

{
  browser: {
    enabled: true,
    evaluateEnabled: true,
    defaultProfile: "user",
    ssrfPolicy: {
      // dangerouslyAllowPrivateNetwork: true, // opt in only for trusted private-network access
      // allowPrivateNetwork: true, // legacy alias
      // hostnameAllowlist: ["*.example.com", "example.com"],
      // allowedHostnames: ["localhost"],
    },
    tabCleanup: {
      enabled: true,
      idleMinutes: 120,
      maxTabsPerSession: 8,
      sweepMinutes: 5,
    },
    profiles: {
      openclaw: { cdpPort: 18800, color: "#FF4500" },
      work: {
        cdpPort: 18801,
        color: "#0066CC",
        executablePath: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
      },
      user: { driver: "existing-session", attachOnly: true, color: "#00AA00" },
      brave: {
        driver: "existing-session",
        attachOnly: true,
        userDataDir: "~/Library/Application Support/BraveSoftware/Brave-Browser",
        color: "#FB542B",
      },
      remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" },
    },
    color: "#FF4500",
    // headless: false,
    // noSandbox: false,
    // extraArgs: [],
    // executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
    // attachOnly: false,
  },
}
  • evaluateEnabled: falseact:evaluatewait --fn을 비활성화합니다.
  • tabCleanup은 유휴 시간이 지난 후 또는 세션이 한도를 초과할 때 추적 중인 기본 에이전트 탭을 회수합니다. 이러한 개별 정리 모드를 비활성화하려면 idleMinutes: 0 또는 maxTabsPerSession: 0을 설정하세요.
  • ssrfPolicy.dangerouslyAllowPrivateNetwork는 설정하지 않으면 비활성화되므로, 브라우저 탐색은 기본적으로 엄격하게 유지됩니다.
  • 비공개 네트워크 브라우저 탐색을 의도적으로 신뢰하는 경우에만 ssrfPolicy.dangerouslyAllowPrivateNetwork: true를 설정하세요.
  • 엄격 모드에서는 원격 CDP 프로필 엔드포인트(profiles.*.cdpUrl)도 도달 가능성/탐색 확인 중 동일한 비공개 네트워크 차단의 적용을 받습니다.
  • ssrfPolicy.allowPrivateNetwork는 레거시 별칭으로 계속 지원됩니다.
  • 엄격 모드에서는 명시적 예외에 ssrfPolicy.hostnameAllowlistssrfPolicy.allowedHostnames를 사용하세요.
  • 원격 프로필은 연결 전용입니다(시작/중지/재설정 비활성화).
  • profiles.*.cdpUrlhttp://, https://, ws://, wss://를 허용합니다. OpenClaw가 /json/version을 탐색하도록 하려면 HTTP(S)를 사용하고, 제공자가 직접 DevTools WebSocket URL을 제공하는 경우 WS(S)를 사용하세요.
  • remoteCdpTimeoutMsremoteCdpHandshakeTimeoutMs는 원격 및 attachOnly CDP 도달 가능성과 탭 열기 요청에 적용됩니다. 관리형 loopback 프로필은 로컬 CDP 기본값을 유지합니다.
  • 외부에서 관리되는 CDP 서비스가 loopback을 통해 도달 가능한 경우 해당 프로필의 attachOnly: true를 설정하세요. 그렇지 않으면 OpenClaw는 loopback 포트를 로컬 관리형 브라우저 프로필로 취급하여 로컬 포트 소유권 오류를 보고할 수 있습니다.
  • existing-session 프로필은 CDP 대신 Chrome MCP를 사용하며, 선택한 호스트 또는 연결된 브라우저 노드를 통해 연결할 수 있습니다.
  • existing-session 프로필은 Brave 또는 Edge 같은 특정 Chromium 기반 브라우저 프로필을 대상으로 지정하도록 userDataDir을 설정할 수 있습니다.
  • existing-session 프로필은 현재 Chrome MCP 경로 제한을 유지합니다: CSS 선택자 대상 지정 대신 스냅샷/ref 기반 작업, 단일 파일 업로드 훅, 대화 상자 타임아웃 재정의 없음, wait --load networkidle 없음, 그리고 responsebody, PDF 내보내기, 다운로드 가로채기 또는 배치 작업 없음.
  • 로컬 관리형 openclaw 프로필은 cdpPortcdpUrl을 자동 할당합니다. 원격 CDP에만 cdpUrl을 명시적으로 설정하세요.
  • 로컬 관리형 프로필은 해당 프로필에 대해 전역 browser.executablePath를 재정의하도록 executablePath를 설정할 수 있습니다. 이를 사용해 한 프로필은 Chrome에서, 다른 프로필은 Brave에서 실행하세요.
  • 로컬 관리형 프로필은 프로세스 시작 후 Chrome CDP HTTP 탐색에 browser.localLaunchTimeoutMs를 사용하고, 실행 후 CDP websocket 준비 상태에는 browser.localCdpReadyTimeoutMs를 사용합니다. Chrome은 성공적으로 시작되지만 준비 상태 확인이 시작과 경합하는 느린 호스트에서는 이 값을 높이세요. 두 값 모두 120000ms 이하의 양의 정수여야 하며, 잘못된 구성 값은 거부됩니다.
  • 자동 감지 순서: Chromium 기반인 경우 기본 브라우저 → Chrome → Brave → Edge → Chromium → Chrome Canary.
  • browser.executablePathbrowser.profiles.<name>.executablePath는 Chromium 실행 전에 OS 홈 디렉터리에 대해 ~~/...를 모두 허용합니다. existing-session 프로필의 프로필별 userDataDir도 틸드 확장됩니다.
  • 제어 서비스: loopback 전용(gateway.port에서 파생된 포트, 기본값 18791).
  • extraArgs는 로컬 Chromium 시작에 추가 실행 플래그를 덧붙입니다(예: --disable-gpu, 창 크기 지정 또는 디버그 플래그).

UI

{
  ui: {
    seamColor: "#FF4500",
    assistant: {
      name: "OpenClaw",
      avatar: "CB", // emoji, short text, image URL, or data URI
    },
  },
}
  • seamColor: 네이티브 앱 UI 크롬의 강조 색상(Talk Mode 말풍선 색조 등).
  • assistant: Control UI ID 재정의입니다. 활성 에이전트 ID로 폴백합니다.

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",
      // embedSandbox: "scripts", // strict | scripts | trusted
      // allowExternalEmbedUrls: false, // dangerous: allow absolute external http(s) embed URLs
      // chatMessageMaxWidth: "min(1280px, 82%)", // optional grouped chat message max-width
      // 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,
    nodes: {
      pairing: {
        // Optional. Default unset/disabled.
        autoApproveCidrs: ["192.168.1.0/24", "fd00:1234:5678::/64"],
      },
      allowCommands: ["canvas.navigate"],
      denyCommands: ["system.run"],
    },
    tools: {
      // Additional /tools/invoke HTTP denies
      deny: ["browser"],
      // Remove tools from the default HTTP deny list
      allow: ["gateway"],
    },
    push: {
      apns: {
        relay: {
          baseUrl: "https://relay.example.com",
          timeoutMs: 10000,
        },
      },
    },
  },
}
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.
  • 레거시 바인드 별칭: gateway.bind에서는 호스트 별칭(0.0.0.0, 127.0.0.1, localhost, ::, ::1)이 아니라 바인드 모드 값(auto, loopback, lan, tailnet, custom)을 사용하세요.
  • Docker 참고: 기본 loopback 바인드는 컨테이너 내부의 127.0.0.1에서 수신합니다. Docker 브리지 네트워킹(-p 18789:18789)에서는 트래픽이 eth0으로 도착하므로 Gateway에 접근할 수 없습니다. --network host를 사용하거나, 모든 인터페이스에서 수신하도록 bind: "lan"(또는 customBindHost: "0.0.0.0"와 함께 bind: "custom")을 설정하세요.
  • 인증: 기본적으로 필요합니다. 논루프백 바인드는 Gateway 인증이 필요합니다. 실제로는 공유 토큰/비밀번호 또는 gateway.auth.mode: "trusted-proxy"를 사용하는 ID 인식 리버스 프록시를 의미합니다. 온보딩 마법사는 기본적으로 토큰을 생성합니다.
  • gateway.auth.tokengateway.auth.password가 모두 구성된 경우(SecretRef 포함), gateway.auth.modetoken 또는 password로 명시적으로 설정하세요. 둘 다 구성되어 있고 모드가 설정되지 않으면 시작 및 서비스 설치/복구 흐름이 실패합니다.
  • gateway.auth.mode: "none": 명시적 무인증 모드입니다. 신뢰할 수 있는 local loopback 설정에만 사용하세요. 이는 의도적으로 온보딩 프롬프트에서 제공되지 않습니다.
  • gateway.auth.mode: "trusted-proxy": 브라우저/사용자 인증을 ID 인식 리버스 프록시에 위임하고 gateway.trustedProxies의 ID 헤더를 신뢰합니다(신뢰할 수 있는 프록시 인증 참조). 이 모드는 기본적으로 논루프백 프록시 소스를 기대합니다. 동일 호스트 loopback 리버스 프록시는 명시적으로 gateway.auth.trustedProxy.allowLoopback = true가 필요합니다. 내부 동일 호스트 호출자는 로컬 직접 폴백으로 gateway.auth.password를 사용할 수 있습니다. gateway.auth.token은 trusted-proxy 모드와 계속 상호 배타적입니다.
  • gateway.auth.allowTailscale: true이면 Tailscale Serve ID 헤더가 Control UI/WebSocket 인증을 충족할 수 있습니다(tailscale whois로 확인). HTTP API 엔드포인트는 해당 Tailscale 헤더 인증을 사용하지 않습니다. 대신 Gateway의 일반 HTTP 인증 모드를 따릅니다. 이 토큰 없는 흐름은 Gateway 호스트가 신뢰된다고 가정합니다. tailscale.mode = "serve"이면 기본값은 true입니다.
  • gateway.auth.rateLimit: 선택적 인증 실패 제한기입니다. 클라이언트 IP별 및 인증 범위별로 적용됩니다(shared-secret과 device-token은 독립적으로 추적됨). 차단된 시도는 429 + Retry-After를 반환합니다.
  • 비동기 Tailscale Serve Control UI 경로에서는 동일한 {scope, clientIp}에 대한 실패 시도가 실패 기록 전에 직렬화됩니다. 따라서 동일 클라이언트의 동시 잘못된 시도는 둘 다 단순 불일치로 경합 통과하는 대신 두 번째 요청에서 제한기에 걸릴 수 있습니다.
  • gateway.auth.rateLimit.exemptLoopback의 기본값은 true입니다. 테스트 설정이나 엄격한 프록시 배포를 위해 localhost 트래픽도 의도적으로 속도 제한하려면 false로 설정하세요.
  • 브라우저 출처 WS 인증 시도는 항상 loopback 예외가 비활성화된 상태로 제한됩니다(브라우저 기반 localhost 무차별 대입에 대한 심층 방어).
  • loopback에서는 이러한 브라우저 출처 잠금이 정규화된 Origin 값별로 격리되므로, 한 localhost 출처에서 반복 실패해도 다른 출처가 자동으로 잠기지 않습니다.
  • tailscale.mode: serve(tailnet만, loopback 바인드) 또는 funnel(공개, 인증 필요).
  • controlUi.allowedOrigins: Gateway WebSocket 연결에 대한 명시적 브라우저 출처 허용 목록입니다. 브라우저 클라이언트가 논루프백 출처에서 올 것으로 예상되면 필요합니다.
  • controlUi.chatMessageMaxWidth: 그룹화된 Control UI 채팅 메시지의 선택적 최대 너비입니다. 960px, 82%, min(1280px, 82%), calc(100% - 2rem) 같은 제한된 CSS 너비 값을 허용합니다.
  • controlUi.dangerouslyAllowHostHeaderOriginFallback: Host 헤더 출처 정책에 의도적으로 의존하는 배포를 위해 Host-header 출처 폴백을 활성화하는 위험한 모드입니다.
  • remote.transport: ssh(기본값) 또는 direct(ws/wss). direct의 경우 remote.urlws:// 또는 wss://여야 합니다.
  • OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1: 신뢰할 수 있는 사설 네트워크 IP에 대해 평문 ws://를 허용하는 클라이언트 측 프로세스 환경 비상 우회 설정입니다. 평문 기본값은 계속 loopback 전용입니다. 이에 해당하는 openclaw.json 설정은 없으며, browser.ssrfPolicy.dangerouslyAllowPrivateNetwork 같은 브라우저 사설 네트워크 구성은 Gateway WebSocket 클라이언트에 영향을 주지 않습니다.
  • gateway.remote.token / .password는 원격 클라이언트 자격 증명 필드입니다. 이것만으로 Gateway 인증을 구성하지는 않습니다.
  • gateway.push.apns.relay.baseUrl: 공식/TestFlight iOS 빌드가 relay-backed 등록을 Gateway에 게시한 뒤 사용하는 외부 APNs relay의 기본 HTTPS URL입니다. 이 URL은 iOS 빌드에 컴파일된 relay URL과 일치해야 합니다.
  • gateway.push.apns.relay.timeoutMs: Gateway에서 relay로 보내는 전송 제한 시간(밀리초)입니다. 기본값은 10000입니다.
  • relay-backed 등록은 특정 Gateway ID에 위임됩니다. 페어링된 iOS 앱은 gateway.identity.get을 가져와 그 ID를 relay 등록에 포함하고, 등록 범위의 전송 권한 부여를 Gateway로 전달합니다. 다른 Gateway는 저장된 해당 등록을 재사용할 수 없습니다.
  • OPENCLAW_APNS_RELAY_BASE_URL / OPENCLAW_APNS_RELAY_TIMEOUT_MS: 위 relay 구성에 대한 임시 환경 변수 재정의입니다.
  • OPENCLAW_APNS_RELAY_ALLOW_HTTP=true: loopback HTTP relay URL을 위한 개발 전용 탈출구입니다. 프로덕션 relay URL은 HTTPS를 유지해야 합니다.
  • gateway.handshakeTimeoutMs: 인증 전 Gateway WebSocket 핸드셰이크 제한 시간(밀리초)입니다. 기본값: 15000. 설정된 경우 OPENCLAW_HANDSHAKE_TIMEOUT_MS가 우선합니다. 시작 예열이 아직 안정화되는 동안에도 로컬 클라이언트가 연결할 수 있는 부하가 높은 호스트 또는 저전력 호스트에서는 이 값을 늘리세요.
  • gateway.channelHealthCheckMinutes: 채널 상태 모니터 간격(분)입니다. 전역적으로 상태 모니터 재시작을 비활성화하려면 0으로 설정하세요. 기본값: 5.
  • gateway.channelStaleEventThresholdMinutes: 오래된 소켓 임계값(분)입니다. 이 값은 gateway.channelHealthCheckMinutes보다 크거나 같게 유지하세요. 기본값: 30.
  • gateway.channelMaxRestartsPerHour: 이동 1시간 동안 채널/계정별 상태 모니터 재시작 최대 횟수입니다. 기본값: 10.
  • channels.<provider>.healthMonitor.enabled: 전역 모니터는 활성화된 상태로 유지하면서 채널별 상태 모니터 재시작을 제외합니다.
  • channels.<provider>.accounts.<accountId>.healthMonitor.enabled: 다중 계정 채널의 계정별 재정의입니다. 설정되면 채널 수준 재정보다 우선합니다.
  • 로컬 Gateway 호출 경로는 gateway.auth.*가 설정되지 않은 경우에만 gateway.remote.*를 폴백으로 사용할 수 있습니다.
  • gateway.auth.token / gateway.auth.password가 SecretRef를 통해 명시적으로 구성되었고 해석되지 않으면, 해석은 안전하게 실패합니다(원격 폴백으로 가려지지 않음).
  • trustedProxies: TLS를 종료하거나 전달된 클라이언트 헤더를 삽입하는 리버스 프록시 IP입니다. 제어하는 프록시만 나열하세요. loopback 항목은 동일 호스트 프록시/로컬 감지 설정(예: Tailscale Serve 또는 로컬 리버스 프록시)에도 여전히 유효하지만, 이것이 loopback 요청을 gateway.auth.mode: "trusted-proxy"에 적합하게 만들지는 않습니다.
  • allowRealIpFallback: true이면 X-Forwarded-For가 없을 때 Gateway가 X-Real-IP를 허용합니다. 안전한 실패 동작을 위해 기본값은 false입니다.
  • gateway.nodes.pairing.autoApproveCidrs: 요청된 범위가 없는 최초 Node 장치 페어링을 자동 승인하기 위한 선택적 CIDR/IP 허용 목록입니다. 설정되지 않으면 비활성화됩니다. 이는 운영자/브라우저/Control UI/WebChat 페어링을 자동 승인하지 않으며, 역할, 범위, 메타데이터 또는 공개 키 업그레이드도 자동 승인하지 않습니다.
  • gateway.nodes.allowCommands / gateway.nodes.denyCommands: 페어링 및 플랫폼 허용 목록 평가 후 선언된 Node 명령에 대한 전역 허용/거부 제어입니다. camera.snap, camera.clip, screen.record 같은 위험한 Node 명령을 사용하려면 allowCommands를 사용하세요. denyCommands는 플랫폼 기본값이나 명시적 허용에 포함될 명령이라도 제거합니다. Node가 선언된 명령 목록을 변경한 뒤에는 해당 장치 페어링을 거부하고 다시 승인하여 Gateway가 업데이트된 명령 스냅샷을 저장하도록 하세요.
  • gateway.tools.deny: HTTP POST /tools/invoke에 대해 차단되는 추가 도구 이름입니다(기본 거부 목록 확장).
  • gateway.tools.allow: 기본 HTTP 거부 목록에서 도구 이름을 제거합니다.

OpenAI 호환 엔드포인트

  • Chat Completions: 기본적으로 비활성화되어 있습니다. gateway.http.endpoints.chatCompletions.enabled: true로 활성화하세요.
  • Responses API: gateway.http.endpoints.responses.enabled.
  • Responses URL 입력 강화:
    • gateway.http.endpoints.responses.maxUrlParts
    • gateway.http.endpoints.responses.files.urlAllowlist
    • gateway.http.endpoints.responses.images.urlAllowlist 빈 허용 목록은 설정되지 않은 것으로 처리됩니다. URL 가져오기를 비활성화하려면 gateway.http.endpoints.responses.files.allowUrl=false 및/또는 gateway.http.endpoints.responses.images.allowUrl=false를 사용하세요.
  • 선택적 응답 강화 헤더:

다중 인스턴스 격리

고유한 포트와 상태 디렉터리로 한 호스트에서 여러 Gateway를 실행합니다.

OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \
OPENCLAW_STATE_DIR=~/.openclaw-a \
openclaw gateway --port 19001

편의 플래그: --dev(~/.openclaw-dev + 포트 19001 사용), --profile <name>(~/.openclaw-<name> 사용).

여러 Gateway를 참조하세요.

gateway.tls

{
  gateway: {
    tls: {
      enabled: false,
      autoGenerate: false,
      certPath: "/etc/openclaw/tls/server.crt",
      keyPath: "/etc/openclaw/tls/server.key",
      caPath: "/etc/openclaw/tls/ca-bundle.crt",
    },
  },
}
  • enabled: Gateway 리스너(HTTPS/WSS)에서 TLS 종료를 활성화합니다(기본값: false).
  • autoGenerate: 명시적 파일이 구성되지 않은 경우 로컬 자체 서명 인증서/키 쌍을 자동 생성합니다. 로컬/개발 용도로만 사용하세요.
  • certPath: TLS 인증서 파일의 파일 시스템 경로입니다.
  • keyPath: TLS 개인 키 파일의 파일 시스템 경로입니다. 권한을 제한해 두세요.
  • caPath: 클라이언트 검증 또는 사용자 지정 신뢰 체인을 위한 선택적 CA 번들 경로입니다.

gateway.reload

{
  gateway: {
    reload: {
      mode: "hybrid", // off | restart | hot | hybrid
      debounceMs: 500,
      deferralTimeoutMs: 300000,
    },
  },
}
  • mode: 런타임에서 구성 편집이 적용되는 방식을 제어합니다.
    • "off": 실시간 편집을 무시합니다. 변경 사항에는 명시적 재시작이 필요합니다.
    • "restart": 구성 변경 시 항상 Gateway 프로세스를 재시작합니다.
    • "hot": 재시작하지 않고 프로세스 내부에서 변경 사항을 적용합니다.
    • "hybrid"(기본값): 먼저 핫 리로드를 시도하고, 필요한 경우 재시작으로 폴백합니다.
  • debounceMs: 구성 변경이 적용되기 전의 디바운스 창(ms)입니다(음수가 아닌 정수).
  • deferralTimeoutMs: 재시작 또는 채널 핫 리로드를 강제하기 전에 진행 중인 작업을 기다리는 선택적 최대 시간(ms)입니다. 기본 제한 대기(300000)를 사용하려면 생략하세요. 무기한 대기하고 주기적으로 아직 대기 중이라는 경고를 기록하려면 0으로 설정하세요.

후크

{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
    maxBodyBytes: 262144,
    defaultSessionKey: "hook:ingress",
    allowRequestSessionKey: true,
    allowedSessionKeyPrefixes: ["hook:", "hook:gmail:"],
    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.4-mini",
      },
    ],
  },
}

인증: Authorization: Bearer <token> 또는 x-openclaw-token: <token>. 쿼리 문자열 hook 토큰은 거부됩니다.

유효성 검사 및 안전 참고 사항:

  • hooks.enabled=true에는 비어 있지 않은 hooks.token이 필요합니다.
  • hooks.tokengateway.auth.token달라야 합니다. Gateway 토큰 재사용은 거부됩니다.
  • hooks.path/일 수 없습니다. /hooks 같은 전용 하위 경로를 사용하세요.
  • hooks.allowRequestSessionKey=true인 경우 hooks.allowedSessionKeyPrefixes를 제한하세요(예: ["hook:"]).
  • 매핑 또는 프리셋이 템플릿 기반 sessionKey를 사용하는 경우 hooks.allowedSessionKeyPrefixes를 설정하고 hooks.allowRequestSessionKey=true로 설정하세요. 정적 매핑 키에는 해당 옵트인이 필요하지 않습니다.

엔드포인트:

  • POST /hooks/wake{ text, mode?: "now"|"next-heartbeat" }
  • POST /hooks/agent{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }
    • 요청 페이로드의 sessionKeyhooks.allowRequestSessionKey=true일 때만 허용됩니다(기본값: false).
  • POST /hooks/<name>hooks.mappings를 통해 확인됩니다.
    • 템플릿으로 렌더링된 매핑 sessionKey 값은 외부에서 제공된 것으로 처리되며, 마찬가지로 hooks.allowRequestSessionKey=true가 필요합니다.
매핑 세부 정보
  • match.path/hooks 뒤의 하위 경로와 일치합니다(예: /hooks/gmailgmail).
  • match.source는 일반 경로의 페이로드 필드와 일치합니다.
  • {{messages[0].subject}} 같은 템플릿은 페이로드에서 읽습니다.
  • transform은 hook 작업을 반환하는 JS/TS 모듈을 가리킬 수 있습니다.
  • transform.module은 상대 경로여야 하며 hooks.transformsDir 내부에 유지됩니다(절대 경로와 경로 순회는 거부됩니다).
  • hooks.transformsDir~/.openclaw/hooks/transforms 아래에 두세요. 워크스페이스 skill 디렉터리는 거부됩니다. openclaw doctor가 이 경로를 유효하지 않다고 보고하면 transform 모듈을 hooks transform 디렉터리로 이동하거나 hooks.transformsDir를 제거하세요.
  • agentId는 특정 에이전트로 라우팅합니다. 알 수 없는 ID는 기본값으로 폴백됩니다.
  • allowedAgentIds: 명시적 라우팅을 제한합니다(* 또는 생략 = 모두 허용, [] = 모두 거부).
  • defaultSessionKey: 명시적 sessionKey가 없는 hook 에이전트 실행에 사용할 선택적 고정 세션 키입니다.
  • allowRequestSessionKey: /hooks/agent 호출자와 템플릿 기반 매핑 세션 키가 sessionKey를 설정하도록 허용합니다(기본값: false).
  • allowedSessionKeyPrefixes: 명시적 sessionKey 값(요청 + 매핑)에 대한 선택적 접두사 허용 목록입니다. 예: ["hook:"]. 매핑 또는 프리셋이 템플릿 기반 sessionKey를 사용하면 필수입니다.
  • deliver: true는 최종 응답을 채널로 보냅니다. channel의 기본값은 last입니다.
  • model은 이 hook 실행에 사용할 LLM을 재정의합니다(모델 카탈로그가 설정된 경우 허용되어야 함).

Gmail 통합

  • 기본 제공 Gmail 프리셋은 sessionKey: "hook:gmail:{{messages[0].id}}"를 사용합니다.
  • 메시지별 라우팅을 유지하는 경우 hooks.allowRequestSessionKey: true를 설정하고 hooks.allowedSessionKeyPrefixes를 Gmail 네임스페이스와 일치하도록 제한하세요. 예: ["hook:", "hook:gmail:"].
  • hooks.allowRequestSessionKey: false가 필요한 경우 템플릿 기반 기본값 대신 정적 sessionKey로 프리셋을 재정의하세요.
{
  hooks: {
    gmail: {
      account: "[email protected]",
      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 Plugin 호스트

{
  plugins: {
    entries: {
      canvas: {
        config: {
          host: {
            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 바인드: canvas 경로에는 다른 Gateway HTTP 표면과 마찬가지로 Gateway 인증(토큰/비밀번호/신뢰할 수 있는 프록시)이 필요합니다.
  • Node WebView는 일반적으로 인증 헤더를 보내지 않습니다. Node가 페어링되고 연결된 뒤 Gateway는 canvas/A2UI 접근을 위한 Node 범위 기능 URL을 알립니다.
  • 기능 URL은 활성 Node WS 세션에 바인딩되며 빠르게 만료됩니다. IP 기반 폴백은 사용되지 않습니다.
  • 제공되는 HTML에 실시간 다시 로드 클라이언트를 삽입합니다.
  • 비어 있을 때 시작용 index.html을 자동 생성합니다.
  • 또한 /__openclaw__/a2ui/에서 A2UI를 제공합니다.
  • 변경 사항에는 Gateway 재시작이 필요합니다.
  • 큰 디렉터리 또는 EMFILE 오류에서는 실시간 다시 로드를 비활성화하세요.

검색

mDNS(Bonjour)

{
  discovery: {
    mdns: {
      mode: "minimal", // minimal | full | off
    },
  },
}
  • minimal(번들 bonjour Plugin이 활성화된 경우 기본값): TXT 레코드에서 cliPath + sshPort를 생략합니다.
  • full: cliPath + sshPort를 포함합니다. LAN 멀티캐스트 광고에는 여전히 번들 bonjour Plugin이 활성화되어 있어야 합니다.
  • off: Plugin 활성화 상태를 변경하지 않고 LAN 멀티캐스트 광고를 억제합니다.
  • 번들 bonjour Plugin은 macOS 호스트에서 자동 시작되며 Linux, Windows, 컨테이너화된 Gateway 배포에서는 옵트인입니다.
  • 호스트 이름은 유효한 DNS 레이블인 경우 시스템 호스트 이름을 기본값으로 사용하고, 그렇지 않으면 openclaw로 폴백됩니다. OPENCLAW_MDNS_HOSTNAME으로 재정의하세요.

광역(DNS-SD)

{
  discovery: {
    wideArea: { enabled: true },
  },
}

~/.openclaw/dns/ 아래에 유니캐스트 DNS-SD 존을 작성합니다. 네트워크 간 검색에는 DNS 서버(CoreDNS 권장) + Tailscale 분할 DNS를 함께 사용하세요.

설정: openclaw dns setup --apply.


환경

env (인라인 env vars)

{
  env: {
    OPENROUTER_API_KEY: "sk-or-...",
    vars: {
      GROQ_API_KEY: "gsk-...",
    },
    shellEnv: {
      enabled: true,
      timeoutMs: 15000,
    },
  },
}
  • 인라인 env vars는 프로세스 env에 해당 키가 없을 때만 적용됩니다.
  • .env 파일: CWD .env + ~/.openclaw/.env (둘 다 기존 변수를 덮어쓰지 않음).
  • shellEnv: 로그인 셸 프로필에서 누락된 예상 키를 가져옵니다.
  • 전체 우선순위는 환경을 참조하세요.

환경 변수 치환

모든 설정 문자열에서 ${VAR_NAME}으로 env vars를 참조하세요.

{
  gateway: {
    auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" },
  },
}
  • 대문자 이름만 일치합니다: [A-Z_][A-Z0-9_]*.
  • 누락되었거나 비어 있는 변수는 설정 로드 시 오류를 발생시킵니다.
  • 리터럴 ${VAR}에는 $${VAR}로 이스케이프하세요.
  • $include와 함께 작동합니다.

비밀 정보

비밀 정보 참조는 추가 방식입니다. 일반 텍스트 값도 계속 작동합니다.

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" ids에는 . 또는 .. 슬래시 구분 경로 세그먼트가 포함되면 안 됩니다(예: a/../b는 거부됨)

지원되는 자격 증명 영역

  • 표준 매트릭스: SecretRef 자격 증명 영역
  • secrets apply는 지원되는 openclaw.json 자격 증명 경로를 대상으로 합니다.
  • auth-profiles.json 참조는 런타임 해석 및 감사 범위에 포함됩니다.

비밀 정보 providers 설정

{
  secrets: {
    providers: {
      default: { source: "env" }, // optional explicit env provider
      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 provider는 mode: "json"mode: "singleValue"를 지원합니다(singleValue 모드에서는 id"value"여야 함).
  • Windows ACL 검증을 사용할 수 없으면 파일 및 exec provider 경로는 안전하게 실패합니다. 검증할 수 없는 신뢰할 수 있는 경로에만 allowInsecurePath: true를 설정하세요.
  • exec provider는 절대 command 경로가 필요하며 stdin/stdout에서 프로토콜 페이로드를 사용합니다.
  • 기본적으로 심볼릭 링크 command 경로는 거부됩니다. 해석된 대상 경로를 검증하면서 심볼릭 링크 경로를 허용하려면 allowSymlinkCommand: true를 설정하세요.
  • trustedDirs가 설정된 경우, 신뢰할 수 있는 디렉터리 검사는 해석된 대상 경로에 적용됩니다.
  • exec 하위 환경은 기본적으로 최소화됩니다. 필요한 변수는 passEnv로 명시적으로 전달하세요.
  • 비밀 정보 참조는 활성화 시점에 인메모리 스냅샷으로 해석되며, 이후 요청 경로는 스냅샷만 읽습니다.
  • 활성화 중에는 활성 영역 필터링이 적용됩니다. 활성화된 영역의 해석되지 않은 참조는 시작/다시 로드를 실패시키고, 비활성 영역은 진단 정보와 함께 건너뜁니다.

인증 저장소

{
  auth: {
    profiles: {
      "anthropic:default": { provider: "anthropic", mode: "api_key" },
      "anthropic:work": { provider: "anthropic", mode: "api_key" },
      "openai-codex:personal": { provider: "openai-codex", mode: "oauth" },
    },
    order: {
      anthropic: ["anthropic:default", "anthropic:work"],
      "openai-codex": ["openai-codex:personal"],
    },
  },
}
  • 에이전트별 프로필은 <agentDir>/auth-profiles.json에 저장됩니다.
  • auth-profiles.json은 정적 자격 증명 모드에서 값 수준 참조(api_keykeyRef, tokentokenRef)를 지원합니다.
  • { "provider": { "apiKey": "..." } } 같은 레거시 플랫 auth-profiles.json 맵은 런타임 형식이 아닙니다. openclaw doctor --fix.legacy-flat.*.bak 백업과 함께 이를 표준 provider:default API-key 프로필로 다시 작성합니다.
  • OAuth 모드 프로필(auth.profiles.<id>.mode = "oauth")은 SecretRef 기반 인증 프로필 자격 증명을 지원하지 않습니다.
  • 정적 런타임 자격 증명은 인메모리 해석 스냅샷에서 가져옵니다. 레거시 정적 auth.json 항목은 발견 시 제거됩니다.
  • 레거시 OAuth는 ~/.openclaw/credentials/oauth.json에서 가져옵니다.
  • OAuth를 참조하세요.
  • 비밀 정보 런타임 동작 및 audit/configure/apply 도구: 비밀 정보 관리.

auth.cooldowns

{
  auth: {
    cooldowns: {
      billingBackoffHours: 5,
      billingBackoffHoursByProvider: { anthropic: 3, openai: 8 },
      billingMaxHours: 24,
      authPermanentBackoffMinutes: 10,
      authPermanentMaxMinutes: 60,
      failureWindowHours: 24,
      overloadedProfileRotations: 1,
      overloadedBackoffMs: 0,
      rateLimitedProfileRotations: 1,
    },
  },
}
  • billingBackoffHours: 프로필이 실제 결제/크레딧 부족 오류로 실패할 때 적용되는 시간 단위 기본 백오프입니다(기본값: 5). 명시적인 결제 텍스트는 401/403 응답에서도 여기에 분류될 수 있지만, 공급자별 텍스트 매처는 이를 소유한 공급자의 범위로 유지됩니다(예: OpenRouter Key limit exceeded). 재시도 가능한 HTTP 402 사용 기간 또는 조직/워크스페이스 지출 한도 메시지는 대신 rate_limit 경로에 남습니다.
  • billingBackoffHoursByProvider: 결제 백오프 시간에 대한 선택적 공급자별 재정의입니다.
  • billingMaxHours: 결제 백오프 지수 증가의 시간 단위 상한입니다(기본값: 24).
  • authPermanentBackoffMinutes: 신뢰도 높은 auth_permanent 실패에 대한 분 단위 기본 백오프입니다(기본값: 10).
  • authPermanentMaxMinutes: auth_permanent 백오프 증가의 분 단위 상한입니다(기본값: 60).
  • failureWindowHours: 백오프 카운터에 사용되는 시간 단위 롤링 윈도우입니다(기본값: 24).
  • overloadedProfileRotations: 모델 폴백으로 전환하기 전 과부하 오류에 대해 허용되는 동일 공급자 인증 프로필 로테이션의 최대 횟수입니다(기본값: 1). ModelNotReadyException 같은 공급자 사용 중 형태가 여기에 분류됩니다.
  • overloadedBackoffMs: 과부하된 공급자/프로필 로테이션을 재시도하기 전의 고정 지연 시간입니다(기본값: 0).
  • rateLimitedProfileRotations: 모델 폴백으로 전환하기 전 속도 제한 오류에 대해 허용되는 동일 공급자 인증 프로필 로테이션의 최대 횟수입니다(기본값: 1). 해당 속도 제한 버킷에는 Too many concurrent requests, ThrottlingException, concurrency limit reached, workers_ai ... quota limit exceeded, resource exhausted 같은 공급자 형태의 텍스트가 포함됩니다.

로깅

{
  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일 때 consoleLeveldebug로 올라갑니다.
  • maxFileBytes: 로테이션 전 활성 로그 파일의 최대 크기(바이트)입니다(양의 정수, 기본값: 104857600 = 100MB). OpenClaw는 활성 파일 옆에 번호가 붙은 아카이브를 최대 5개까지 유지합니다.
  • redactSensitive / redactPatterns: 콘솔 출력, 파일 로그, OTLP 로그 레코드, 저장된 세션 트랜스크립트 텍스트에 대한 최선 노력 방식의 마스킹입니다. redactSensitive: "off"는 이 일반 로그/트랜스크립트 정책만 비활성화합니다. UI/도구/진단 안전 표면은 여전히 내보내기 전에 시크릿을 수정합니다.

진단

{
  diagnostics: {
    enabled: true,
    flags: ["telegram.*"],
    stuckSessionWarnMs: 30000,
    stuckSessionAbortMs: 600000,

    otel: {
      enabled: false,
      endpoint: "https://otel-collector.example.com:4318",
      tracesEndpoint: "https://traces.example.com/v1/traces",
      metricsEndpoint: "https://metrics.example.com/v1/metrics",
      logsEndpoint: "https://logs.example.com/v1/logs",
      protocol: "http/protobuf", // http/protobuf | grpc
      headers: { "x-tenant-id": "my-org" },
      serviceName: "openclaw-gateway",
      traces: true,
      metrics: true,
      logs: false,
      sampleRate: 1.0,
      flushIntervalMs: 5000,
      captureContent: {
        enabled: false,
        inputMessages: false,
        outputMessages: false,
        toolInputs: false,
        toolOutputs: false,
        systemPrompt: false,
      },
    },

    cacheTrace: {
      enabled: false,
      filePath: "~/.openclaw/logs/cache-trace.jsonl",
      includeMessages: true,
      includePrompt: true,
      includeSystem: true,
    },
  },
}
  • enabled: 계측 출력의 마스터 토글입니다(기본값: true).
  • flags: 대상 로그 출력을 활성화하는 플래그 문자열 배열입니다("telegram.*" 또는 "*" 같은 와일드카드 지원).
  • stuckSessionWarnMs: 장기 실행 처리 세션을 session.long_running, session.stalled 또는 session.stuck으로 분류하기 위한 진행 없음 기간 임계값(ms)입니다. 응답, 도구, 상태, 블록, ACP 진행은 타이머를 재설정합니다. 반복되는 session.stuck 진단은 변경이 없으면 백오프됩니다.
  • stuckSessionAbortMs: 복구를 위해 적격한 정체 활성 작업을 중단 드레인할 수 있기 전의 진행 없음 기간 임계값(ms)입니다. 설정하지 않으면 OpenClaw는 최소 10분 및 stuckSessionWarnMs의 5배인 더 안전한 확장 임베디드 실행 윈도우를 사용합니다.
  • otel.enabled: OpenTelemetry 내보내기 파이프라인을 활성화합니다(기본값: false). 전체 구성, 신호 카탈로그, 개인정보 보호 모델은 OpenTelemetry 내보내기를 참조하세요.
  • otel.endpoint: OTel 내보내기를 위한 컬렉터 URL입니다.
  • otel.tracesEndpoint / otel.metricsEndpoint / otel.logsEndpoint: 선택적 신호별 OTLP 엔드포인트입니다. 설정하면 해당 신호에 한해 otel.endpoint를 재정의합니다.
  • otel.protocol: "http/protobuf"(기본값) 또는 "grpc".
  • otel.headers: OTel 내보내기 요청과 함께 전송되는 추가 HTTP/gRPC 메타데이터 헤더입니다.
  • otel.serviceName: 리소스 속성의 서비스 이름입니다.
  • otel.traces / otel.metrics / otel.logs: 트레이스, 메트릭 또는 로그 내보내기를 활성화합니다.
  • otel.sampleRate: 트레이스 샘플링 비율 0-1.
  • otel.flushIntervalMs: 주기적 텔레메트리 플러시 간격(ms)입니다.
  • otel.captureContent: OTEL span 속성에 대한 원시 콘텐츠 캡처 옵트인입니다. 기본값은 꺼짐입니다. 불리언 true는 시스템이 아닌 메시지/도구 콘텐츠를 캡처합니다. 객체 형식에서는 inputMessages, outputMessages, toolInputs, toolOutputs, systemPrompt를 명시적으로 활성화할 수 있습니다.
  • OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental: 최신 실험적 GenAI span 공급자 속성을 위한 환경 토글입니다. 기본적으로 span은 호환성을 위해 기존 gen_ai.system 속성을 유지하며, GenAI 메트릭은 제한된 의미 속성을 사용합니다.
  • OPENCLAW_OTEL_PRELOADED=1: 이미 전역 OpenTelemetry SDK를 등록한 호스트를 위한 환경 토글입니다. 그러면 OpenClaw는 Plugin 소유 SDK 시작/종료를 건너뛰면서 진단 리스너는 활성 상태로 유지합니다.
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: 일치하는 구성 키가 설정되지 않았을 때 사용되는 신호별 엔드포인트 환경 변수입니다.
  • cacheTrace.enabled: 임베디드 실행에 대한 캐시 트레이스 스냅샷을 기록합니다(기본값: false).
  • cacheTrace.filePath: 캐시 트레이스 JSONL의 출력 경로입니다(기본값: $OPENCLAW_STATE_DIR/logs/cache-trace.jsonl).
  • cacheTrace.includeMessages / includePrompt / includeSystem: 캐시 트레이스 출력에 포함할 내용을 제어합니다(모두 기본값: true).

업데이트

{
  update: {
    channel: "stable", // stable | beta | dev
    checkOnStart: true,

    auto: {
      enabled: false,
      stableDelayHours: 6,
      stableJitterHours: 12,
      betaCheckIntervalHours: 1,
    },
  },
}
  • channel: npm/git 설치의 릴리스 채널입니다 - "stable", "beta" 또는 "dev".
  • checkOnStart: gateway 시작 시 npm 업데이트를 확인합니다(기본값: true).
  • auto.enabled: 패키지 설치에 대한 백그라운드 자동 업데이트를 활성화합니다(기본값: false).
  • auto.stableDelayHours: stable 채널 자동 적용 전 최소 지연 시간(시간)입니다(기본값: 6, 최대: 168).
  • auto.stableJitterHours: 추가 stable 채널 롤아웃 분산 윈도우(시간)입니다(기본값: 12, 최대: 168).
  • auto.betaCheckIntervalHours: beta 채널 확인이 실행되는 빈도(시간)입니다(기본값: 1, 최대: 24).

ACP

{
  acp: {
    enabled: true,
    dispatch: { enabled: true },
    backend: "acpx",
    defaultAgent: "main",
    allowedAgents: ["main", "ops"],
    maxConcurrentSessions: 10,

    stream: {
      coalesceIdleMs: 50,
      maxChunkChars: 1000,
      repeatSuppression: true,
      deliveryMode: "live", // live | final_only
      hiddenBoundarySeparator: "paragraph", // none | space | newline | paragraph
      maxOutputChars: 50000,
      maxSessionUpdateChars: 500,
    },

    runtime: {
      ttlMinutes: 30,
    },
  },
}
  • enabled: 전역 ACP 기능 게이트입니다(기본값: true, ACP 디스패치와 spawn affordance를 숨기려면 false로 설정).
  • dispatch.enabled: ACP 세션 turn 디스패치에 대한 독립 게이트입니다(기본값: true). 실행을 차단하면서 ACP 명령은 계속 사용할 수 있도록 하려면 false로 설정하세요.
  • backend: 기본 ACP 런타임 백엔드 ID입니다(등록된 ACP 런타임 Plugin과 일치해야 함). 먼저 백엔드 Plugin을 설치하고, plugins.allow가 설정되어 있으면 백엔드 Plugin ID(예: acpx)를 포함하세요. 그렇지 않으면 ACP 백엔드가 로드되지 않습니다.
  • defaultAgent: spawn이 명시적 대상을 지정하지 않을 때의 폴백 ACP 대상 agent ID입니다.
  • allowedAgents: ACP 런타임 세션에 허용되는 agent ID의 허용 목록입니다. 비어 있으면 추가 제한이 없음을 의미합니다.
  • maxConcurrentSessions: 동시에 활성화될 수 있는 ACP 세션의 최대 수입니다.
  • stream.coalesceIdleMs: 스트리밍된 텍스트의 idle 플러시 윈도우(ms)입니다.
  • stream.maxChunkChars: 스트리밍 블록 투영을 분할하기 전의 최대 청크 크기입니다.
  • stream.repeatSuppression: turn마다 반복되는 상태/도구 줄을 억제합니다(기본값: true).
  • stream.deliveryMode: "live"는 증분 스트리밍하고, "final_only"는 turn 종료 이벤트까지 버퍼링합니다.
  • stream.hiddenBoundarySeparator: 숨겨진 도구 이벤트 이후 표시 텍스트 앞의 구분자입니다(기본값: "paragraph").
  • stream.maxOutputChars: ACP turn마다 투영되는 assistant 출력 문자의 최대 수입니다.
  • stream.maxSessionUpdateChars: 투영된 ACP 상태/업데이트 줄의 최대 문자 수입니다.
  • stream.tagVisibility: 스트리밍된 이벤트에 대한 태그 이름별 불리언 표시 여부 재정의 레코드입니다.
  • runtime.ttlMinutes: ACP 세션 worker가 적격 cleanup 대상이 되기 전의 idle TTL(분)입니다.
  • runtime.installCommand: ACP 런타임 환경을 부트스트랩할 때 실행할 선택적 설치 명령입니다.

CLI

{
  cli: {
    banner: {
      taglineMode: "off", // random | default | off
    },
  },
}
  • cli.banner.taglineMode는 배너 태그라인 스타일을 제어합니다:
    • "random"(기본값): 회전하는 재미/계절 태그라인.
    • "default": 고정 중립 태그라인(All your chats, one OpenClaw.).
    • "off": 태그라인 텍스트 없음(배너 제목/버전은 계속 표시됨).
  • 전체 배너를 숨기려면(태그라인만이 아니라) env OPENCLAW_HIDE_BANNER=1을 설정하세요.

마법사

CLI 안내 설정 플로우(onboard, configure, doctor)가 작성하는 메타데이터:

{
  wizard: {
    lastRunAt: "2026-01-01T00:00:00.000Z",
    lastRunVersion: "2026.1.4",
    lastRunCommit: "abc1234",
    lastRunCommand: "configure",
    lastRunMode: "local",
  },
}

ID

Agent 기본값agents.list ID 필드를 참조하세요.


브리지(레거시, 제거됨)

현재 빌드에는 더 이상 TCP 브리지가 포함되지 않습니다. Node는 Gateway WebSocket을 통해 연결됩니다. bridge.* 키는 더 이상 config 스키마의 일부가 아닙니다(제거될 때까지 검증이 실패합니다. openclaw doctor --fix로 알 수 없는 키를 제거할 수 있습니다).

레거시 브리지 config(역사적 참고)
{
"bridge": {
  "enabled": true,
  "port": 18790,
  "bind": "tailnet",
  "tls": {
    "enabled": true,
    "autoGenerate": true
  }
}
}

Cron

{
  cron: {
    enabled: true,
    maxConcurrentRuns: 2, // cron dispatch + isolated cron agent-turn execution
    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 transcript의 정리도 제어합니다. 기본값: 24h; 비활성화하려면 false로 설정합니다.
  • runLog.maxBytes: 정리하기 전 실행 로그 파일(cron/runs/<jobId>.jsonl)당 최대 크기입니다. 기본값: 2_000_000바이트.
  • runLog.keepLines: 실행 로그 정리가 트리거될 때 보존할 최신 줄 수입니다. 기본값: 2000.
  • webhookToken: cron Webhook POST 전달(delivery.mode = "webhook")에 사용하는 bearer 토큰입니다. 생략하면 인증 헤더를 보내지 않습니다.
  • webhook: 아직 notify: true가 있는 저장된 작업에만 사용되는, 사용 중단된 기존 fallback Webhook URL(http/https)입니다.

cron.retry

{
  cron: {
    retry: {
      maxAttempts: 3,
      backoffMs: [30000, 60000, 300000],
      retryOn: ["rate_limit", "overloaded", "network", "timeout", "server_error"],
    },
  },
}
  • maxAttempts: 일시적 오류에서 일회성 작업에 대한 최대 재시도 횟수입니다(기본값: 3; 범위: 0-10).
  • backoffMs: 각 재시도 시도에 대한 ms 단위 backoff 지연 배열입니다(기본값: [30000, 60000, 300000]; 1-10개 항목).
  • retryOn: 재시도를 트리거하는 오류 유형입니다 - "rate_limit", "overloaded", "network", "timeout", "server_error". 생략하면 모든 일시적 유형을 재시도합니다.

일회성 cron 작업에만 적용됩니다. 반복 작업은 별도의 실패 처리를 사용합니다.

cron.failureAlert

{
  cron: {
    failureAlert: {
      enabled: false,
      after: 3,
      cooldownMs: 3600000,
      includeSkipped: false,
      mode: "announce",
      accountId: "main",
    },
  },
}
  • enabled: cron 작업의 실패 알림을 활성화합니다(기본값: false).
  • after: 알림이 발생하기 전 연속 실패 횟수입니다(양의 정수, 최솟값: 1).
  • cooldownMs: 같은 작업에 대해 반복 알림 사이에 필요한 최소 밀리초입니다(음이 아닌 정수).
  • includeSkipped: 연속으로 건너뛴 실행을 알림 임계값에 포함해 계산합니다(기본값: false). 건너뛴 실행은 별도로 추적되며 실행 오류 backoff에는 영향을 주지 않습니다.
  • mode: 전달 모드입니다 - "announce"는 채널 메시지를 통해 보내고, "webhook"은 구성된 Webhook에 게시합니다.
  • accountId: 알림 전달 범위를 지정할 선택적 계정 또는 채널 id입니다.

cron.failureDestination

{
  cron: {
    failureDestination: {
      mode: "announce",
      channel: "last",
      to: "channel:C1234567890",
      accountId: "main",
    },
  },
}
  • 모든 작업에 적용되는 cron 실패 알림의 기본 대상입니다.
  • mode: "announce" 또는 "webhook"입니다. 충분한 대상 데이터가 있으면 기본값은 "announce"입니다.
  • channel: announce 전달에 대한 채널 override입니다. "last"는 마지막으로 알려진 전달 채널을 재사용합니다.
  • to: 명시적인 announce 대상 또는 Webhook URL입니다. Webhook 모드에 필요합니다.
  • accountId: 전달에 대한 선택적 계정 override입니다.
  • 작업별 delivery.failureDestination이 이 전역 기본값을 override합니다.
  • 전역 실패 대상과 작업별 실패 대상이 모두 설정되지 않은 경우, 이미 announce로 전달하는 작업은 실패 시 해당 기본 announce 대상으로 fallback합니다.
  • delivery.failureDestination은 작업의 기본 delivery.mode"webhook"인 경우를 제외하고 sessionTarget="isolated" 작업에만 지원됩니다.

Cron 작업을 참조하세요. 격리된 cron 실행은 background tasks로 추적됩니다.


Media model 템플릿 변수

tools.media.models[].args에서 확장되는 템플릿 자리표시자:

변수 설명
{{Body}} 전체 수신 메시지 본문
{{RawBody}} 원시 본문(기록/보낸 사람 래퍼 없음)
{{BodyStripped}} 그룹 멘션이 제거된 본문
{{From}} 보낸 사람 식별자
{{To}} 대상 식별자
{{MessageSid}} 채널 메시지 id
{{SessionId}} 현재 세션 UUID
{{IsNewSession}} 새 세션이 생성되면 "true"
{{MediaUrl}} 수신 미디어 pseudo-URL
{{MediaPath}} 로컬 미디어 경로
{{MediaType}} 미디어 유형(image/audio/document/…)
{{Transcript}} 오디오 transcript
{{Prompt}} CLI 항목에 대해 확인된 미디어 prompt
{{MaxChars}} CLI 항목에 대해 확인된 최대 출력 문자 수
{{ChatType}} "direct" 또는 "group"
{{GroupSubject}} 그룹 제목(최선의 노력)
{{GroupMembers}} 그룹 구성원 미리 보기(최선의 노력)
{{SenderName}} 보낸 사람 표시 이름(최선의 노력)
{{SenderE164}} 보낸 사람 전화번호(최선의 노력)
{{Provider}} Provider 힌트(whatsapp, telegram, discord 등)

Config include($include)

config를 여러 파일로 분할합니다:

// ~/.openclaw/openclaw.json
{
  gateway: { port: 18789 },
  agents: { $include: "./agents.json5" },
  broadcast: {
    $include: ["./clients/mueller.json5", "./clients/schmidt.json5"],
  },
}

병합 동작:

  • 단일 파일: 포함하는 객체를 대체합니다.
  • 파일 배열: 순서대로 deep-merge됩니다(나중 항목이 이전 항목을 override).
  • 형제 키: include 후에 병합됩니다(include된 값을 override).
  • 중첩 include: 최대 10단계 깊이까지 가능합니다.
  • 경로: include하는 파일을 기준으로 해석되지만, 최상위 config 디렉터리(openclaw.jsondirname) 안에 있어야 합니다. 절대 경로/../ 형식은 여전히 해당 경계 안으로 해석되는 경우에만 허용됩니다.
  • 단일 파일 include가 뒷받침하는 하나의 최상위 섹션만 변경하는 OpenClaw 소유 쓰기는 해당 include 파일로 write-through됩니다. 예를 들어 plugins installplugins.json5에서 plugins: { $include: "./plugins.json5" }를 업데이트하고 openclaw.json은 그대로 둡니다.
  • 루트 include, include 배열, 형제 override가 있는 include는 OpenClaw 소유 쓰기에 대해 읽기 전용입니다. 이러한 쓰기는 config를 flatten하지 않고 fail closed됩니다.
  • 오류: 누락된 파일, parse 오류, 순환 include에 대해 명확한 메시지를 제공합니다.

관련: Configuration · Configuration Examples · Doctor

관련