Self-host Executor, the open-source MCP gateway
Add your tools once; every agent reaches them through one private MCP URL.
Shelley handles the setup. About 10 minutes.
Prefer a terminal?
curl -fsSL https://exe-staging.dev/deploy/executor/prompt.txt | ssh exe.dev new --prompt=/dev/stdinExecutor is an open-source gateway between your agents and your tools. You add MCP servers, OpenAPI and GraphQL APIs, and accounts such as Gmail or GitHub to it once; it keeps their credentials and asks before risky calls. Every agent then connects to one MCP endpoint and finds the tool it needs by searching, instead of loading hundreds of tool definitions into its context. Executor 2, in beta, goes further: an agent can write new tools for you, with storage, schedules and webhooks, and they keep running on the server.
A VM makes a good home for it: always on, with HTTPS and a disk for the catalog and credentials. exe.dev's proxy keeps it private, which matters more than usual here. Executor 2 has no admin password to preset: the first person to finish its setup page owns the server. Behind your exe.dev login, that can only be you.
What you get#
- Executor 2 at
https://my-executor.exe.xyz, in Docker, restarted on failure and after a reboot. - Its database, generated keys and your apps' code in
~/executor/data. - An owner account that only you can create, because the setup page is behind your exe.dev login.
- One MCP endpoint,
/mcp, that Claude Code, Codex, Shelley and other agents share. - A backup and update procedure for the data directory.
What's running, and where
https://my-executor.exe.xyz/
the dashboard, behind your exe.dev login and your Executor account
https://my-executor.exe.xyz/mcp
the MCP endpoint; agents send an exe.dev VM token and an Executor token
Deploy with Shelley#
Click Deploy and Shelley will set up Executor on a new VM, then check that it works. No config-file wrangling required.
Prefer a terminal?
curl -fsSL \
https://exe-staging.dev/deploy/executor/prompt.txt \
| ssh exe.dev new --prompt=/dev/stdinWhen it's done, run this on your computer (only you can):
ssh exe.dev ssh-key generate-api-key --vm=my-executor --label=executor-agents --exp=90dWhat Shelley is told
Set up Executor on this VM by following the exe.dev recipe at https://exe-staging.dev/deploy/executor.md from top to bottom.
The recipe's example VM name is my-executor. This VM's name is the output of `hostname`: use it wherever the recipe writes my-executor. Skip the step that creates the VM; you are on it.
You are done when all of these are true. Check each one yourself:
- Executor 2 at `https://my-executor.exe.xyz`, in Docker, restarted on failure and after a reboot.
- Its database, generated keys and your apps' code in `~/executor/data`.
- An owner account that only you can create, because the setup page is behind your exe.dev login.
- One MCP endpoint, `/mcp`, that Claude Code, Codex, Shelley and other agents share.
- A backup and update procedure for the data directory.
Read the whole recipe, closed details included, and follow "Set up by
hand" in order, skipping VM creation; the walkthrough above it is for
the owner. Use the pinned image tag as written. Never make the VM public:
the first person to finish Executor's setup page becomes its owner, and
that must be the owner. Don't set EXECUTOR_APPS_ALLOW_PRIVATE_FETCH unless
the owner asks. On an existing VM, ask before replacing anything on port
8000. The VM can't reach its own https://<vm>.exe.xyz, so checks use
localhost. Finish by sending the owner to https://<vm>.exe.xyz/ to create
their account, then to "Add your tools" and "Connect your agents", with the
`ssh-key generate-api-key` command to run on their computer.
Finish with the URLs I should open and these commands, which only I can run, from my own computer (with this VM's name in them):
ssh exe.dev ssh-key generate-api-key --vm=my-executor --label=executor-agents --exp=90d
Also at /deploy/executor/prompt.txt. The recipe it follows is /deploy/executor.md.
Add your tools#
Open https://my-executor.exe.xyz/ and create your account: an
organization name, your name, an email and a password. Skip Connect your
accounts for now.
On Apps, choose Add app:
- From an MCP server takes a remote MCP server's URL. Try
https://mcp.deepwiki.com/mcp: Executor finds its three tools and makes an app of them. Servers that need a sign-in use OAuth, from the app's Accounts tab. - Browse app catalog lists ready-made apps such as Gmail, GitHub, Linear
and Stripe. Some need an OAuth client of your own; give the provider
https://my-executor.exe.xyz/api/oauth/callbackas its redirect URL. - From scratch gives you a prompt for your agent, which then writes the app: for an OpenAPI or GraphQL API, a service with an API key, or a tool of your own.
Each app is TypeScript code you can read on its Source tab. Apps made from an MCP server ask for your approval before any tool the server marks as destructive; edit that rule there.
Connect your agents#
Each agent sends two headers:
X-Exedev-Authorization: Bearer exe1.…, a VM token that gets it through exe.dev's proxy, which removes it before Executor sees the request.Authorization: Bearer exp_…, an Executor personal access token.
Make the VM token on your computer (--exp sets when it expires):
ssh exe.dev ssh-key generate-api-key --vm=my-executor --label=executor-agents --exp=90d
For the Executor token, open your avatar menu → Account settings →
Tokens → Create token, name it after the agent, and limit it to
your organization. It's shown once. Below, replace exe1.paste-yours-here
and exp_paste-yours-here with yours.
Claude Code, on your computer or a VM like the one in Claude Code on exe.dev:
claude mcp add --transport http --scope user executor https://my-executor.exe.xyz/mcp \
--header "X-Exedev-Authorization: Bearer exe1.paste-yours-here" \
--header "Authorization: Bearer exp_paste-yours-here"
claude mcp list
Expect executor: https://my-executor.exe.xyz/mcp (HTTP) - ✔ Connected.
Codex, on your computer or a Codex VM, in
~/.codex/config.toml:
[mcp_servers.executor]
url = "https://my-executor.exe.xyz/mcp"
http_headers = { "X-Exedev-Authorization" = "Bearer exe1.paste-yours-here", "Authorization" = "Bearer exp_paste-yours-here" }
Shelley, on any of your VMs:
shelley mcp add executor -d "Executor: my apps and tools" \
-H "X-Exedev-Authorization: Bearer exe1.paste-yours-here" \
-H "Authorization: Bearer exp_paste-yours-here" \
https://my-executor.exe.xyz/mcp
shelley mcp call executor.search query=deepwiki
Other clients: any MCP client that speaks Streamable HTTP and can send
headers works the same way. An agent on the Executor VM itself can skip the
VM token and use http://localhost:8000/mcp.
Tip
For agents on your other exe.dev VMs, a VM-to-VM integration can add both headers at exe.dev's edge, so no token is stored on the agent's VM. On your computer, for an agent on
my-hermes-agent:ssh exe.dev integrations add http-proxy --name executor-hermes --target https://my-executor.exe.xyz/ --peer --bearer exp_paste-yours-here --attach vm:my-hermes-agent. The agent's URL is thenhttps://executor-hermes.int.exe.xyz/mcp, with no headers.
Try it#
Ask your agent:
Use executor to find out how the UsefulSoftwareCo/executor repository is structured.
It searches Executor's catalog, finds the DeepWiki tools, and calls one.
The six tools an agent sees are always the same (search, describe,
call, execute, resume, skills); the apps behind them are what you
add. To have an agent add one:
Use executor to add an app for the Linear API.
When a call needs your approval, the agent shows you the request and passes on your answer.
Keys off the VM#
API keys you give Executor stay in its encrypted database, not in your
agents. To keep some off the VM entirely, use an exe.dev
integration: exe.dev holds the secret and adds it at
its edge when the VM calls https://<name>.int.exe.xyz. Executor's app
sandbox refuses private addresses, which these are, until you allow them in
~/executor/compose.yaml, under environment:
EXECUTOR_APPS_ALLOW_PRIVATE_FETCH: "true"
Then run docker compose up -d in ~/executor, and ask your agent for an
app that calls https://<name>.int.exe.xyz with no credentials.
Warning
This applies to every app, not just one: any app can then reach every integration attached to the VM and services on the VM itself. Allow it only if you read the apps your agents write.
Cloud agents#
claude.ai, ChatGPT, and agents running in their makers' clouds can't send an
exe.dev token, so they can reach only a public VM. Executor then is the only
lock, and a real one: /mcp refuses requests without a token, and clients
sign in with OAuth in your browser, which needs your Executor password and
your approval. Create your account first, then, on your computer:
ssh exe.dev share set-public my-executor
Add https://my-executor.exe.xyz/mcp to the app as a custom connector and
sign in. Claude Code (/mcp) and Codex (codex mcp login executor) can sign
in the same way. OAuth connections can also be limited to some apps: on
Connections, make a connection and use its MCP URL.
Warning
Public means Executor's sign-in page faces the internet. Use a strong password, approve only connections you just started, and go back with
ssh exe.dev share set-private my-executorwhen you're done.
The nuts and bolts#
Happy with what Shelley set up? Stop here. Below are the steps it followed, and maintenance for later.
Set up by hand
Create the VM#
On your computer (pick another name if my-executor is taken):
ssh exe.dev new --name=my-executor
ssh my-executor.exe.xyz
Everything else runs on the VM.
Run Executor#
Executor's official image listens on port 4400; Compose publishes it on
8000, where exe.dev's proxy sends https://<vm>.exe.xyz/.
BETTER_AUTH_URL must be exactly that address, or sign-in fails. The
catalog feed fills Browse app catalog, and DO_NOT_TRACK turns off the
anonymous usage events that released images send by default:
mkdir -p ~/executor && cd ~/executor
echo "BETTER_AUTH_URL=https://$(hostname).exe.xyz" > .env
cat > compose.yaml <<'EOF'
services:
executor:
image: ghcr.io/usefulsoftwareco/executor-selfhost:2.0.0-beta.34
init: true
restart: unless-stopped
ports:
- "8000:4400"
environment:
BETTER_AUTH_URL: ${BETTER_AUTH_URL}
EXECUTOR_CATALOG_URL: https://catalog.executor.sh/index.json
DO_NOT_TRACK: "1"
volumes:
- ./data:/app/data
stop_grace_period: 30s
EOF
sudo systemctl enable --now docker.service
docker compose up -d
On first start, Executor creates its database and two keys,
auth-secret.key and encryption.key, in ~/executor/data.
Check it#
until curl -fsS http://localhost:8000/health; do sleep 2; done; echo
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://localhost:8000/mcp
Expect {"status":"ok"}, then 401: the MCP endpoint wants a token. Then
open https://my-executor.exe.xyz/ and create your account, as in
Add your tools.
Back up and restore
Everything is in ~/executor/data: the database, both key files, and your
apps' code. Stop Executor for a consistent copy:
cd ~/executor
docker compose stop
(umask 077; tar -czf - data compose.yaml .env > ~/executor-$(date -u +%Y%m%d).tar.gz)
docker compose start
The archive holds the keys, so it's readable only by you. Copy it off the VM too. To restore one:
cd ~/executor
docker compose stop
rm -rf data
tar -xzf ~/executor-20261031.tar.gz -C ~/executor
docker compose start
A backup without the key files can't be opened.
Update
Back up first. Then change the tag in ~/executor/compose.yaml to the
newest release
(2.0.0-beta.35, for example) and recreate the container:
cd ~/executor
docker compose pull && docker compose up -d
Executor migrates its data on startup. To follow every beta without editing
the file, use the beta tag instead.
Troubleshooting
- Sign-in loops or fails:
BETTER_AUTH_URLin~/executor/.envisn't exactlyhttps://<vm>.exe.xyz. Fix it anddocker compose up -d. - An agent gets
401: withoutX-Exedev-Authorization, exe.dev refuses it; with it, Executor wantsAuthorization: Bearer exp_…. Check both, theBearerbefore each, and that neither has expired. - "Could not reach this MCP server": Executor fetches the URL from the
VM. Check it from there with
curl -i <url>. - Logs:
docker compose -f ~/executor/compose.yaml logs --tail 100.
Frequently asked questions#
Executor 1 or Executor 2?
This page runs Executor 2, which is in beta and is what executor.sh and its docs now describe: apps with tools, skills, storage, schedules and webhooks. The 1.x line (1.6.11 on Oct 22, 2026) is still the latest image tag and npm release, with its own data format; 2.0 doesn't upgrade a 1.x install in place. Betas come out almost daily, so the page pins one tag.
What does it cost?
Executor is MIT-licensed and runs no model of its own, so just your VM plan. Your agents' model use bills wherever those agents run.
Who can reach it?
exe.dev's proxy lets in only you (signed in) and holders of a VM token for this VM, then Executor wants its own sign-in or token. A leaked Executor token is useless without a VM token, and the reverse.
Where are my API keys and OAuth tokens kept?
In Executor's database on the VM, encrypted with encryption.key in the same data directory. Agents get tools, never the credentials behind them. Back up the whole directory: without the key files, Executor won't start.
Does it phone home?
Released images send anonymous usage events (counts, timings, error types; never tool inputs, outputs or credentials) to the Executor team by default. This page turns that off with DO_NOT_TRACK: "1" in compose.yaml; remove the line to send them.
Can claude.ai or ChatGPT use it?
Only if the VM is public, since they connect from their makers' servers. See Cloud agents.
Updated Oct 31, 2026 · tested end to end Oct 31, 2026 · Markdown · manifest.json · Something wrong? Tell us