Summary
Every MCP JSON-RPC request shares one hardcoded 30s timeout, including tools/call. There is no flag, config key, or mcp.json field to raise it, so any tool that legitimately takes longer than 30s can never succeed.
crates/jcode-base/src/mcp/client.rs:46 (at 02439b4):
let response = tokio::time::timeout(std::time::Duration::from_secs(30), rx)
.await
.context("Request timeout")?
request() is the single path used by initialize (client.rs:301), tools/list (client.rs:103) and tools/call (client.rs:71), so the same 30s covers server startup and long-running tool work alike.
I believe this is also the root cause of #617 — a slow-starting server blows the same budget during initialize.
Reproduction
Minimal MCP server (slow_mcp.py, needs pip install mcp):
import time
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("slowsrv")
@mcp.tool()
def slow_ping(seconds: int = 45) -> str:
"""Sleep then return a token."""
time.sleep(seconds)
return "SLOW-TOKEN-OK"
mcp.run()
.jcode/mcp.json:
{"mcpServers": {"slow": {"command": "python", "args": ["/abs/path/slow_mcp.py"], "env": {}}}}
jcode run 'Call slow_ping with seconds=45 exactly once, then report what it returned.'
Expected: the tool returns SLOW-TOKEN-OK after 45s.
Actual (0.68.0): the call fails at exactly 30s with Error: Request timeout, and the model reports the timeout instead of the result. I also tried timeout, timeout_ms, timeout_secs and tool_timeout_ms keys on the server entry in mcp.json — none are read.
Impact
I maintain a benchmark harness that drives Microsoft Word through an MCP server, where a single document edit routinely runs longer than 30s (the first call on a busy pool especially). Under jcode those calls come back as Request timeout and the model retries them; the work still completes, but every run burns turns and tokens on retries, and a slow enough backend can never finish at all. Anything else with real I/O behind it — builds, test suites, deploys, browser automation, remote APIs — has the same ceiling.
Suggestion
Two things would fix it, in rough priority order:
- Make the timeout configurable, and use a longer default for
tools/call than for initialize/tools/list. Comparable clients all expose this: Claude Code has MCP_TIMEOUT / MCP_TOOL_TIMEOUT, VS Code and Cursor take a per-server timeout in mcp.json, goose and kimi-cli both have their own knobs. A per-server field in mcp.json plus a global default in config.toml would match what people already expect.
- Optionally, reset the deadline on MCP progress notifications — the spec allows implementations to do this so well-behaved long-running tools stay alive.
Happy to test a patch against the real workload if that helps. Environment: jcode 0.68.0 (installed via jcode.sh/install), Linux x86_64.
Summary
Every MCP JSON-RPC request shares one hardcoded 30s timeout, including
tools/call. There is no flag, config key, ormcp.jsonfield to raise it, so any tool that legitimately takes longer than 30s can never succeed.crates/jcode-base/src/mcp/client.rs:46(at 02439b4):request()is the single path used byinitialize(client.rs:301),tools/list(client.rs:103) andtools/call(client.rs:71), so the same 30s covers server startup and long-running tool work alike.I believe this is also the root cause of #617 — a slow-starting server blows the same budget during
initialize.Reproduction
Minimal MCP server (
slow_mcp.py, needspip install mcp):.jcode/mcp.json:{"mcpServers": {"slow": {"command": "python", "args": ["/abs/path/slow_mcp.py"], "env": {}}}}Expected: the tool returns
SLOW-TOKEN-OKafter 45s.Actual (0.68.0): the call fails at exactly 30s with
Error: Request timeout, and the model reports the timeout instead of the result. I also triedtimeout,timeout_ms,timeout_secsandtool_timeout_mskeys on the server entry inmcp.json— none are read.Impact
I maintain a benchmark harness that drives Microsoft Word through an MCP server, where a single document edit routinely runs longer than 30s (the first call on a busy pool especially). Under jcode those calls come back as
Request timeoutand the model retries them; the work still completes, but every run burns turns and tokens on retries, and a slow enough backend can never finish at all. Anything else with real I/O behind it — builds, test suites, deploys, browser automation, remote APIs — has the same ceiling.Suggestion
Two things would fix it, in rough priority order:
tools/callthan forinitialize/tools/list. Comparable clients all expose this: Claude Code hasMCP_TIMEOUT/MCP_TOOL_TIMEOUT, VS Code and Cursor take a per-servertimeoutinmcp.json, goose and kimi-cli both have their own knobs. A per-server field inmcp.jsonplus a global default inconfig.tomlwould match what people already expect.Happy to test a patch against the real workload if that helps. Environment: jcode 0.68.0 (installed via
jcode.sh/install), Linux x86_64.