Tencent/WeKnora · error
failed to list tools: %w
Error message
failed to list tools: %w
What it means
ListTools wraps errors from c.client.ListTools after a successful initialize. It indicates the tools/list RPC failed: the connection dropped, the server returned a JSON-RPC error, the request timed out, or the server does not support the tools capability. checkErrorAndDisconnectIfNeeded runs first and may mark the client disconnected on fatal errors.
Source
Thrown at internal/mcp/client.go:426
Title: result.ServerInfo.Title,
Description: result.ServerInfo.Description,
},
}, nil
}
// ListTools retrieves the list of available tools
func (c *mcpGoClient) ListTools(ctx context.Context) ([]*types.MCPTool, error) {
if !c.initialized {
return nil, ErrNotConnected
}
req := mcp.ListToolsRequest{}
result, err := oauthCall(ctx, c, func() (*mcp.ListToolsResult, error) {
return c.client.ListTools(ctx, req)
})
if err != nil {
c.checkErrorAndDisconnectIfNeeded(err)
return nil, fmt.Errorf("failed to list tools: %w", err)
}
// Convert to our types
tools := make([]*types.MCPTool, len(result.Tools))
for i, tool := range result.Tools {
data, _ := json.Marshal(tool.InputSchema)
tools[i] = &types.MCPTool{
Name: tool.Name,
Description: tool.Description,
InputSchema: data,
}
}
return tools, nil
}
// ListResources retrieves the list of available resources
func (c *mcpGoClient) ListResources(ctx context.Context) ([]*types.MCPResource, error) {View on GitHub (pinned to 988cbb0330)
Solutions
- Reconnect: call Connect + Initialize again (check for ErrNotConnected / disconnected state) and retry ListTools
- Increase the AdvancedConfig.Timeout or use a shorter-lived context appropriate to the RPC
- Verify the server advertises the tools capability in its initialize response
- Check proxy/LB idle timeouts that kill long-lived SSE/streamable sessions
Example fix
// before
tools, err := c.ListTools(ctx)
if err != nil { return nil, err }
// after
tools, err := c.ListTools(ctx)
if err != nil {
if rerr := reconnectAndInit(ctx, c); rerr != nil { return nil, rerr }
tools, err = c.ListTools(ctx)
if err != nil { return nil, err }
} Defensive patterns
Strategy: retry
Validate before calling
func listToolsWithReconnect(ctx context.Context, c MCPClient) ([]*types.MCPTool, error) {
tools, err := c.ListTools(ctx)
if err == nil { return tools, nil }
_ = c.Disconnect()
if err := c.Connect(ctx); err != nil { return nil, err }
if _, err := c.Initialize(ctx); err != nil { return nil, err }
return c.ListTools(ctx)
} Type guard
func isListToolsFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to list tools")
} Try / catch
tools, err := c.ListTools(ctx)
if err != nil {
if errors.Is(err, ErrNotConnected) || isListToolsFailure(err) {
return listToolsWithReconnect(ctx, c) // single reconnect+retry
}
return nil, err
} Prevention
- Keep clients short-lived or add periodic reconnects before server session expiry
- Set proxy/LB idle timeouts longer than the longest expected RPC
- Verify server tools capability in InitializeResult before listing
When it happens
Trigger: ListTools called on an initialized client whose session has since expired/been closed by the server, whose context deadline expired mid-RPC, or whose server replies with a JSON-RPC error (e.g. capability not implemented).
Common situations: Long-lived client reused past the server's session timeout; server restarted between initialize and list tools; calling ListTools against a server that doesn't advertise the tools capability; idle SSE connection severed by a proxy/load balancer.
Related errors
- failed to list resources: %w
- failed to list resources: %w
- failed to create SSE client: %w
- URL is required for HTTP Streamable transport
- failed to create HTTP streamable client: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/91c42135f24cd4c6.
Report an issue: GitHub.