Skip to content

Configuration

GolemBot uses a single configuration file: golem.yaml in the assistant directory root.

Minimal Config

A working golem.yaml only needs two lines:

yaml
name: my-bot
engine: claude-code

Everything else below is optional — add fields as you need them.

Full Example

yaml
name: my-assistant
engine: claude-code          # cursor | claude-code | opencode | codex
model: claude-sonnet         # optional, preferred model

# Optional: bypass agent permission prompts
skipPermissions: true

# Optional: Codex runtime mode (Codex engine only)
codex:
  mode: unrestricted         # optional shorthand: unrestricted | safe
  sandbox: workspace-write   # read-only | workspace-write | danger-full-access
  approval: on-request       # untrusted | on-request | never
  search: true
  addDirs:
    - ../shared-assets

# Optional: granular agent permissions (Cursor engine only)
permissions:
  allowedPaths:
    - ./src
    - ./tests
  deniedPaths:
    - ./.env
    - ./secrets
  allowedCommands:
    - npm test
    - npm run build
  deniedCommands:
    - rm -rf *

# Optional: role/persona definition — injected into AGENTS.md as a System Instructions
# section, read by the engine once per session (not prepended to every message)
systemPrompt: |
  You are a marketing assistant named Aria. Never introduce yourself as OpenCode
  or any coding assistant. Reply in the same language the user uses.

# Optional: production hardening
timeout: 120                 # engine timeout in seconds (default: 300)
maxConcurrent: 20            # max parallel chats (default: 10)
maxQueuePerSession: 2        # max queued requests per user (default: 3)
sessionTtlDays: 14           # prune idle sessions after N days (default: 30)

# Optional: streaming message delivery for IM channels
streaming:
  mode: streaming            # buffered (default) | streaming
  showToolCalls: true        # show 🔧 tool hints in IM (default: false)

# Optional: group chat behaviour (applies to all channels)
groupChat:
  groupPolicy: mention-only  # mention-only (default) | smart | always
  historyLimit: 20           # recent messages to inject as context (default: 20)
  maxTurns: 10               # max consecutive bot replies per group (default: 10)

# Optional: scheduled tasks
tasks:
  - id: daily-standup
    name: daily-standup
    schedule: "0 9 * * 1-5"
    prompt: |
      Summarize all git commits in the last 24 hours,
      grouped by author. Flag any breaking changes.
    enabled: true
    target:
      channel: feishu
      chatId: "oc_xxxxx"

# Optional: persistent message queue (crash-safe, sequential processing)
inbox:
  enabled: true
  retentionDays: 7             # days to keep completed entries (default: 7)

# Optional: catch up on missed messages after restart
historyFetch:
  enabled: true
  pollIntervalMinutes: 15      # periodic poll interval (default: 15)
  initialLookbackMinutes: 60   # first-run lookback window (default: 60)

# Optional: route engine to a third-party LLM provider
provider:
  baseUrl: "https://openrouter.ai/api"
  apiKey: "${OPENROUTER_API_KEY}"
  model: "anthropic/claude-sonnet-4"
  models:                            # per-engine overrides
    codex: "openai/gpt-4.1-mini"

# Optional: IM channel configuration
channels:
  feishu:
    appId: ${FEISHU_APP_ID}
    appSecret: ${FEISHU_APP_SECRET}
  dingtalk:
    clientId: ${DINGTALK_CLIENT_ID}
    clientSecret: ${DINGTALK_CLIENT_SECRET}
  wecom:
    botId: ${WECOM_BOT_ID}
    secret: ${WECOM_SECRET}

# Optional: gateway service configuration
gateway:
  port: 3000
  host: 127.0.0.1
  token: ${GOLEM_TOKEN}

Fields

Required

FieldTypeDescription
namestringAssistant name
enginestringEngine type: cursor, claude-code, opencode, or codex

Optional

