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

Version 2.1.209

This release introduces runtime capabilities for published Artifacts, allowing pages to call the user's claude.ai MCP connectors live from within a published Artifact. It also lifts previous restrictions that blocked /login and /model commands in background sessions, making these commands behave identically across interactive and background contexts.

Official notes ✓ synced Package @anthropic-ai/claude-code Diff v2.1.208 → v2.1.209Provider claudeModel claude-sonnet-4-6
6
Features & Changes
1
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.209 — shown here alongside the source-level analysis below. Text is unmodified from the upstream changelog.
View on GitHub ↗
  • Fixed /model and other dialogs being blocked in claude agents background sessions (reverts an overly broad guard)
Source: anthropics/claude-code · CHANGELOG.md · 1 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

1 item

Artifact Runtime Capabilities (MCP) #

New
What

Published Artifact pages can now declare runtime capabilities — starting with mcp, which lets the page call the user's connected claude.ai data sources at runtime rather than embedding static data from the conversation.

Usage
Artifact tool: { capabilities: { mcp: { servers: [...] } } }
Details
  • Artifacts accept a new capabilities input that declares which runtime abilities the published page requires.
  • The first supported capability is mcp, enabling the page to call the user's claude.ai connectors (Slack, Google Drive, etc.) via window.claude.mcp at open time.
  • Omitting capabilities on a republish carries the stored declaration forward; passing {} explicitly clears all capabilities.
  • A new skill, artifact-capabilities, must be loaded before declaring any capability or writing window.claude.* runtime code — it carries the current contract's typed call definitions and per-capability guidance.
  • Type definitions (.d.ts files) for the runtime contract are extracted to a local cache directory and are authoritative over any memorized API shape.
  • Connector tools appear in the tool list as mcp__<connector>__<toolName>; the server value in the capabilities declaration is the <connector> segment.
  • Only claude.ai connectors are valid — locally-configured MCP servers cannot be declared as Artifact capabilities.
  • The dataviz/artifact skill prompt gains a new "## Live data via connected sources" section when this feature is enabled, explaining the workflow.
  • The Artifact tool description itself now mentions the capabilities input and the requirement to load the artifact-capabilities skill.
Status

[Gradual Rollout] — controlled by CLAUDE_CODE_ARTIFACT_MCP env var or tengu_cloth_snorkel feature flag.

Evidence

New skill registered as registerArtifactCapabilitiesSkill (search for "Runtime capabilities for published Artifacts"); capabilities schema added (search for "Runtime capabilities this page declares, as {name: config}"); gated by n4y() which checks CLAUDE_CODE_ARTIFACT_MCP ?? Qe("tengu_cloth_snorkel", !1)

Improvements

5 items

Background Sessions Now Support /login and /model #

New

Background sessions (headless/remote jobs) previously blocked both the /login command and the /model model picker with hard errors. Those restrictions have been removed — both commands now work the same way in background sessions as in interactive terminals.

The following messages were removed from the codebase:

  • "Can't run /login in a background session — log in from a regular interactive terminal (claude), then respawn this job."
  • "Can't open the model picker in a background session — use /model <name> to switch this session's model."

The model fable consent flow (for usage-credits consent when switching to certain models) also no longer short-circuits in background sessions.

Evidence

si() (is-background-session) guard removed from the /login handler (search for "Can't run /login in a background session"); same guard removed from the model picker and model-switch flow (search for "Can't open the model picker in a background session")

Max Subscription Upgrade Flow Simplified #

New

The "upgrade to Max" subscription flow previously showed different messages depending on whether the user was in a background session. Background-session-specific strings were removed:

  • "You are already on the highest Max subscription plan. For additional usage, run /login from an interactive terminal to switch to an API usage-billed account." — collapsed to a single message without the background-session qualifier.
  • "Visit ... to upgrade to Max, then run /login from an interactive terminal to use your new plan." and "Visit ... to upgrade to Max. Run /login after upgrading to use your new plan." — replaced with a direct call to open the upgrade URL without a fallback text path.
Evidence

