Skip to main content
Glama
README.md
# Gemini CLI MCP

A lightweight MCP server that exposes the official **Gemini CLI** to MCP clients such as Claude Code, while adding transparent API-key rotation for `429` rate-limit responses.

## Why this exists

Gemini CLI already provides headless execution with `--prompt` and structured JSON output. This project wraps that CLI instead of reimplementing its agent runtime.

The extra feature is the local API gateway:

```text
MCP client
   |
   v
Gemini CLI process
   |
   | GOOGLE_GEMINI_BASE_URL
   v
Local API gateway
   |
   +---- key A ----> Gemini API
   |
   +---- key B ----> Gemini API
   |
   +---- key C ----> Gemini API
```

When Gemini API returns `429`, the gateway marks the current key as temporarily unavailable, retries the same HTTP request with the next available key, and only returns an error if the retry budget is exhausted.

This means the **same Gemini CLI process and session can continue**. The MCP does not restart the agent from the beginning of the job just because an intermediate API request was rate-limited.

> API keys must be keys you own or are authorized to use. Respect Google's quotas, terms, and rate limits.

## Requirements

- Node.js 18+
- Gemini CLI installed and available in `PATH` (as `gemini` on macOS/Linux or `gemini.cmd` on Windows)
- Gemini API key(s) from Google AI Studio when using API-key authentication

Gemini CLI documents `GEMINI_API_KEY` as its API-key authentication environment variable.

On Windows, the MCP automatically detects and uses `gemini.cmd`. To use a different command, set the `GEMINI_CMD` environment variable.

Gemini CLI headless mode supports `--prompt` / `-p` and structured output formats including `json` and `stream-json`.

## Install with npm

```bash
npm install -g @alvarosw/gemini-cli-mcp
```

## Configure API keys

Single key:

```bash
export GEMINI_API_KEY="your-key"
```

Multiple keys:

```bash
export GEMINI_API_KEYS="key-one,key-two,key-three"
```

On PowerShell:

```powershell
$env:GEMINI_API_KEYS="key-one,key-two,key-three"
```

`GEMINI_API_KEYS` accepts comma, semicolon, or newline-separated values.

## Claude Code

```bash
claude mcp add gemini \
  --env GEMINI_CLI_TRUST_WORKSPACE=true \
  --scope user --transport stdio \
  -- npx @alvarosw/gemini-cli-mcp
```

With multiple keys:

```bash
claude mcp add gemini \
  --env GEMINI_API_KEYS="key-1,key-2,key-3" \
  --env GEMINI_CLI_TRUST_WORKSPACE=true \
  --scope user --transport stdio \
  -- npx @alvarosw/gemini-cli-mcp
```

On macOS/Linux:

```bash
claude mcp add gemini \
  --env GEMINI_API_KEYS="key-one,key-two,key-three" \
  --env GEMINI_CLI_TRUST_WORKSPACE=true \
  --scope user --transport stdio \
  -- npx @alvarosw/gemini-cli-mcp
```

Prefer configuring the keys in your shell environment or a secret manager rather than committing them to a project.

## Other MCP clients

Generic MCP configuration:

```json
{
  "mcpServers": {
    "gemini": {
      "command": "npx",
      "args": ["-y", "@alvarosw/gemini-cli-mcp"],
      "env": {
        "GEMINI_API_KEYS": "key-one,key-two,key-three"
      }
    }
  }
}
```

This pattern works with MCP hosts that support local stdio servers and environment variables.

## Tools

### `gemini_run`

Run Gemini CLI in headless mode with common options:

- prompt
- model
- output format
- approval mode
- sandbox / yolo
- session resume
- included directories
- allowed MCP servers
- extensions
- experimental integrations
- arbitrary extra CLI arguments

Example payload:

```json
{
  "prompt": "Review the authentication flow in this repository and propose fixes.",
  "cwd": "/path/to/project",
  "model": "auto",
  "outputFormat": "json",
  "approvalMode": "plan"
}
```

### `gemini_raw`

Pass arbitrary arguments directly to the Gemini CLI when `gemini_run` does not cover a new CLI capability.

```json
{
  "args": ["--version"]
}
```

### `gemini_usage`

Shows the local key-pool state: number of keys, cooldowns, failures, and last HTTP status.

This is **not** a provider-side quota report.

### `gemini_version`

Returns the installed Gemini CLI version.

### `gemini_help`

Returns the current Gemini CLI help output.

### `gemini_models`

Runs a non-interactive model-selection query. For exact current CLI behavior, use `gemini_raw` with the desired model-related flags.

### `gemini_cli_info`

Shows the active CLI command, proxy address, and redacted key-pool status.

## API-key failover

The proxy rotates keys only for upstream `429` responses.

For example:

```text
Request #1 -> key A -> 200
Request #2 -> key A -> 429
               |
               +-> key B -> 200
Request #3 -> key B -> 200
```

Keys that return `429` are placed on cooldown using the upstream `Retry-After` value when available, otherwise `GEMINI_KEY_COOLDOWN_MS` (default: 60 seconds).

### Configuration

| Variable | Default | Description |
| --- | --- | --- |
| `GEMINI_API_KEYS` | — | Comma/semicolon/newline-separated API keys |
| `GEMINI_API_KEY` | — | Fallback single API key |
| `GEMINI_KEY_COOLDOWN_MS` | `60000` | Cooldown when `Retry-After` is unavailable |
| `GEMINI_MAX_KEY_RETRIES` | `key count - 1` | Maximum fallback attempts per request |
| `GEMINI_PROXY_HOST` | `127.0.0.1` | Local proxy bind host |
| `GEMINI_PROXY_PORT` | `0` | Local proxy port; `0` selects a free port |
| `GEMINI_TARGET_URL` | Google Gemini API | Upstream Gemini API base URL |
| `GEMINI_CMD` | `gemini` on macOS/Linux; `gemini.cmd` on Windows | Gemini CLI executable |

## Important limitation

This gateway solves the important case where the CLI process makes multiple model requests and one intermediate request receives `429`: the **failed HTTP request is retried in place**, so the surrounding Gemini CLI session is not restarted.

It does not make an already-started streaming response resumable after bytes have been delivered. Rate-limit responses normally arrive as HTTP status responses before the response body, so the gateway can retry those requests cleanly.

## Security

The API gateway is bound to `127.0.0.1` by default and is intended for local use. Do not expose it publicly.

API keys are injected into the upstream request at the gateway and are never returned by MCP tools. `gemini_usage` and `gemini_cli_info` redact key values.

## Development

```bash
npm install
npm start
```

Run syntax checks:

```bash
node --check src/index.js
node --check src/tools.js
node --check src/gemini.js
node --check src/key-pool.js
node --check src/proxy.js
```

## References

- [Gemini CLI documentation](https://geminicli.com/docs/)
- [Gemini CLI headless mode](https://geminicli.com/docs/cli/headless/)
- [Gemini CLI authentication](https://geminicli.com/docs/get-started/authentication/)