sipeed/picoclaw · error
failed to connect to MCP server %q: %w
Error message
failed to connect to MCP server %q: %w
What it means
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.
Source
Thrown at cmd/picoclaw/internal/mcp/show.go:174
name := args[0]
server, exists := cfg.Tools.MCP.Servers[name]
if !exists {
return fmt.Errorf("MCP server %q not found", name)
}
serverInfo := buildServerInfo(name, server, cfg.Tools.MCP.Discovery.Enabled)
if !server.Enabled {
cliui.PrintMCPShow(cmd.OutOrStdout(), serverInfo, nil, true)
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
details, err := serverShowProbe(ctx, name, server, cfg.WorkspacePath())
if err != nil {
return fmt.Errorf("failed to connect to MCP server %q: %w", name, err)
}
tools := make([]cliui.MCPShowTool, 0, len(details))
for _, d := range details {
params := make([]cliui.MCPShowParam, 0, len(d.Parameters))
for _, p := range d.Parameters {
params = append(params, cliui.MCPShowParam{
Name: p.Name,
Type: p.Type,
Description: p.Description,
Required: p.Required,
})
}
tools = append(tools, cliui.MCPShowTool{
Name: d.Name,
Description: d.Description,
Parameters: params,
})View on GitHub (pinned to 49183d7e8d)
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
Example fix
# before $ picoclaw mcp show weather --timeout 10s failed to connect to MCP server "weather": failed to connect to server weather: context deadline exceeded # after $ picoclaw mcp show weather --timeout 60s
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight before probing a stdio server
if cmd := server.Command; cmd != "" && strings.ContainsRune(cmd, os.PathSeparator) {
if info, err := os.Stat(cmd); err != nil {
return fmt.Errorf("command %s missing: %w", cmd, err)
} else if info.IsDir() || (runtime.GOOS != "windows" && info.Mode()&0o111 == 0) {
return fmt.Errorf("command %s not executable", cmd)
}
}
for k := range server.Env {
if strings.HasPrefix(server.Env[k], "$") {
return fmt.Errorf("env %s looks like an unresolved variable", k)
}
} Type guard
func isConnectFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to connect to MCP server")
}
func isProbeTimeout(err error) bool {
return errors.Is(err, context.DeadlineExceeded) // works through the %w chain
} Try / catch
details, err := serverShowProbe(ctx, name, server, ws)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// retry once with a longer --timeout (default is 10s)
ctx2, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
details, err = serverShowProbe(ctx2, name, server, ws)
}
if err != nil {
return fmt.Errorf("failed to connect to MCP server %q: %w", name, err)
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to reach MCP server %q: %w
- failed to confirm overwrite: %w
- aborted: MCP server %q already exists
- missing value for %s
- usage: picoclaw mcp add [flags] <name> <command-or-url> [arg
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/7336b666043b6e63.
Report an issue: GitHub.