siyuan-note/siyuan · error

mcp server [%s] not connected

Error message

mcp server [%s] not connected

What it means

Returned by callMCPTool when no connected ClientSession exists for the given server name. getMCPSession walks mcpConns under mcpMu and returns nil if no conn.ServerName matches; the tool-call cannot proceed. This is a connectivity/ordering problem, not a tool-arg problem.

Source

Thrown at kernel/mcp/client/mcp.go:801

	return tools.CallToolResult{
		Content: []tools.ContentItem{{
			Type: "text",
			Text: "mcp tool returned invalid content after execution; execution result may have side effects and must not be " +
				"retried automatically",
		}},
		IsError:          true,
		ExecutionUnknown: true,
	}
}

func trustedReadOnlyHint(server conf.MCPServer, tool *mcp.Tool) bool {
	return server.TrustToolAnnotations && tool.Annotations != nil && tool.Annotations.ReadOnlyHint
}

func callMCPTool(parentCtx context.Context, serverName, toolName string, timeout time.Duration, args map[string]any) (*mcp.CallToolResult, error) {
	session := getMCPSession(serverName)
	if session == nil {
		return nil, fmt.Errorf("mcp server [%s] not connected", serverName)
	}

	ctx, cancel := context.WithTimeout(parentCtx, timeout)
	defer cancel()

	return session.CallTool(ctx, &mcp.CallToolParams{
		Name:      toolName,
		Arguments: args,
	})
}

func getMCPSession(serverName string) *mcp.ClientSession {
	mcpMu.Lock()
	defer mcpMu.Unlock()
	for _, conn := range mcpConns {
		if conn.ServerName == serverName {
			return conn.Session
		}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Check the MCP runtime state for the server (state, error message) via the kernel's MCP status API before issuing tool calls.
  2. Ensure the server is enabled and connected; if it failed, read its connection error and fix it (see the stdio/http connect errors).
  3. Verify serverName matches exactly (case-sensitive) the Name field of a connected server.
  4. After reconnecting, the ToolListChanged handler triggers reconnectMCPServer; do not call tools on that server until reconnect completes.
Defensive patterns

Strategy: validation

Validate before calling

// Check connectivity before issuing a tool call.
func serverConnected(name string) bool {
    return client.GetMCPSession(name) != nil // (would require exporting getMCPSession)
}

Try / catch

// On 'not connected', do NOT retry the tool call blindly; refresh server state first.
if strings.Contains(err.Error(), "not connected") {
    // read MCP runtime state, reconnect if appropriate, then retry once
}

Prevention

When it happens

Trigger: An AI agent or kernel code path invokes callMCPTool(parentCtx, serverName, toolName, timeout, args) while the named MCP server is not in mcpConns: it was never started, failed to connect, was disconnected, or the name does not match (case-sensitive).

Common situations: Server was disabled in config or its connect failed silently; the agent used a stale tool list after a ToolListChanged event but before reconnect completed; name mismatch between the tool's owning server and the name passed in; server crashed and reconnectMCPServer has not yet succeeded.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/2fdfc9b21fb6951d. Report an issue: GitHub.