🏠 Home ← Docs Index
Open Beta 📖 Interactive Reader Raw .md llms.txt

GoClaw CLI Reference

The GoClaw gateway runs from a single binary. All commands are executed in the format goclaw <command>; goclaw <command> --help lists a command's flags.

Start Gateway: goclaw (without arguments) → HTTP/WS gateway starts (default port 8080).


Quick Start

goclaw setup              # Configuration wizard (first time)
goclaw quickstart         # Short setup wizard: which AI and its key, the agent's name and purpose
goclaw                    # Start gateway (after preparing config)
goclaw chat               # LLM chat (does not require gateway)
goclaw chat --debug       # Chat with debug logging

Setup & Configuration

goclaw setup              # Interactive wizard
goclaw quickstart         # Quick wizard (minimal prompts)

# Script-friendly (non-interactive)
goclaw setup --non-interactive \
  --auth-choice gemini-api-key \
  --gemini-api-key $GEMINI_KEY \
  --gateway-port 8080 \
  --gateway-bind lan

goclaw setup flags

--non-interactive writes a new config.yaml from the defaults and these flags, replacing one that is already there. Without --gateway-token it generates a token and prints it.

Flag Description
--non-interactive Non-interactive mode, writes config directly from flags
--auth-choice <provider> gemini-api-key | openai-api-key | anthropic-api-key | deepseek-api-key | ollama | custom-api-key
--gemini-api-key <key> Gemini API key
--openai-api-key <key> OpenAI API key
--anthropic-api-key <key> Anthropic API key
--deepseek-api-key <key> DeepSeek API key
--custom-base-url <url> Custom provider base URL (also the base URL for deepseek-api-key and ollama)
--custom-model-id <id> Custom model ID
--custom-api-key <key> Custom provider API key
--model <name> Specify model name (ignored for anthropic-api-key)
--workspace <path> Agent workspace path (default: ~/.goclaw/workspace)
--gateway-port <port> HTTP/WS port (default: 8080)
--gateway-bind loopback|lan Bind network interface (default: loopback)
--gateway-token <token> Static authentication token
--mode local|remote No effect: the config written is always for a local gateway
--remote-url <url> No effect: with --mode remote the URL is printed, not saved
--install-daemon No effect: prints a reminder to run goclaw service install
--skip-skills No effect

Gateway Runtime

goclaw                    # Start gateway
goclaw --debug            # Start gateway with debug logging
goclaw status             # Status of the running gateway
goclaw doctor             # Run health checks
goclaw version            # View version information

One gateway runs per state directory: a second one started on the same directory exits with another GoClaw gateway is already running.

