---
title: "Run Gemini CLI on a remote server"
description: "Google's Gemini CLI on your own VM: the Gemini API key held by an exe.dev integration, a tmux session that outlives your laptop, headless runs, MCP."
url: https://exe-staging.dev/deploy/gemini-cli
category: "AI agents"
updated: 2026-11-02
---

# Run Gemini CLI on a remote server

Google's terminal agent on a VM of its own, with the API key kept off it.

- **Software:** Gemini CLI (https://geminicli.com/)
- **Source:** https://github.com/google-gemini/gemini-cli
- **License:** Apache-2.0
- **Time:** 10 minutes
- **Example VM name:** `my-gemini-cli` (yours will differ; on the VM, `hostname` prints it)
- **Machine-readable:** https://exe-staging.dev/deploy/gemini-cli/manifest.json

## What you get

- 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

Running on the VM:

- **Gemini CLI**: @google/gemini-cli from npm, on Node.js 24, data in `~/.gemini`
- **Gemini integration**: exe.dev holds your Gemini API key and adds it to each request
- **Your project**: a Git repository, data in `~/project`
- **tmux**: keeps your terminal session running when you disconnect

How it is reached:

- ssh my-gemini-cli.exe.xyz (private): your terminal
- https://gemini.int.exe.xyz/ (private): the Gemini API, from this VM only, with your key added by exe.dev

## Deploy with Shelley

Open https://exe-staging.dev/new?prompt=Set%20up%20Gemini%20CLI%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Fgemini-cli.md%20from%20top%20to%20bottom.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-gemini-cli.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-gemini-cli.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20Gemini%20CLI%20on%20Node.js%2024%2C%20answering%20a%20headless%20%60gemini%20-p%60%20prompt%0A-%20A%20Gemini%20API%20key%20stored%20in%20an%20exe.dev%20integration%2C%20never%20on%20the%20VM%0A-%20A%20Git%20repository%20at%20%60~%2Fproject%60%20on%20persistent%20disk%0A-%20A%20%60gemini%60%20tmux%20session%20that%20survives%20disconnects%0A%0ARun%20the%20VM-side%20commands%20in%20%22Install%20Gemini%20CLI%22%20and%20%22Connect%20it%20to%0AGemini%22.%20Only%20the%20owner%20can%20create%20the%20Gemini%20integration%2C%20in%20their%0Abrowser%2C%20and%20the%20API%20key%20must%20never%20be%20on%20this%20VM%3A%20give%20them%20the%0Aintegration%20link%20from%20%22Connect%20it%20to%20Gemini%22%20with%20this%20VM%27s%20name%20in%20it%2C%0Aand%20wait%20until%20they%20say%20it%27s%20done.%20Never%20ask%20for%20the%20key.%20If%0A%60~%2F.gemini%2Fsettings.json%60%20already%20exists%2C%20set%20%60security.auth.selectedType%60%0Ain%20it%20instead%20of%20replacing%20the%20file.%20Create%20tmux%20detached%0A%28%60tmux%20new%20-d%20-s%20gemini%20-c%20~%2Fproject%60%29%20rather%20than%20attaching%2C%20and%20reuse%0Athe%20session%20if%20it%20exists.%20Do%20not%20launch%20interactive%20Gemini%20CLI%3B%20leave%20the%0Afolder-trust%20question%20to%20the%20owner.%20Verify%20with%0A%60curl%20-fsS%20https%3A%2F%2Fgemini.int.exe.xyz%2Fv1beta%2Fmodels%20%3E%2Fdev%2Fnull%60%20and%2C%20from%0A~%2Fproject%2C%20%60gemini%20--skip-trust%20-m%20flash-lite%20-p%20%22Reply%20with%20exactly%3A%20OK%22%60%2C%20and%0Acheck%20%60tmux%20has-session%20-t%20gemini%60.%20Skip%20the%20later%20optional%20sections%20and%0AFAQ.%20Finish%20with%20the%20SSH%20command%20from%20%22Take%20a%20break%22%2C%20using%20this%20VM%27s%0Aname%2C%20and%20tell%20the%20owner%20to%20run%20%60gemini%60%20inside%20it.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A to create a VM whose agent, Shelley, follows this recipe. From a terminal:

```sh
curl -fsSL https://exe-staging.dev/deploy/gemini-cli/prompt.txt | ssh exe.dev new --prompt=/dev/stdin
```

Or follow the steps below by hand.

[Gemini CLI](https://geminicli.com/) 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](https://aistudio.google.com/app/apikey). You give the key to
exe.dev rather than the VM: a Gemini [integration](/docs/integrations) adds it
to each request on the way out, so nothing on the VM, Gemini CLI included,
can read it.

> [!NOTE]
> On June 18, 2026 Google moved personal accounts (free, Google AI Pro and
> Google AI Ultra) from Gemini CLI to Antigravity CLI, its closed-source
> successor, and they can no longer sign in to Gemini CLI. Gemini API keys,
> Vertex AI and organizations with a Gemini Code Assist Standard or
> Enterprise license still work, and Google still updates Gemini CLI,
> though it isn't tuned for Gemini 4 models. To use your Google
> account or AI plan, [run Antigravity CLI on a VM](/deploy/antigravity-cli)
> instead.

## 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:

```bash
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:

```bash
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:

```text
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:

```bash
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:

```bash
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:

```bash
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:

```bash
tmux new -A -s gemini -c ~/project
```

Inside that session, start Gemini CLI:

```bash
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:

```bash
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-backup` on 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:

```bash
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`:

```bash
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:

```text
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](https://geminicli.com/docs/cli/headless) has the
`stream-json` event format.

## Add MCP servers

Gemini CLI loads [MCP](https://modelcontextprotocol.io/) 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](/deploy/exe-mcp) 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:

```bash
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`:

```bash
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](/deploy/exe-mcp#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](https://geminicli.com/docs/tools/mcp-server) for
per-tool filters and OAuth servers.

## Work on a GitHub repository

The [GitHub integration](/docs/integrations-github) lets the VM clone and
push a repository without a GitHub token on it. Connect your GitHub account
on the [Integrations page](https://exe.dev/integrations) once, then, on your
computer, add the repository (replace `you/your-repo`):

```bash
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:

```bash
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

<details class="dp-details">
<summary>An API key on the VM, a Code Assist license, or Vertex AI</summary>

### 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:

```bash
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:

```bash
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](/docs/integrations-gcp-wif) 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](https://geminicli.com/docs/get-started/authentication#vertex-ai)
covers the other Vertex AI options.

</details>

## 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 `.env` it finds, starting in the current folder, so a project with
  its own `.env` hides yours. Copy the two lines into the project's
  `.gemini/.env` (and keep that out of Git), or run
  `set -a; . ~/.gemini/.env; set +a` before `gemini`. It also skips
  `.env` files in folders you haven't trusted; trust the folder, or pass
  `--skip-trust` to headless runs.
- **`Gemini CLI is not running in a trusted directory`**: a headless run in
  a new folder. Add `--skip-trust`, or open `gemini` there once and trust it.
- **`403` and `integration not found or not attached to this VM`**: the
  Gemini integration isn't attached to this VM, or isn't called `gemini`.
  Check on the [Integrations page](https://exe.dev/integrations), and use
  its name in `GOOGLE_GEMINI_BASE_URL`.
- **`429` and `You 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: 0` means none). Switch model with `/model` or
  `-m flash-lite`, or link billing to the project in
  [Google AI Studio](https://aistudio.google.com/).
- **`503` and `This 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.
- **`404` and `no longer available to new users`**: an older model name,
  such as `gemini-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](https://aistudio.google.com/).
- **`Invalid auth method selected`**: `~/.gemini/settings.json` has no
  `selectedType`; write it as in "Connect it to Gemini".
- **Anything else**: Gemini CLI saves the full error report under `/tmp`
  and names the file in the message. Run `gemini --debug` for more, or see
  Google's [troubleshooting guide](https://geminicli.com/docs/resources/troubleshooting).

## 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](/docs/integrations-llm) 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](/deploy/codex), [Claude Code](/deploy/claude-code) or [OpenCode](/deploy/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](#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](/deploy/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](https://ai.google.dev/gemini-api/docs/pricing); 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](https://aistudio.google.com/) 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`.


## Related

- [Run Antigravity CLI on an always-on server](https://exe-staging.dev/deploy/antigravity-cli.md): Google's terminal agent on an always-on VM, steered from your phone's browser.
- [Run Codex on a remote server](https://exe-staging.dev/deploy/codex.md): A computer for Codex. An early night for your laptop.
- [Run Claude Code on a remote server](https://exe-staging.dev/deploy/claude-code.md): A computer for Claude. A breather for your laptop.
- [Run OpenCode on a remote server](https://exe-staging.dev/deploy/opencode.md): Every model, one VM, and an agent that works while your laptop sleeps.
- [Give any agent a sandbox over MCP](https://exe-staging.dev/deploy/exe-mcp.md): One URL gives your agent real VMs to run code on, host apps from, and hand work to.
- [Host OpenClaw](https://exe-staging.dev/deploy/openclaw.md): An AI sidekick with its own computer. Your laptop can take a nap.
