Krowk
A coding agent harness: one session, on any machine, model or agent.
Krowk is an agent harness built for power users who run coding agents all day. It runs Claude, GPT, Grok or any OpenAI-compatible model, using your existing subscription or an API key, or drives Claude Code and Codex. A session can move to another model or agent mid-conversation, and syncs to your other machines end-to-end encrypted. It follows Claude Code's permissions, skills and hooks, keeps track of every agent session on your machine, and publishes screenshots, diffs and logs as links that unfurl in GitHub, Slack, Linear and Basecamp. It assumes you're comfortable in a terminal, with git and with configuration files.
krowk connect # sign in with a Claude, ChatGPT or SuperGrok subscription, or an API key
krowk # open the agent
krowk -p "fix the build" # run one prompt headless (--output-format json)
krowk --resume # continue an earlier session
Install
curl -fsSL https://krowk.com/install | bash
npx @krowk/cli
cargo install --locked --git https://github.com/krowkcom/krowk --features harness krowk
Builds are published for Linux and macOS (amd64/arm64) and Windows (amd64). On a workstation the installer gives you the full build, which includes the agent. In CI and containers it gives you the lean build, which only publishes. Pass --full or --lean to choose (curl … | bash -s -- --full).
The agent
- A prompt that stays put. The agent takes the whole terminal, and the prompt and status line stay on the bottom rows while you scroll the conversation with the mouse wheel or PgUp/PgDn, and dragging over it copies. When you leave, your shell comes back as it was, with the
krowk --resume <id>line to open the session again. Choose Screen: inline in/settings(or set"tui": {"screen": "inline"}in~/.krowk/config.json) to draw at the bottom of the terminal instead, with everything in your normal scrollback as it streams, which suits SSH, tmux and phone terminals. - Tools. It can read, write, edit, run bash, grep, glob and publish. It also keeps a todo list, runs subagents in parallel, each with its own context and a cheaper model, and asks you with options to pick from when a choice is yours.
- Compatible with Claude Code. It uses the same permission modes,
allow/ask/denyrules and settings files. It readsAGENTS.md,CLAUDE.mdand.cursor/rules, and loads Claude-format skills, hooks and.claude/agentswithout changes. It adds anunhingedmode that never asks for permission. - Multiple accounts. You can connect several accounts per provider and rename them in
/connect. A second account is added with--name work. - Cost limits.
--max-usdand--max-tokensstop a session before it goes over a limit, subagents included.
In the prompt, / lists the commands and ? shows the keys.
Worktrees
Agents running at once can each work in a git worktree of their own, on a branch krowk/<hex>, so they don't overwrite each other's files.
- Subagents.
isolation: "worktree"on thesubagentcall, orisolation: worktreein an agent definition's frontmatter, runs the child in a new worktree started from your files as they are, uncommitted changes included. When it finishes, an unchanged worktree is removed; a changed one is applied back to your working tree (never your index or HEAD) and removed. A conflict, a submodule change or a change to.git,.claude,.codexor.krowkkeeps it, and the summary names it. - A session of its own.
krowk --worktree(orkrowk -p --worktree) starts the session in a new worktree. On exit an unchanged one is removed and a kept one is named. - By default.
"worktrees": { "default": true }, in your config or a trusted repository's.krowk/config.json, starts every new session in a repository that way, whatever model or agent runs it. A worktree it can't make stops the session rather than letting it run in your checkout;--worktree=falseruns one in place. As with--worktree, the session runs in krowk's own process rather than the background host, so it ends with the terminal, and/newcarries on in the same worktree. - No hand-made ones. Whatever the backend or mode, an agent's
git worktree add, or Claude Code'sEnterWorktreeandAgentwithisolation: "worktree", is refused and pointed to krowk's worktrees. So is an upload to a paste site (gh gist create,curl -Fto 0x0.st, transfer.sh and the like), pointed topublish. You can still run any of these at your own prompt. - Ready to build. Submodules are initialised from your checkout,
targetandnode_modulesare cloned in where the file system makes that nearly free (worktrees.seed), the ignored files your.worktreeincludelists (.env, local config) are copied, andworktrees.setupruns a command such asnpm ciin the sandbox. A repository's own setup command runs only once you trust it. On btrfs a worktree is a snapshot, made in tens of milliseconds whatever the repository's size. - The machine's limits. Build and test commands (
cargo,make,npm,pytest, …) from every krowk on the machine queue forbuilds.slotsslots, a quarter of the cores by default. Subagents and--worktreesessions sharesubagents.maxHostagent slots. A worktree is refused when its disk is short of 4 GiB beyond twice its expected size.
{ "worktrees": { "setup": "npm ci" }, "builds": { "slots": 4 }, "subagents": { "maxHost": 16 } }
scripts/bench-worktrees measures all of this on this repository: 20 worktrees made and checked at once, and three subagents applied back.
Sessions
The full build keeps a local store of your agent sessions, whether they came from krowk, Claude Code, Cursor or opencode.
Sync
Sessions sync between your machines end-to-end encrypted: neither krowk's servers nor its relay can read them. Run a session on one machine, then follow it and prompt it from another.
Once sync is set up, every session that runs a turn in the host daemon syncs by itself. Set "sync": {"auto": false} in ~/.krowk/config.json to turn that off, or keep one directory off sync with sync.exclude or a .krowk/no-sync file. A session nobody has used or watched for 10 minutes (sync.idleMinutes) stops syncing until its next prompt on this machine, or until another device, your phone included, opens it while the host daemon runs and has stayed online. krowk sync status says what applies where you are, and krowk host enable keeps sessions synced on an always-on machine.
Publishing
krowk push screenshot.png --pull-request="https://github.com/acme/storefront/pull/412"
✓ Uploaded screenshot.png → https://krowk.com/a/art_2e1d
412 KB · run run_8Kd2wq
Each link shows a card with the repo, commit, branch, PR, session and agent, all detected from git and CI. You can push without a key: anonymous uploads last 24 hours and can be claimed into a workspace with krowk claim.
Useful push flags include --private, --caption, --link, --metadata key=value, and --destination github|slack|linear|…, which prints the paste format that tool expects. Metadata is public, so never put a secret in it.
In CI, the repository doubles as a GitHub Action:
- uses: krowkcom/krowk@v0
id: krowk
with:
files: screenshots/**/*.png
token: ${{ secrets.KROWK_TOKEN }}
It outputs urls, markdown (ready to post as a PR comment), run-slug and json, and adds the links to the job summary.
Using krowk from other agents
skills/krowk/SKILL.mdteaches another agent how to use krowk. The installer adds it to~/.claude/skills.- In Claude Code,
/plugin marketplace add krowkcom/krowkand then/plugin install krowk@krowkadd the skill and the MCP server together. When krowk drives Claude Code itself, the plugin's server stays off and krowk's own tools are used. - Output is JSON when piped.
krowk help --jsondescribes every command, and--jqfilters the output without needing jq installed:URL=$(krowk push shot.png --jq '.data.artifacts[0].url'). krowk-mcpserves the same features over MCP stdio, for any other MCP client, or for Claude Code without the plugin:claude mcp add krowk -- krowk-mcp.- Exit codes:
0ok ·1bad command ·2not found ·3needs credentials ·4refused ·5rate limited ·6transfer failed ·7server error ·8gone.
Configuration
Everything krowk keeps is in ~/.krowk/ (move it with KROWK_HOME): settings in config.json, keys in credentials.json, and sessions in sessions/. A repository can commit .krowk/config.json to pin a workspace or add permission rules.
MCP servers
krowk's own agent uses the MCP servers you already set up for Claude Code: mcpServers in ~/.claude.json (user and per-project) and in Claude's settings.json, plus mcpServers in ~/.krowk/config.json. A repository's .mcp.json is used only after you trust the repository, and your own servers of the same name win over it. Each server takes Claude Code's shape, with ${VAR} and ${VAR:-default} expanded:
{
"mcpServers": {
"github": { "command": "github-mcp-server", "args": ["stdio"], "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" } },
"docs": { "type": "http", "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer ${DOCS_TOKEN}" } }
}
}
The model sees two tools, mcp_search and mcp_call, however many MCP tools there are, so they cost no context until one is used. No server starts until the first search. Permission rules name a tool as Mcp(server:tool) or mcp__server__tool, and Mcp(server) names all of a server's tools; a server denied whole is never started.
Development
make check # clippy, unit tests and golden tests
make dev # fast build, linked into ~/.cargo/bin
make mock # local registry; run any command with --dev
See CHANGELOG.md for what changed in each release, and crates/krowk-bench for the performance and size budgets.
Who uses Krowk?
License
MIT