Follow Discord
Sweep 06 Nov 2026 · 01:32Z Build v2.1.319 537 read Stable v2.1.311 Latest v2.1.318 Next v2.1.319 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Customize sessions in self-hosted environments changedself-hosted-environments-configuration

Nearest release: v2.1.319, published under an hour after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 6 Nov 2026 00:17 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 6 Nov 2026 00:37 UTC.

Upstream edited
Recorded here
Lines+11added
Lines−3removed
From line 42 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits43to this page, all time

### Pin a permission mode from your wrapper ### Pre-approve specific tools

The whole hunk

from line 42, old and new numbered
/
lines
from line 42
4242| `CLAUDE_CODE_REMOTE_SLACK_CHANNEL_ID` | For a Claude Tag session, the ID of the Slack channel or direct message that the session serves or that its thread is in, such as `C0123ABCDE`. A Slack timestamp identifies a message within one channel, so record this ID together with `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS`. Unset for other sessions, and can be unset for a Claude Tag session too. |
4343| `CLAUDE_SESSION_INGRESS_TOKEN_FILE` | Absolute path to a per-session file holding the current session JWT, kept fresh across token refreshes. Shell subprocesses read it for their `Authorization` header when downloading attachments the user added to the session. `exec` preserves the variable automatically; a wrapper that rebuilds the child's environment must carry the variable over, or attachment downloads silently stop working. |
4444| `CLAUDE_CONFIG_DIR` | Per-session Claude config directory, written at session start from the snapshot of the runner host's config that the runner captures at startup; see [Permissions and tool approval](#permissions-and-tool-approval). Writes here are isolated to this session. The directory stays under `<base-dir>/_sessions/` after the session ends unless you start the runner with [`--remove-session-state`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags); see [Reuse a pre-warmed checkout](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#reuse-a-pre-warmed-checkout). |
45| `CLAUDE_CODE_REMOTE_MCP_CONFIG` | Path to a file in `CLAUDE_CONFIG_DIR` holding the MCP server definitions that Anthropic's control plane delivered for this session. If your wrapper rebuilds the child's environment, carry this variable over. Without it, when the control plane updates the delivered servers, the child shuts down any stdio, HTTP, or SSE server your wrapper adds with [`--mcp-config`](https://code.claude.com/docs/en/cli-reference#cli-flags) that isn't in the update. Requires Claude Code v2.1.299 or later. |
45| `CLAUDE_CODE_REMOTE_MCP_CONFIG` | Path to a file in `CLAUDE_CONFIG_DIR` holding the control plane's delivered MCP servers. If your wrapper rebuilds the child's environment, carry this variable, [`CLAUDE_CODE_REMOTE`](https://code.claude.com/docs/en/env-vars#variables), and `CLAUDE_CODE_ENVIRONMENT_KIND` over unchanged; the runner sets all three. If `CLAUDE_CODE_REMOTE` arrives but this variable or `CLAUDE_CODE_ENVIRONMENT_KIND` doesn't, the child stops stdio, HTTP, and SSE servers your wrapper adds with [`--mcp-config`](https://code.claude.com/docs/en/cli-reference#cli-flags) that an update of the delivered servers omits. Requires Claude Code v2.1.299 or later. |
4646| `ANTHROPIC_BASE_URL` | The API base URL the child will use, delivered by the control plane per session and normally `https://api.anthropic.com`. Don't override it: the session's inference credential is an Anthropic-issued OAuth token that other providers don't accept. |
4747| `CLAUDE_CODE_OAUTH_TOKEN` | The short-lived OAuth access token the child uses for model inference, with a lifetime of about 30 minutes. The runner re-mints it before expiry and delivers the rotation over the child's stdin, so a wrapper that doesn't [keep stdin attached](#keep-stdin-and-file-descriptor-3-attached) sees only the initial value. Don't rely on your organization's IP allowlist to bound this token's use: treat it as a bearer credential that stays usable for roughly 30 minutes if it leaks, and don't log it, write it to disk, or forward it outside the session container. |
4848| `CLAUDE_RUNNER_ALIVE_EVERY_MS` | The runner sets how often, in milliseconds, the child reports that it's alive when a [turn starts before the child initializes](https://code.claude.com/docs/en/self-hosted-environments-reference.md#session-startup-timeout). If your wrapper rebuilds the child's environment, carry this variable over, or the runner can release the session during that turn and log `no child output for <n> — releasing`. Requires v2.1.309 or later on the runner and child. |
from line 824
824824 
825825A self-hosted session has no terminal attached, so an unanswered permission prompt stalls the turn until the user responds in the UI. Anthropic's control plane sends each session's tool list and permission rules with the work payload; the default configuration pre-approves routine tool calls, including `Bash`, and cloud sessions [pre-approve file edits regardless of mode](https://code.claude.com/docs/en/permission-modes.md#switch-permission-modes). A call that nothing pre-approves prompts through the session UI.
826826 
827### Pin a permission mode from your wrapper
828 
827829> [!NOTE]
828830>
829831> Only pin auto mode on an environment whose session containers run with [default-deny network egress](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#default-deny-egress) and the rest of the [hardening section](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#harden-your-deployment) in place. Routine tool calls, including `Bash` network requests, run without a human in the loop on both the default pre-approved tool set and in auto mode, so the network boundary is what limits where those calls can reach.
830832 
831To keep prompts to a minimum regardless of what the control plane sends, pin [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) from your wrapper script or [`command` hook](#command). Auto mode lets sessions run without routine permission prompts: a separate classifier model reviews actions before they run and blocks the ones it rejects, and explicit ask rules still force a prompt; the permission modes page covers what the classifier checks. The runner appends server-computed flags before invoking the wrapper, and for single-value flags such as `--permission-mode` the parser honors the last occurrence, so a flag you append after `"$@"` overrides the server-sent value:
833To start sessions in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) until claude.ai/code or another client sets a permission mode for them, pin it from your wrapper script or [`command` hook](#command). The runner invokes the wrapper with its own flags as arguments, and Claude Code applies the last `--permission-mode` on the command line, so append yours after `"$@"`:
832834 
833835```bash theme={null}
834836#!/bin/bash
from line 837
835837exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@" --permission-mode auto
836838```
837839 
838To pre-approve specific tools instead, append `--allowed-tools` with your rules, for example `--allowed-tools "Bash(bazel *) Bash(yarn *) mcp__internal__*"`. List flags such as `--allowed-tools` and `--disallowed-tools` accumulate across occurrences rather than overriding, so your rules apply on top of any rules the control plane sends. To narrow, append `--disallowed-tools`, which denies tools even if another rule allows them.
840Once a client sets a mode, your appended mode no longer applies, even after the session restarts on the runner. claude.ai/code, for example, sets one with the session's first message when its mode dropdown shows Auto, or when someone picked a mode there.
841 
842In auto mode, a separate classifier model reviews actions before they run and blocks the ones it rejects. An explicit ask rule still forces a prompt. A call that a [deny rule](https://code.claude.com/docs/en/permissions.md#manage-permissions) blocks stays blocked in every mode.
843 
844### Pre-approve specific tools
845 
846To pre-approve specific tools, append `--allowed-tools` with your rules after `"$@"` in your wrapper script, for example `--allowed-tools "Bash(bazel *) Bash(yarn *) mcp__internal__*"`. List flags such as `--allowed-tools` and `--disallowed-tools` accumulate across occurrences rather than overriding, so your rules apply on top of any rules the control plane sends. To narrow, append `--disallowed-tools`, which denies tools even if another rule allows them.
839847 
840848### How each session's config is assembled
841849 
Feedback