husk
Connects the server to Discord as a bot, letting users run commands, inspect tasks, and receive results through server or direct message chats.
Lets the server provision and manage disposable Linux machines using Docker containers, providing the agent with a shell, filesystem, network, and ports within an isolated container.
Allows the server to use Google AI models (e.g., Gemini via Google AI Studio) as the agent's model backend for reasoning and planning.
Allows the server to use local Ollama models (e.g., Gemma, Llama, Qwen) as the reasoning backend, enabling free, private, and local operation without an API key.
Allows the server to use OpenAI models for agent reasoning and task planning, expanding the model flexibility beyond local options.
Lets the server provision and manage disposable Linux machines using Podman containers, offering a rootless and daemonless alternative to Docker for isolated agent environments.
Enables the server to run as a Slack bot, allowing users to interact with the disposable computer and task execution directly in Slack channels and DMs.
Enables the server to operate as a Telegram bot, allowing users to send commands and view task outputs within Telegram chats.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@huskspin up a disposable Linux box and show me the OS details"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Husk gives your AI chat named local workspaces. Save public web sources, ask your AI for a cited brief, comparison, or action list, then review and download the result. Reopen the same workspace in your next chat. No Husk account, Docker, terminal, or additional model API key is needed for this starter flow.
For coding and automation, Husk also provides optional computer tools: a shell, files, and a browser. Existing MCP and CLI computer workflows remain available.
0.2.0 public preview. Download the unsigned desktop extension from the GitHub prerelease. It has passed automated checks; installation and first-task completion inside Claude Desktop still need beta testing. See the one-day delivery and launch checklist.
Start with a workspace
Download husk-0.2.0.mcpb from the public preview.
Install it in Claude Desktop through Settings → Extensions
→ Advanced settings → Install Extension. Claude Desktop supplies Node.js. This
candidate is unsigned; organization policies may restrict custom extensions.
Ask Claude: “Create a Husk workspace called My first brief and open its viewer.” Add public page URLs, choose a starter prompt, paste it back into Claude, then return to review and download the saved result. Keep Claude running while the viewer is open.
The workspace guide explains the full flow, privacy, recovery, and limits. To build the installer as a contributor:
npm ci
npm run build
npm run bundle:mcpb
npm run smoke:starter -- --bundleThe artifact and checksum are written to build/. The smoke test extracts that
archive and checks restart persistence, access control, assets, downloads, and ZIP export.
Open interactively — pan, zoom, trace relationships · SVG · all 16 diagrams
Related MCP server: linux-harness-mcp
Computer tools for developers
npx @husk-ai/cli setupsetup asks where your chats' computers should run (Docker, Podman, this machine, SSH or
Fly, with the reason any of them is unavailable and its fix), adds Husk to the chat apps
it finds (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Codex, Gemini CLI),
and starts the one Husk every chat goes through, printing its console link. It backs up
each app's config file before changing it and touches only its own husk entry.
--remove takes it out again. The console's Connect page does the same.
setup, the shared Husk and the console's Connect page are on main and not yet
published: npm has 0.1.4. Until the next release, run it from a checkout with
npm ci && npm run build && node packages/cli/dist/bin.js setup.
Once the next release is on npm, you can let the chat do it. Paste this into Claude Code,
Codex, Gemini CLI, Cursor or any chat that can run a command (the Connect page makes one
for a single app). Until then the npx line in it fails, because npm's 0.1.4 has no
setup: use the checkout command above instead.
Set up Husk for me, so you get a computer of your own for tasks: a terminal and a real browser, kept apart from my files.
1. Run this in a terminal:
npx -y @husk-ai/cli@latest setup --computer auto --apps all --yes
It picks the safest computer this machine can run (a Docker container if Docker is installed) and adds Husk to my chat apps. If you can't run terminal commands, show me that line and I'll run it.
2. Tell me to restart my chat apps so the Husk tools load.
3. Tell me that if the Husk desktop app is installed, it shows your computer in a small window and I can take over any time.
After the restart: call computer_info, open https://example.com in the browser, and tell me what you see.A desktop app (apps/desktop) carries the same Husk with its own Node and keeps each
chat's computer one click away: a very small 3D computer for each in the bottom-right
corner, which names its chat app when you hover it. Click one and a compact Computers
window opens, its tabs your computers (each with its chat app's logo), the browser
live on a white screen, Take over a click away. Minimize it and it goes to a notch at
the top of the screen (around the real notch on a Mac). It sits in the tray to tell you
when a chat is waiting for you. Its installers build and pass a smoke test in CI but are
not released or signed yet; see apps/desktop.
To add Husk to one app by hand instead:
claude mcp add husk -- npx -y @husk-ai/mcpThat is the whole setup. Nothing is created until the first tool call, so an installed husk that nobody uses costs nothing. Works with Cursor, Zed, or anything else that speaks MCP.
In Claude Code you can install it as a plugin instead, which adds a husk skill that
teaches the model when to use which tool and when to hand the computer to you:
/plugin install husk --marketplace Hotragn/huskThe default computer profile exposes eight workspace tools plus 26 computer tools.
Eight are for the machine — shell, read_file, write_file,
edit_file, list_dir, expose_port, browse, computer_info — fifteen
browser_* tools that drive a real Chromium inside that same machine, addressed by
accessibility ref rather than pixel coordinates, hand_off / hand_off_done,
which give you the computer for a login, a 2FA code or a CAPTCHA and give it back
only when you say you're done, and computer_open_ui, which gives the chat a link
to show you the computer. Apps that render MCP Apps cards also get the card's two
tools.
The first tool result says what kind of machine it got. A model that thinks it is sandboxed when it is not makes worse decisions than one that knows.
Every chat on the machine goes through one shared Husk, started on the first tool call,
so husk serve's console shows each chat's computer, its live browser and what it did
last, and takes over a handoff from any of them. HUSK_DAEMON=off keeps a chat's tools
in its own process.
The CLI
npx @husk-ai/cli onboard # guided setup, five steps, start here
npx @husk-ai/cli doctor # or go straight to what this machine can offer
npx @husk-ai/cli up dev --flavor python # bring up a Linux computer
npx @husk-ai/cli exec dev -- 'uname -sr && python3 -V'
npx @husk-ai/cli rm dev # tear it downonboard names your provider and how isolated it really is, creates a computer and
destroys it in front of you, points at the shortest route to a model if you have none,
and prints the MCP line for your editor. It never asks for an API key — husk reads
credentials from the environment and does not store them, so it prints the export line
and re-checks.
On Windows cmd.exe, use double quotes -- it does not strip single ones, so the
quotes would reach the container as part of the command:
npx @husk-ai/cli exec dev -- "uname -sr && python3 -V"--flavor python is there because the default base flavour is
debian:bookworm-slim, which has no python3 -- and a quickstart whose third line
prints python3: not found is not a quickstart. On a laptop with Docker running, that
sequence prints Linux 6.18.33.2-microsoft-standard-WSL2 and Python 3.12.14; with
Docker stopped and WSL2 installed it picks local and prints the same kernel with the
distro's own Python 3.14.4. doctor reports every provider it probed, which one it
would pick, and why the others were skipped.
Turn a chat into a bot
A conversation that worked once becomes a file you can run again.
husk import # lists transcripts it found
husk import --pick 1 # imports one, prints its id
husk distill <id> --out triage.yaml # conversation → agent spec
husk run triage.yaml "check the build"Importers read Claude Code JSONL, ChatGPT, Cursor, Gemini and markdown into one
Transcript. Branched threads are rebuilt by walking parentUuid back from the last
leaf. The distiller runs with no API key at all, and the model-backed mode falls back to
that free path rather than failing. Secrets are stripped before the file is written,
not after.
What comes out is YAML you can read and diff:
name: triage
model: sonnet
persona: |
You triage CI failures for a TypeScript monorepo.
Always read the failing job log before guessing.
tools: [computer, files]
computer:
flavor: node
network: { mode: egress, allow: ['*.github.com'] }
limits: { maxSteps: 24, maxCostUsd: 0.25 }husk distill prints its confidence and everything it could not work out, so a thin
transcript announces itself instead of producing a plausible-looking persona nobody
checks. Five worked examples live in examples/.
What is in it
A machine, not an interpreter. Files, a shell, ports, a browser.
/worksurvives the whole session, andpersistkeeps it past that.Five computer providers.
docker,podman,ssh,fly,local. One interface;autotakes the highest available.Eleven model providers. Ollama, Anthropic, OpenAI, Google, Groq, DeepSeek, Cerebras, OpenRouter, Mistral, Together, LM Studio. Aliases resolve across all of them, so one
husk.yamlruns on Opus or on a local Gemma.Four adapters. Discord, Slack, Telegram, webhook.
No product telemetry. The installed runtime has no analytics, crash reporter, or version ping. The marketing and documentation websites use Vercel Web Analytics.
No native modules.
npm installfinishes on Windows with no C++ toolchain. Node 20.10 or newer.Automated regression tests and archive smoke checks.
npm testchecks the packages; integration cases that need an unavailable provider are explicitly skipped.
How it works
Thirteen packages and five apps. Dependencies run downhill: core imports nothing from
the workspace, every other package except console-assets (the built console, no code)
imports it, and nothing imports @husk-ai/cli.
packages/
core contracts, husk.yaml schema, primitives
runtime computer providers: docker, podman, local, ssh, fly
models one surface over eleven model providers
sessions transcript importers + the distiller
browser Chromium lifecycle and CDP automation
agent tool-calling loop and built-in tools
adapters Discord, Slack, Telegram, webhook
mcp MCP server (stdio), and the shared Husk every chat forwards to
server control-plane API + bot host
sdk typed client for the control plane
workspaces named local workspaces: sources, results, export
console-assets the built console, served by server
cli the husk command
apps/
console dashboard: live terminal, files, browser
desktop the desktop app: corner, Computers window, notch, tray
mac Husk Bar, a macOS menu-bar companion
docs documentation site (Next.js + MDX)
web marketing site (Next.js + Three.js)server reaches @husk-ai/agent through a dynamic import and never declares it as a
dependency, so the control plane starts on a tree where the agent was never built.
Four flavours choose the image: base, python, node, full. Husk publishes none of
its own. base is debian:bookworm-slim, python is python:3.12-slim, node is
node:22-slim, and full is Playwright's image, which already carries the twenty-odd
shared libraries Chromium links against. An image you publish is an operating system you
have promised to keep patched, and Debian and the Playwright team already do that better.
Set HUSK_REGISTRY to point the lot at your own mirror.
Providers
auto walks the ladder and takes the highest rung that answers. Every rung is free
except fly, which is metered. An explicit --provider that turns out to be
unavailable is an error, never a quiet downgrade to weaker isolation.
Provider | Priority | Isolation | Cost | Notes |
| 20 | Kernel namespaces, cgroups, seccomp, read-only root | Free | Default when the daemon is up |
| 18 | Kernel, rootless | Free | Linux without Docker |
| 16 | Whatever the remote gives you | Free if you own the box | An Oracle Always Free instance, a Pi, a VPS |
| 14 | microVM | Metered | Bursty parallel work |
| 10 | Guardrails only | Free | WSL2 gives real Linux; POSIX runs your own shell with guardrails |
The
localprovider is not a sandbox. It stops accidents, not adversaries.husk doctorreportsisolated: falsefor it, and the first MCP tool result says so again.
Security model
These hold in every mode, local included, and were re-checked against a live local
and a live docker computer for 0.1.4: the command deny list, the environment scrub,
output caps, process-tree kill, redact() on every result and audited() on every MCP
call.
The path jail is not one of them, and this paragraph used to say it was
(#120). It is a local control, and there
it confines the file tools rather than the shell. On docker, podman and fly the
container is the boundary, so the file tools address the container's own filesystem:
read_file /etc/passwd returns the container's copy, and /dev/shm takes a write.
Neither reaches your machine, which is the point of running those providers — a jail
inside a kernel boundary is largely redundant. Claiming one anyway is exactly what this
section exists not to do.
What local does not give you is a kernel boundary. It shares your kernel, your network
and your user account.
169.254.169.254 stays blocked even under network.mode: full, because full means
the internet and not the cloud metadata service that hands IAM credentials to whatever
asks. Loopback and the RFC1918 ranges are the same problem one hop out. An operator who
wants one of them names it in allow, where a reviewer reading the husk.yaml can see
the decision.
Address spellings are normalised first. 127.1, 2130706433 and 0x7f000001 are all
127.0.0.1 to curl, to Chromium and to Python's urllib, so a rule that only understands
four dotted octets is not a rule.
Documentation
Architecture — why it is shaped this way
API reference — the control-plane HTTP contract
Build contract — conventions every package obeys
Security model — what is isolated and what is not
Examples — five
husk.yamlrecipes and an MCP session demoDiagrams — 16 interactive architecture, dataflow and design diagrams
Status
Alpha, pre-1.0. The husk.yaml schema and the HTTP contract can still change between
releases. What is known not to work today:
On container providers the rendered browser needs the
fullflavor. CI drives the fifteenbrowser_*tools on Docker withfull(Playwright's image, which carries Chromium's libraries). The slim flavors cannot run Chromium: their root filesystem is read-only, so the libraries cannot be added later.base(debian:bookworm-slim) has neither curl nor python3, so evenbrowsefails there. Pass--flavor full, or choose "Include a browser" inhusk setupor on the Connect page.flyis the least exercised provider. It has tests. It has far fewer real hours thandockerandlocal.
Development
git clone https://github.com/Hotragn/husk.git && cd husk
npm install
npm run build
npm testContributing
Contributions are welcome. CONTRIBUTING.md covers the build contract, the test requirements, and how to add a provider or a model.
Contributors
Everyone who has shipped something here is on the contributors graph, which counts commits rather than asking anyone to remember to add a name.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent Linux computers for AI agents: desktop, signed-in browser, vault, apps and shell.
Linux VMs for AI agents: create VMs, run commands, edit files and open preview URLs.
Cloud desktops for AI agents: create a Linux computer, see its screen, click, type and run tasks.
214 tools for AI agents over one MCP endpoint: image, video, audio, 3D, data, storage, mail, GPUs.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to remotely read/write files and execute commands on Linux servers via MCP protocol.4 npm1MIT
- AlicenseNot gradedqualityDmaintenanceExposes a Linux host with shell, Python, and filesystem tools as MCP tools over HTTPS, enabling AI agents to execute commands and manage files remotely.7 npmMIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to operate a persistent Linux sandbox in the cloud, running commands, managing files, using Git, and publishing artifacts through a Streamable HTTP MCP endpoint.-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to operate a real, private, local Docker-based computer with durable files, terminal access, web research, and a persistent browser or desktop. It supports multiple agent clients via MCP or OpenAPI, with live viewing and human takeover.13Apache 2.0