claude-code - 💡(How to fix) Fix [BUG] Desktop app cancels stdio MCP tool calls at ~60s and ignores MCP_TOOL_TIMEOUT; the CLI honors it

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

A long-running stdio MCP tool call is cancelled by the Claude Code desktop app with MCP error -32001: Request timed out after ~60 seconds, even though MCP_TOOL_TIMEOUT is set to a much larger value (e.g. 900000 = 15 min) in ~/.claude/settings.json env and is verifiably present in the process environment, and the Claude Code CLI runs the exact same stdio server and tool call past 60 seconds to completion.

The 60s figure matches the MCP TypeScript SDK default DEFAULT_REQUEST_TIMEOUT_MSEC = 60000, which suggests the desktop host uses the SDK default request timeout for tool calls and never threads MCP_TOOL_TIMEOUT (or the per-server .mcp.json timeout) into the client request options.

This is not the HTTP/SSE first-byte budget (the server is stdio), and not the 4-minute desktop cap reported in #44032 (we measured ~60s, not ~240s).

Error Message

A long-running stdio MCP tool call is cancelled by the Claude Code desktop app with MCP error -32001: Request timed out after ~60 seconds, even though MCP_TOOL_TIMEOUT is set to a much larger value (e.g. 900000 = 15 min) in ~/.claude/settings.json env and is verifiably present in the process environment, and the Claude Code CLI runs the exact same stdio server and tool call past 60 seconds to completion. | Desktop app | MCP error -32001: Request timed out at ~60s | bracketed at 69.08s end-to-end incl. agent overhead; underlying timeout ~= 60s (= SDK DEFAULT_REQUEST_TIMEOUT_MSEC) |

  • Desktop app: MCP error -32001: Request timed out at ~60s (ignores MCP_TOOL_TIMEOUT and the per-server timeout).

Root Cause

The same call the CLI runs to completion is cancelled by the desktop app ~6s short of finishing, purely because the desktop host enforces the 60s SDK default and ignores MCP_TOOL_TIMEOUT.

Code Example

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "sleep-server", version: "1.0.0" });
server.tool(
  "sleep",
  { seconds: z.number() },
  async ({ seconds }) => {
    await new Promise((r) => setTimeout(r, seconds * 1000));
    return { content: [{ type: "text", text: `slept ${seconds}s` }] };
  },
);
await server.connect(new StdioServerTransport());
RAW_BUFFERClick to expand / collapse

Summary

A long-running stdio MCP tool call is cancelled by the Claude Code desktop app with MCP error -32001: Request timed out after ~60 seconds, even though MCP_TOOL_TIMEOUT is set to a much larger value (e.g. 900000 = 15 min) in ~/.claude/settings.json env and is verifiably present in the process environment, and the Claude Code CLI runs the exact same stdio server and tool call past 60 seconds to completion.

The 60s figure matches the MCP TypeScript SDK default DEFAULT_REQUEST_TIMEOUT_MSEC = 60000, which suggests the desktop host uses the SDK default request timeout for tool calls and never threads MCP_TOOL_TIMEOUT (or the per-server .mcp.json timeout) into the client request options.

This is not the HTTP/SSE first-byte budget (the server is stdio), and not the 4-minute desktop cap reported in #44032 (we measured ~60s, not ~240s).

Environment

  • Host where it FAILS: Claude Code desktop app, version Claude 1.9659.1 (193bcb) (build 2026-05-28T16:22:15.000Z)
  • Host where it WORKS: Claude Code CLI 2.1.154
  • OS: macOS (Darwin 25.4.0, arm64); Node v22.22.2
  • MCP server transport: stdio (@modelcontextprotocol/sdk, StdioServerTransport)
  • ~/.claude/settings.json contains "env": { "MCP_TOOL_TIMEOUT": "900000" }
  • Confirmed in the failing session: printenv MCP_TOOL_TIMEOUT -> 900000 (the var is inherited by the process; it is simply not applied to MCP tool-call requests)

Expected behavior