FieldTypeDefaultDescription
modelstringPreferred model. Format varies by engine — see each engine's docs for valid values
skipPermissionsbooleantrueWhether to bypass agent permission prompts
codexobjectCodex-specific runtime options — see codex section
timeoutnumber300Engine invocation timeout in seconds. The underlying CLI process is killed and a type: 'error' event is emitted
maxConcurrentnumber10Maximum number of parallel chat() calls across all sessions
maxQueuePerSessionnumber3Maximum number of requests that can be queued per session key
sessionTtlDaysnumber30Sessions not used for this many days are pruned at next startup
systemPromptstringRole/persona instructions injected into AGENTS.md as a ## System Instructions section. The engine reads this once as system-level context — it is not prepended to every message, so token cost stays flat across multi-turn conversations
permissionsobjectGranular agent permissions — see permissions section. Currently Cursor engine only
streamingobjectStreaming message delivery for IM channels
tasksarrayScheduled tasks — see tasks section
channelsobjectIM channel configurations
inboxobjectPersistent message queue — see inbox section
historyFetchobjectHistory fetch for missed messages — see historyFetch section
oauthTokenstringClaude Max subscription token (from claude setup-token). Claude Code engine only — see Claude Code
personaobjectStructured agent identity — see persona section
providerobjectThird-party LLM provider routing — see Provider Routing
gatewayobjectGateway service settings

permissions

Granular agent access control. When configured, golembot init generates .cursor/cli.json and the Cursor engine omits --trust so the CLI enforces these rules.

Cursor only

Currently only the Cursor engine supports granular permissions via .cursor/cli.json. For other engines, this config is parsed but has no effect.

yaml
permissions:
  allowedPaths:
    - ./src
    - ./tests
  deniedPaths:
    - ./.env
    - ./secrets
  allowedCommands:
    - npm test
    - npm run build
  deniedCommands:
    - rm -rf *
FieldTypeDescription
allowedPathsstring[]Paths the agent is allowed to read/write (relative to workspace)
deniedPathsstring[]Paths the agent must not access
allowedCommandsstring[]Shell commands the agent is allowed to run
deniedCommandsstring[]Shell commands the agent must not run

All fields are optional. Empty or omitted arrays have no effect. Run golembot init after changing permissions to regenerate .cursor/cli.json.

codex

Codex-specific execution settings.

yaml
codex:
  mode: unrestricted
  sandbox: workspace-write
  approval: on-request
  search: false
  addDirs:
    - ../shared-assets
FieldTypeDefaultDescription
modestringunrestrictedCompatibility shorthand. unrestricted runs Codex with --dangerously-bypass-approvals-and-sandbox. safe uses --full-auto
sandboxstringFine-grained sandbox control: read-only, workspace-write, or danger-full-access
approvalstringFine-grained approval policy: untrusted, on-request, or never (passed before exec)
searchbooleanfalseEnable Codex live web search (--search, passed before exec)
addDirsstring[]Extra writable directories passed as --add-dir (resolved relative to the workspace when not absolute)

If sandbox or approval is set, GolemBot uses explicit --sandbox / --ask-for-approval flags and does not use mode. approval and search are forwarded as top-level Codex CLI flags before exec; sandbox and addDirs remain on the exec subcommand. When only one of sandbox or approval is set, the other defaults to workspace-write / on-request.

persona

Structured agent identity rendered into AGENTS.md. The role field is also propagated to fleet registration, enabling multi-bot peer awareness.

yaml
persona:
  role: product analyst
FieldTypeDescription
rolestringAgent's domain role (e.g. "product analyst", "customer support", "user researcher")
displayNamestringDisplay name (defaults to name)
tonestringCommunication style (e.g. "professional", "casual")
boundariesstring[]Topics or actions the agent should decline

You can also set the role during initialization with golembot init --role "product analyst".

streaming

Controls how the gateway delivers messages to IM channels.

