Between July 14 and July 20, 2026, Claude Code shipped a cluster of releases (v2.1.207 through v2.1.216) under the banner of general stability work rather than a headline feature. Buried in that run is a change that matters more than its changelog entry suggests: MCP tool calls that run long no longer block the session. Alongside it came a new safety tool, a visibility fix for slow calls, and a set of permission-check corrections that close real gaps in how Claude Code approves commands.
None of this shipped as a “what’s new” feature announcement — the weekly digest that week led with Artifacts pulling live data from MCP connectors. The background-execution change, the EndConversation tool, and the permission fixes are documented only in the CLI’s own release notes and the MCP reference page. This is a walkthrough of what actually changed, sourced from the primary documentation, for anyone building or operating MCP servers against Claude Code.
This guide covers changes shipped between Claude Code v2.1.210 and v2.1.216. Automatic MCP backgrounding requires v2.1.212 or later; the EndConversation tool and the progress heartbeat require v2.1.214 or later. Check your version with
claude --versionand update withclaude update.
The problem: a slow MCP call used to block the whole session
Before this update, Claude Code already had two layers of timeout protecting MCP tool calls from running forever:
- A per-server wall-clock timeout. Configurable via a
timeoutfield in milliseconds on a server’s.mcp.jsonentry, or globally via theMCP_TOOL_TIMEOUTenvironment variable. If neither is set, the default is about 28 hours. This is a hard limit — progress notifications from the server don’t extend it. - An idle timeout. If a server sends neither a response nor an MCP progress notification within a window, the call aborts with an error instead of waiting for the wall-clock limit. That window defaults to five minutes for HTTP, SSE, WebSocket, and claude.ai connector servers, and 30 minutes for stdio servers.
Neither of those layers solved the actual problem developers were hitting: a tool call that was alive and making progress — a long-running build, a large database export, a multi-step API workflow behind an MCP wrapper — would still occupy the main conversation for its entire duration. The session wasn’t broken, but it was unusable until the call returned. For anyone running MCP servers that wrap genuinely slow operations, this meant either padding every tool with artificial chunking to stay under a few minutes, or accepting that certain tools would freeze the session for the length of the underlying task.
What changed in v2.1.212: automatic backgrounding
Claude Code v2.1.212 (released July 17, 2026) added automatic backgrounding for long MCP tool calls. The official MCP documentation describes the mechanism precisely:
“An MCP tool call in the main conversation that is still running after two minutes moves to a background task instead of blocking the session. Claude receives the task ID immediately and keeps working, and the result arrives as a task notification when the call settles.”
The release note for the change itself is more compact: “MCP tool calls running longer than 2 minutes now move to the background automatically so the session stays usable; configure the threshold or disable with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS.”
The mechanics, as documented:
- Threshold: two minutes by default, in the main conversation only.
- Where it shows up: the backgrounded call appears as a task in
/tasks, where it can be inspected or stopped. It does not survive exiting the session. - The existing timeouts still apply. Backgrounding doesn’t replace the wall-clock or idle timeout — it just stops the call from blocking the conversation while those timers run out in the background.
- Configuration:
CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSchanges the two-minute threshold (in milliseconds); setting it to0turns automatic backgrounding off entirely.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1also disables it, along with every other background-task feature in the CLI.
Four cases are explicitly excluded from automatic backgrounding, and each has a practical reason:
- Calls from subagents. Claude Code backgrounds only main-conversation calls — a subagent invoking a slow MCP tool still blocks that subagent’s own execution.
- Calls to IDE servers.
- Calls in non-interactive mode (
claude -p/ headless), unlessCLAUDE_AUTO_BACKGROUND_TASKS=1is set — because a one-shot scripted run can exit before a backgrounded result ever arrives, silently losing the output. - Calls blocked on an open elicitation dialog. If the server is waiting on user input rather than doing slow work, Claude Code treats that as blocked-on-you, not slow, and won’t move it to the background until the dialog resolves.
Before and after
| Before v2.1.212 | v2.1.212 and later | |
|---|---|---|
| MCP call under 2 minutes | Session waits for the result | Same — no change |
| MCP call over 2 minutes, main conversation | Session blocked until the call returns or times out | Moves to a background task; Claude keeps working, result arrives as a task notification |
| MCP call over 2 minutes, subagent | Subagent blocked for the duration | Still blocked — subagent calls are exempt from backgrounding |
MCP call over 2 minutes, headless (-p) mode | Process waits for the result | Still waits, unless CLAUDE_AUTO_BACKGROUND_TASKS=1 |
| Existing wall-clock / idle timeouts | Apply as configured | Still apply, now enforced against the background task rather than the blocked session |
The progress heartbeat (v2.1.214)
Shipped one release later, on July 18, 2026: “Added a periodic progress heartbeat for long-running tool calls that previously went silent.” This is a distinct, complementary fix — it addresses the UX problem of a tool call that’s actually alive but gives Claude Code nothing to show while it runs, which previously looked indistinguishable from a stalled call in the interface. It is not the same mechanism as the MCP protocol’s own progress notifications, which servers can already send and which factor into the idle-timeout calculation described above; the heartbeat is Claude Code’s own indicator that a call is still active.
The practical effect for anyone building MCP servers: a tool that runs for two, five, or twenty minutes now reads as “working” rather than “hung,” whether or not the server itself is well-behaved about sending MCP progress notifications. That said, the two mechanisms solve different problems — the heartbeat is about visibility, and MCP progress notifications are what actually keeps the idle timeout from firing on a server that has gone genuinely silent.
The EndConversation tool (v2.1.214)
The same release added a tool Claude itself can invoke, not something an MCP developer calls directly: “Added the EndConversation tool: Claude can end sessions with highly abusive users or jailbreak attempts, as on claude.ai since 2025.” Anthropic’s research on the underlying behavior (referenced directly in the release note) covers the claude.ai precedent this extends to Claude Code.
It’s a separate concern from backgrounding and heartbeats — it’s not a timeout or execution-model change — but it belongs in the same stability-update cluster because it changes what a session lifecycle can look like from the outside. For anyone running Claude Code as the backend of a user-facing or agentic product (a support bot built on MCP tools, a scheduled task pipeline, a customer-facing coding assistant), it means a conversation can now terminate for a reason other than reaching its goal or hitting an error — and any wrapper code around a Claude Code session should treat “session ended by EndConversation” as a distinct, expected termination path rather than an anomaly to retry.
Permission-check hardening
The same release window tightened several permission-check paths. None of these are MCP-protocol changes, but several are directly relevant to how MCP servers get invoked and how their output reaches a session:
Closed gaps in command approval (v2.1.214):
- A permission-check bypass affecting commands run in Windows PowerShell 5.1 sessions was fixed.
- Bash permission checks now fail closed on file-descriptor redirect forms that bash parses differently than the permission analyzer did — previously a mismatch here could let a command through without the prompt it should have triggered.
- Commands over 10,000 characters now always prompt instead of running automatically, closing a case where very long commands were misjudged.
- zsh variable subscripts and modifiers inside
[[ ]]comparisons, previously treated as inert text, now correctly trigger an approval prompt. - Certain
helpandmaninvocations that could run unsafe options, command substitutions, or backslash paths no longer auto-approve.
A new prompt for daemon-redirection (v2.1.212): docker commands — including the Podman docker shim — carrying daemon-redirect flags (--url, --connection, --identity, and Podman’s remote mode) now require a permission prompt where they previously ran without one. This matters specifically for MCP setups: it’s common to launch or manage an MCP server’s runtime inside a container, and a daemon-redirect flag is exactly the kind of thing that could point a “safe” docker command at an unintended remote daemon.
Sanitized permission previews in chat channels (v2.1.211): permission previews relayed to chat channels — the mechanism an MCP server uses when it declares the claude/channel capability to push messages into a session, for example from Telegram, Discord, or a webhook — no longer let bidirectional-override, zero-width, or look-alike quote characters alter how the approval message displays. Before the fix, a tool input containing those characters could visually change what a permission prompt appeared to say inside a channel integration, without changing what would actually run. This is the one item in this list that’s specific to MCP-adjacent surface area rather than the CLI’s general command-approval logic.
None of these individually reads as a headline security fix, but taken together they’re the kind of accuracy work that matters most for anyone whose MCP tools shell out to git, docker, or another CLI as part of their implementation — which describes a large share of MCP servers in practice.
Practical guidance for building MCP servers against this model
Design for a call that might get detached from the conversation. Once a tool call passes two minutes in the main conversation, it’s a background task, not a blocking call — the result comes back as a task notification, not as the next turn’s input. Servers whose tools have side effects should be safe to call and forget: don’t design a tool around the assumption that the client will still be “waiting” in a way that lets you assume ordering with whatever the user does next.
Send progress notifications, not just eventual results. The idle timeout — five minutes for HTTP/SSE/WebSocket/connector servers, 30 minutes for stdio — fires when a server sends neither a response nor a progress notification within the window, independent of whether the call has also been backgrounded. A tool that’s legitimately working for ten minutes but sends nothing in that time can still be aborted even after it’s out of the way in the background. If your server does long-running work, emit MCP progress notifications periodically; the backgrounding change removes the session-blocking problem, but it doesn’t remove the idle-timeout problem.
Remember subagent calls are exempt. If your MCP tools are likely to be invoked from subagents (common in delegated multi-agent workflows), don’t assume the two-minute backgrounding safety net applies — subagent calls still block until they complete or time out. For tools that are genuinely slow, this is a reason to keep the subagent-facing entry points fast and push slow work to tools that are more likely to be called from the main conversation, or to decompose the operation into smaller calls a subagent can poll.
Set the per-server timeout deliberately. It’s a hard wall-clock cap that progress notifications do not extend, and it also acts as a floor under the idle timeout — so a timeout set too low can abort legitimate long calls even if you’re sending heartbeats correctly, and one set casually high (the unset default is roughly 28 hours) can leave a genuinely stuck call occupying a background task slot indefinitely. Set it to match the actual expected upper bound of the operation, not a guess.
Don’t rely on automatic backgrounding in headless pipelines. In -p / non-interactive mode, calls don’t background by default because a one-shot run can exit before a backgrounded result arrives. If your MCP server is meant to be used from scripted or CI-style invocations of Claude Code, either keep tool calls under two minutes or document that callers need CLAUDE_AUTO_BACKGROUND_TASKS=1 and a process that stays alive long enough to receive the notification.
If you use the channels capability, assume the display layer is now adversarial-input-aware — but your payload still shouldn’t rely on formatting. The v2.1.211 fix sanitizes how permission previews render in chat channels; it doesn’t change what characters your server can send. Continue treating any text a channel-connected server pushes into a permission prompt as something a user will actually read, not as a trusted rendering surface.
Environment variable reference
| Variable | Effect |
|---|---|
CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS | Changes the auto-backgrounding threshold (default: 2 minutes / 120000ms). Set to 0 to disable. |
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS | Set to 1 to disable all background-task features, including MCP auto-backgrounding. |
CLAUDE_AUTO_BACKGROUND_TASKS | Set to 1 to allow backgrounding in non-interactive (-p) mode. |
MCP_TOOL_TIMEOUT | Global per-call wall-clock timeout in milliseconds (overridden per-server by .mcp.json’s timeout field). Defaults to roughly 28 hours if unset. |
CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT | Changes the idle-timeout window (default 5 minutes for HTTP/SSE/WebSocket/connector, 30 minutes for stdio). Set to 0 to disable. |
MCP_TIMEOUT | Startup connection timeout, separate from tool execution timeouts (e.g. MCP_TIMEOUT=10000 for 10 seconds). |
Frequently asked questions
Does automatic backgrounding change how long a tool call is allowed to run?
No. The wall-clock and idle timeouts are unchanged and still apply. Backgrounding only changes whether the main conversation is blocked while those timeouts are pending — it doesn’t extend or shorten them.
Will my existing MCP server need code changes to work with this?
Not to keep functioning — the change is entirely on Claude Code’s side of the connection. But a server that does slow work without sending progress notifications is still exposed to the idle timeout, exactly as it was before this update; backgrounding doesn’t fix that on its own.
Is EndConversation something my MCP server can trigger?
No — it’s a tool Claude itself invokes to end a session in response to abusive input or jailbreak attempts, not an MCP server capability. The relevant design implication is on the client side of any product built on Claude Code: handle session termination via this path as a normal, expected outcome.
Are the permission-check fixes specific to MCP?
Mostly not — they’re general Bash and PowerShell command-approval fixes. The one MCP-specific item is the sanitization of permission previews relayed through the claude/channel capability, which closes a display-spoofing gap in that integration path specifically.
Related resources
- Connect Claude Code to tools via MCP — official reference, including the “Automatic backgrounding of long tool calls” and timeout sections this article is based on
- Claude Code changelog — full release notes for v2.1.212 and v2.1.214
- Claude Code Agent View: Complete Guide to Background Sessions — how
/tasksand background sessions work more broadly, for the mechanism backgrounded MCP calls now use - Claude Code Artifacts with Live Data: How MCP-Connected Dashboards Work — the other MCP-related change shipped the same month, on the artifacts side rather than the execution side