2025-12-09 17:51:05 +00:00
---
summary: "All configuration options for ~/.clawdis/clawdis.json with examples"
read_when:
- Adding or modifying config fields
---
2025-12-13 13:25:49 +00:00
<!-- {% raw %} -->
2025-12-03 15:45:32 +00:00
# Configuration 🔧
2025-12-13 13:25:49 +00:00
CLAWDIS reads an optional **JSON5** config from `~/.clawdis/clawdis.json` (comments + trailing commas allowed).
2025-12-03 15:45:32 +00:00
2025-12-17 11:29:12 +01:00
If the file is missing, CLAWDIS uses safe-ish defaults (embedded Pi agent + per-sender sessions + workspace `~/clawd` ). You usually only need a config to:
2025-12-13 13:25:49 +00:00
- restrict who can trigger the bot (`inbound.allowFrom` )
- tune group mention behavior (`inbound.groupChat` )
2025-12-17 11:29:12 +01:00
- set the agent’ s workspace (`inbound.workspace` )
- tune the embedded agent (`inbound.agent` ) and session behavior (`inbound.session` )
- set the agent’ s identity (`identity` )
2025-12-03 15:45:32 +00:00
2025-12-13 13:25:49 +00:00
## Minimal config (recommended starting point)
2025-12-03 15:45:32 +00:00
2025-12-13 13:25:49 +00:00
```json5
2025-12-03 15:45:32 +00:00
{
2025-12-13 13:25:49 +00:00
inbound: {
2025-12-17 11:29:12 +01:00
allowFrom: ["+15555550123"],
workspace: "~/clawd"
2025-12-03 15:45:32 +00:00
}
}
```
2025-12-13 13:25:49 +00:00
## Common options
2025-12-03 15:45:32 +00:00
2025-12-14 04:21:27 +00:00
### `identity`
Optional agent identity used for defaults and UX. This is written by the macOS onboarding assistant.
If set, CLAWDIS derives defaults (only when you haven’ t set them explicitly):
- `inbound.responsePrefix` from `identity.emoji`
- `inbound.groupChat.mentionPatterns` from `identity.name` (so “@Samantha ” works in groups)
```json5
{
identity: { name: "Samantha", theme: "helpful sloth", emoji: "🦥" }
}
```
2025-12-03 15:45:32 +00:00
### `logging`
2025-12-13 13:25:49 +00:00
- Default log file: `/tmp/clawdis/clawdis-YYYY-MM-DD.log`
- If you want a stable path, set `logging.file` to `/tmp/clawdis/clawdis.log` .
2025-12-21 13:23:42 +00:00
- Console output can be tuned separately via:
- `logging.consoleLevel` (defaults to `info` , bumps to `debug` when `--verbose` )
- `logging.consoleStyle` (`pretty` | `compact` | `json` )
2025-12-13 13:25:49 +00:00
```json5
{
2025-12-21 13:23:42 +00:00
logging: {
level: "info",
file: "/tmp/clawdis/clawdis.log",
consoleLevel: "info",
2025-12-21 13:34:13 +00:00
consoleStyle: "pretty"
2025-12-21 13:23:42 +00:00
}
2025-12-13 13:25:49 +00:00
}
```
2025-12-03 15:45:32 +00:00
### `inbound.allowFrom`
2025-12-13 13:25:49 +00:00
Allowlist of E.164 phone numbers that may trigger auto-replies.
2025-12-03 15:45:32 +00:00
2025-12-13 13:25:49 +00:00
```json5
{
inbound: { allowFrom: ["+15555550123", "+447700900123"] }
}
2025-12-03 15:45:32 +00:00
```
### `inbound.groupChat`
2025-12-22 19:32:12 +01:00
Group messages default to **require mention** (either metadata mention or regex patterns). You can switch to always-on activation.
2025-12-03 15:45:32 +00:00
2025-12-13 13:25:49 +00:00
```json5
{
inbound: {
groupChat: {
2025-12-22 19:32:12 +01:00
activation: "mention", // mention | always
2025-12-13 13:25:49 +00:00
mentionPatterns: ["@clawd ", "clawdbot", "clawd"],
historyLimit: 50
}
}
}
```
2025-12-13 02:34:11 +00:00
2025-12-22 19:32:12 +01:00
Notes:
- `activation` defaults to `mention` .
- `requireMention` is still supported for backwards compatibility (`false` ≈ `activation: "always"` ).
2025-12-17 11:29:12 +01:00
### `inbound.workspace`
2025-12-13 02:34:11 +00:00
2025-12-17 11:29:12 +01:00
Sets the **single global workspace directory** used by the agent for file operations.
2025-12-13 02:34:11 +00:00
2025-12-17 11:29:12 +01:00
Default: `~/clawd` .
2025-12-13 02:34:11 +00:00
2025-12-17 11:29:12 +01:00
```json5
{
inbound: { workspace: "~/clawd" }
}
```
2025-12-14 04:21:27 +00:00
2025-12-17 11:29:12 +01:00
### `inbound.agent`
Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts).
2025-12-13 02:34:11 +00:00
```json5
{
2025-12-13 13:25:49 +00:00
inbound: {
2025-12-17 11:29:12 +01:00
workspace: "~/clawd",
agent: {
provider: "anthropic",
model: "claude-opus-4-5",
thinkingDefault: "low",
verboseDefault: "off",
timeoutSeconds: 600,
mediaMaxMb: 5,
2025-12-13 13:25:49 +00:00
heartbeatMinutes: 30,
2025-12-17 11:29:12 +01:00
contextTokens: 200000
2025-12-13 13:25:49 +00:00
}
2025-12-13 02:34:11 +00:00
}
}
```
2025-12-17 11:29:12 +01:00
### `inbound.session`
Controls session scoping, idle expiry, reset triggers, and where the session store is written.
```json5
{
inbound: {
session: {
scope: "per-sender",
idleMinutes: 60,
resetTriggers: ["/new"],
store: "~/.clawdis/sessions/sessions.json",
mainKey: "main"
}
}
}
```
2025-12-14 02:59:31 +00:00
2025-12-20 12:23:53 +00:00
### `skills` (skill config/env)
2025-12-20 12:22:15 +01:00
2025-12-20 12:23:53 +00:00
Configure skill toggles and env injection. Applies to **bundled** skills and `~/.clawdis/skills` (workspace skills still win on name conflicts).
2025-12-20 12:22:15 +01:00
Common fields per skill:
2025-12-20 12:23:53 +00:00
- `enabled` : set `false` to disable a skill even if it’ s bundled/installed.
2025-12-20 12:22:15 +01:00
- `env` : environment variables injected for the agent run (only if not already set).
- `apiKey` : optional convenience for skills that declare a primary env var (e.g. `nano-banana-pro` → `GEMINI_API_KEY` ).
Example:
```json5
{
skills: {
"nano-banana-pro": {
apiKey: "GEMINI_KEY_HERE",
env: {
GEMINI_API_KEY: "GEMINI_KEY_HERE"
}
},
peekaboo: { enabled: true },
sag: { enabled: false }
}
}
```
2025-12-20 17:13:36 +01:00
### `skillsInstall` (installer preference)
Controls which installer is surfaced by the macOS Skills UI when a skill offers
2025-12-20 17:31:09 +01:00
multiple install options. Defaults to **brew when available** and **npm** for
node installs.
2025-12-20 17:13:36 +01:00
```json5
{
skillsInstall: {
preferBrew: true,
2025-12-20 17:31:09 +01:00
nodeManager: "npm" // npm | pnpm | yarn
2025-12-20 17:13:36 +01:00
}
}
```
2025-12-20 12:26:58 +00:00
### `skillsLoad`
Additional skill directories to scan (lowest precedence). This is useful if you keep skills in a separate repo but want Clawdis to pick them up without copying them into the workspace.
```json5
{
skillsLoad: {
extraDirs: [
"~/Projects/agent-scripts/skills",
"~/Projects/oss/some-skill-pack/skills"
]
}
}
```
2025-12-13 15:15:09 +00:00
### `browser` (clawd-managed Chrome)
Clawdis can start a **dedicated, isolated** Chrome/Chromium instance for clawd and expose a small loopback control server.
Defaults:
- enabled: `true`
2025-12-13 15:29:39 +00:00
- control URL: `http://127.0.0.1:18791` (CDP uses `18792` )
2025-12-13 15:15:09 +00:00
- profile color: `#FF4500` (lobster-orange)
2025-12-13 17:37:00 +00:00
- Note: the control server is started by the running gateway (Clawdis.app menubar, or `clawdis gateway` ).
2025-12-13 15:15:09 +00:00
```json5
{
browser: {
enabled: true,
2025-12-13 15:29:39 +00:00
controlUrl: "http://127.0.0.1:18791",
2025-12-13 15:15:09 +00:00
color: "#FF4500 ",
// Advanced:
// headless: false,
// attachOnly: false,
}
}
```
2025-12-20 02:08:04 +00:00
### `gateway` (Gateway server mode + bind)
Use `gateway.mode` to explicitly declare whether this machine should run the Gateway.
Defaults:
- mode: **unset** (treated as “do not auto-start”)
- bind: `loopback`
```json5
{
gateway: {
mode: "local", // or "remote"
bind: "loopback",
// controlUi: { enabled: true }
2025-12-21 00:44:39 +00:00
// auth: { mode: "token" | "password" | "system" }
// tailscale: { mode: "off" | "serve" | "funnel" }
2025-12-20 02:08:04 +00:00
}
}
```
Notes:
- `clawdis gateway` refuses to start unless `gateway.mode` is set to `local` (or you pass the override flag).
2025-12-21 00:44:39 +00:00
Auth and Tailscale:
- `gateway.auth.mode` sets the handshake requirements (`token` , `password` , or `system` /PAM).
- When `gateway.auth.mode` is set, only that method is accepted (plus optional Tailscale headers).
- `gateway.auth.password` can be set here, or via `CLAWDIS_GATEWAY_PASSWORD` (recommended).
- `gateway.auth.username` defaults to the current OS user; override with `CLAWDIS_GATEWAY_USERNAME` .
- `gateway.auth.allowTailscale` controls whether Tailscale identity headers can satisfy auth.
- `gateway.tailscale.mode: "serve"` uses Tailscale Serve (tailnet only, loopback bind).
- `gateway.tailscale.mode: "funnel"` exposes the dashboard publicly; requires auth.
- `gateway.tailscale.resetOnExit` resets Serve/Funnel config on shutdown.
2025-12-20 17:31:09 +01:00
### `canvasHost` (LAN/tailnet Canvas file server + live reload)
2025-12-18 11:36:46 +01:00
2025-12-20 17:31:09 +01:00
The Gateway serves a directory of HTML/CSS/JS over HTTP so iOS/Android nodes can simply `canvas.navigate` to it.
2025-12-18 11:36:46 +01:00
Default root: `~/clawd/canvas`
2025-12-20 17:31:09 +01:00
Default port: `18793` (chosen to avoid the clawd browser CDP port `18792` )
2025-12-20 22:25:09 +01:00
The server listens on the **bridge bind host** (LAN or Tailnet) so nodes can reach it.
2025-12-18 11:36:46 +01:00
2025-12-18 23:32:48 +01:00
The server:
2025-12-18 11:36:46 +01:00
- serves files under `canvasHost.root`
- injects a tiny live-reload client into served HTML
2025-12-20 17:31:09 +01:00
- watches the directory and broadcasts reloads over a WebSocket endpoint at `/__clawdis/ws`
2025-12-18 23:32:48 +01:00
- auto-creates a starter `index.html` when the directory is empty (so you see something immediately)
2025-12-20 22:25:09 +01:00
- also serves A2UI at `/__clawdis__/a2ui/` and is advertised to nodes as `canvasHostUrl`
(always used by nodes for Canvas/A2UI)
2025-12-18 11:36:46 +01:00
```json5
{
canvasHost: {
2025-12-20 17:31:09 +01:00
root: "~/clawd/canvas",
port: 18793
2025-12-18 11:36:46 +01:00
}
}
```
2025-12-18 23:32:48 +01:00
Disable with:
- config: `canvasHost: { enabled: false }`
- env: `CLAWDIS_SKIP_CANVAS_HOST=1`
2025-12-18 13:18:33 +01:00
### `bridge` (node bridge server)
2025-12-17 17:01:10 +01:00
2025-12-18 13:18:33 +01:00
The Gateway can expose a simple TCP bridge for nodes (iOS/Android), typically on port `18790` .
2025-12-17 17:01:10 +01:00
Defaults:
- enabled: `true`
- port: `18790`
- bind: `lan` (binds to `0.0.0.0` )
Bind modes:
- `lan` : `0.0.0.0` (reachable on any interface, including LAN/Wi‑ Fi and Tailscale)
- `tailnet` : bind only to the machine’ s Tailscale IP (recommended for Vienna ⇄ London)
- `loopback` : `127.0.0.1` (local only)
- `auto` : prefer tailnet IP if present, else `lan`
```json5
{
bridge: {
enabled: true,
port: 18790,
bind: "tailnet"
}
}
```
### `discovery.wideArea` (Wide-Area Bonjour / unicast DNS‑ SD)
When enabled, the Gateway writes a unicast DNS-SD zone for `_clawdis-bridge._tcp` under `~/.clawdis/dns/` using the standard discovery domain `clawdis.internal.`
To make iOS/Android discover across networks (Vienna ⇄ London), pair this with:
- a DNS server on the gateway host serving `clawdis.internal.` (CoreDNS is recommended)
- Tailscale **split DNS** so clients resolve `clawdis.internal` via that server
One-time setup helper (gateway host):
```bash
clawdis dns setup --apply
```
```json5
{
discovery: { wideArea: { enabled: true } }
}
```
2025-12-13 13:25:49 +00:00
## Template variables
2025-12-03 15:45:32 +00:00
2025-12-17 11:29:12 +01:00
Template placeholders are expanded in `inbound.transcribeAudio.command` (and any future templated command fields).
2025-12-03 15:45:32 +00:00
| Variable | Description |
|----------|-------------|
2025-12-13 13:25:49 +00:00
| `{{Body}}` | Full inbound message body |
| `{{BodyStripped}}` | Body with group mentions stripped (best default for agents) |
| `{{From}}` | Sender identifier (E.164 for WhatsApp; may differ per surface) |
| `{{To}}` | Destination identifier |
| `{{MessageSid}}` | Provider message id (when available) |
2025-12-03 15:45:32 +00:00
| `{{SessionId}}` | Current session UUID |
2025-12-13 13:25:49 +00:00
| `{{IsNewSession}}` | `"true"` when a new session was created |
| `{{MediaUrl}}` | Inbound media pseudo-URL (if present) |
| `{{MediaPath}}` | Local media path (if downloaded) |
| `{{MediaType}}` | Media type (image/audio/document/…) |
| `{{Transcript}}` | Audio transcript (when enabled) |
| `{{ChatType}}` | `"direct"` or `"group"` |
| `{{GroupSubject}}` | Group subject (best effort) |
| `{{GroupMembers}}` | Group members preview (best effort) |
| `{{SenderName}}` | Sender display name (best effort) |
| `{{SenderE164}}` | Sender phone number (best effort) |
| `{{Surface}}` | Surface hint (whatsapp|telegram|webchat|…) |
## Cron (Gateway scheduler)
Cron is a Gateway-owned scheduler for wakeups and scheduled jobs. See [Cron + wakeups ](./cron.md ) for the full RFC and CLI examples.
2025-12-03 15:45:32 +00:00
2025-12-13 13:25:49 +00:00
```json5
{
cron: {
enabled: true,
maxConcurrentRuns: 2
}
2025-12-03 15:45:32 +00:00
}
```
---
2025-12-17 11:29:12 +01:00
*Next: [Agent Runtime ](./agent.md )* 🦞
2025-12-13 13:25:49 +00:00
<!-- {% endraw %} -->