FieldTypeDefaultDescription
modestringbufferedbuffered — accumulate the full reply and send once. streaming — send text incrementally at paragraph boundaries and tool call events
showToolCallsbooleanfalseWhen true, send a 🔧 toolName... hint to the chat each time the agent invokes a tool

In buffered mode (default), the bot waits until the agent finishes and sends one complete message. In streaming mode, the bot flushes text to IM at semantic boundaries:

  • Paragraph breaks (\n\n) — completed paragraphs are sent immediately
  • Tool calls — accumulated text is flushed before the tool hint
  • Done — any remaining text is flushed

Streaming mode provides faster visual feedback for long, multi-step agent responses.

yaml
streaming:
  mode: streaming
  showToolCalls: true

channels

Configure one or more IM platforms. Only configured channels are started by the gateway.

groupChat

Controls how the bot participates in group chats — response policies, @mention handling, quote reply, and group memory.

yaml
groupChat:
  groupPolicy: smart     # mention-only (default) | smart | always
  historyLimit: 30       # inject last 30 messages as context (default: 20)
  maxTurns: 5            # stop after 5 consecutive bot replies (default: 10)

See Group Chat for full details on policies, mention handling, quote reply, and group memory.

tasks

Define scheduled tasks that run automatically on a cron schedule. Each task sends a prompt to the engine and (optionally) delivers the result to an IM channel.

yaml
tasks:
  - id: daily-standup
    name: daily-standup
    schedule: "0 9 * * 1-5"
    prompt: |
      Summarize all git commits in the last 24 hours,
      grouped by author. Flag any breaking changes.
    enabled: true
    target:
      channel: feishu
      chatId: "oc_xxxxx"

See Scheduled Tasks for full configuration reference, schedule formats, management commands, and use case examples.

Conversation History

GolemBot automatically records conversations and restores context when sessions are lost. No configuration needed. See Memory for details.

provider

Route any engine to a third-party LLM API. See Provider Routing for full documentation.

FieldTypeDescription
baseUrlstringProvider API endpoint
apiKeystringAPI key (supports ${ENV_VAR} placeholders)
modelstringDefault model for all engines
modelsobjectPer-engine model overrides (key = engine name)
fallbackobjectSecondary provider config — GolemBot switches to this after consecutive failures. Same fields as provider (except nested fallback is ignored)
failoverThresholdnumberConsecutive errors before activating fallback (default: 3)

gateway

FieldTypeDefaultDescription
portnumber3000HTTP service port
hoststring127.0.0.1Bind address
tokenstringBearer token for HTTP API authentication

inbox

Persistent message queue — messages survive crashes and are consumed sequentially.

yaml
inbox:
  enabled: true          # default: false
  retentionDays: 7       # days to keep completed entries

historyFetch

Catch up on missed messages after restart with intelligent triage.

yaml
historyFetch:
  enabled: true
  pollIntervalMinutes: 15
  initialLookbackMinutes: 60

See Inbox & History Fetch for full details on crash recovery, smart triage, platform support, and deduplication.

Environment Variable Placeholders

Sensitive fields support ${ENV_VAR} syntax. At load time, GolemBot resolves these against process.env.

yaml
gateway:
  token: ${GOLEM_TOKEN}    # resolved from process.env.GOLEM_TOKEN

This works for all string values within channels and gateway blocks. Use a .env file alongside golem.yaml — the CLI auto-loads .env from the working directory at startup.

.env Example

sh
FEISHU_APP_ID=cli_xxxxxxxxxx
FEISHU_APP_SECRET=xxxxxxxxxx
GOLEM_TOKEN=my-secret-token
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxx

TIP

Add .env to .gitignore and commit .env.example (without real values) for sharing.

Model Names by Engine

The model value format is different for each engine:

EngineFormatExampleWhere to find values
cursorCursor model namesonnet-4.6Cursor → Settings → Models
claude-codeAnthropic model IDclaude-sonnet-4-6claude models
opencodeprovider/modelanthropic/claude-sonnet-4-5opencode models
codexOpenAI model namecodex-mini-latestcodex models

See the individual engine pages for full model tables and runtime override syntax.

Full Example

yaml
name: my-bot
engine: claude-code

groupChat:
  groupPolicy: smart
  historyLimit: 30
  maxTurns: 5

inbox:
  enabled: true
  retentionDays: 7

historyFetch:
  enabled: true
  pollIntervalMinutes: 15
  initialLookbackMinutes: 60

channels:
  slack:
    botToken: ${SLACK_BOT_TOKEN}
    appToken: ${SLACK_APP_TOKEN}

gateway:
  port: 3000
  token: ${GOLEM_TOKEN}

Dashboard Configuration Panel

When running golembot gateway, the web dashboard includes a Configuration Panel that displays all golem.yaml settings and supports inline editing — hover over a value, click the pencil button (✎), modify, and save. Changes are written to golem.yaml immediately.

For full details on the dashboard, inline editing workflow, and hot-reload vs restart behavior, see Dashboard.

Skills Are Not Configured

Skills are not declared in golem.yaml. The skills/ directory is the single source of truth — whatever skill directories exist, those capabilities are loaded. See Skills.

GolemConfig TypeScript Type

typescript
interface GolemConfig {
  name: string;
  engine: string;
  model?: string;
  skipPermissions?: boolean;
  codex?: {
    mode?: 'safe' | 'unrestricted';
    sandbox?: 'read-only' | 'workspace-write' | 'danger-full-access';
    approval?: 'untrusted' | 'on-request' | 'never';
    search?: boolean;
    addDirs?: string[];
  };
  timeout?: number;             // seconds, default 300
  maxConcurrent?: number;       // default 10
  maxQueuePerSession?: number;  // default 3
  sessionTtlDays?: number;      // default 30
  systemPrompt?: string;
  permissions?: {
    allowedPaths?: string[];
    deniedPaths?: string[];
    allowedCommands?: string[];
    deniedCommands?: string[];
  };
  streaming?: {
    mode?: 'buffered' | 'streaming';  // default: 'buffered'
    showToolCalls?: boolean;          // default: false
  };
  groupChat?: {
    groupPolicy?: 'mention-only' | 'smart' | 'always';  // default: 'mention-only'
    historyLimit?: number;   // default: 20
    maxTurns?: number;       // default: 10
  };
  tasks?: Array<{
    id: string;
    name: string;
    schedule: string;
    prompt: string;
    enabled?: boolean;       // default: true
    target?: {
      channel: string;
      chatId: string;
    };
  }>;
  channels?: {
    feishu?: { appId: string; appSecret: string };
    dingtalk?: { clientId: string; clientSecret: string };
    wecom?: {
      botId: string; secret: string; websocketUrl?: string;
    };
    slack?: { botToken: string; appToken: string };
    telegram?: { botToken: string };
    discord?: { botToken: string; botName?: string };
    // Custom adapter: any key with _adapter field
    [key: string]: { _adapter: string; [k: string]: unknown } | undefined;
  };
  inbox?: {
    enabled?: boolean;           // default: false
    retentionDays?: number;      // default: 7
  };
  historyFetch?: {
    enabled?: boolean;           // default: false
    pollIntervalMinutes?: number;    // default: 15
    initialLookbackMinutes?: number; // default: 60
  };
  provider?: {
    baseUrl?: string;
    apiKey?: string;
    model?: string;
    models?: Record<string, string>;
    fallback?: {                 // secondary provider for automatic failover
      baseUrl?: string;
      apiKey?: string;
      model?: string;
    };
    failoverThreshold?: number;  // default: 3
  };
  oauthToken?: string;           // Claude Max setup-token (claude-code engine only)
  gateway?: {
    port?: number;
    host?: string;
    token?: string;
  };
}

Released under the MIT License.