goclaw doctor checks the config file, the state, workspace and memory directories, the secrets vault, the database and its memory schema, each configured integration (datasources, observability tools, GitLab, SonarQube, MCP servers, enabled channels, mail, and a live call to the AI provider and to each agent's fallback models), whether the gateway is running and, on Linux, whether the installed service starts at boot. A line marked ⚠ is a warning, not an issue: it works today, as an agent with no fallback model does until its provider is down.

status, sessions, message and the memory commands talk to the running gateway, which they find through <state dir>/gateway.lock, and send gateway.auth.token from config.yaml. They do not open the secrets vault: a token written as ${secret:NAME} is sent as written and refused. ${env:VAR} works.


Config Management

goclaw config get ai.provider
goclaw config set ai.provider=gemini
goclaw config set tools.git.allow_write=true
goclaw config append skills.allow=my-skill
goclaw config remove skills.deny=my-skill
goclaw config delete channels.msteams.webhook_port
Command Description
config get <key> Read config value
config set <key=value> Set config value
config append <key=value> Append value to list config
config remove <key=value> Remove value from list config
config delete <key> Remove the key itself, comments kept. Takes keys GoClaw does not know, so it clears a typo or a setting the start-up log reports as unknown or removed

Secrets

An encrypted vault (AES-256-GCM) for the credentials config.yaml refers to with ${secret:NAME}, so tokens never sit in the config file.

goclaw secret gen APP_KEY_ERP --provider app_api   # generate one, store, print once
goclaw secret set GEMINI_API_KEY AIza...           # store a value you already have
goclaw secret get GEMINI_API_KEY                   # print the decrypted value
goclaw secret list                                 # all secrets, values masked
goclaw secret list --show-values
goclaw secret delete GEMINI_API_KEY
Command Description
secret gen <key> Generate a random value, store it, and print it once
secret set <key> <value> Store a value you supply — takes both arguments
secret get <key> Print the decrypted value
secret list List names with masked values
secret delete <key> Remove a secret

secret gen is for the shared secrets GoClaw asks for but does not issue — channels.app_api.api_key, jwt_secret, webhook tokens. Run it once per calling system to give each its own credential:

goclaw secret gen APP_KEY_DJANGO --provider app_api
goclaw secret gen APP_KEY_ERP    --provider app_api
Flag Default Description
--length 32 Random bytes to generate (minimum 16)
--format hex Encoding of the stored value: hex or base64
--category api_key api_key, token, password, credential
--provider — Owning provider, e.g. app_api, gitlab
--force false Replace an existing secret of the same name

Regenerating over an existing name needs --force: it revokes whatever is still presenting the old value, and the only copy of that value is gone.

A running gateway picks up vault writes on its own: the secrets page re-reads the file per request. A ${secret:NAME} already expanded into the live config is refreshed on the next config load, so touch config.yaml after adding a secret the config refers to.

Set GOCLAW_SECRET_KEY on a production host before writing to the vault. Without it the passphrase is derived from machine and user identifiers — the gateway warns about this at startup — and the encryption offers little protection against someone who already has access to the host.

See Secrets architecture for the interpolation syntax and App API for issuing one key per caller.

Password generator

goclaw genpass (also gp, password) prints strong random passwords and stores nothing. To generate a value and keep it in the vault, use secret gen.

goclaw genpass                          # profile high: 24 characters, all character classes
goclaw genpass --profile ultra -n 5     # five passwords of 32 characters
goclaw genpass --profile pin -l 8       # an 8-digit PIN
goclaw genpass --no-symbols -l 20       # letters and digits only

Profiles: high (default, 24), ultra (32), pin (6 digits), alpha (20, no symbols); -l/--length changes the length.


Chat

goclaw chat           # Chat with default agent (does not require gateway)
goclaw chat --debug   # Chat with debug logging

Message

# Requires a running gateway
goclaw message "Hello from CLI"                    # channel: web
goclaw message discord "Deploy production please"
goclaw message msteams "Report is ready"

The agent answers the text and the command prints the reply; nothing is posted to the channel. With a single argument the channel is web: the text goes into the Web UI's admin conversation (admin-session) as the admin. With another channel it is answered as a message from a sender named cli on that channel, in the session p2p:cli:<default agent>.


Agents

goclaw agents list
goclaw agents add analyst
goclaw agents bind analyst discord
goclaw agents unbind analyst discord
goclaw agents delete analyst

Sessions

goclaw sessions list
goclaw sessions inspect

Memory

The memory commands go through the running gateway and stop with an error when it is not running. memory check and memory migrate open the database themselves and need no gateway. The commands that delete or rewrite records (clear, clear-user, forget, notes clear, notes purge, replay, migrate) first copy the database to <state dir>/backups/gc_state_<timestamp>.sqlite; dedupe and notes delete do not.

Command Description
memory check [--db PATH] [--json] Read-only health report: schema migrations, chunk types, oversized chunks, missing embeddings, orphaned and stale chunks. --db points it at another database file, a backup for example
memory stats Record and search-index statistics
memory reindex Rebuild the search index from all memory sources
memory export --file F / memory import --file F Knowledge catalog (agent notes and agent config) to or from a JSON file
memory replay [channel] [--dry-run] Restore Memory.md from session archives
memory relearn [--agent=ID] [--dry-run] [--force] Re-extract agent notes from session archives; --force also reprocesses archives that have not changed
memory revise [--dry-run] Retire learned facts and preferences that a newer one supersedes
memory revisions [--run ID] [--record ID] [--limit N] List those decisions, newest first (default 50)
memory revisions undo <memory-id> or --run <run-id> Restore a retired record, or everything one run retired. The same record does not replace it again
memory backfill-metadata [--batch-size N] [--dry-run] Extract topics and entities for records that have none (LLM calls; default 10 records per call)
memory migrate [--dry-run] Apply pending memory schema migrations; --dry-run lists the statements
memory prune [--stale=DAYS] [--min-len=N] Delete search-index chunks: those never read and indexed more than DAYS ago (default 90), and those shorter than N characters (default 80) indexed before the same cutoff. Memory records are not touched
memory dedupe [--ratio=R] Delete near-duplicate chunks of the same source, and duplicate agent notes (Jaccard similarity ≥ R, default 0.9)
memory forget [--older=AGE] Delete global-scope records created before AGE: 90d (default), 6m, 1y, or a date 2026-01-01
memory clear [--yes] Delete all memory records, every scope
memory clear-user <user-id> [--yes] Delete one user's personal records
memory notes list | grep | delete | clear | purge Manage agent notes
# Statistics and health
goclaw memory stats
goclaw memory check
goclaw memory check --db ~/.goclaw/backups/gc_state_20260405_120000.sqlite --json

# Export Knowledge Catalog to JSON
goclaw memory export --file catalog.json

# Import Knowledge Catalog
goclaw memory import --file catalog.json

# Rebuild/Reindex memory index
goclaw memory reindex

# Replay/Restore Memory.md from archive
goclaw memory replay discord
goclaw memory replay discord --dry-run

# Relearn agent notes from session archives
goclaw memory relearn                     # main agent (default)
goclaw memory relearn --agent=analyst      # specific agent
goclaw memory relearn --dry-run           # preview what facts would be generated

# Retire learned facts/preferences a newer one supersedes (tagged, never deleted)
goclaw memory revise --dry-run            # preview: each old record, what replaces it, and why
goclaw memory revise                      # apply
goclaw memory revisions                   # what was retired, by what, and why
goclaw memory revisions undo <memory-id>  # put one back

# Cleanup
goclaw memory prune                          # default: stale=90d, min-len=80
goclaw memory prune --stale=60               # chunks never read, indexed more than 60 days ago
goclaw memory prune --min-len=120            # also older chunks shorter than 120 characters

# Delete duplicate chunks and agent notes (Jaccard similarity)
goclaw memory dedupe                         # default ratio=0.9
goclaw memory dedupe --ratio=0.85

# Delete old global SQLite records
goclaw memory forget --older=6m
goclaw memory forget --older=1y
goclaw memory forget --older=2026-01-01

# Clear all memory
goclaw memory clear --yes
goclaw memory clear

# Clear specific user's personal memory
goclaw memory clear-user u_123456 --yes

# Manage agent notes
goclaw memory notes list
goclaw memory notes grep ticket
goclaw memory notes delete 100000000000000105
goclaw memory notes clear --yes
goclaw memory notes purge '%Table%does NOT exist%' --yes

--dry-run on prune, dedupe and forget only prints a note and exits: it previews nothing. Look first with memory check (stale and oversized chunks) and memory stats.

Recommended Workflow/Sequence:

goclaw memory stats               # 1. View current status
goclaw memory check               # 2. Stale, oversized and orphaned chunks (read-only)
goclaw memory notes list          # 3. Check agent notes
goclaw memory notes grep Table    # 4. Find incorrect notes
goclaw memory notes purge '%Table%' --yes  # 5. Delete incorrect notes
goclaw memory prune               # 6. Remove noise
goclaw memory dedupe              # 7. Remove duplicates
goclaw memory forget --older=6m   # 8. Delete old records
goclaw memory reindex             # 9. Rebuild index

How the agent uses memory: Memory and Context. The revision trail: Audit and undo.

Knowledge graph

The graph is kept in kg.sqlite in the state directory, or in the file memory.graph.path names. These commands open it and the main database directly.

Command Description
graph stats Entity, relation and topic counts, next to the entity and relation counts in the main database
graph check Graph reachable, tables readable, counts close to the main database's, one-hop traversal and full-text search working
graph migrate [--dry-run] Copy memory entities and relations from the main database into the graph. Safe to repeat
graph reindex [--dry-run] [--with-llm] [--scopes=global,personal] Sync each memory record's entities and relations into the graph; --with-llm also queues Gemini extraction for records that have none
graph cleanup [--dry-run] Delete entities no memory mentions, from the main database and the graph

Database Snapshots

goclaw db writes and reads .gclaw files: gzip-compressed JSON of the database tables, and optionally workspace files and wiki attachments. These commands open the database directly.

goclaw db export -o backup.gclaw                                   # the core tables
goclaw db export -o backup.gclaw --sessions --usage --files --attachments
goclaw db export -o ops.gclaw --agent-id=ops                       # one agent's rows
goclaw db inspect backup.gclaw                                     # manifest and row counts
goclaw db import -i backup.gclaw --dry-run
goclaw db import -i backup.gclaw --replace
Command / flag Description
db export Write a snapshot (default file goclaw-export_YYYY_MM_DD.gclaw, or -o/--output)
--agent-id <id> Only that agent's rows in the tables that have an agent_id column; other tables are exported whole
--sessions, --chunks, --executions, --usage Add conversation history, search-index chunks with embeddings (large), SOP run history, token and voice usage
--files, --attachments Add workspace markdown files; add wiki attachments with their files (large)
--no-compress Write plain JSON
db inspect <file> [--json] Print a snapshot's manifest and row counts per table
db import -i <file> Import a snapshot. A row whose key already exists is kept unless --replace; --dry-run writes nothing. What could not be imported is listed, and the command exits non-zero

The fleet toolkit fetches these snapshots from remote agents with make fetch_db.


Skills

goclaw skills list
goclaw skills install github:user/my-skills                      # every skills/**/SKILL.md in the repository
goclaw skills install github:user/my-skills/skills/foo/SKILL.md  # one file, from the main branch
goclaw skills install https://example.com/skills/foo/SKILL.md    # the SKILL.md file itself
goclaw skills install ./my-skill/                                # local directory or file
goclaw skills add github:user/my-skills                          # choose from a list
goclaw skills show git
goclaw skills remove my-skill
Command Description
skills list Loaded skills with their source and status
skills check [name] Binary dependencies of every skill; with a name, a compatibility report for that skill
skills scan [name] Security scan of all skills, or of one
skills install <source> [--force] Install from an http(s) URL, github:user/repo[/path/to/SKILL.md] or a local path
skills add <github:user/repo> [--force] Clone a repository and pick its skills from a list; without a terminal, every compatible skill is installed
skills show <name> Skill content and metadata
skills remove <name> Remove a user-installed skill

A URL must point at a SKILL.md file: what it returns is saved as the skill, so a repository's web page (https://github.com/user/my-skill) would be saved as HTML. For a repository use github:user/my-skill, which clones it with git. Every install, local paths included, runs a compatibility check first and stops on a FAIL verdict; --force installs anyway. Every skill an install or add puts in place is then security-scanned, and one with a critical finding is removed again (the command exits non-zero). A repository with a single SKILL.md at its root is installed under the repository's name. Skills are installed under <state dir>/skills/.


Tools — Offline Testing & Debugging

goclaw tools allows calling registered tools directly from the CLI without an LLM. There is no need for the gateway to be running — the configuration and SQLite store will load automatically.

Subcommands

Command Description
tools list List all registered tools
tools exec <tool> [k=v ...] Execute a tool directly and print the full output
tools bench <tool> [k=v ...] [--runs=N] Measure tool execution speed
# List all tools
goclaw tools list

# Execute tool directly
goclaw tools exec datetime
goclaw tools exec datetime action=diff from=2026-01-01 to=2026-03-30
goclaw tools exec gitlab action=mrs_list project=myorg/backend
goclaw tools exec db_query datasource=main query="SELECT count(*) FROM users"
goclaw tools exec memory_search query='deploy error' max_results=10

# Benchmark execution speed
goclaw tools bench datetime action=now --runs=50
goclaw tools bench db_query datasource=main query='SELECT 1' --runs=20

Output Example:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Tool:  datetime
Args:  {"action":"now"}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2026-03-30T08:45:00+08:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Time: 1ms | Chars: 25 | Lines: 1

Arg Type Coercion

Values are automatically coerced into types. The shell removes one level of quotes before goclaw sees an argument, so the examples below are written as you type them:

You type Tool receives Description
limit=5 number Every number is a float64, as in a model's tool call
ratio=0.85 number Floating-point number
active=true bool Boolean
name=hello string Simple text
"id='12345'" string Quotes that reach goclaw keep the value a string, not a number
'filter={"k":"v"}' JSON object JSON object; quote it, or the shell strips its quotes
'tags=["a","b"]' JSON array JSON array; quote it, or the shell strips its quotes (zsh also reads [...] as a glob)

→ For detailed examples of all tools, see the Tool Execution Reference page.


Teams Integration

goclaw teams setup    # Fully interactive configuration wizard

# Package from channels.msteams.* in config.yaml
goclaw teams package

# Or give the values as flags: zip + config
goclaw teams package \
  --app-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  --app-password="YOUR_CLIENT_SECRET" \
  --tenant-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  --app-name="GoClaw Bot" \
  --icon-source=./logo.png \
  --out="./teams-app.zip"

# A changed package for an app already in Teams: raise the version
goclaw teams package --app-version=1.0.1

Every flag overrides a value from config.yaml; only the App ID has to come from one or the other. --app-id, --app-password and --tenant-id given as flags are also written to channels.msteams.* in config.yaml (--app-id sets channels.msteams.enabled: true too) once the package is built, and so are the four publisher flags, under channels.msteams.app_package. A package Teams would refuse (an App ID that is not a GUID, a version not of the form 1.0.1, an image that gives no valid icon) is not written.

Flag Default Description
--app-id channels.msteams.app_id Microsoft App ID of the Azure Bot (required here or in config.yaml)
--app-password channels.msteams.app_password Client Secret value
--tenant-id channels.msteams.tenant_id Directory (tenant) ID, for a single-tenant bot
--app-name channels.msteams.bot_name, else GoClaw Bot Bot name in Teams (cut to 30 characters for name.short)
--app-version 1.0.0 Manifest version; raise it for every changed package of an app already uploaded
--developer-name channels.msteams.app_package.developer_name, else Ulab LLC Publisher shown on the app's page in Teams, at most 32 characters
--website-url channels.msteams.app_package.website_url, else https://goclaw.ulab.mn/ Publisher's website (https://)
--privacy-url channels.msteams.app_package.privacy_url, else https://goclaw.ulab.mn/privacy.html Privacy policy (https://)
--terms-of-use-url channels.msteams.app_package.terms_of_use_url, else https://goclaw.ulab.mn/terms.html Terms of use (https://)
--out ./teams-app.zip Zip output path
--icon-source GoClaw's own icons PNG, JPEG or GIF file or http(s) URL, resized to the 192×192 color and 32×32 outline icons
--ffmpeg — Deprecated and ignored: icons are resized without ffmpeg

⚠️ --app-id must be the Microsoft App ID from Azure Bot → Configuration.

→ Read more: MS Teams Channel Setup


GitLab Webhooks

goclaw gitlab hook setup                               # wizard: GitLab webhook, GoClaw route and vault secret
goclaw gitlab hook list
goclaw gitlab hook test <key>                          # default trigger: push_events
goclaw gitlab hook test <key> --trigger issues_events
goclaw gitlab hook remove <key>                        # from GitLab and GoClaw
goclaw gitlab hook remove <key> --keep-route           # from GitLab only
goclaw gitlab hook remove <key> --keep-gitlab          # from GoClaw only

→ Read more: GitLab Webhook Integration


Pairing

goclaw pairing pending [channel]                       # pending requests (default channel: discord)
goclaw pairing list [channel]                          # approved users (default channel: discord)
goclaw pairing approve <CODE>                          # role user
goclaw pairing approve <CODE> --role admin
goclaw pairing revoke <user-id>                        # the u_… ID that approve prints
goclaw pairing link <user-id> <channel> <account-id>   # add a channel account to an existing user

While the gateway is running, approve on the Web UI's Pairing tab or through the API. The running gateway does not see a pairing change made with the CLI until it restarts, and its next write to the pairing files can drop it. See Pairing: REST API.


Service (OS Daemon)

goclaw service install                  # Install per-user systemd / launchd service
sudo goclaw service install --system    # Install system service (runs as your user)
goclaw service uninstall                # Uninstall service
goclaw service start                    # Start service
goclaw service stop                     # Stop service
goclaw service restart                  # Restart service
goclaw service status                   # Show service status

goclaw service install writes a per-user service; sudo goclaw service install --system writes a system service that still runs as an ordinary user: the one who ran sudo, or the one --run-as <user> names. Its data is in that user's ~/.goclaw. On Linux a per-user service starts at boot only while lingering is on for its user; install turns it on, or prints sudo loginctl enable-linger <user> when it cannot. An installed service keeps the settings of the version that wrote it: to write it again, run goclaw service uninstall and then goclaw service install. goclaw doctor says when an installed service will not start at boot, and how to fix it. goclaw service start on a service that already runs says so and exits 0; goclaw service restart stops it first and starts the new binary. On macOS both also start a job launchd has loaded but is not running (one that crashed), which launchctl load refuses with "Load failed: 5: Input/output error".

goclaw service status says whether the service runs and where its logs are: the gateway's own log (~/.goclaw/logs/gateway.log, or logging.file.path), and on macOS what the service printed (~/Library/Logs/goclaw.stdout.log and goclaw.stderr.log, where a crash at start-up shows). On Linux it gives the journalctl commands.

On a Mac, the service can wait for someone to click Allow. macOS asks at the Mac's screen, and whoever installs the service over SSH or a terminal does not see it:

macOS sees an unsigned program as new after every update, so both can ask again. goclaw service install, start, status and goclaw doctor say which of them applies to this Mac, with the command to run.

Per-user --system
Linux (systemd) ~/.config/systemd/user/goclaw.service /etc/systemd/system/goclaw.service
macOS (launchd) ~/Library/LaunchAgents/goclaw.plist /Library/LaunchDaemons/goclaw.plist

On Linux the service logs to the journal; on macOS to ~/Library/Logs/goclaw.stdout.log and goclaw.stderr.log.


Update

goclaw update                     # the latest release
goclaw update --backup            # back up database and state files before updating
goclaw update --version v0.0.96   # a given release
goclaw update --force             # install even when that version is already running

goclaw update reads the latest version from https://goclaw.ulab.mn/releases/latest.json, downloads the binary for this platform to a temporary file, checks its SHA-256 against the release's checksums.json (and on macOS its code signature, when the binary is signed), keeps the current binary as <binary>.prev, puts the new one in its place and restarts the installed service. With --backup, it first snapshots the SQLite databases (gc_state.sqlite, kg.sqlite) and state files (config.yaml, credentials/, workspace/, agents/, memory/, skills/, extensions/, plugins/) to ~/.goclaw/backups/goclaw-backup_<version>_<new-version>_<timestamp>.tar.gz (keeping the 3 most recent update archives). When the binary directory (such as /usr/local/bin) or a --system service requires root and goclaw update was run without sudo, it asks for sudo; when run as sudo goclaw update on a host with a per-user service, it restarts the invoking user's service as that user rather than root's. The fleet toolkit runs it on several hosts.

The site keeps only the newest release. When it does not answer, or does not have the version asked for, goclaw update downloads from the release bucket, https://storage.googleapis.com/goclaw-releases/releases/, which keeps every release from v0.2.2 on; so --version can also go back to an earlier one. The binary is checked against the checksums.json it came with either way.


Transcribe

goclaw transcribe audio.wav
goclaw transcribe audio.wav --language mn

SBOM

goclaw sbom                                    # summary of the modules compiled in
goclaw sbom -f cyclonedx -o goclaw.cdx.json    # CycloneDX 1.5 JSON
goclaw sbom -f spdx -o goclaw.spdx.json        # SPDX 2.3 JSON
goclaw sbom -f json                            # JSON summary

→ Read more: SBOM & supply chain


Version

goclaw version

Output:

goclaw v1.2.3
  commit : abc1234
  built  : 2026-04-03T14:53:00Z

Shell Completion

goclaw completion bash > /etc/bash_completion.d/goclaw
goclaw completion zsh > "${fpath[1]}/_goclaw"
goclaw completion fish > ~/.config/fish/completions/goclaw.fish
goclaw completion powershell

Environment Variables

Variable Description
GOCLAW_STATE_DIR State directory: config.yaml, database, vault, workspace, logs (default ~/.goclaw)
GOCLAW_HOME Home directory to look for .goclaw in, when GOCLAW_STATE_DIR is not set
GOCLAW_SECRET_KEY Passphrase of the secrets vault (see Secrets)
PORT Overrides server.port
AI_PROVIDER Overrides ai.provider
DEBUG 1 or true: debug logging in the gateway, as --debug
GOCLAW_LOG_PROMPTS 1 or true: write every prompt and response to the log in full. They carry memory and tool results, so credentials and customer data can end up in the log
GOCLAW_DEBUG 1: CLI commands print how they look for the running gateway

API keys and tokens are set in config.yaml, not read from environment variables of their own. To keep one out of the file, write a reference in its field: ${GEMINI_API_KEY}, ${env:VAR}, ${secret:NAME} or ${file:/path} (see Configuration Interpolation). Two fallbacks exist: with ai.gemini.api_key empty, the Gemini chat client takes GEMINI_API_KEY or GOOGLE_API_KEY from the environment, and so do the background model calls (the session summarizer, fact extraction, the belief-revision judge, consolidation, memory_replay, skill quality checks and the Draft buttons), which ask the default agent's own model when there is no Gemini key in either place; and memory embeddings take GEMINI_API_KEY or OPENAI_API_KEY when ai.gemini.api_key or ai.openai.api_key is empty.