Files
clawdbot/docs/gateway/configuration-examples.md
Lloyd ab994d2c63 feat(agent): add human-like delay between block replies
Adds `agent.humanDelay` config option to create natural rhythm between
streamed message bubbles. When enabled, introduces a random delay
(default 800-2500ms) between block replies, making multi-message
responses feel more like natural human texting.

Config example:
```json
{
  "agent": {
    "blockStreamingDefault": "on",
    "humanDelay": {
      "enabled": true,
      "minMs": 800,
      "maxMs": 2500
    }
  }
}
```

- First message sends immediately
- Subsequent messages wait a random delay before sending
- Works with iMessage, Signal, and Discord providers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:12:50 +01:00

11 KiB

summary, read_when
summary read_when
Schema-accurate configuration examples for common Clawdbot setups
Learning how to configure Clawdbot
Looking for configuration examples
Setting up Clawdbot for the first time

Configuration Examples

Examples below are aligned with the current config schema. For the exhaustive reference and per-field notes, see Configuration.

Quick start

Absolute minimum

{
  agent: { workspace: "~/clawd" },
  whatsapp: { allowFrom: ["+15555550123"] }
}

Save to ~/.clawdbot/clawdbot.json and you can DM the bot from that number.

{
  identity: {
    name: "Clawd",
    theme: "helpful assistant",
    emoji: "🦞"
  },
  agent: {
    workspace: "~/clawd",
    model: { primary: "anthropic/claude-sonnet-4-5" }
  },
  whatsapp: {
    allowFrom: ["+15555550123"],
    groups: { "*": { requireMention: true } }
  }
}

Expanded example (major options)

JSON5 lets you use comments and trailing commas. Regular JSON works too.

{
  // Environment + shell
  env: {
    OPENROUTER_API_KEY: "sk-or-...",
    vars: {
      GROQ_API_KEY: "gsk-..."
    },
    shellEnv: {
      enabled: true,
      timeoutMs: 15000
    }
  },

  // Auth profile metadata (secrets live in auth-profiles.json)
  auth: {
    profiles: {
      "anthropic:me@example.com": { provider: "anthropic", mode: "oauth", email: "me@example.com" },
      "anthropic:work": { provider: "anthropic", mode: "api_key" },
      "openai:default": { provider: "openai", mode: "api_key" },
      "openai-codex:default": { provider: "openai-codex", mode: "oauth" }
    },
    order: {
      anthropic: ["anthropic:me@example.com", "anthropic:work"],
      openai: ["openai:default"],
      "openai-codex": ["openai-codex:default"]
    }
  },

  // Identity
  identity: {
    name: "Samantha",
    theme: "helpful sloth",
    emoji: "🦥"
  },

  // Logging
  logging: {
    level: "info",
    file: "/tmp/clawdbot/clawdbot.log",
    consoleLevel: "info",
    consoleStyle: "pretty",
    redactSensitive: "tools"
  },

  // Message formatting
  messages: {
    messagePrefix: "[clawdbot]",
    responsePrefix: ">",
    ackReaction: "👀",
    ackReactionScope: "group-mentions"
  },

  // Routing + queue
  routing: {
    groupChat: {
      mentionPatterns: ["@clawd", "clawdbot"],
      historyLimit: 50
    },
    queue: {
      mode: "collect",
      debounceMs: 1000,
      cap: 20,
      drop: "summarize",
      byProvider: {
        whatsapp: "collect",
        telegram: "collect",
        discord: "collect",
        slack: "collect",
        signal: "collect",
        imessage: "collect",
        webchat: "collect"
      }
    },
    transcribeAudio: {
      command: ["whisper", "--model", "base"],
      timeoutSeconds: 120
    }
  },

  // Session behavior
  session: {
    scope: "per-sender",
    idleMinutes: 60,
    heartbeatIdleMinutes: 120,
    resetTriggers: ["/new", "/reset"],
    store: "~/.clawdbot/agents/default/sessions/sessions.json",
    typingIntervalSeconds: 5,
    sendPolicy: {
      default: "allow",
      rules: [
        { action: "deny", match: { provider: "discord", chatType: "group" } }
      ]
    }
  },

  // Providers
  whatsapp: {
    dmPolicy: "pairing",
    allowFrom: ["+15555550123"],
    groupPolicy: "open",
    groups: { "*": { requireMention: true } }
  },

  telegram: {
    enabled: true,
    botToken: "YOUR_TELEGRAM_BOT_TOKEN",
    allowFrom: ["123456789"],
    groupPolicy: "open",
    groups: { "*": { requireMention: true } }
  },

  discord: {
    enabled: true,
    token: "YOUR_DISCORD_BOT_TOKEN",
    dm: { enabled: true, allowFrom: ["steipete"] },
    guilds: {
      "123456789012345678": {
        slug: "friends-of-clawd",
        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: "clawd",
      sessionPrefix: "slack:slash",
      ephemeral: true
    }
  },

  // Agent runtime
  agents: {
    defaults: {
      workspace: "~/clawd",
      userTimezone: "America/Chicago",
      model: {
        primary: "anthropic/claude-sonnet-4-5",
        fallbacks: ["anthropic/claude-opus-4-5", "openai/gpt-5.2"]
      },
      imageModel: {
        primary: "openrouter/anthropic/claude-sonnet-4-5"
      },
      models: {
        "anthropic/claude-opus-4-5": { alias: "opus" },
        "anthropic/claude-sonnet-4-5": { alias: "sonnet" },
        "openai/gpt-5.2": { alias: "gpt" }
      },
      thinkingDefault: "low",
      verboseDefault: "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-5",
        target: "last",
        to: "+15555550123",
        prompt: "HEARTBEAT",
        ackMaxChars: 30
      },
      sandbox: {
        mode: "non-main",
        perSession: true,
        workspaceRoot: "~/.clawdbot/sandboxes",
        docker: {
          image: "clawdbot-sandbox:bookworm-slim",
          workdir: "/workspace",
          readOnlyRoot: true,
          tmpfs: ["/tmp", "/var/tmp", "/run"],
          network: "none",
          user: "1000:1000"
        },
        browser: {
          enabled: false
        }
      }
    }
  },

  tools: {
    allow: ["bash", "process", "read", "write", "edit"],
    deny: ["browser", "canvas"],
    bash: {
      backgroundMs: 10000,
      timeoutSec: 1800,
      cleanupMs: 1800000
    },
    elevated: {
      enabled: true,
      allowFrom: {
        whatsapp: ["+15555550123"],
        telegram: ["123456789"],
        discord: ["steipete"],
        slack: ["U123"],
        signal: ["+15555550123"],
        imessage: ["user@example.com"],
        webchat: ["session:demo"]
      }
    }
  },

  // Custom model providers
  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 jobs
  cron: {
    enabled: true,
    store: "~/.clawdbot/cron/cron.json",
    maxConcurrentRuns: 2
  },

  // Webhooks
  hooks: {
    enabled: true,
    path: "/hooks",
    token: "shared-secret",
    presets: ["gmail"],
    transformsDir: "~/.clawdbot/hooks",
    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,
        provider: "last",
        to: "+15555550123",
        thinking: "low",
        timeoutSeconds: 300,
        transform: { module: "./transforms/gmail.js", export: "transformGmail" }
      }
    ],
    gmail: {
      account: "clawdbot@gmail.com",
      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 + networking
  gateway: {
    mode: "local",
    port: 18789,
    bind: "loopback",
    controlUi: { enabled: true, basePath: "/clawdbot" },
    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: ["brave-search", "gemini"],
    load: {
      extraDirs: ["~/Projects/agent-scripts/skills"]
    },
    install: {
      preferBrew: true,
      nodeManager: "npm"
    },
    entries: {
      "nano-banana-pro": {
        enabled: true,
        apiKey: "GEMINI_KEY_HERE",
        env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" }
      },
      peekaboo: { enabled: true }
    }
  }
}