A stdio MCP tool call should run until MCP_TOOL_TIMEOUT (or the per-server .mcp.json timeout) elapses, consistently across the CLI and the desktop app. Per the docs, MCP_TOOL_TIMEOUT is the per-tool-call execution timeout and a per-server timeout overrides it: https://code.claude.com/docs/en/mcp

Actual behavior

The desktop app cancels the tool call at ~60s with -32001: Request timed out regardless of MCP_TOOL_TIMEOUT. The CLI honors the configured timeout and the same call completes.

Measurement

Same stdio server, same tool, same machine, same ~/.claude/settings.json (with MCP_TOOL_TIMEOUT=900000, verified present in both hosts via printenv). The tool call genuinely takes ~66s of work.

HostResultWall-clock
Desktop appMCP error -32001: Request timed out at ~60sbracketed at 69.08s end-to-end incl. agent overhead; underlying timeout ~= 60s (= SDK DEFAULT_REQUEST_TIMEOUT_MSEC)
CLIcompleted successfully (no -32001)~66s of actual work; 93.7s end-to-end incl. agent overhead

The same call the CLI runs to completion is cancelled by the desktop app ~6s short of finishing, purely because the desktop host enforces the 60s SDK default and ignores MCP_TOOL_TIMEOUT.

Minimal reproduction

A ~15-line stdio MCP server with one tool that sleeps for a requested duration. This mirrors the sleep-based repro in #16837 (which covers the startup timeout MCP_TIMEOUT) but targets tool-call execution.

sleep-server.mjs:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "sleep-server", version: "1.0.0" });
server.tool(
  "sleep",
  { seconds: z.number() },
  async ({ seconds }) => {
    await new Promise((r) => setTimeout(r, seconds * 1000));
    return { content: [{ type: "text", text: `slept ${seconds}s` }] };
  },
);
await server.connect(new StdioServerTransport());

Steps:

  1. claude mcp add --transport stdio sleep -- node /abs/path/sleep-server.mjs
  2. Set "env": { "MCP_TOOL_TIMEOUT": "900000" } in ~/.claude/settings.json (and/or add "timeout": 900000 to the server's entry).
  3. Restart both hosts so the env is picked up.
  4. Invoke the sleep tool with seconds: 180.

Result:

  • CLI: returns slept 180s after ~180s (honors MCP_TOOL_TIMEOUT).
  • Desktop app: MCP error -32001: Request timed out at ~60s (ignores MCP_TOOL_TIMEOUT and the per-server timeout).

To pin the exact desktop cutoff, binary-search seconds (e.g. 50, 55, 59, 65) - the boundary lands at ~60s.

Impact

Any MCP server with a tool that legitimately takes >60s (LLM/agent calls with high reasoning effort, large builds, data exports, long queries) is unusable from the desktop app but fine from the CLI. There is no setting that raises the desktop limit: MCP_TOOL_TIMEOUT is ignored, the .mcp.json timeout field is reportedly ignored (#43791), and the server cannot extend it via progress notifications (the SDK request timeout does not reset on progress).

Relationship to existing issues (why this is distinct)

  • #16837 - MCP_TIMEOUT (server startup/connection) capped at ~60s, reproduced on the CLI. Different timeout (startup, not tool execution) and different host.
  • #44032 - desktop tool calls cancelled at ~240s, Windows + Obsidian servers, closed as "not planned/invalid." This report is macOS, stdio, measured at ~60s, and frames the precise CLI-honors / desktop-ignores MCP_TOOL_TIMEOUT contrast.
  • #43791 - timeout field in desktop config not honored (consistent with this report).
  • #47076 / #5221 / #22542 - feature requests to make the desktop tool timeout configurable (still open).

Ask

Make the desktop app honor MCP_TOOL_TIMEOUT and the per-server .mcp.json timeout for tool-call execution, matching the CLI - or, at minimum, document the desktop's fixed ~60s tool-call limit and expose a way to raise it.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

A stdio MCP tool call should run until MCP_TOOL_TIMEOUT (or the per-server .mcp.json timeout) elapses, consistently across the CLI and the desktop app. Per the docs, MCP_TOOL_TIMEOUT is the per-tool-call execution timeout and a per-server timeout overrides it: https://code.claude.com/docs/en/mcp

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING