Skillforge Field notes on shipping with AI tools

Claude Code MCP Tasks: Long Tool Calls in the Background

claude-codemcp

Claude Code now has two different ways a slow MCP tool call can stop blocking your session, and they behave differently when you exit. One is automatic backgrounding: a call still running after two minutes moves to a background task. The other is an MCP task: the server accepts a long job and Claude Code follows it. This page explains which one you get, how to make Claude wait for the result instead, and what happens to the work when you close the terminal.

Verified against: the Claude Code MCP page and environment variables page fetched on 2026-11-08, and the GitHub changelog entry for 2.1.319. This is documentation reading, not a live run. MCP tasks need a server that speaks the 2026-07-28 protocol revision and the tasks extension, and we did not run one for this page, so every behavior below is as documented, not as observed.

The short answer

  • Automatic backgrounding (older, since v2.1.212): an MCP tool call in the main conversation that is still running after two minutes moves to a background task. The task does not survive exiting the session.
  • MCP tasks (public beta, v2.1.304 or later): the server itself runs a long job, such as a report export or a build, and Claude's tool call returns once the server accepts it. A task on a remote server keeps running after you exit.
  • To make Claude wait in an interactive session, set CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS to 0 (wait for every MCP call) or CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND to 1 (wait for a task's result, but still move to a plain background call after two minutes).
  • A plain claude -p "<prompt>" run never gets MCP tasks. Scheduled one-shot runs are unaffected.

The 2.1.319 changelog also lists "Added support for MCP tasks in the terminal: when an MCP server runs a tool call as a task, Claude Code moves it to the background right away and tells Claude the result when it finishes", and the CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND variable that turns that behavior off.

Automatic backgrounding, in detail

Per the MCP page, Claude receives the task ID immediately and keeps working, and the result arrives as a task notification when the call settles. The task appears in /tasks, where you can stop it. Stopping cancels the call and tells Claude no result is coming, but the page says that does not guarantee the server stops.

The usual per-call limits still apply while it runs in the background: the wall-clock limit (per-server timeout or MCP_TOOL_TIMEOUT) and the idle timeout (CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT). We measured those timers separately in Claude Code MCP Timeout in Headless Runs.

Some calls never move to the background, per the same page:

  • calls from subagents (only main-conversation calls move)
  • calls to IDE servers
  • calls in non-interactive mode, unless CLAUDE_AUTO_BACKGROUND_TASKS is 1
  • a call waiting on an open elicitation dialog, until the dialog closes

The knobs: CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS changes the threshold (default 120000, so two minutes) or turns it off at 0. CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 turns off automatic backgrounding and background commands.

What a call needs to become an MCP task

All of these must hold, per the "What a call needs to become an MCP task" section:

  1. The server supports tasks.
  2. It is an HTTP, stdio, or claude.ai connector server connected on protocol revision 2026-07-28. Setting MCP_SDK_GENERATION=v1 or MCP_PROTOCOL_NEGOTIATION=legacy rules that out.
  3. The session fetches feature flags. That excludes third-party providers such as Amazon Bedrock, and sessions with telemetry or flag fetching turned off.
  4. Anthropic has turned MCP tasks on for your kind of session. On v2.1.304 or later the page lists terminal CLI sessions, Agent SDK sessions, and GitHub Actions runs. The VS Code extension and desktop app do not have them.
  5. The call comes from the main conversation, not a subagent.
  6. The session is interactive, or it is an Agent SDK session or a claude -p run reading --input-format stream-json with CLAUDE_AUTO_BACKGROUND_TASKS at 1, CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND not 1, and CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS not 0.

Any other call is a plain tool call. If you build an SDK host, keep the input stream open: the docs say the run does not wait for MCP tasks after input closes.

Because item 3 depends on a server-side flag fetch, a feature can be missing in the first session after an upgrade. The environment variables page says Claude Code saves flags it fetched on the machine, so the next session has the feature.

Make Claude wait for the result

Two variables, set for example in the env block of settings.json:

{
  "env": {
    "CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS": "0"
  }
}
VariableEffect on a long MCP call
CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS=0Claude waits for every MCP tool call until it ends
CLAUDE_CODE_DISABLE_MCP_TASK_BACKGROUND=1Claude waits for a task's result, but after two minutes (by default) the call moves to a plain background call, which is not an MCP task and does not survive exiting

While Claude waits, pressing Esc or hitting the wall-clock limit or idle timeout ends the call, and Claude Code asks the server to cancel the task. The page also notes that CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 or bare mode alone does not make Claude wait for MCP tasks.

Which to choose: if a workflow needs the result before the next step (a build whose output you are about to deploy), waiting is simpler. If the job takes an hour, a task you can follow and resume is the point of the feature.

What happens when you exit, clear, or resume

From the "Exit, clear, or resume while an MCP task runs" table:

SituationWhat happens
/clear, /branch, or /resume another session while Claude Code stays openThe result arrives in your current conversation
You exit Claude CodeNo exit option cancels a remote server's task. A stdio server's process stops on exit, so unless its documentation says the work outlives the process, finish or stop those tasks in /tasks first
claude --resume, --continue, or /resume interactivelyOnce the server connects, Claude Code follows the task again, if the server still knows it. Keep the server's name and connection settings unchanged
--resume or --continue in a one-shot claude -p runThat run does not follow the task
New session or --fork-sessionThe new session does not follow the task

The result goes to Claude, not into the transcript. The transcript gets a line such as MCP task <server task id> (<server>/<tool>) completed. and you ask Claude for the result. If Claude is idle when the result arrives, it starts on it unprompted.

In a non-interactive session, a task that asks for input is canceled on the server without running your Elicitation hooks or calling the SDK's onElicitation callback.

Reading the status messages

The MCP page lists messages shown in a task's /tasks entry or closing transcript line. The ones worth recognizing:

  • needs a sign-in to <server>: sign in from /mcp.
  • reconnecting…: if it stays, reconnect from /mcp.
  • server '<name>' is not configured in this session; the task may still be running on it: the server was removed, renamed, or left out of --mcp-config. Restore it under the same name and resume.
  • A message starting server '<name>' was reconfigured to a different transport since this task was created: restore the earlier settings, then resume.
  • A line ending outcome unknown.: Claude Code stopped following the task. The docs warn that a second call may repeat the work, so find out what the server did before calling the tool again.

While a message shows, the job may still be running: Claude Code leaves it alone and keeps checking. The 300-second messages stay on the entry even after contact returns.

For server authors

The page describes the contract only briefly here. On a 2026-07-28 connection, each request carries Claude Code's client capabilities under params._meta["io.modelcontextprotocol/clientCapabilities"], with "io.modelcontextprotocol/tasks": {} under extensions when the call can become a task. Answer with a task only when that extension is present. Otherwise the call fails with the tool error Unsupported result type 'task' for tools/call, and the same error appears if your answer has no taskId or no valid status. The full message shapes are in the MCP tasks extension specification, which we did not implement for this page.

What we have not confirmed

  • We did not run an MCP task. Nothing here was observed on a live server.
  • CLAUDE_CODE_DISABLE_FEATURE_FLAGS (added in 2.1.319 per the changelog, "stops feature-flag fetching without turning off telemetry") was not on the environment variables page we fetched. Since tasks need flag fetching, setting it would presumably rule them out, but that is our inference, not a documented statement.
  • The docs describe the feature as a public beta, so details may change.

FAQ

What is an MCP task in Claude Code?

A long job that an MCP server runs itself, using the MCP tasks extension. Claude's tool call returns once the server accepts the job, and Claude Code follows its status until it finishes.

Why did my long MCP call go to the background?

A main-conversation MCP call still running after two minutes moves to a background task by default. Change the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS, or set it to 0 to turn this off.

Does an MCP task survive closing Claude Code?

A task on a remote server keeps running after you exit, and you can resume the same session to follow it. A stdio server's process stops when Claude Code exits, so check that server's documentation first. A plain auto-backgrounded call does not survive exiting.

Do MCP tasks work in claude -p?

Not in a one-shot claude -p "<prompt>" run. They work in Agent SDK sessions and claude -p runs reading --input-format stream-json, with CLAUDE_AUTO_BACKGROUND_TASKS=1 and the input kept open.

How do I stop an MCP task?

Select it in /tasks and press x, or ask Claude to. Claude Code asks the server to cancel it, though the server may still finish it. Esc does not stop a background task.

Why is the feature missing after I upgraded?

Tasks depend on feature flags fetched from Anthropic. The environment variables page says the first session after an upgrade can be missing a flag-gated feature, and the next session on that machine has it.