{"record":{"id":"7336b666043b6e63","repo":"sipeed/picoclaw","slug":"failed-to-connect-to-mcp-server-q-w","errorCode":null,"errorMessage":"failed to connect to MCP server %q: %w","messagePattern":"failed to connect to MCP server %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/mcp/show.go","lineNumber":174,"sourceCode":"\t\t\tname := args[0]\n\t\t\tserver, exists := cfg.Tools.MCP.Servers[name]\n\t\t\tif !exists {\n\t\t\t\treturn fmt.Errorf(\"MCP server %q not found\", name)\n\t\t\t}\n\n\t\t\tserverInfo := buildServerInfo(name, server, cfg.Tools.MCP.Discovery.Enabled)\n\n\t\t\tif !server.Enabled {\n\t\t\t\tcliui.PrintMCPShow(cmd.OutOrStdout(), serverInfo, nil, true)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\t\t\tdefer cancel()\n\n\t\t\tdetails, err := serverShowProbe(ctx, name, server, cfg.WorkspacePath())\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to connect to MCP server %q: %w\", name, err)\n\t\t\t}\n\n\t\t\ttools := make([]cliui.MCPShowTool, 0, len(details))\n\t\t\tfor _, d := range details {\n\t\t\t\tparams := make([]cliui.MCPShowParam, 0, len(d.Parameters))\n\t\t\t\tfor _, p := range d.Parameters {\n\t\t\t\t\tparams = append(params, cliui.MCPShowParam{\n\t\t\t\t\t\tName:        p.Name,\n\t\t\t\t\t\tType:        p.Type,\n\t\t\t\t\t\tDescription: p.Description,\n\t\t\t\t\t\tRequired:    p.Required,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\ttools = append(tools, cliui.MCPShowTool{\n\t\t\t\t\tName:        d.Name,\n\t\t\t\t\tDescription: d.Description,\n\t\t\t\t\tParameters:  params,\n\t\t\t\t})","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/mcp/show.go#L156-L192","documentation":"Wrapper around every probe failure in picoclaw mcp show <name>. The command builds a one-server Manager (Enabled forced true), calls LoadFromMCPConfig — which spawns the server process and performs the MCP initialize handshake — and any failure there is reported under this message with %w, so the underlying cause stays visible. The whole probe runs under the --timeout flag, default 10s.","triggerScenarios":"Server binary exits immediately (missing env vars such as API keys, bad args, missing runtime); local command path missing or not executable (validateLocalCommandPath failures bubble up here); remote URL refused or unreachable; initialize handshake or tools listing exceeding the 10s default on slow-starting servers.","commonSituations":"Server secrets present in the user's shell but absent from the config env/env_file map; first start of heavy servers (python/uvx resolving packages) blowing the default timeout; moved or deleted binaries; wrong base URL for remote MCP servers.","solutions":["Re-run with a bigger budget: picoclaw mcp show <name> --timeout 60s","Run the configured command by hand with the same env and args and watch its stderr","Check the server's env and env_file entries supply every secret the server needs","For local commands verify the path exists and is executable; for URLs, curl the endpoint","Read the wrapped error text — it names the actual transport, spawn, or handshake failure"],"exampleFix":"# before\n$ picoclaw mcp show weather --timeout 10s\nfailed to connect to MCP server \"weather\": failed to connect to server weather: context deadline exceeded\n\n# after\n$ picoclaw mcp show weather --timeout 60s","handlingStrategy":"try-catch","validationCode":"// pre-flight before probing a stdio server\nif cmd := server.Command; cmd != \"\" && strings.ContainsRune(cmd, os.PathSeparator) {\n  if info, err := os.Stat(cmd); err != nil {\n    return fmt.Errorf(\"command %s missing: %w\", cmd, err)\n  } else if info.IsDir() || (runtime.GOOS != \"windows\" && info.Mode()&0o111 == 0) {\n    return fmt.Errorf(\"command %s not executable\", cmd)\n  }\n}\nfor k := range server.Env {\n  if strings.HasPrefix(server.Env[k], \"$\") {\n    return fmt.Errorf(\"env %s looks like an unresolved variable\", k)\n  }\n}","typeGuard":"func isConnectFailure(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"failed to connect to MCP server\")\n}\n\nfunc isProbeTimeout(err error) bool {\n  return errors.Is(err, context.DeadlineExceeded) // works through the %w chain\n}","tryCatchPattern":"details, err := serverShowProbe(ctx, name, server, ws)\nif err != nil {\n  if errors.Is(err, context.DeadlineExceeded) {\n    // retry once with a longer --timeout (default is 10s)\n    ctx2, cancel := context.WithTimeout(context.Background(), 60*time.Second)\n    defer cancel()\n    details, err = serverShowProbe(ctx2, name, server, ws)\n  }\n  if err != nil {\n    return fmt.Errorf(\"failed to connect to MCP server %q: %w\", name, err)\n  }\n}","preventionTips":["Pass --timeout 60s for slow-starting servers (first npx/uvx runs, JVM-based servers)","Put required secrets in the server's env/env_file, not only in your shell","Smoke-test the server command by hand before adding it to picoclaw"],"tags":["mcp","network","connection","timeout","cli"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}