---
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.dev/deploy/gemini-cli
category: "AI agents"
updated: 2026-10-28
---

# 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.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.dev/new?prompt=Set%20up%20Gemini%20CLI%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe.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.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. 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.

## 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. 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 Codex on a remote server](https://exe.dev/deploy/codex.md): A computer for Codex. An early night for your laptop.
- [Run Claude Code on a remote server](https://exe.dev/deploy/claude-code.md): A computer for Claude. A breather for your laptop.
- [Run OpenCode on a remote server](https://exe.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.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.dev/deploy/openclaw.md): An AI sidekick with its own computer. Your laptop can take a nap.
- [Self-host Hermes Agent](https://exe.dev/deploy/hermes-agent.md): An agent that remembers you, on a computer that never sleeps.
