← All changelogs v2.1.211 claude · claude-sonnet-4-6
Claude Code · Source-level changelog

Version 2.1.211

This release adds a new RefreshMcpTools built-in tool for re-syncing MCP server tool lists, a --forward-subagent-text CLI flag for streaming subagent output in print mode, and screenshot save-to-disk support for Claude in Chrome. The Claude Design permission model is significantly reworked from time-limited project grants to permanent durable write grants. Several improvements land for Windows Claude in Chrome browser resolution, macOS terminal bell behavior, and OAuth lock handling.

Official notes ✓ synced Package @anthropic-ai/claude-code Diff v2.1.210 → v2.1.211Provider claudeModel claude-sonnet-4-6
13
Features & Changes
4
Bug Fixes
0
In Development
0
Env Vars / Flags

Official Changelog

Official · Anthropic
Anthropic’s official release notes
Published verbatim by Anthropic for v2.1.211 — shown here alongside the source-level analysis below. Text is unmodified from the upstream changelog.
View on GitHub ↗
  • Added --forward-subagent-text flag and CLAUDE_CODE_FORWARD_SUBAGENT_TEXT environment variable to include subagent text and thinking in stream-json output
  • Fixed permission previews relayed to chat channels not neutralizing bidirectional-override, zero-width, and look-alike quote characters, so tool inputs cannot visually alter the approval message
  • Fixed auto mode overriding a PreToolUse hook's ask decision for unsandboxed Bash — a hook ask now floors the decision at a prompt
  • Fixed parallel Claude Code sessions all logging out simultaneously after wake-from-sleep when many sessions share one credential store
  • Fixed plugin MCP servers not reconnecting after an idle web session woke, leaving MCP calls failing until the next message
  • Fixed Claude Code on Vertex and Bedrock attempting the default Opus model at startup and printing a spurious fallback notice when a model is explicitly configured
  • Fixed subagents spawned with an explicit model override reverting to the parent's model when resumed or sent a follow-up message
  • Fixed nested .claude/rules/*.md files loading even when setting sources exclude project settings
  • Fixed file upload validation: filenames ending in a DOS device suffix (.prn) or trailing dot are now accepted, and files with multiple hard links are refused
  • Fixed file uploads to Claude in Chrome from remote and CLI sessions
  • Fixed edits that leave the input as "?" being silently swallowed and toggling the shortcuts panel
  • Fixed a startup hang when the Claude in Chrome extension is enabled but Chrome is not running
  • Fixed a 300ms delay revealing async content (Settings tabs, Stats, diff views, and other loading states)
  • Fixed reopening a just-stopped background session from the agents view starting a blank conversation under the same session id
  • Fixed /loop hiding the session from /resume after a single use
  • Fixed screen reader users losing the audible terminal bell after /terminal-setup or onboarding terminal setup
  • Fixed background jobs on LLM gateway auth (ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL) coming back "Not logged in" after the daemon respawns them
  • Fixed claude agents jobs becoming permanently undeletable when git no longer recognizes their worktree — the row now shows why the delete was refused instead of silently reappearing
  • Fixed /clear not resetting the session cost counter — the statusline's cost now starts at $0 after /clear
  • Fixed Claude in Chrome setup pages failing to open in the browser on Windows
  • Fixed headless print-mode sessions on Windows crashing or silently exiting when stdin is unreadable
  • Fixed background session titles in the agents view showing the naming model's refusal text when the prompt contains a link
  • Fixed background agents killed by the user auto-respawning, and revived agents re-running stale prompts from old sessions
  • Fixed routines with no schedule reporting a next run time in the year 1
  • Hardened synced skill/plugin directory naming on Windows and kept CCR web fetch/search proxies working after /clear
  • Improved terminal layout and rendering performance
  • Improved background agent result reporting — Claude now reports the status of still-running agents and waits for the real completion instead of fabricating results
  • Improved the memory index over-limit warning to measure only loaded content, excluding frontmatter and HTML comments
  • Updated integer environment variables (timeouts, token budgets, retry counts) to accept scientific notation and digit-separator spellings like 1e6 and 64_000
  • Updated documentation links to the current docs sites
  • Changed "always allow" permission rules to save at the repository root, so approvals granted in a git worktree persist across sessions and worktrees
  • Changed /usage-credits to ask for confirmation before sending a request to organization admins
  • Changed Vim mode s and S (substitute char/line) to work in NORMAL mode, matching vim behavior
  • [VSCode] Updated the Remote Control banner to describe what it does
  • Claude in Chrome: hardened file-upload path validation
  • Claude in Chrome: save_to_disk on screenshot actions now writes the image to disk and returns the path; previously it did nothing
  • Fixed a prompt-caching regression on Bedrock, Vertex, Mantle, and Foundry that billed the trailing system context block as fresh input tokens on every request.
Source: anthropics/claude-code · CHANGELOG.md · 37 entries · synced automatically when Anthropic publishes official notes for a version.
Source-Level Analysis
Reverse-engineered from a diff of the bundled CLI — deeper, structured detail. Unofficial.

New Features

3 items

RefreshMcpTools — Re-sync MCP Server Tool Lists #

New
What

A new built-in tool, RefreshMcpTools, lets Claude re-query tool lists from connected MCP servers and update its available tool set without restarting the session. It reports which tools were added or removed.

Usage
# Refresh all connected servers
RefreshMcpTools

# Refresh a specific server
RefreshMcpTools({ server: "myserver" })
Details
  • Triggers when a device or app comes online after a failed tool call, when expected tools are missing, or when a server's tools look stale after reconnection.
  • Returns per-server status: refreshed (tool list applied), error (previous list kept), or not_connected (server offline — this tool never dials).
  • Reports toolCount, added, and removed for each refreshed server.
  • Only activates when MCP clients are connected; hidden when no servers are configured.
  • Does not re-dial disconnected servers — it only re-reads over existing live connections.
Evidence

Complete new tool definition (search for "RefreshMcpTools")

--forward-subagent-text CLI Flag #

New
What

New flag for --print mode that forwards subagent text and thinking blocks as structured assistant/user messages with parent_tool_use_id set, enabling callers to reconstruct the full agent conversation tree from the stream.

Usage
claude --print --output-format=stream-json --forward-subagent-text "your prompt"
Details
  • Requires both --print and --output-format=stream-json. When explicitly specified on the CLI without those flags, the process exits with: "Error: --forward-subagent-text requires --print and --output-format=stream-json." When the option is supplied programmatically via the SDK forwardSubagentText: true init-config field, it silently degrades to false rather than erroring if the output conditions are not met.
  • Without the flag, only tool_use and tool_result content blocks from subagent turns are forwarded upstream in the progress event stream. With the flag enabled, all content types — including text and thinking blocks — are forwarded.
  • Forwarded subagent messages are emitted as progress events (data.type === "agent_progress") carrying the full assistant or user message wrapper. The stream-json serializer converts these into top-level assistant/user message events with parent_tool_use_id set to the spawning agent's tool-use ID, allowing callers to reconstruct the full agent conversation tree.
  • When forwardSubagentText is active, thinking blocks in subagent turns are not suppressed: the thinking configuration object is returned unchanged rather than having its display property overridden to "omitted" — which is the default behaviour for non-interactive stream-json sessions.
  • Allows external tooling (CI pipelines, orchestration layers) to receive the complete content of nested subagent turns rather than only the top-level result.
Evidence

New CLI flag added to the argument parser (search for "--forward-subagent-text"); forwarding gate (search for "forwardSubagentText" near "tool_use" and "tool_result" checks); thinking-config passthrough in Flc function

Screenshot Save-to-Disk for Claude in Chrome #

New
What

The computer tool inside Claude in Chrome now supports a save_to_disk parameter that persists screenshots to a local temporary directory and returns the file path(s) in the tool result.

Details
  • Pass save_to_disk: true on a computer or browser_batch tool call to save screenshots to disk.
  • Claude includes the saved path(s) in its response so they can be attached for the user.
  • If the screenshot directory cannot be created, the image is still returned inline.
  • If save_to_disk has no effect in the current session context, Claude is instructed not to retry.
  • Supports PNG, JPEG, WebP, and GIF output formats.
  • Screenshots are saved as screenshot-<timestamp>-<n>.<ext> under a session-scoped temp directory.
Evidence

New save_to_disk handling function with text "Screenshot saved to: " (search for "Screenshot saved to:")

Improvements

10 items

Claude Design: Permanent Durable Project Write Grants #

New
What

The approval model for Claude Design project writes is fundamentally reworked. The old time-limited "4-hour project grant" from finalize_plan scope:"project" is replaced by a permanent durable grant that persists until explicitly revoked at claude.ai/design settings.

Details
  • The first write to a project triggers a one-time interactive approval. After approval, Claude can write to any file in the project without further prompts until revoked.
  • The approval approval message now reads: "Approving writes the listed files now, and lets Claude write to ANY file in the project…" rather than the previous "without another prompt for up to 4 hours".
  • Grants are revocable at any time via claude.ai/design settings.
  • finalize_plan scope:"project" is now deprecated — the client returns a deny message directing callers to use direct writes instead.
  • copy_files without a plan_token is now always rejected (requires finalize_plan with explicit destination paths).
  • Write batches that are too large to display in the approval dialog are rejected and must be split or issued via finalize_plan.
  • Projects shared from another organization cannot receive durable grants — those require per-batch plan_token flows.
  • Durable grants are not available in non-interactive sessions, plan mode, subagent sessions, or PermissionRequest-hook contexts.
Evidence

Replaced approval text (search for "first write under a project grant")

Windows Browser Resolution for Claude in Chrome via App Paths #

New
What

On Windows, Claude in Chrome now uses the Windows Registry App Paths mechanism (via reg.exe) to locate installed browser executables for Edge and Vivaldi, rather than only falling back to rundll32.

Details
  • Queries both HKCU and HKLM registry hives under SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths for msedge.exe and vivaldi.exe.
  • Falls back to rundll32 url,OpenURL if registry resolution fails or the exe cannot be verified.
  • Expands %VARIABLE% environment-variable tokens in registry values.
  • Rejects results that point to a directory rather than an executable.
  • Uses a timeout to avoid blocking on slow or stale registry entries.
Evidence

Windows App Paths registry key (search for "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths")

Audible Bell Behavior on macOS Terminal.app #

New
What

When Claude Code sets up Option+Enter as a newline key on macOS Terminal.app, it now disables the audible bell instead of switching to a visual bell. Screen-reader users are not affected.

Details
  • If Terminal.app is in screen-reader mode, the audible bell setting is left unchanged.
  • The setup notification now reads "Option+Enter for newlines and no audible bell" (previously "visual bell").
  • If no Terminal.app changes are needed (e.g., Shift+Return already works), a message confirms this without modifying preferences.
Evidence

Updated Terminal.app profile modification messages (search for "Disabled the audible bell")

--callback-port Validation Tightened #

New
What

The MCP OAuth callback port flag (--callback-port) now validates that the port number falls within the valid TCP range [1, 65535], rather than only checking it is a positive integer.

Details
  • The error message now reads: "Error: --callback-port must be an integer in [1, 65535]"
  • Port 0 is no longer accepted. The validation expression is !Number.isInteger(m) || m <= 0 || m > 65535, so port 0, negative values, and non-integer inputs (e.g. 1.5 or non-numeric strings that parse to NaN) are all rejected.
  • The same validation is applied in two separate command paths: claude mcp add (for SSE and HTTP transports) and claude mcp oauth identity-provider set.
Evidence

Updated validation error string (search for "--callback-port must be an integer in [1, 65535]")

CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS Environment Variable #

New
What

A new environment variable, CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS, controls how old an interrupted assistant turn can be before it is no longer automatically resumed on session restart. This prevents stale interrupted turns from being replayed after a long pause.

Details
  • If CLAUDE_CODE_RESUME_INTERRUPTED_TURN is set and the interrupted turn's timestamp is older than this value, the resume is skipped.
  • Defaults to 3,600,000 ms (1 hour) when the variable is present but not set to a valid finite positive number; set to 0 to disable age-gating entirely.
  • The variable is passed through to child processes alongside the existing CLAUDE_CODE_RESUME_INTERRUPTED_TURN.
Evidence

New env var with fallback (search for "CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS")

OAuth Refresh Lock: Named Error, Compromise Detection, and Longer Stale Timeout #

New
What

The OAuth token refresh lock now uses a named error class (OAuthRefreshLockContendedError), exposes an isCompromised() predicate and an abort signal, and raises the stale-lock timeout from 10 seconds to 60 seconds with a 5-second update heartbeat.

Details
  • OAuthRefreshLockContendedError is thrown when the lock is contended after max attempts, replacing the previous untyped error.
  • A new onCompromised callback receives a dedicated AbortController signal that is aborted when compromise is detected, allowing in-flight refreshes to be cancelled.
  • The increased stale timeout (60 s) reduces false-positive "lock compromised" events on slow systems.
Evidence

New named error class (search for "OAuthRefreshLockContendedError")

Chrome Tool Error Classification #

New
What

Errors from Chrome bridge tools (javascript_tool, computer, get_page_text) are now classified into structured named error types for telemetry, replacing untyped catch-all error handling.

Details
  • JavaScript tool errors: js_permission_denied, js_timeout, js_execution_error, js_exception, tab_not_found.
  • Computer (input/action) tool errors: computer_permission_denied, computer_element_not_found, computer_action_failed, computer_zoom_shortcut_unsupported, computer_exception.
  • Page text extraction errors: get_page_text_permission_denied, get_page_text_too_large, get_page_text_no_content, get_page_text_script_error, get_page_text_exception.
  • Shared cross-tool error: navigation_blocked, permission_denied_user, authentication_failed, session_expired, domain_blocked, security_check_failed.
Evidence

Error classification registry (search for "js_permission_denied")

Auto Front-Load of Tab Context for Navigate Without tabId #

New
What

When the navigate tool is called with a URL but no tabId, Claude in Chrome now automatically issues a tabs_context_mcp call in the background to acquire a tab, then injects the tab context into the result. The caller no longer needs to call tabs_context_mcp first for simple URL navigation.

Details
  • A short timeout bounds the background lookup; if it exceeds the limit, the tool returns an error instructing the caller to retry or call tabs_context_mcp explicitly.
  • url: "back" and url: "forward" still require an explicit tabId (they have no meaningful default).
  • The tab context JSON (from the front-loaded lookup) is appended to the successful navigate result for reference.
Evidence

Auto tab lookup logic (search for "The hidden tabs_context_mcp lookup did not respond within")

settings.local.json Ownership Verification Before Canonicalization #

New
What

Before relocating the local settings consent store to the canonical git repository root, Claude now verifies via POSIX uid semantics that the user owns the root directory, its .git entry, and its .claude entry.

Details
  • If any of those entries are owned by a different user, the store stays at the current working directory (the pre-canonicalization behavior) and a warning is logged.
  • On platforms without uid semantics (Windows), canonicalization is skipped and logged as POSIX-only.
  • Protects against shared-repository scenarios where a foreign-owned repo root could have its consent state hijacked.
Evidence

Ownership check log messages (search for "localSettings: not canonicalizing the consent store to")

Bug Fixes

4 items
  • OAuth callback port parsing now correctly rejects port 0 and enforces the full TCP range, fixing cases where a 0 port was silently accepted (search for "--callback-port must be an integer in [1, 65535]")
  • Interrupted turn auto-resume now skips turns that are too old, preventing unexpected re-execution of stale assistant turns after long restarts (search for "CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS")
  • Claude in Chrome navigate without a tabId no longer requires a manual tabs_context_mcp preflight call for URL navigation (search for "tabs_context_mcp returned an error.")
  • settings.local.json consent store is no longer silently moved to a repo root that is owned by a different system user (search for "localSettings: not canonicalizing the consent store")