shaft-cli command line
shaft-cli is an MCP client and command-line interface to
shaft-mcp. It brings the full shaft-mcp tool set to the
command line with zero tool-logic duplication, operating in two modes:
stateless one-shot commands and a persistent session mode for stateful tools.
Install
Pass --install-shaft-cli to the shaft-mcp installer (the copy-paste command
on the Connect shaft-mcp page) to also install shaft-cli —
no local Java or Python required; the installer bootstraps whatever is missing.
The flag is independent of --client, so it can be combined with any MCP
client target, or run on its own.
The installer downloads and SHA-256-verifies shaft-cli-<version>.jar from
Maven Central, then writes a runnable launcher (shaft-cli on macOS/Linux,
shaft-cli.cmd on Windows) plus a shaft-cli.args Java argfile next to it,
under the platform's application-data root:
- Windows:
%LOCALAPPDATA%\ShaftHQ\shaft-cli\versions\<version>\ - macOS:
~/Library/Application Support/ShaftHQ/shaft-cli/versions/<version>/ - Linux:
${XDG_DATA_HOME:-~/.local/share}/shafthq/shaft-cli/versions/<version>/
shaft-mcp is a prerequisite; install it with the same command. shaft-cli locates it in this order:
- The
SHAFT_MCP_JARenvironment variable - The installer's versions directory
- A sibling
../shaft-mcp/target(development checkout)
Modes
One-shot mode (default): each command spawns an ephemeral shaft-mcp child process over stdio, runs a single tool call, and exits. Suitable for stateless tools like guide search and doctor analysis.
Session mode: shaft-cli session start launches a persistent shaft-mcp
daemon (HTTP on a localhost port) and records the session endpoint to
~/.shaft/cli-session.json. Subsequent commands connect over HTTP, preserving
browser and device state across invocations. Commands that need live state
(browser, element, capture) fail fast when no session is running, unless
--stdio-ok is passed.
Routing: if a live session exists, commands use HTTP; otherwise a one-shot stdio child is spawned.
Commands
All commands support -h/--help; the root supports -V/--version.
shaft-cli tools [--json] — list all available tools (name and first
sentence of description). --json outputs the raw tools/list result.
shaft-cli call <TOOL> [key=value ...] [--args '<json>'] [--json] [--stdio-ok] — invoke any tool by name. Arguments come from repeated
key=value pairs (values are coerced: true/false to booleans,
integers/decimals to numbers, {...}/[...] to JSON, otherwise strings)
and/or --args '{"k":"v"}' (key=value overrides keys from --args).
--json outputs the raw JSON-RPC result instead of rendered text.
shaft-cli session start | status | stop — manage the daemon. start
prints the port and pid; status prints
running — port <port>, pid <pid>, started <iso-8601>.
Curated aliases (same options as call):
shaft-cli browser navigate|screenshot|dom|url(session required)shaft-cli element click|type|hover(session required)shaft-cli capture start|stop|status|code(session required)shaft-cli guide search(stateless)shaft-cli doctor analyze|suggest(stateless)
Examples
shaft-cli tools
# trace_latest — returns recent persisted SHAFT trace indexes from target/shaft-traces
# [...]
shaft-cli session start
# shaft-cli session started on port 12345 (pid 9876).
shaft-cli session status
# running — port 12345, pid 9876, started 2025-12-20T14:30:45Z
shaft-cli call shaft_guide_search query='click element' maxResults=1
# [JSON guide-search result]
shaft-cli guide search query='click element' --stdio-ok
# [guide search works with no session]
shaft-cli call test_plan_explore targetUrl=https://example.test goal='checkout happy path' maxDepth=2
# [Markdown test plans written to specs/]
Exit codes
- 0: success
- 1: tool error, transport error, or
--jsonresult withisError - 2: unknown alias action