Repository navigation
Description
Summary
In 2.0.13, adding timeout to an MCP server entry silently removes that entire MCP server from the normalized config. The field is documented in the schema for both local and remote servers, so there is no way to raise the 5s default tool-discovery timeout — which makes slow MCP servers intermittently fail with Request timed out.
Environment
- opencode version:
2.0.13(opencode --version→opencode v2.0.13),channel=latest local=false - OS:
Linux a100server 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 - Terminal:
TERM=xterm-256color,COLORTERM=truecolor - Shell:
/bin/bash - Install/channel:
curl -fsSL https://opencode.ai/v2/install | bash(V2,~/.opencode/bin/opencode) - Active plugins: none
Reproduction
- Add a
timeoutto any MCP server entry, e.g. a remote one:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"servers": {
"demo": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer {env:GITHUB_PERSONAL_ACCESS_TOKEN}" },
"timeout": 60000
}
}
}
}- Run
opencode debug config. demo(here:mcp.servers.github) is not in the output — the whole server is gone.
Same result for a local server: add "timeout": 60000 to an existing local entry and it disappears from opencode debug config too.
Removing timeout makes the server come back. Deterministic across repeated runs; no error is shown on the CLI, only a WARN in the log:
level=WARN message="configuration normalization diagnostic" source=~/.config/opencode/opencode.json path=$.mcp.servers.github kind=invalid action="skipped malformed recognized value"
Fields that are not dropped (so this is specific to timeout): oauth: false and enabled: true on a remote server are both accepted.
Expected Behavior
timeout should be accepted (it is part of the published schema and the embedded schema), or, if unsupported in this build, the field should be ignored/reported while keeping the server configured. The server must not be silently discarded.
Actual Behavior
The entire MCP server entry is dropped from the normalized config. opencode mcp list then shows only the remaining servers.
Schema at https://opencode.ai/config.json claims both variants support it:
McpLocalConfig.timeout— "Timeout in ms for MCP server requests. Defaults to 5000 (5 seconds) if not specified."McpRemoteConfig.timeout— same description.
There also appears to be schema divergence inside the 2.0.13 binary: the embedded JSON schema lists timeout under McpLocalConfig but not under McpRemoteConfig, while the runtime Effect schema defines it for both (McpRemoteConfig also gets enabled and oauth). Regardless of which one the normalizer uses, both variants are dropped in practice.
Additional Context
- Impact: the default 5s tool-discovery timeout cannot be raised. A remote MCP server whose
initialize→notifications/initialized→tools/listhandshake takes ~4.4s (52 tools, 124KB payload) returned✗ ... failed: Request timed out.fromopencode mcp list, while the identical handshake done manually withcurlsucceeded (initialize 0.78s, initialized 0.72s, tools/list 4.53s). With no way to set a longer timeout this is flaky/unfixable from config. - Workaround: none for the timeout itself. (The specific remote server I was debugging was ultimately fixed by adding
oauth: falseto disable OAuth auto-detection, which is a separate issue — buttimeoutcould not be used to make slow handshakes reliable.) - Related, possibly same-area issues: Support per-server MCP execution timeout in config #23096 (per-server MCP timeout, notes
mcp.<server>.timeoutcontrols tool discovery with a 5s default), Documentation for MCP timeout configuration doesn't match schema #23648 (schema vs docs wording), mcp: Windows service registers zero MCP servers from global config #50710 (Windows service registers zero MCP servers from global config).
Activity
chuangye-gu commentedon Sep 23, 2026
Reopening — the fix never landed, and the
completedstate here was misleading.A fix was submitted for this: #50810 (
fix(config): retain MCP timeout entries, +36/−10 including a test). It was closed by the compliance bot, not by a maintainer — the PR description was missing the required template sections and wasn't updated within the 2-hour window. It was never merged, and the author hasn't re-submitted.Mainline is still pre-fix:
packages/opencode/src/config/v2-compat.tsis at blob9e4e0bf540, which is exactly the before side of #50810's diff (index 9e4e0bf54089..40f5f64d75a8), with no commits touching that file since 2026-08-27. So this reproduces on 2.0.13 and 2.0.14.Why it isn't cosmetic: the 5s default MCP request timeout can't be raised, so a remote MCP server with a slow handshake fails intermittently with
Request timed out.I measuredtools/listagainst a remote MCP server at 1.6–8.0s over 6 runs, andopencode mcp listfails whenever it exceeds 5s.For reference, the patch in #50810 is small and looks correct: let
Timeoutaccept a plainPositiveIntalongside the{startup, request, catalog, execution}struct, and add atypeof input === "number"branch inlowerTimeout()(plus relax the global-timeout guard).