sark

Configuration

Every var and secret, with what happens if you leave it unset.

Secrets go in via wrangler secret put (or .dev.vars locally); everything else is a var.

wrangler.jsonc is a public template, not where your settings live. The values that identify a deployment — PUBLIC_URL, the allowlists, TEMPLATE_BOX_ID, and the worker name — belong in .deploy.env (gitignored), and npm run deploy injects them as wrangler overrides. npm run check-config fails if real values reach the tracked file, and runs in CI. The rest of the vars are ordinary tuning knobs and can be edited in place.

Secrets

If unset
BOX_API_KEYbox_... from the Box dashboard.Nothing works; every box call fails.
MCP_TOKEN_SECRETAny long random string. Signs thread-scoped MCP tokens.Tokens can't be minted or verified; the agent can never reply.
API_TOKENGuards /api.Every /api route returns 503, failing closed.
SLACK_BOT_TOKENxoxb-.... Optional.The bot can't post; threads fall back to MemoryTransport.
SLACK_SIGNING_SECRETOptional./slack/events and /slack/interactive return 503.

npm run dev-vars generates the first three for local development; see Install.

Vars

Defaults as committed:

wrangler.jsonc
"vars": {
  "TEMPLATE_BOX_ID": "",
  "BOX_BASE_URL": "https://ascii.dev/api/box/v1",
  "PUBLIC_URL": "https://<your-worker>.workers.dev",
  "BOX_PROVIDER": "claude-code",
  "BOX_MODEL": "",
  "BOX_TTL_SECONDS": "3600",
  "IDLE_STOP_SECONDS": "900",
  "PROMPT_HARD_CAP_SECONDS": "1200",
  "ALLOWED_CHANNELS": "",
  "ALLOWED_USERS": "",
  "ALLOWED_TEAMS": ""
}

PUBLIC_URL

The public origin of this Worker. Baked into each box's env as SLACK_MCP_URL (${PUBLIC_URL}/mcp) at fork time, and it's how the agent finds its way back.

If it's wrong or unreachable, every run falls through to the watchdog instead of the agent speaking for itself. Because box env is fixed at fork time, changing this does not update boxes that already exist.

TEMPLATE_BOX_ID

Box to fork per thread. Empty means each thread gets a fresh box: no repos, nothing installed. See Deploy.

BOX_BASE_URL

Box API v1 base. Only change it to point at a different Box deployment.

BOX_PROVIDER / BOX_MODEL

Which agent runs inside the box (claude-code by default) and, optionally, which model. An empty BOX_MODEL means the box's own default. sark does not interpret either value; they're passed straight through to POST /boxes/{id}/prompt.

Timers

All three parse as positive numbers, falling back to their default if unset, zero, negative, or unparseable.

Default
BOX_TTL_SECONDS3600TTL set on the box itself. Applied on create, or with a follow-up PATCH after a fork.
IDLE_STOP_SECONDS900Quiet period before a thread archives its box. Also the wake-up interval a finished thread schedules.
PROMPT_HARD_CAP_SECONDS1200Wall-clock cap on a single run. Past it, the watchdog gives up and says so.

Allowlists

Comma-separated Slack IDs; whitespace is trimmed and empty entries dropped.

ALLOWED_CHANNELSChannel IDs (C…) that may use the bot.
ALLOWED_USERSUser IDs (U…) that may use the bot anywhere.
ALLOWED_TEAMSWorkspace IDs (T…). When non-empty, the event's team must match.

Both channel and user lists empty means every mention is refused. See the allowlist.

Compile-time limits

These are constants in the source, not configuration. They're here so you know they exist.

ValueWhere
Prompt characters16,000MAX_PROMPT_CHARS
Queued messages per thread20MAX_QUEUED_PROMPTS
MCP batch size32MAX_BATCH_SIZE
MCP request body1 MBsrc/mcp/server.ts
Recorded messages kept500MAX_RECORDED
Token lifetime12 hoursTHREAD_TOKEN_MAX_AGE_SECONDS
Token refreshat half-life (6h)TOKEN_REFRESH_MS
Box readiness timeout180sBOX_READY_TIMEOUT_MS
Box poll interval2sBOX_POLL_MS
Watchdog interval5sWATCHDOG_MS
Slack event_ids remembered100alreadySeen

Durable Object binding

wrangler.jsonc
"durable_objects": {
  "bindings": [{ "name": "THREAD_SESSIONS", "class_name": "ThreadSession" }]
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["ThreadSession"] }]

new_sqlite_classes means the SQLite-backed Durable Object storage, which is not available on the Workers free plan.

On this page