Getting started
Installation
Get the binary, give it a model, serve it, keep it up to date, and run it as a service.
Shelley is a single executable for macOS and Linux, on amd64 or arm64. The web UI is embedded in it. Getting it running takes about three minutes, give or take a download: get the binary, give it a model, serve it.
Rather not install anything? Shelley comes running on exe.dev VMs: a machine of its own, already behind auth, no API keys required. Try it.
Get the binary
curl
This grabs the latest release for your OS and CPU:
os=$(uname -s | tr '[:upper:]' '[:lower:]')
arch=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
url=https://github.com/boldsoftware/shelley/releases/latest/download
curl -fLo shelley "$url/shelley_${os}_${arch}"
chmod +x shelley
Each release also has a checksums.txt. To check the download, in the same
shell (use sha256sum if you don’t have shasum):
curl -fsSL "$url/checksums.txt" | grep "shelley_${os}_${arch}$"
shasum -a 256 shelley
The two hashes should match. Then put it on your PATH; the agent runs
shelley itself to load skills and reach
MCP servers:
sudo mv shelley /usr/local/bin/
Prefer clicking? Binaries and checksums are on the releases page.
Homebrew
The cask works on macOS and Linux and puts shelley on your PATH:
brew install --cask boldsoftware/tap/shelley
From source
You need Go (the version in
go.mod), Node.js,
and Python 3. The Makefile fetches the pinned pnpm through npx and downloads a
pinned exe-scroll release from GitHub, so it needs network access too.
git clone https://github.com/boldsoftware/shelley.git
cd shelley
make
The binary lands in bin/shelley; copy it onto your PATH (for example,
sudo cp bin/shelley /usr/local/bin/). If you’re hacking on Shelley itself,
make serve builds the UI and runs Shelley from source.
Give it a model
Shelley picks up API keys from the environment. Set one or more:
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-... # also enables voice recordings
export GEMINI_API_KEY=...
export FIREWORKS_API_KEY=...
Check what it found with shelley models. Self-hosted and other compatible
endpoints can be added later from Manage… in the model picker. See
Models and API keys for the details.
No key yet? shelley --predictable-only serve runs against a built-in fake
model, so you can kick the tires for free.
Serve it
mkdir -p ~/.shelley
shelley --db ~/.shelley/shelley.db serve
Then open http://localhost:9000.
-
Pick a database path.
--dbdefaults toshelley.dbin the current directory, so starting Shelley from somewhere else gets you a fresh, empty database. Hence the fixed path above. -
Flag order matters. Global flags (
--db,--config,--default-model,--predictable-only,--debug) go beforeserve. Server flags (--port,-socket,-require-header) go after it. One dash or two, either works:shelley --db ~/.shelley/shelley.db serve --port 8080--port 0picks a free port; add--port-file <path>to have Shelley write down the one it got. -
Working directory. Your first conversation starts in the directory you launched Shelley from; after that, new ones default to the last directory you picked. You can change it per conversation.
-
The browser tool drives a local Chrome or Chromium if it can find one.
-
More flags.
shelley -handshelley serve -hlist the rest; see also Command line.
Mind the door. Shelley is single-user and ships with no authentication and no sandbox. It runs commands as you, and it listens on all network interfaces. On a laptop, keep it behind a firewall, or put it behind something that does auth (a VPN like Tailscale, an authenticating proxy). Better yet, give it a machine of its own. See Running it safely.
Upgrading
A new release is cut automatically on every push to main that passes tests.
Tags look like v0.N.9OCTAL, where N is the commit count and the digits after
the 9 are the short (six-hex-digit) commit SHA in octal. shelley version
prints what you’re running.
Shelley checks for new releases itself: the server fetches release metadata
from boldsoftware.github.io/shelley when the UI loads (cached for six hours).
If the latest release is five or more days newer than yours, a dot appears on
the ⋮ menu.
To upgrade, open the ⋮ menu and choose Check for New Version. The Version
dialog shows what changed and offers an upgrade button. Upgrading downloads the
release binary for your platform, checks it against the release’s
checksums.txt, and replaces the running executable in place. If you can’t
write to that file, Shelley tries passwordless sudo. Then the process exits:
- Under systemd, the button says Upgrade Shelley & Restart, and with a setup like the one below, systemd starts it again.
- Otherwise it says Upgrade & Kill Shelley Server, and you start it again yourself.
Either way, conversations that were in the middle of a turn carry on once the new version is up.
The same dialog has an Auto-upgrade when idle (checks daily) checkbox, off by default. With it on, Shelley checks a minute after starting and then daily, waits up to an hour for a moment when no conversation is working, upgrades, and exits. That’s only useful if something restarts it.
On exe.dev, shelley install <vmname> in the exe.dev shell also works; see
Shelley on exe.dev.
You can also upgrade by hand: download the new binary the same way you got the
first one (or brew upgrade --cask shelley), and restart. To turn update
checks off entirely, set SHELLEY_SKIP_VERSION_CHECK=true in Shelley’s
environment.
Running it as a service
Shelley doesn’t ship a service file, but serve supports systemd socket
activation with -systemd-activation: systemd owns the listening socket and
hands it to Shelley. That is also the only way to have Shelley listen on one
address, such as 127.0.0.1, rather than all of them. A minimal pair of units,
modeled on how exe.dev runs Shelley (replace you with your user):
# /etc/systemd/system/shelley.socket
[Unit]
Description=Shelley socket
[Socket]
ListenStream=127.0.0.1:9000
[Install]
WantedBy=sockets.target
# /etc/systemd/system/shelley.service
[Unit]
Description=Shelley
BindsTo=shelley.socket
After=shelley.socket
[Service]
Type=exec
User=you
WorkingDirectory=/home/you
EnvironmentFile=/home/you/.shelley/env
ExecStart=/usr/local/bin/shelley --db /home/you/.shelley/shelley.db serve -systemd-activation
Restart=on-failure
KillMode=process
[Install]
WantedBy=multi-user.target
Put your API keys in the EnvironmentFile, one NAME=value per line, and
chmod 600 it. Then:
sudo systemctl daemon-reload
sudo systemctl enable --now shelley.socket shelley.service
journalctl -u shelley -f
A few notes on those choices:
ListenStream=127.0.0.1:9000keeps Shelley on loopback. Reach it through an SSH tunnel or a proxy (Running it safely), or useListenStream=9000for all interfaces.WorkingDirectoryis where your first conversation starts.KillMode=processmeans restarting Shelley doesn’t kill the processes the agent started, like the dev server it just spun up.- Commands the agent runs inherit the service’s environment, including systemd’s
short default
PATH. Add anEnvironment=PATH=...line if your tools live elsewhere. - After an upgrade Shelley exits cleanly, so
Restart=on-failureleaves it stopped. The socket stays open, and the next request starts it again.
Where files live
| What | Where |
|---|---|
| Conversations, settings, custom models, MCP servers | The --db file, plus its -wal and -shm files |
| Terminal sessions | terminals/, next to the database |
| Unix socket for the CLI | ~/.config/shelley/shelley.sock (honors $XDG_CONFIG_HOME) |
| Hooks | ~/.config/shelley/hooks/ |
| Skills you create | ~/.config/shelley/<name>/SKILL.md |
| Your customized Shelley’s source | ~/.config/shelley/shelley-customization |
| Your AGENTS.md | ~/.config/shelley/AGENTS.md, among other places |
| History of AGENTS.md edits made in the UI | ~/.local/state/shelley/agents-md.git |
| Uploads, screenshots, recordings, browser downloads | /tmp/shelley-* |
| Terminal helper binary (macOS only) | ~/Library/Caches/shelley/ |
Uninstalling
Stop Shelley (and sudo systemctl disable --now shelley.socket shelley.service
if you set up the units), then remove the binary and its data. Look before you
delete ~/.config/shelley: your hooks, skills, AGENTS.md, and any
customizations to Shelley itself live there.
sudo rm /usr/local/bin/shelley # or: brew uninstall --cask shelley
rm -rf ~/.shelley # the --db directory used above
rm -rf ~/.config/shelley ~/.local/state/shelley
rm -rf /tmp/shelley-*
rm -rf ~/Library/Caches/shelley # macOS only