Command line
Install Executor on your machine. Keep your apps, accounts and data local.
The local server runs Executor on one machine for one person. It holds your accounts, runs your apps, and serves an MCP endpoint for your agents.
Install and start
With npm, on Node 14.18.0 or newer. Executor carries its own runtime, so Node only starts it. Check that executor --version prints 2.0.0-beta.26 before starting. Supports macOS on Apple Silicon and Intel, Linux (glibc) on ARM64 and x64, and Windows on x64.
npm i -g executor@beta --include=optional
executor --version
executorWithout Node, on macOS or Linux: the script checks the download against the release's SHA256SUMS and links ~/.local/bin/executor.
curl -fsSL https://executor.sh/docs/install.sh | sh
executor --version
executorWithout Node, on Windows, in PowerShell:
irm https://executor.sh/docs/install.ps1 | iexWith Homebrew, on macOS or Linux:
brew install usefulsoftwareco/tap/executor-betaexecutor starts Executor in the background, opens the dashboard in your
browser and exits. Executor keeps running until you stop it; see
The background Executor. Executor is one executable
with its runtime, dashboard, Git and workerd beside it; no source checkout, Node
or Bun is needed to run it.
The npm package is a small launcher: npm installs the executable for your
platform as an optional dependency. If executor reports that its native
runtime is missing, npm skipped optional dependencies; install again with
--include=optional.
The install script keeps each release in ~/.executor/v2/runtime/versions/,
points ~/.executor/v2/runtime/current at the one in use and links
~/.local/bin/executor to it. It never edits your shell profile: if
~/.local/bin is not on your PATH, it prints the line to add. On Windows the
script adds %USERPROFILE%\.executor\v2\runtime\current to your user PATH.
Pass a version to install that release, for example
curl -fsSL https://executor.sh/docs/install.sh | sh -s -- 2.0.0-beta.16.
If executor --version still shows v1, your shell is finding an older install.
Run type -a executor on macOS or Linux, or where.exe executor on Windows,
to see which executable takes priority. Remove the old install with the package
manager that installed it, then open a new terminal. For example, use
bun remove -g executor for an old Bun install. This does not delete your data.
On first launch, Executor saves its API and encryption keys in macOS Keychain,
Windows Credential Manager, or Linux Secret Service. Unlock the credential store
and allow Executor access when asked. If there is no credential store on the
first launch, for example on a Linux server without GNOME Keyring, Executor saves
the keys to keys.json in its data directory instead. The file is readable only
by your user. Keep that directory private. If a credential store exists but
access is denied, for example because you dismissed the prompt or the store is
locked, Executor stops without writing keys.json. Start it again to be asked
again. Where no prompt can appear, such as over SSH, unlock the store first: on
Linux run gnome-keyring-daemon --unlock, on macOS security unlock-keychain.
To use keys.json on a new data directory even when a credential store works,
set EXECUTOR_KEY_STORAGE=file for its first start. Set
EXECUTOR_KEY_STORAGE=os to require the credential store and never fall back to
keys.json. Executor never switches an existing directory’s key storage: a
value that does not match the directory stops startup and changes nothing.
| Command | Purpose |
|---|---|
executor |
Start the background Executor if it is not running, open the dashboard and exit. |
executor service |
Start, stop and configure the background Executor. |
executor serve |
Run Executor in this terminal, without opening a browser, until you press Ctrl+C. |
executor pair |
Print a new connection link for the background Executor. |
executor apps |
Create, edit, deploy and install apps. See Author an app. |
executor upgrade |
Install the newest release the way Executor was installed; --rollback returns to the previous one. |
executor rotate-key |
Replace the saved API key. Run executor service restart, then update clients that used the old key. |
executor pair asks the background Executor for a link, waiting up to 30
seconds while it starts. It only reads: it never starts Executor or creates a
data directory or keys. When you set EXECUTOR_API_KEY, it sends that key
instead, to the background Executor or, when none runs, to the server on
EXECUTOR_PORT.
Coming from Executor 1
Executor 2 answers the old commands with the command to run instead.
| Executor 1 | Executor 2 |
|---|---|
executor web |
executor starts the background Executor if needed and opens the dashboard. |
executor open |
executor pair prints a connection link for the background Executor. |
executor daemon run |
executor service start starts the background Executor without opening a browser. It runs until executor service stop. |
executor install |
Nothing to install. executor or executor service start starts the background Executor, which runs until you stop it; it does not start with your computer. |
executor mcp |
The background Executor serves MCP over HTTP at http://127.0.0.1:4312/mcp; see Connect an agent. |
executor call, executor tools, executor resume |
Agents call tools through the MCP endpoint. |
executor server |
No server profiles. executor apps commands take --host, and executor rotate-key replaces executor server rotate-token. |
executor login |
executor apps login --host https://api.executor.sh signs in to hosted Executor for app commands. |
executor docs |
Open executor.sh/docs. |
The background Executor
Each data directory has one background Executor that every command shares. The
first command that needs it starts it: executor, executor service start or
an executor apps command. It keeps running after that command exits, until you
run executor service stop. Nothing is installed with your operating system, so
it does not start again after you restart your computer: MCP clients cannot
connect until you run executor or executor service start.
The desktop app uses the same background Executor. When you stop it, with
executor service stop or by changing a setting, the desktop app says it was
stopped and does not start it again. It reconnects once a command starts it, or
when you click Start there.
When the background Executor runs another version, for example after
brew upgrade or an install with your package manager, executor stops it and
starts its own version. Other commands use whichever version is running.
| Command | Purpose |
|---|---|
executor service start |
Start the background Executor, or confirm that it runs, and print its URL. |
executor service stop |
Stop it. |
executor service restart |
Stop it and start this version. |
executor service status |
Print its URL, version and process ID, with starting before them while it starts, or stopped. |
executor service get [setting] |
Print every setting as JSON, or one setting. |
executor service set <setting> <value> |
Change a setting. |
executor service unset <setting> |
Remove a setting. |
| Setting | Purpose |
|---|---|
port |
The port it listens on. EXECUTOR_PORT wins over it; the default is 4312. Each data directory’s background Executor needs its own port. |
env |
Extra environment variables for it: executor service set env <name> <value>, executor service unset env <name>. |
disabled |
true makes executor, and executor apps commands without --host or EXECUTOR_HOST, run a private server for the command instead, as --standalone does. executor service start, executor pair and the desktop app still use the background Executor. |
Changing port or env, or setting disabled to true, stops the background
Executor; the next command that needs it starts it with the new settings. It
runs with the environment of the command that started it plus env, so use
env for variables it should always have, such as EXECUTOR_BROWSER_ORIGIN.
EXECUTOR_API_KEY and EXECUTOR_ENCRYPTION_KEY reach it only when both are
set, as for supplied keys; EXECUTOR_API_KEY alone is only the key the command
itself sends.
The data directory holds the settings in service.json. While Executor runs,
server.json records its address, process ID and a password that changes each
time it starts, and .server.lock stops a second server from opening the same
data directory. service.json and server.json are readable only by your user.
executor --standalone runs a private server on a free port for that command
instead, until you press Ctrl+C. It uses the same data directory, so stop the
background Executor first or set EXECUTOR_DATA_DIR to another folder.
executor --server <url> opens the dashboard of an Executor server that already
runs at that URL, using EXECUTOR_API_KEY or the API key saved in the data
directory. executor serve runs Executor in your terminal instead of the
background, so stop the background Executor first; while it runs, other commands
use it as they would the background Executor.
Configure it
| Variable | Purpose |
|---|---|
EXECUTOR_PORT |
Port. Wins over the port setting; the default is 4312. |
EXECUTOR_NO_UPDATE_CHECK |
Set to 1 to skip the daily check for a newer release. |
EXECUTOR_DATA_DIR |
Data directory, default ~/.executor/v2/cli. |
EXECUTOR_BROWSER_ORIGIN |
Exact HTTPS origin for generated browser links. |
EXECUTOR_WEBHOOK_ORIGIN |
Exact HTTPS origin that receives webhooks. |
EXECUTOR_KEY_STORAGE |
file or os: key storage for a new data directory. |
DO_NOT_TRACK or EXECUTOR_DISABLE_ANALYTICS |
Set to 1 to turn off anonymous usage analytics and feedback. |
To keep keys in a secret manager instead, supply both EXECUTOR_API_KEY (at
least 32 characters) and EXECUTOR_ENCRYPTION_KEY (exactly 64 hexadecimal
characters) before the first start. Keep these same keys for every start.
Executor does not save supplied keys. A directory keeps its chosen key source
across upgrades: a directory using the credential store still needs it later,
and a directory using keys.json needs that file.
Connect an agent
Use the dashboard’s Connect card to add the local MCP endpoint to your
agent. See Add an MCP client for Claude Code, Cursor and Codex.
The client connects to the background Executor. After you restart your
computer, run executor or executor service start first; until then the
client’s connection is refused. If you change the port, update the client’s URL.
Back up and update
Back up the data directory, including installation.json, and its matching
OS credential. The credential service is com.usefulsoftware.executor.v2;
its account ID is in installation.json. Copying only the database to another
machine is not enough to restore it. If you supplied keys, back them up in
your secret manager.
Missing keys stop startup. Executor will not generate replacements for an existing installation. Restore the original keys to recover access.
executor and executor serve check npm at most once a day for a newer
release on their channel and print a reminder to run executor upgrade. Beta
installs are told about stable once it is newer. The check never installs
anything and is skipped in CI. The v2 data directory stays the same when beta
becomes stable. Uninstalling the package does not delete data or keys.
executor upgrade installs the newest release on your channel the way
Executor was installed, which it tells from where Executor’s files live. For an
install from the install script, it downloads the release, checks it against
the release’s SHA256SUMS, confirms the new version starts, and then switches
current to it. The version it replaced stays installed, and
executor upgrade --rollback switches back to it. For npm, pnpm, Bun or Yarn,
it runs that package manager; --method npm|pnpm|bun|yarn chooses one instead.
It first checks that your Node.js meets the new launcher’s requirement, and
afterwards runs executor --version to confirm the new command works. A
Homebrew install is upgraded with brew upgrade.
executor upgrade # newest release on your channel
executor upgrade 2.0.0-beta.16 # a specific release
executor upgrade --rollback # back to the previous release (install script)
executor upgrade --method pnpm # install with pnpm
On a terminal it asks before installing; --yes skips the question. Without a
terminal, as for agents and CI, it installs without asking. Installing an older
release needs the version and confirmation, or --yes without a terminal. If
you run Executor through npx, bunx or pnpm dlx, there is nothing to
upgrade: run npx executor@beta to get the newest release. When Executor cannot
tell which package manager installed it, it prints the install command for each
one instead of guessing.
The upgrade replaces the files the background Executor runs from, so
executor upgrade and executor upgrade --rollback stop it first and start it
again on the new version afterwards. If the upgrade fails or you cancel it, the
old version starts again. If the new version does not start, the upgrade still
succeeds and tells you to run executor service start. A background Executor
from a development build keeps running. Executor never updates itself without
being asked.
The desktop app shares the background Executor with the command line. It
checks for updates in the background and asks before restarting to install one.
Beta installs follow beta releases and move to stable when it is newer. On
Linux, only the AppImage updates itself; install a newer .deb over the
existing package.