siyuan-note/siyuan · error

unsupported server type

Error message

unsupported server type: %s

What it means

connectServer dispatches on the configured MCP server's Type field, which must be exactly "stdio" or "http". Any other value (including empty) falls into the default branch and produces this error. It is a configuration validation failure surfaced before any connection attempt.

Solutions

  1. Set server.Type to exactly "stdio" or "http" in the MCP server configuration
  2. If the server is SSE/streamable-HTTP based, use type "http" with the correct URL
  3. Check for case or spelling mistakes in the type value (it is lowercase and case-sensitive)
  4. Re-add the server through the SiYuan MCP settings UI so the type field is written correctly

Example fix

// before
{"name": "myserver", "type": "sse", "url": "http://localhost:3000/sse"}
// after
{"name": "myserver", "type": "http", "url": "http://localhost:3000"}
Defensive patterns

Strategy: validation

Validate before calling

func validMCPServerType(t string) bool {
    switch t {
    case "stdio", "http":
        return true
    }
    return false
}
// call before connectServer: if !validMCPServerType(server.Type) { reject config }

Type guard

null

Try / catch

session, cmd, oauth, err := connectServer(ctx, server, interactive)
if err != nil {
    if strings.Contains(err.Error(), "unsupported server type") {
        logging.LogWarnf("mcp: fix config type for [%s]: %v", server.Name, err)
    }
    return err
}

Prevention

When it happens

Trigger: connectOneServer processes a conf.MCPServer whose server.Type is not "stdio" or "http", e.g. a typo like "Stdio", "sse", "streamable-http", or an unset field.

Common situations: Hand-editing the MCP server config JSON with an unsupported type string, migrating from another client's config format that used "sse" or "websocket", or a config written by an older/newer version with different type names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/03fc876647002e91. Report an issue: GitHub.

Appendix: 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...)
	// stdio 环境变量插值不受密钥 AllowedHosts 约束:目标是本地子进程而非网络主机,管理员在 Env 中
	// 引用 {{secrets.NAME}} 本身就是对该服务器的显式授权,与直接写入明文属于同一信任级别。
	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 {

View on GitHub (pinned to 9f775e8a12)