@joeyshi12/casper
v0.10.2
Published
Web client for kiro-cli over the Agent Client Protocol
Maintainers
Readme
A web client for kiro-cli, over its Agent Client Protocol (ACP). Start a long
Kiro task and it keeps running server-side; on reconnect the client replays
exactly what it missed.
Features
- Sessions you can create, search, rename and delete. Live ones run in a bounded process pool; idle ones go dormant and resume on demand.
- Per-session model and agent, from the live model list and kiro's agents.
- Rich rendering of Markdown, Mermaid, syntax-highlighted code, and MCP tool calls with their status, input and output.
- File browser for the session's workspace, previewing text, images and PDFs. HTML renders as a live page, sandboxed, and either can go fullscreen.
- Widgets: the agent calls a
show_widgettool over MCP and the result renders inline as a live page. Charts, simulations, animated diagrams. Sandboxed, and they can send a message back. - Observability for credits spent, context-window usage and turn duration.
- PWA that installs to a home screen and reconnects when the network returns.
Install
Needs Node 24+, since Casper keeps its state in SQLite via the built-in
node:sqlite. It also needs kiro-cli installed and logged in.
Casper is a client for it, so nothing works without it.
npm install -g @joeyshi12/casper
casperThe first run generates an access token, prints it in a bordered block, and drops
the casper agent into ~/.kiro/agents. Open the printed URL and paste the token.
To survive reboots, install the systemd user service:
casper service installsystemd is optional. Without it, run casper from your own init system, under
nohup, or in tmux.
| Command | |
|---|---|
| casper | Run the server in the foreground |
| casper token | Print the access token |
| casper reset-token [value] | Set a new token and sign every device out |
| casper doctor | Check kiro-cli, settings, data directory, web app and MCP server |
| casper mcp | Run the widget MCP server on stdio (kiro spawns this for you) |
| casper service install | Run as a systemd user service |
| casper service uninstall | Remove the service, keeping settings and sessions |
| casper service status | Show the service status |
The casper agent gets the widget tools automatically. To give them to another
agent, point it at the same server:
kiro-cli mcp add --name casper --agent <agent> --command casper --args mcpTo update, npm install -g @joeyshi12/casper@latest. Re-run
casper service install afterwards if you use the service: the unit records
absolute node and package paths, and both move on upgrade. Your token and sessions
survive.
To remove it:
casper service uninstall
npm uninstall -g @joeyshi12/casper
rm -rf ~/.casper ~/.config/casper # only if you want sessions and settings gone tooConfiguration
Settings live in ~/.config/casper/config.json (or $XDG_CONFIG_HOME/casper/),
written 0600 because it holds the token:
{
"port": 4319,
"defaultCwd": "/home/you/projects",
"fileRoot": "/home/you",
"defaultAgent": "casper"
}A missing or malformed file is ignored with a warning rather than failing startup, and unrecognised keys are reported so a typo doesn't pass silently.
Every setting also works as an environment variable, and the environment wins,
which is handy for containers and one-off runs. Two are environment-only:
CASPER_DATA_DIR, because it says where data lives and so can't be read from
inside it, and CASPER_WEB_DIST, which is install layout rather than a preference.
| Variable | Config key | Default | |
|---|---|---|---|
| HOST | host | 0.0.0.0 | Bind address |
| PORT | port | 4319 | Server port |
| CASPER_TOKEN | token | (generated) | Entered once at login, exchanged for a per-device cookie |
| CASPER_SESSION_TTL_SECONDS | sessionTtlSeconds | 604800 | Device-login lifetime, slid forward on activity |
| KIRO_BIN | kiroBin | kiro-cli | Path to the kiro-cli binary |
| CASPER_KIRO_SESSIONS_DIR | kiroSessionsDir | ~/.kiro/sessions/cli | Where kiro-cli keeps its own session files, which Casper reads |
| DEFAULT_CWD | defaultCwd | cwd | Working directory for new sessions |
| DEFAULT_AGENT | defaultAgent | casper | Agent for new sessions, so widgets work out of the box. If it is missing, kiro falls back to kiro_default on its own |
| CASPER_FILE_ROOT | fileRoot | / | Confines the file browser. Defaults to everything the server can read; narrow it to keep authenticated users out of system files |
| MAX_LIVE_SESSIONS | maxLiveSessions | 6 | Concurrent live kiro processes |
| EVENT_BUFFER_SIZE | eventBufferSize | 5000 | Events kept per session for replay on reconnect; a client older than the buffer refetches instead |
| CASPER_MAX_UPLOAD_BYTES | maxUploadBytes | 104857600 | Largest single uploaded file |
| CASPER_DATA_DIR | (env only) | ~/.casper | Where casper.db and uploaded files live |
| CASPER_WEB_DIST | (env only) | beside the bundle | Built web app to serve |
Beyond your LAN, put a TLS-terminating reverse proxy in front of
http://127.0.0.1:4319, forwarding WebSocket upgrades with a long read timeout for
lengthy turns. PWA install and reliable reconnects need HTTPS.
Security
Casper launches kiro with --trust-all-tools so unattended runs never block on
approvals. The agent can run commands and write files without asking, so treat
access to Casper as equivalent to a shell on the machine.
The token is 24 random bytes, generated for you and exchanged at login for a
per-device cookie; only its hash is stored. Comparison is constant-time, and
/api/login allows ten failures per quarter hour per address before answering 429.
The settings file and the database are both 0600.
Develop
npm install
CASPER_TOKEN=dev npm run dev # server and web dev servers together
npm test
npm run e2e # prompt, disconnect mid-turn, reconnect, replayunset NODE_ENV first if you have it set: a stray production breaks installs and
builds here.
The repo is an npm workspace: shared/ for types, web/ for the React app, and
server/, which is the package published to npm. npm run build bundles the server
with esbuild and copies the built web app in beside it.
