MCP, auth, and one-off commands
One-off commands
Section titled “One-off commands”Not everything is a conversation. These run the CLI, read what it printed, and exit — a question with an answer rather than a process you talk to over time.
await command.version(); // '2.1.170', or null when undeterminableawait command.usage(); // the usage report as the CLI prints itawait command.update(); // CommandResult — success differs by install methodawait command.describe(); // models, agents, account, settings in force hereawait command.supportsModel('haiku'); // booleanawait command.exec(['mcp', 'list']); // the escape hatch| Method | Worth knowing |
|---|---|
version() |
null rather than throwing. “Which version” is a question a host asks to decide what to offer, and a CLI that will not answer is a fact to handle. |
describe() |
Runs in its own ephemeral session, so asking a CLI to describe itself does not disturb what it was doing or land in the user’s transcript. null on timeout — an older CLI may not support the request. |
supportsModel(m) |
Asked by sending the cheapest possible turn and seeing whether it comes back. Entitlement depends on the account and org, so the honest test is to try. Costs a request — cache the answer. |
exec(args) |
A CLI gains subcommands faster than this library wraps them. Arguments are passed without a shell, so quoting and metacharacters stay literal. |
Authentication
Section titled “Authentication”const status = await command.auth.status();status.loggedIn; // booleanstatus.raw; // the account's own description of itself, uneditedstatus.text; // the human-readable output, for when JSON is absentSigning in is a conversation with the user rather than a question with an answer, so it returns a live session:
const login = command.auth.login('console'); // or 'claudeai', the default
login.onUrl((url) => showToUser(url));login.onFinished((code) => console.log('sign-in exited', code));
login.submitCode(pastedCode);login.cancel();MCP servers
Section titled “MCP servers”Each of these runs the documented CLI command and parses what it printed.
await command.mcp.list(); // McpListEntry[] — names and statusesawait command.mcp.get('playwright'); // McpServer | null — transport details tooawait command.mcp.all(); // every server in full: list, then describe each
await command.mcp.add('playwright', { command: 'npx', args: ['@executeautomation/playwright-mcp-server'],}, { scope: 'user' });
await command.mcp.remove('playwright', { scope: 'user' });| Method | Worth knowing |
|---|---|
list() |
Names and statuses only — that is all claude mcp list reports. Returns [] when the command fails, because no MCP configured is the ordinary case and is indistinguishable from failure in the output. |
all() |
Two commands per server, so noticeably slower. Worth it only when transport details are actually needed. |
add() |
“Already exists” is accepted as a state rather than raised as an error. The CLI reports failure in its output rather than by exit code. |
remove() |
Pass the scope for project- and local-scoped servers, or the CLI looks in the wrong configuration file and finds nothing. |
The config travels as a single positional argument, which is why none of this goes through a shell — on win32 cmd.exe would tokenise the JSON’s quotes, &, | and spaces, corrupting the config and opening an injection surface.
Where to go next
Section titled “Where to go next”- Cross-platform — the caret escaping that keeps
mcp add-jsonintact on Windows.