on main help sign in
fix(mcp): improve timeout errors (#1108)

* fix(mcp): improve timeout errors refs #970 Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: improve Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> --------- Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

commit2fd3b4360e011a2c5c8d81181317b85d43a21b40 authorCarlos Alexandro Becker <caarlos0@users.noreply.github.com> dateTue 23 Sep 2025, 12:12 (1 year ago) parent0da5e6b
1 file changed+19−6
internal/llm/agent/mcp-tools.go+19−6
internal/llm/agent/mcp-tools.go+19−6
@@ -152,13 +152,14 @@ func getOrRenewClient(ctx context.Context, name string) (*client.Client, error)
152152 m := config.Get().MCP[name]
153153 state, _ := mcpStates.Get(name)
154154
155− pingCtx, cancel := context.WithTimeout(ctx, mcpTimeout(m))
155+ timeout := mcpTimeout(m)
156+ pingCtx, cancel := context.WithTimeout(ctx, timeout)
156157 defer cancel()
157158 err := c.Ping(pingCtx)
158159 if err == nil {
159160 return c, nil
160161 }
161− updateMCPState(name, MCPStateError, err, nil, state.ToolCount)
162+ updateMCPState(name, MCPStateError, maybeTimeoutErr(err, timeout), nil, state.ToolCount)
162163
163164 c, err = createAndInitializeClient(ctx, name, m)
164165 if err != nil {
@@ -334,17 +335,22 @@ func createAndInitializeClient(ctx context.Context, name string, m config.MCPCon
334335 slog.Error("error creating mcp client", "error", err, "name", name)
335336 return nil, err
336337 }
338+
339+ timeout := mcpTimeout(m)
340+ initCtx, cancel := context.WithTimeout(ctx, timeout)
341+ defer cancel()
342+
337343 // Only call Start() for non-stdio clients, as stdio clients auto-start
338344 if m.Type != config.MCPStdio {
339− if err := c.Start(ctx); err != nil {
340− updateMCPState(name, MCPStateError, err, nil, 0)
345+ if err := c.Start(initCtx); err != nil {
346+ updateMCPState(name, MCPStateError, maybeTimeoutErr(err, timeout), nil, 0)
341347 slog.Error("error starting mcp client", "error", err, "name", name)
342348 _ = c.Close()
343349 return nil, err
344350 }
345351 }
346− if _, err := c.Initialize(ctx, mcpInitRequest); err != nil {
347− updateMCPState(name, MCPStateError, err, nil, 0)
352+ if _, err := c.Initialize(initCtx, mcpInitRequest); err != nil {
353+ updateMCPState(name, MCPStateError, maybeTimeoutErr(err, timeout), nil, 0)
348354 slog.Error("error initializing mcp client", "error", err, "name", name)
349355 _ = c.Close()
350356 return nil, err
@@ -354,6 +360,13 @@ func createAndInitializeClient(ctx context.Context, name string, m config.MCPCon
354360 return c, nil
355361}
356362
363+func maybeTimeoutErr(err error, timeout time.Duration) error {
364+ if errors.Is(err, context.DeadlineExceeded) {
365+ return fmt.Errorf("timed out after %s", timeout)
366+ }
367+ return err
368+}
369+
357370func createMcpClient(name string, m config.MCPConfig) (*client.Client, error) {
358371 switch m.Type {
359372 case config.MCPStdio: