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.16 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 the server and opens the dashboard in your browser. 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, and Executor prints its path when it creates it. 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 server and open the dashboard. |
executor serve |
Start without opening a browser. |
executor pair |
Print a new connection link for the running server. |
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. Restart Executor, then update clients that used the old key. |
executor pair asks the server on EXECUTOR_PORT for a link, using the API key
saved in EXECUTOR_DATA_DIR, or EXECUTOR_API_KEY when you set it. Run it with
the same values as the server. It only reads the key: it never creates a data
directory or keys. If it reports that the server did not accept the key, the
server uses another data directory, or its key was rotated and it has not
restarted yet. Executor desktop keeps its own data directory; use its
File > Open in browser menu item instead.
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 server and opens the dashboard. If the server is already running, executor pair prints a link to open instead. |
executor open |
executor pair prints a connection link for the running server. |
executor daemon run |
executor serve starts the server without opening a browser. |
executor install, executor service install |
No background service yet. Keep executor serve running while your agents use Executor. |
executor mcp |
The running server 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. |
Configure it
| Variable | Purpose |
|---|---|
EXECUTOR_PORT |
Port, default 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. Keep Executor running while the client is connected.
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. A running executor or executor serve keeps using
the old version until you restart it; executor upgrade says when one is
running. Executor never updates itself without being asked.
The desktop app uses the same local server with a separate
profile. 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.