On this page
MCP Tool Call Timeout: Why Long Tools Fail and How to Fix It (Nov 2026)

Most long MCP tool calls fail on an idle timer, not a hard limit. In Claude Code, a call with no response and no progress for 5 minutes (HTTP servers) or 30 minutes (stdio) is aborted. Raise the server's timeout or the idle window, or better, have the server send progress or return a task.

This is a common complaint right now. An r/ClaudeCode post shared a "fix for MCP tools timing out on long runs (tests, builds…)" (thread), and an r/LLMDevs user wrote a proxy because long calls kept timing out (thread). Both use the same idea: return a job ID now and fetch the result later.

Why this happens

The MCP spec says implementations should set a timeout on every request they send, so a hung server can't hang the client forever, and cancel the request when it runs out. They may reset that timer when the server sends a progress notification, but they should still enforce a maximum (MCP spec, Cancellation: Timeouts). In the current 2026-07-28 spec this rule sits on the Cancellation page; earlier versions had it under Lifecycle, which went away with the initialize handshake. The Tools page adds that clients should "implement timeouts for tool calls" (MCP spec, Tools).

So a tool that runs a 10-minute build and says nothing until the end looks exactly like a hung server. The client gives up, even though the work is fine.

Claude Code: the four timers

Claude Code documents these in its MCP docs. Values are in milliseconds.

Timer Default What it limits How to change it
Idle timeout 5 min (HTTP, SSE, WebSocket, connectors), 30 min (stdio); not used for IDE or SDK in-process servers No response and no progress for this long aborts the call CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT (0 turns the check off)
Wall-clock limit about 28 hours Total time for one tool call MCP_TOOL_TIMEOUT for all servers, or a per-server timeout
Per-request first-byte timer (HTTP, SSE, connectors; not stdio or WebSocket) the greatest of 60 s, the tool timeout, and MCP_TIMEOUT Each request until the server's first response byte Raise the per-server timeout
Server startup - How long a server has to start MCP_TIMEOUT, e.g. MCP_TIMEOUT=10000 claude

Two details that trip people up:

  • The per-server timeout is a hard wall-clock limit, and progress notifications don't extend it. Add it to the server's entry in .mcp.json, for example "timeout": 600000 for ten minutes. A per-server timeout of at least 1000 also stops Claude Code aborting that server's calls for idleness any sooner.
  • Long calls move to the background after two minutes. That doesn't stop the timers. It just means the session isn't blocked while the call runs. You can change the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS.

What to do as a user: if a specific server runs long jobs (test suites, builds, exports), give that one server a per-server timeout that fits its longest real job. Don't raise the idle window for every server.

Cursor and VS Code: neither documents an MCP tool-call timeout setting on its MCP configuration page (Cursor, VS Code). Cursor's FAQ says a server that crashes or times out shows an error in chat and a failed tool call. For long jobs in those clients, the server-side fixes below are the reliable route.

Server-side fixes (for server authors)

These work in every client, because they make a long job look alive or make it short.

1. Send progress notifications

If the client includes a progressToken in the request, the server can send notifications/progress while it works (MCP spec, Progress). Progress notifications travel on the response stream of the request they belong to:

{
  "jsonrpc": "2.0",
  "method": "notifications/progress",
  "params": {
    "progressToken": "abc123",
    "progress": 50,
    "total": 100,
    "message": "Reticulating splines..."
  }
}

progress must increase with each notification. In Claude Code, progress counts as activity for the idle timeout, so a build that reports every minute won't be cut off at five. It won't extend a per-server timeout, though.

2. Return a task (or a job ID) instead of blocking

MCP has tasks for this: the server answers a long tools/call with a task ID, and the client polls tasks/get until the task is completed or failed. In the 2026-07-28 spec, tasks moved out of the core protocol into an official extension, io.modelcontextprotocol/tasks, which replaces the old blocking tasks/result with polling (MCP Tasks extension, changelog).

Claude Code supports MCP tasks in public beta from v2.1.304, in terminal CLI sessions, Agent SDK sessions and GitHub Actions runs; the VS Code extension, the desktop app and one-shot claude -p runs don't get them. The tool-call limits apply until the server answers with the task. After that, by default, a task in the background has no Claude Code time limit (Claude Code MCP docs).

If your client doesn't support tasks yet, the Reddit pattern works anywhere: one tool starts the job and returns an ID, and a second tool returns the status or result.

3. Make the work smaller

Split one huge call into steps (for example, run tests per package, or export per page), or stream partial results through a resource the model can read. Short calls are also easier for a human to review and approve.

Safety note: don't just raise timeouts on tools that write

A timeout is also a safety brake. Before raising one, check what the tool does:

  • A timed-out write may still have happened. The client stops waiting and sends a cancellation, but the server may already have created the issue, sent the message or run the migration. If the model then retries, you can get the change twice.
  • Long write tools deserve a task, not a longer timer. A task gives you a status to check and a cancel to send.
  • Check the trust signals before you give a server more rope. A server that can run commands or write to production deserves a short leash. Our trust grade shows which servers can write and how they authenticate. For example, Playwright (C) and Chrome DevTools (C) can run code by default, so a long timeout there means a long time running code nobody is watching.

Sometimes the timeout isn't your config at all. An r/atlassian thread with 30+ comments was a service-side slowdown of the hosted Atlassian server (thread). If every call to one hosted server suddenly times out, check the vendor's status page before changing anything. Our Atlassian listing links its docs.

Frequently asked questions

What is the default MCP tool timeout in Claude Code?

The hard limit (MCP_TOOL_TIMEOUT) defaults to about 28 hours. The one you usually hit is the idle timeout: 5 minutes with no response or progress for HTTP-type servers, 30 minutes for stdio servers.

What's the difference between MCP_TIMEOUT and MCP_TOOL_TIMEOUT?

MCP_TIMEOUT is how long a server gets to start (it also feeds the HTTP first-byte timer). MCP_TOOL_TIMEOUT is the wall-clock limit for each tool call across all servers. A per-server timeout in .mcp.json overrides MCP_TOOL_TIMEOUT for that server.

Do progress notifications prevent timeouts?

They reset Claude Code's idle timer, so a server that reports progress won't be cut off for silence. They don't extend a per-server timeout, and the spec says clients should always keep a maximum.

Can I turn the timeout off?

You can turn off Claude Code's idle check with CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT=0, but we don't recommend it globally. A hung server would then hold the call until the wall-clock limit.

How do I set a timeout in Cursor or VS Code?

Neither documents one on its MCP configuration page. Fix it on the server side with progress notifications or a start/poll pair of tools.

More: MCP server security risk · Why MCP servers eat your context window · Browse the directory