siyuan-note/siyuan · error
command is required for stdio server
Error message
command is required for stdio server
What it means
Returned by `connectStdio` when a server of type `"stdio"` has an empty `Command` field. The stdio transport spawns the server via `exec.Command(server.Command, server.Args...)`, so a missing command leaves nothing to launch; the guard fails fast before attempting the spawn.
Source
Thrown at kernel/mcp/client/mcp.go:450
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)
}
cmd.Env = cmdEnv
stdin, err := cmd.StdinPipe()
if err != nil {
return nil, nil, fmt.Errorf("stdin pipe: %w", err)
}
stdout, err := cmd.StdoutPipe()View on GitHub (pinned to 251596fc0d)
Solutions
- Provide a non-empty `command` for the stdio server, e.g. `"command": "npx"`.
- If the server is HTTP-based, set `type` to `"http"` and fill `url` instead of `command`.
- Validate the config that any `stdio` entry has both a `command` and (optionally) `args`.
Example fix
// before
{ "name": "srv", "type": "stdio", "args": ["-m", "my_server"] }
// after
{ "name": "srv", "type": "stdio", "command": "python", "args": ["-m", "my_server"] } Defensive patterns
Strategy: validation
Validate before calling
// Validate stdio server entries before attempting to connect:
if server.Type == "stdio" && strings.TrimSpace(server.Command) == "" {
return fmt.Errorf("command is required for stdio server")
} Type guard
func isValidStdioServer(s conf.MCPServer) bool {
return s.Type == "stdio" && strings.TrimSpace(s.Command) != ""
} Prevention
- Always set a non-empty command for stdio MCP servers.
- For HTTP servers, set type to http and fill url instead of command.
- Validate the full config envelope (type + required transport field) at load time.
When it happens
Trigger: A `stdio` MCP server config where `command` is omitted or empty, even though `args` may be present. The check `server.Command == ""` is the first thing `connectStdio` does.
Common situations: Configuring only `args` and forgetting `command`; a templated config whose `$COMMAND` variable expanded to empty; a server entry meant to be `http` but mistyped as `stdio`.
Related errors
- unsupported server type: %s
- start command: %w
- tools/list returned an empty response
- tools/list repeated cursor %q
- environment: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ab0427c15d43f989.
Report an issue: GitHub.