You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add init_timeout (global default + per-server override) controlling the
deadline for an upstream's MCP initialize handshake. Un-isolated stdio
servers previously inherited the caller's ~30s context and were killed
mid-startup during legitimate first-run warmup (cache/index build); with
docker run --rm the partial work was discarded and retries looped forever
(GH #760).
- config: InitTimeout *Duration on Config and ServerConfig; ResolveInitTimeout
(per-server > global > 30s default; <=0 maps to default, never disabled);
bounds {0} u [1s,30m] in Validate().
- upstream/manager: resolveConnectTimeout applied at AddServer, ConnectAll
(wrap ALL connects, not just Docker), and the post-OAuth retry; Docker
isolation keeps a 3m floor, a larger override still wins.
- Plumb init_timeout through the upstream_servers MCP tool (add/patch),
REST AddServerRequest allowlist + GET serialization, config merge/copy,
storage UpstreamRecord, contracts.Server, and mcpproxy upstream patch
--init-timeout.
- Docs (configuration.md) + regenerated oas/swagger.yaml.
Related #760
Copy file name to clipboardExpand all lines: cmd/mcpproxy/upstream_cmd.go
+19-2Lines changed: 19 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -286,6 +286,7 @@ Examples:
286
286
upstreamPatchHeaderRemove []string
287
287
upstreamPatchEnvs []string
288
288
upstreamPatchEnvRemove []string
289
+
upstreamPatchInitTimeoutstring
289
290
290
291
// Import command flags
291
292
upstreamImportServerstring
@@ -361,6 +362,7 @@ func init() {
361
362
upstreamPatchCmd.Flags().StringArrayVar(&upstreamPatchHeaderRemove, "header-remove", nil, "HTTP header name to delete (repeatable)")
362
363
upstreamPatchCmd.Flags().StringArrayVar(&upstreamPatchEnvs, "env", nil, "Environment variable to upsert in KEY=value format (repeatable)")
363
364
upstreamPatchCmd.Flags().StringArrayVar(&upstreamPatchEnvRemove, "env-remove", nil, "Environment variable name to delete (repeatable)")
365
+
upstreamPatchCmd.Flags().StringVar(&upstreamPatchInitTimeout, "init-timeout", "", "MCP initialize handshake deadline as a duration (e.g. '120s', '3m'); raise for upstreams that warm up before responding to initialize")
364
366
365
367
// Inspect command flags
366
368
upstreamInspectCmd.Flags().StringVar(&upstreamInspectTool, "tool", "", "Show details for a specific tool")
Copy file name to clipboardExpand all lines: docs/configuration.md
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -86,7 +86,8 @@ MCPProxy looks for configuration in these locations (in order):
86
86
{
87
87
"tools_limit": 15,
88
88
"tool_response_limit": 20000,
89
-
"call_tool_timeout": "2m"
89
+
"call_tool_timeout": "2m",
90
+
"init_timeout": "30s"
90
91
}
91
92
```
92
93
@@ -95,6 +96,7 @@ MCPProxy looks for configuration in these locations (in order):
95
96
|`tools_limit`| integer |`15`| Maximum number of tools to return per request (1-1000) |
96
97
|`tool_response_limit`| integer |`20000`| Maximum characters in tool responses (0 = unlimited) |
97
98
|`call_tool_timeout`| string |`"2m"`| Timeout for tool calls (e.g., `"30s"`, `"2m"`, `"5m"`). **Note**: When using agents like Codex or Claude as MCP servers, you may need to increase this timeout significantly, even up to 10 minutes (`"10m"`), as these agents may require longer processing times for complex operations |
99
+
|`init_timeout`| duration |`"30s"`| Deadline for an upstream's MCP `initialize` handshake (e.g. `"30s"`, `"120s"`, `"3m"`). Raise this for servers that do legitimate first-run warmup — building a cache/index or prefetching — before they answer `initialize`, so they are not killed mid-startup. Global default; can be overridden per server (see [Server Fields](#server-fields)). Range: `1s`–`30m`; `"0s"`/unset uses the 30s default. |
98
100
99
101
### Discovery & Health Checks
100
102
@@ -208,6 +210,7 @@ the proxy.
208
210
|`launcher_wait_timeout`| duration | No | When `command` is set together with an HTTP/SSE `url`, how long mcpproxy waits for that URL to become reachable after spawning the child (e.g. `"15s"`, default `"30s"`) |
209
211
|`health_check_interval`| duration | No | Per-server override for the global [`health_check_interval`](#discovery--health-checks). `"0s"` disables the liveness probe for this server only. Range: `5s`–`1h`. Omit to inherit the global value. |
210
212
|`tool_discovery_interval`| duration | No | Per-server override for the global [`tool_discovery_interval`](#discovery--health-checks). Overrides the global/default cadence for this server only; `"0s"` disables the periodic tool-discovery sweep for this server (connect-time and reactive `list_changed` discovery still run). Range: `30s`–`24h`. Omit to inherit the global value. |
213
+
|`init_timeout`| duration | No | Per-server override for the global [`init_timeout`](#search--tool-limits) — the MCP `initialize` handshake deadline. Raise it for an upstream that warms up (caches/indexes data) before responding to `initialize` (e.g. `"120s"`, `"3m"`); without it such a server is killed mid-startup and, with `docker run --rm`, retries forever. Range: `1s`–`30m`. Omit to inherit the global value (30s default). Settable via the `upstream_servers` tool and `mcpproxy upstream patch --init-timeout`. |
211
214
|`oauth`| object | No | OAuth configuration (see [OAuth Configuration](#oauth-configuration)) |
212
215
|`isolation`| object | No | Per-server Docker isolation settings (see [Docker Isolation](#docker-isolation)) |
213
216
|`enabled`| boolean | No | Enable/disable server (default: `true`) |
EnabledTools []string`json:"enabled_tools,omitempty" mapstructure:"enabled_tools"`// Allowlist: only these tools are exposed; mutually exclusive with disabled_tools
371
409
DisabledTools []string`json:"disabled_tools,omitempty" mapstructure:"disabled_tools"`// Denylist: these tools are hidden; mutually exclusive with enabled_tools
0 commit comments