{"record":{"id":"20aa91400ad0adb7","repo":"sipeed/picoclaw","slug":"failed-to-reach-mcp-server-q-w","errorCode":null,"errorMessage":"failed to reach MCP server %q: %w","messagePattern":"failed to reach MCP server %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/mcp/test.go","lineNumber":35,"sourceCode":"\t\tArgs:  cobra.ExactArgs(1),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tcfg, err := loadConfig()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\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\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\t\t\tdefer cancel()\n\n\t\t\tresult, err := serverProbe(ctx, name, server, cfg.WorkspacePath())\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to reach MCP server %q: %w\", name, err)\n\t\t\t}\n\n\t\t\tfmt.Fprintf(cmd.OutOrStdout(), \"✓ MCP server %q reachable (%d tools).\\n\", name, result.ToolCount)\n\t\t\treturn nil\n\t\t},\n\t}\n\n\tcmd.Flags().DurationVar(&timeout, \"timeout\", 5*time.Second, \"Connection timeout\")\n\n\treturn cmd\n}\n","sourceCodeStart":17,"sourceCodeEnd":47,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/mcp/test.go#L17-L47","documentation":"Wrapper around the probe failure in picoclaw mcp test <name>. The probe forces Enabled=true on a single-server Manager config and calls LoadFromMCPConfig, which spawns the local command or dials the remote URL and performs the MCP handshake. Any failure — spawn errors, path validation, transport errors, handshake or timeout — is reported under this message with %w, preserving the underlying cause. The probe runs under --timeout, default 5s.","triggerScenarios":"Server process fails to start (missing binary, missing env secrets, bad args); local command is a directory or lacks the execute bit; remote endpoint refused/unreachable; handshake exceeding the 5s default on slow-starting servers (e.g. first run of npx/uvx downloading packages).","commonSituations":"Local servers whose secrets live only in the user's shell; cold starts of package-run servers exceeding 5s; wrong command path after moving a binary; firewalled or mis-routed remote MCP URLs.","solutions":["Raise the budget: picoclaw mcp test <name> --timeout 30s","Run the configured command manually with the same env/args and check it starts and speaks MCP on stdio","Verify command path (exists, is a file, is executable) and env/env_file contents","Read the wrapped error — it distinguishes spawn, transport, and handshake failures"],"exampleFix":"# before\n$ picoclaw mcp test weather\nfailed to reach MCP server \"weather\": failed to connect to server weather: context deadline exceeded\n\n# after\n$ picoclaw mcp test weather --timeout 30s","handlingStrategy":"retry","validationCode":"// pre-flight the stdio command before testing connectivity\nif cmd := server.Command; cmd != \"\" {\n  if _, err := exec.LookPath(cmd); err != nil {\n    if info, statErr := os.Stat(cmd); statErr != nil || info.IsDir() {\n      return fmt.Errorf(\"command %s unusable: %v\", cmd, err)\n    }\n  }\n}","typeGuard":"func isReachFailure(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"failed to reach MCP server\")\n}\n\nfunc isProbeTimeout(err error) bool {\n  return errors.Is(err, context.DeadlineExceeded)\n}","tryCatchPattern":"var result probeResult\nvar err error\nfor attempt := 0; attempt < 3; attempt++ {\n  ctx, cancel := context.WithTimeout(context.Background(), timeout*time.Duration(attempt+1))\n  result, err = serverProbe(ctx, name, server, ws)\n  cancel()\n  if err == nil || !errors.Is(err, context.DeadlineExceeded) {\n    break // only retry timeouts; hard failures surface immediately\n  }\n}","preventionTips":["Use --timeout 30s or more for cold starts (package downloads on first npx/uvx run)","Warm the server once manually so caches exist before automated tests","Distinguish timeouts (retryable) from spawn/auth failures (not) via the wrapped error"],"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"}