Common patterns

Multi-platform setup

{
  agent: { workspace: "~/clawd" },
  whatsapp: { allowFrom: ["+15555550123"] },
  telegram: {
    enabled: true,
    botToken: "YOUR_TOKEN",
    allowFrom: ["123456789"]
  },
  discord: {
    enabled: true,
    token: "YOUR_TOKEN",
    dm: { allowFrom: ["yourname"] }
  }
}

OAuth with API key failover

{
  auth: {
    profiles: {
      "anthropic:subscription": {
        provider: "anthropic",
        mode: "oauth",
        email: "me@example.com"
      },
      "anthropic:api": {
        provider: "anthropic",
        mode: "api_key"
      }
    },
    order: {
      anthropic: ["anthropic:subscription", "anthropic:api"]
    }
  },
  agent: {
    workspace: "~/clawd",
    model: {
      primary: "anthropic/claude-sonnet-4-5",
      fallbacks: ["anthropic/claude-opus-4-5"]
    }
  }
}

Work bot (restricted access)

{
  identity: {
    name: "WorkBot",
    theme: "professional assistant"
  },
  agent: {
    workspace: "~/work-clawd",
    elevated: { enabled: false }
  },
  slack: {
    enabled: true,
    botToken: "xoxb-...",
    channels: {
      "#engineering": { allow: true, requireMention: true },
      "#general": { allow: true, requireMention: true }
    }
  }
}

Local models only

{
  agent: {
    workspace: "~/clawd",
    model: { primary: "lmstudio/minimax-m2.1-gs32" }
  },
  models: {
    mode: "merge",
    providers: {
      lmstudio: {
        baseUrl: "http://127.0.0.1:1234/v1",
        apiKey: "lmstudio",
        api: "openai-responses",
        models: [
          {
            id: "minimax-m2.1-gs32",
            name: "MiniMax M2.1 GS32",
            reasoning: false,
            input: ["text"],
            cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
            contextWindow: 196608,
            maxTokens: 8192
          }
        ]
      }
    }
  }
}

Tips

  • If you set dmPolicy: "open", the matching allowFrom list must include "*".
  • Provider IDs differ (phone numbers, user IDs, channel IDs). Use the provider docs to confirm the format.
  • Optional sections to add later: web, browser, ui, bridge, discovery, canvasHost, talk, signal, imessage.
  • See Providers and Troubleshooting for deeper setup notes.