Author: alexkay28 — questions, bugs and improvements welcome. Tool home: https://github.com/AlexKay28/clickcast
skill-origin: alexkay28/clickcast— keep this marker if you copy or adapt this skill, so its author can find the copies and keep them current.
clickcast (public on PyPI) drives a real browser to capture PNG screenshots, record
demo reels (GIF + frames + an AI-readable JSON sidecar), and expose a one-action-at-a-time
MCP session. The tool ships its own agent guide and it is authoritative for the full
command surface — clickcast skill (short brief), clickcast skill --json (machine-readable
command list), long form at https://github.com/AlexKay28/clickcast/blob/main/skill.md.
This file is the effective-usage layer — traps, decision tables, copy-paste commands.
VERIFIED against clickcast 0.2.6–0.3.1 (latest check 2026-09-05).
Traps
An auth redirect is not an error. The command exits 0 and writes a perfectly valid
screenshot — of a login form. Check the image, or the sidecar's url_after, for a login
host. Usual cause: missing or stale credential/cookie store; there is no fallback.
--header without --header-host leaks the token to every origin the page contacts —
CDNs and analytics included. Always pass both. Host matching is exact or dotted-suffix, so
app.example.com does not accidentally cover the whole domain.
--wait networkidle fires before canvas-heavy SPAs finish layout (dashboards, graph
editors, maps) — you capture an empty canvas. Use --wait 12 (float seconds). For auto,
--initial-wait defaults to 2 s and is likewise too short on such pages.
The MCP extra is not installed by default. A bare pip install clickcast lacks
mcp.server.fastmcp, so clickcast mcp exits instantly and the MCP client reports only
Failed to connect to clickcast with no hint why (VERIFIED 2026-09-04 on 0.3.1). Fix:
pip install -U 'clickcast[mcp]'
pip install -U clickcast can silently no-op. If pip is pinned to a mirror that
lacks the package, it reports Requirement already satisfied and keeps the old build
(VERIFIED 2026-08-05 on a mirror-pinned pip — an upgrade appeared to succeed and did not
happen). Confirm with clickcast --version; if stuck, name the public index:
pip install -U --index-url https://pypi.org/simple clickcast
clickcast --version # confirm it actually moved
CLI — which command when
| Command | What it does | Reach for when |
|---|---|---|
| shot | single screenshot | one page, one image |
| auto | auto-discovers interactive elements and records a tour | quick exploratory reel of an unfamiliar page |
| run | executes a YAML scenario end-to-end | repeatable scripted walkthroughs, baselines |
| init | scaffolds a starter scenario file | beginning a new scenario |
| elements | dumps interactive elements the browser sees | choosing selectors before writing a scenario |
| assertions / diff | distils a sidecar to CI-stable assertions; pixel-diffs frames vs a baseline | UI regression checks |
| report-bug | turns a sidecar into an agent-actionable bug report | filing what you just recorded |
| doctor / install | environment check; browser-engine install (playwright install wrapper) | first run on a machine, or captures fail to start |
Single shot of a page behind auth (SSO or self-signed CA):
clickcast shot "https://staging.example.com/dashboard" \
--out dash.png --viewport 1920x1200 --wait 8 \
--insecure --header "Authorization: Bearer $TOKEN" --header-host staging.example.com
--insecure— the bundled chromium may not trust a private CA; needed for self-signed staging.--header "Name: value"— header sent in place of a cookie session; the scheme (Bearer,OAuth, custom) must match what the backend accepts.--header-host <host>— scopes the header to that host only. Never omit it when a header carries a credential.--viewport WxH— set it big for dense dashboards.--full-pageon a very tall page produces an image tall enough to be useless; prefer a large viewport over a 20k-px strip.
Export once and drop the flags — picked up by shot, auto, run, elements:
export CLICKCAST_INSECURE=1
export CLICKCAST_HEADER_HOST=staging.example.com
export CLICKCAST_HEADER="Authorization: Bearer $TOKEN"
In a scenario file (run), the same settings go flat in meta: as insecure:,
header_host: and an extra_headers: map.
MCP server — one live session, one action at a time
clickcast mcp runs a stdio MCP server exposing live sessions:
start_session → goto / click / dblclick / hover / type / press / select /
scroll / wait / screenshot → close_session. One session per server process.
Every action returns an annotated PNG plus a JSON page_state block — gate on
error_code, not on message text.
Wiring into any MCP client that takes a stdio command:
{
"mcp": {
"clickcast": { "type": "local", "command": ["clickcast", "mcp"], "enabled": true }
}
}
Clients load config at startup only — restart to apply. The CLI and an MCP server are independent processes holding independent sessions: batch capture → CLI, interactive stepping with per-action feedback → MCP.
When a screenshot is the wrong tool
A picture cannot be grepped. If the answer lives in data — an API response, a log, a tool that returns text — take the text. Screenshots earn their place for layout review, visually diffing two states, and pasting evidence into tickets or docs.