Run Gemini CLI on a remote server
Google's terminal agent on a VM of its own, with the API key kept off it.
Shelley handles the setup. About 10 minutes.
Prefer a terminal?
curl -fsSL https://exe.dev/deploy/gemini-cli/prompt.txt | ssh exe.dev new --prompt=/dev/stdinGemini CLI is Google's open-source coding agent for the terminal. On an exe.dev VM it gets a computer of its own: it keeps working when you close your laptop, and it can install, run and break things you can throw away.
Gemini CLI needs Google's Gemini models, so bring a Gemini API key. You give the key to exe.dev rather than the VM: a Gemini integration adds it to each request on the way out, so nothing on the VM, Gemini CLI included, can read it. Since June 2026 Google serves Gemini CLI only to API keys, Vertex AI and organizations with a Gemini Code Assist license; free and Google AI Pro accounts can no longer sign in to it.
What you get#
- Gemini CLI on Node.js 24, answering a headless
gemini -pprompt - A Gemini API key stored in an exe.dev integration, never on the VM
- A Git repository at
~/projecton persistent disk - A
geminitmux session that survives disconnects
What's running, and where
ssh my-gemini-cli.exe.xyz
your terminal
https://gemini.int.exe.xyz/
the Gemini API, from this VM only, with your key added by exe.dev
Deploy with Shelley#
Click Deploy and Shelley will set up Gemini CLI on a new VM, then check that it works. No config-file wrangling required.
Prefer a terminal?
curl -fsSL \
https://exe.dev/deploy/gemini-cli/prompt.txt \
| ssh exe.dev new --prompt=/dev/stdinWhat Shelley is told
Set up Gemini CLI on this VM by following the exe.dev recipe at https://exe.dev/deploy/gemini-cli.md from top to bottom.
The recipe's example VM name is my-gemini-cli. This VM's name is the output of `hostname`: use it wherever the recipe writes my-gemini-cli. Skip the step that creates the VM; you are on it.
You are done when all of these are true. Check each one yourself:
- Gemini CLI on Node.js 24, answering a headless `gemini -p` prompt
- A Gemini API key stored in an exe.dev integration, never on the VM
- A Git repository at `~/project` on persistent disk
- A `gemini` tmux session that survives disconnects
Run the VM-side commands in "Install Gemini CLI" and "Connect it to
Gemini". Only the owner can create the Gemini integration, in their
browser, and the API key must never be on this VM: give them the
integration link from "Connect it to Gemini" with this VM's name in it,
and wait until they say it's done. Never ask for the key. If
`~/.gemini/settings.json` already exists, set `security.auth.selectedType`
in it instead of replacing the file. Create tmux detached
(`tmux new -d -s gemini -c ~/project`) rather than attaching, and reuse
the session if it exists. Do not launch interactive Gemini CLI; leave the
folder-trust question to the owner. Verify with
`curl -fsS https://gemini.int.exe.xyz/v1beta/models >/dev/null` and, from
~/project, `gemini --skip-trust -m flash-lite -p "Reply with exactly: OK"`, and
check `tmux has-session -t gemini`. Skip the later optional sections and
FAQ. Finish with the SSH command from "Take a break", using this VM's
name, and tell the owner to run `gemini` inside it.
Finish with the URLs I should open.
Also at /deploy/gemini-cli/prompt.txt. The recipe it follows is /deploy/gemini-cli.md.
Install Gemini CLI#
On your computer, create a VM and connect. Pick any free name; if you've already clicked Deploy or have a VM, skip the first command and use its name:
ssh exe.dev new --name=my-gemini-cli
ssh my-gemini-cli.exe.xyz
On the VM, install Node.js 24 from NodeSource (Gemini CLI needs Node.js 20 or newer) and Gemini CLI from npm:
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install -g @google/gemini-cli@latest
gemini --version
It prints a version such as 0.66.0.
Connect it to Gemini#
Open this link on your computer to add a Gemini integration attached to the
VM. Keep the name gemini, paste your Gemini API key, and save:
https://exe.dev/integrations/add?service=gemini&attach=vm:my-gemini-cli
The VM can now reach the Gemini API at https://gemini.int.exe.xyz, with
your key added by exe.dev. On the VM, check it:
curl -fsS https://gemini.int.exe.xyz/v1beta/models | jq -r '.models[0].name'
It prints a model name, such as models/gemini-2.5-flash. A 403 saying integration not found or not attached to this VM means the integration has another name
or isn't attached to this VM yet.
Point Gemini CLI at that address. Gemini CLI insists on an API key value, so it gets a placeholder; the integration replaces it with yours:
mkdir -p ~/.gemini
cat > ~/.gemini/.env <<'EOF'
GOOGLE_GEMINI_BASE_URL=https://gemini.int.exe.xyz
GEMINI_API_KEY=added-by-exe-dev
EOF
chmod 600 ~/.gemini/.env
cat > ~/.gemini/settings.json <<'EOF'
{
"security": { "auth": { "selectedType": "gemini-api-key" } }
}
EOF
Make a project folder, a Git repository so you can review and undo what Gemini changes, and ask it something without opening the interactive screen:
git init ~/project
cd ~/project
gemini --skip-trust -m flash-lite -p "Reply with exactly: OK"
It prints OK. --skip-trust answers the folder-trust question you'll see
in the next step, for this run only, and -m flash-lite picks Google's
smallest current model, which free keys can use too.
Start coding#
Open a tmux session in the project:
tmux new -A -s gemini -c ~/project
Inside that session, start Gemini CLI:
gemini
The first time, it asks whether you trust the files in this folder. Choose
Trust folder: Gemini CLI only reads ~/.gemini/.env and project
settings in folders you trust. Then give it a small task. For example:
Build a tiny website for a lighthouse keeper who reviews passing ships.
Note
Gemini CLI's default model setting, Auto, sends harder prompts to a Pro model. Keys on Google's free tier can't use Pro, so Gemini CLI retries and then falls back to Flash, which can take minutes. With a free key, start it as
gemini -m flash(or-m flash-lite), or pick a model with/model.
Gemini CLI asks before it edits a file or runs a command. Press
Shift+Tab to let it accept edits on its own; type /help for the rest.
Take a break#
Press Ctrl-b, then d to detach. Gemini CLI keeps working on the VM when you disconnect. On your computer, use this command to hop back in:
ssh -t my-gemini-cli.exe.xyz 'tmux new -A -s gemini -c ~/project'
A VM restart ends the running session, but not your saved work. Reconnect
and run gemini --resume latest from your project's folder on the VM to
pick up its last conversation.
Tip
Before a big unattended job, take a copy of the VM with
ssh exe.dev cp my-gemini-cli my-gemini-cli-backupon your computer. If the job goes sideways, carry on from the copy.
Run it headless#
gemini -p runs one prompt and exits, which makes Gemini CLI a tool for
scripts, cron jobs and other agents. It reads anything piped into it:
cd ~/project
git diff | gemini -p "Write a commit message for these changes"
Without a screen to ask on, Gemini CLI refuses anything that needs your
approval. Say what it may do instead: --approval-mode=auto_edit lets it
edit files, and --approval-mode=yolo lets it run any command too, which
is what a throwaway VM is for. -o json returns one JSON object with the
answer in response:
gemini --approval-mode=auto_edit -o json \
-p "Add a README.md that explains this project" | jq -r .response
A scheduled run is one cron line. Run crontab -e and add, for example, a
nightly review at 06:00 UTC:
0 6 * * * cd ~/project && gemini --skip-trust -p "List the TODOs in this repo, most urgent first" >> ~/gemini-todos.log 2>&1
The exit code is 0 on success, 1 on an error, 42 for bad input and
53 when the run hits its turn limit. Google's
headless mode reference has the
stream-json event format.
Add MCP servers#
Gemini CLI loads MCP servers from
~/.gemini/settings.json, or from .gemini/settings.json in a project.
gemini mcp add writes the entry for you: pass --scope user for every
project, as its default is the current project only.
For example, connect exe.dev's MCP server so Gemini can
create VMs of its own: to try something risky on a copy, or to host what it
builds. It runs unattended here, so give it a token that can only touch VMs
tagged agent and expires in 30 days rather than your whole account. On
your computer:
ssh exe.dev ssh-key generate-api-key --label=gemini --tag=agent --exp=30d \
'--cmds="help,whoami,ls,new,rm,ssh,cp,stat,comment,share show,share port"'
It prints a token that starts with exe1.. On the VM, add it to
~/.gemini/.env (replace exe1.… with the token) and register the server.
The single quotes keep ${EXE_TOKEN} as written, so Gemini CLI reads the
token from .env each time it starts instead of saving it in
settings.json:
echo 'EXE_TOKEN=exe1.…' >> ~/.gemini/.env
gemini mcp add --scope user --transport http \
--header 'Authorization: Bearer ${EXE_TOKEN}' exe https://exe.dev/mcp
cd ~/project && gemini mcp list
gemini mcp list shows exe as Connected. In Gemini CLI, /mcp lists
each server's tools. Limit what the agent can touch
explains the token's options.
A local server that runs as a command works the same way, without
--transport: gemini mcp add --scope user <name> <command> [args...].
See Google's MCP guide for
per-tool filters and OAuth servers.
Work on a GitHub repository#
The GitHub integration lets the VM clone and
push a repository without a GitHub token on it. Connect your GitHub account
on the Integrations page once, then, on your
computer, add the repository (replace you/your-repo):
ssh exe.dev integrations add github --name your-repo \
--repository you/your-repo --attach vm:my-gemini-cli
On the VM, clone it, tell Git who you are, and start Gemini CLI in it:
git clone https://github.int.exe.xyz/you/your-repo.git ~/your-repo
git config --global user.name "Your Name"
git config --global user.email you@example.com
tmux new -A -s your-repo -c ~/your-repo
gemini
Ask for a change on a branch, then let Gemini push it and open a pull
request with the preinstalled gh, which goes through the same
integration when GH_HOST points at it:
Fix the flaky date test on a new branch, commit it, push the branch, and open a pull request with
GH_HOST=github.int.exe.xyz gh pr create.
Pushes show up as the exe.dev GitHub App; add --act-as-user to the
integrations add command to push as yourself. Put project instructions
for Gemini in a GEMINI.md at the top of the repository; it reads that
file at the start of every session.
Other ways to sign in#
An API key on the VM, a Code Assist license, or Vertex AI
A Gemini API key on the VM#
If you'd rather not use an integration, put the key itself in
~/.gemini/.env, which only you can read, and drop the
GOOGLE_GEMINI_BASE_URL line:
cat > ~/.gemini/.env <<'EOF'
GEMINI_API_KEY=paste-your-key-here
EOF
chmod 600 ~/.gemini/.env
Anything running on the VM as exedev, Gemini CLI included, can then read
the key.
Sign in with Google (Gemini Code Assist license)#
If your organization gives you a Gemini Code Assist Standard or Enterprise license, sign in with that Google account. Set the Google Cloud project the license belongs to and switch the sign-in method:
cat > ~/.gemini/.env <<'EOF'
GOOGLE_CLOUD_PROJECT=your-project-id
EOF
cat > ~/.gemini/settings.json <<'EOF'
{
"security": { "auth": { "selectedType": "oauth-personal" } }
}
EOF
Start gemini in the tmux session. With no browser on the VM, it prints a
https://accounts.google.com/... link and waits at Enter the authorization code:. Open the link on your computer, sign in, and paste the code it shows
back into the terminal. Gemini CLI keeps the sign-in in
~/.gemini/oauth_creds.json, which headless runs use too.
Vertex AI#
To bill a Google Cloud project instead, Gemini CLI can use Vertex AI. Set
GOOGLE_GENAI_USE_VERTEXAI=true, GOOGLE_CLOUD_PROJECT and
GOOGLE_CLOUD_LOCATION in ~/.gemini/.env, and "selectedType": "vertex-ai" in settings.json. For credentials, exe.dev's
GCP Workload Identity Federation lets the VM
act as a service account with the Vertex AI User role and no key file:
follow that guide, then add the GOOGLE_APPLICATION_CREDENTIALS line it
creates to ~/.gemini/.env. Google's
authentication guide
covers the other Vertex AI options.
Troubleshooting#
When using Gemini API, you must specify the GEMINI_API_KEY environment variable: Gemini CLI didn't read~/.gemini/.env. It reads only the first.envit finds, starting in the current folder, so a project with its own.envhides yours. Copy the two lines into the project's.gemini/.env(and keep that out of Git), or runset -a; . ~/.gemini/.env; set +abeforegemini. It also skips.envfiles in folders you haven't trusted; trust the folder, or pass--skip-trustto headless runs.Gemini CLI is not running in a trusted directory: a headless run in a new folder. Add--skip-trust, or opengeminithere once and trust it.403andintegration not found or not attached to this VM: the Gemini integration isn't attached to this VM, or isn't calledgemini. Check on the Integrations page, and use its name inGOOGLE_GEMINI_BASE_URL.429andYou have exhausted your daily quota on this model: the key's project hit Google's limit for that model; free-tier keys get little or none (limit: 0means none). Switch model with/modelor-m flash-lite, or link billing to the project in Google AI Studio.503andThis model is currently experiencing high demand: Google is busy. Gemini CLI retries on its own; if it gives up, try again or use another model.404andno longer available to new users: an older model name, such asgemini-2.5-flash, that Google has retired for new keys. Use a current one from/model.API key not valid: the key was refused. Check it in Google AI Studio.Invalid auth method selected:~/.gemini/settings.jsonhas noselectedType; write it as in "Connect it to Gemini".- Anything else: Gemini CLI saves the full error report under
/tmpand names the file in the message. Rungemini --debugfor more, or see Google's troubleshooting guide.
Frequently asked questions#
Does Gemini CLI work with exe.dev's LLM gateway, without a key?
No. Gemini CLI only speaks Google's Gemini API, and the LLM gateway serves Claude, GPT and open models, not Gemini. So you need your own Gemini API key (or a Code Assist license, or Vertex AI). For an agent that needs no key at all, use Codex, Claude Code or OpenCode.
Can I sign in with my Google account or my Google AI Pro plan?
Only with an organization's Gemini Code Assist Standard or Enterprise license; see Other ways to sign in. On June 18, 2026 Google stopped serving Gemini CLI to free personal accounts and Google AI Pro and Ultra subscribers and moved them to Antigravity CLI. A Gemini API key from Google AI Studio still works.
How much does it cost?
Google bills Gemini API use to the project that owns your key, at its Gemini API prices; exe.dev doesn't charge for it. The VM is part of your exe.dev plan. A key on Google's free tier works for a quick try, but in October 2026 it got 20 requests a day on the main Flash model and none on Pro; one coding task can take dozens. Link a billing account to the key's project in Google AI Studio for real work.
How do I update Gemini CLI?
On the VM, run sudo npm install -g @google/gemini-cli@latest. Google releases a new version every week. Gemini CLI's own automatic update can't write to the system-wide install, so it may say it failed; the command above is the fix.
How do I back up my work?
Commit and push your code. For a copy of the whole VM, run ssh exe.dev cp my-gemini-cli my-gemini-cli-backup on your computer (choose a free backup name). Your files, ~/.gemini and chat history are in the copy. Attach the Gemini integration to the copy too, with ssh exe.dev integrations attach gemini vm:my-gemini-cli-backup.
Updated Oct 28, 2026 · tested end to end Oct 28, 2026 · Markdown · manifest.json · Something wrong? Tell us