B$t function simplified (search for "You are already on the highest Max subscription plan"); background-session URL-open fallback removed (search for "to upgrade to Max, then run /login from an interactive terminal")

Trusted Devices Check Removed from Remote Control #

New

The Remote Control connection flow previously blocked enrollment if the connecting device was not enrolled in Trusted Devices:

> "Your organization requires Trusted Devices for Remote Control, but this device is not enrolled. Run /login from an interactive terminal to enroll this device, then retry."

This check has been removed. Remote Control connections are no longer gated on Trusted Device enrollment in the CLI.

Evidence

Block removed from PNp function (search for "Your organization requires Trusted Devices for Remote Control")

Refusal Fallback Tracking Improved #

New

The internal mechanism for tracking model refusal fallbacks now carries additional state across requests. Two new session-level fields were added:

  • refusalFallbackHeaderArmed — indicates the fallback header should be sent on the next request
  • refusalFallbackLatchOriginRequestId — records the original request ID that triggered the fallback

When the armed state is active, outgoing API requests now include new HTTP headers:

  • x-cc-fallback-latched-by — the request ID of the original triggering request
  • x-cc-fallback-from-model — the model that refused
  • x-cc-fallback-category — the refusal category
  • x-cc-fallback-trigger — what triggered the fallback
  • x-cc-original-request-id — original request correlation ID

The pZp helper that searches message history for refusal fallback records was refactored to return the full record instead of a pre-filtered subset, enabling richer downstream handling. The XNt function is now called at three points in the main request loop (interactive, forked, and background sessions) to rearm the fallback header when applicable.

Evidence

New state fields (search for "refusalFallbackHeaderArmed"); new header constants (search for "x-cc-fallback-latched-by"); new kgt arming function and XNt recheck function in pretty-v2.1.209.js

Capabilities Display in Tool Listings #

New

Two new helper functions add capability-aware display to Artifact publish operations. Nkd (capabilitiesFromGatedInput) safely extracts the capabilities field from a tool input only when the field is explicitly present — distinguishing "not provided" (carry the stored declaration forward) from "provided as {}" (explicitly clear the grant). Fkd (frameCapabilitiesSummary) converts a capabilities object into a compact parenthesised summary string.

  • For the mcp capability key (when config contains a non-empty servers array), each server entry formats as <serverName>[N tool(s)], joined into a comma-separated list: e.g. mcp: slack[3 tools], gdrive[1 tool].
  • Non-mcp capability keys render as their bare key name with no further sub-structure.
  • If more than 8 servers (or 8 capability segments) are present, the formatter prepends [N total] and shows only the first 8, preventing runaway output on large declarations.
  • The assembled string is hard-truncated at 400 Unicode characters with a ellipsis, then wrapped in parentheses and prefixed with a space: (mcp: slack[3 tools]).
  • Fkd is consumed by the ArtifactTool's toAutoClassifierInput method (via the i4y() wrapper), so the summary appears in the string the permission auto-classifier reads when deciding how to handle an Artifact publish call.
  • When Fkd returns empty but a non-empty capabilities object is present (e.g. capabilities stored from a prior publish), the auto-classifier input falls back to " (carries a stored connector grant)"; if capabilities were explicitly passed as {}, it shows " (clears stored connector grant)"; if the stored capabilities could not be read from the control plane, it appends " (caps: unknown)".
Evidence

Nkd (capabilitiesFromGatedInput) and Fkd (frameCapabilitiesSummary) added (search for "capabilities" in e ? e.capabilities : void 0); Fkd consumed by i4y() inside ArtifactTool.toAutoClassifierInput (search for frameCapabilitiesSummary); overflow enforced by oSo (non-empty servers guard) and qar helper (8-item cap with [N total] prefix, search for qar)

Bug Fixes

1 item
  • Refusal fallback state fields (refusalFallbackOccurred, refusalFallbackHeaderArmed, refusalFallbackLatchOriginRequestId) are now correctly reset on both session clear and session start, preventing stale fallback state from bleeding across sessions. (search for "refusalFallbackLatchOriginRequestId = void 0")