siyuan-note/siyuan · error

unsupported server type: %s

Error message

unsupported server type: %s

What it means

Returned by the MCP client connector's `switch server.Type` when the configured server type is neither `"stdio"` nor `"http"`. These are the only transports the kernel supports for outbound MCP connections; any other value falls through to the default case and yields this error.

Source

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

	}
}

func connectServer(ctx context.Context, server conf.MCPServer, interactive bool) (*mcp.ClientSession, *exec.Cmd, *mcpOAuthHandler, error) {
	c := mcp.NewClient(&mcp.Implementation{Name: "siyuan", Version: "3.0"}, &mcp.ClientOptions{
		ToolListChangedHandler: func(context.Context, *mcp.ToolListChangedRequest) {
			logging.LogInfof("mcp: server [%s] tool list changed, reconnecting", server.Name)
			go reconnectMCPServer(server.ID)
		},
	})

	switch server.Type {
	case "stdio":
		session, cmd, err := connectStdio(ctx, c, server)
		return session, cmd, nil, err
	case "http":
		return connectHTTP(ctx, c, server, interactive)
	default:
		return nil, nil, nil, fmt.Errorf("unsupported server type: %s", server.Type)
	}
}

func connectStdio(ctx context.Context, client *mcp.Client, server conf.MCPServer) (*mcp.ClientSession, *exec.Cmd, error) {
	if server.Command == "" {
		return nil, nil, fmt.Errorf("command is required for stdio server")
	}

	cmd := exec.Command(server.Command, server.Args...)
	cmdEnv, err := buildStdioEnvironment(server, os.LookupEnv, func(value string) string {
		if model.Conf == nil {
			return value
		}
		return conf.ResolveSecretsVars(model.Conf.Secrets, model.Conf.Variables, value)
	}, runtime.GOOS)
	if err != nil {
		return nil, nil, fmt.Errorf("environment: %w", err)
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Set `type` to exactly `"stdio"` for command-based servers or `"http"` for streamable HTTP servers.
  2. Check for surrounding whitespace or hidden characters in the config value.
  3. Re-add the server through the kernel's MCP config UI/API to get a canonical entry.

Example fix

// before
{ "name": "myserver", "type": "STDIO", "command": "./srv" }
// after
{ "name": "myserver", "type": "stdio", "command": "./srv" }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the server type at config-load time:
switch server.Type {
case "stdio", "http":
default:
    return fmt.Errorf("unsupported server type: %s", server.Type)
}

Type guard

func isValidServerType(t string) bool {
    return t == "stdio" || t == "http"
}

Prevention

When it happens

Trigger: An MCP server entry in config whose `type` field is missing, misspelled (e.g. `stdio\n`, `STDIO`, `sse`, `ws`), or set to an unsupported value. The switch is case-sensitive on the exact strings `stdio` and `http`.

Common situations: Hand-editing the MCP server config with a typo; copying a config snippet that used a type from a different MCP client; uppercase or whitespace in the type string; using `sse` when only `http` (streamable) is supported.

Related errors


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