Skip to main content
Glama
wminson

Gemini CLI MCP Server

by wminson
README.md
# Gemini CLI MCP Server

An MCP (Model Context Protocol) server that wraps the Gemini CLI, exposing it over both stdio and SSE (Server-Sent Events) transports.

## Overview

This server allows remote clients to execute Gemini CLI commands through the MCP protocol. It can run as:
- **Local stdio server** (`server.py`) - for direct MCP client integration
- **Network SSE server** (`server_sse.py`) - for remote network access on port 8601

## Features

- **Dual Transport**: Supports both stdio (local) and SSE (network) transports
- **Gemini CLI Integration**: Executes prompts through the Gemini CLI
- **ANSI Stripping**: Cleans terminal escape codes from output
- **Systemd Integration**: Runs as a persistent user service
- **Network Accessible**: Binds to `0.0.0.0` for external access
- **Session Management**: Resume previous sessions, list sessions
- **Extension Support**: List available Gemini CLI extensions
- **YOLO Mode**: Auto-approve actions for automated use

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    Remote MCP Clients                       │
│              (Claude Desktop, other agents)                 │
└─────────────────────────┬───────────────────────────────────┘
                          │ HTTP/SSE (port 8601)
                          ▼
┌─────────────────────────────────────────────────────────────┐
│              Gemini CLI MCP Server                          │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  FastMCP Server                                       │  │
│  │  - /sse endpoint for SSE connections                  │  │
│  │  - /messages/ endpoint for message posting            │  │
│  └───────────────────────────────────────────────────────┘  │
│                          │                                  │
│                          ▼                                  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  MCP Tools (12 tools)                                 │  │
│  │  - run_gemini(): Execute prompts with full options    │  │
│  │  - gemini_resume(): Resume previous sessions          │  │
│  │  - gemini_list_sessions(): List available sessions    │  │
│  │  - gemini_list_extensions(): List CLI extensions      │  │
│  │  - gemini_version(): Get CLI version                  │  │
│  │  - gemini_delete_session(): Delete a session          │  │
│  │  - gemini_json(): Get JSON formatted output           │  │
│  │  - gemini_with_context(): Include files/dirs          │  │
│  │  - gemini_shell(): Execute shell commands             │  │
│  │  - gemini_chat_save(): Save chat session              │  │
│  │  - gemini_help(): Get CLI help                        │  │
│  └───────────────────────────────────────────────────────┘  │
│                          │                                  │
│                          ▼                                  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  Gemini CLI                                           │  │
│  │  $ gemini "prompt" -o text [-m MODEL] [-y]            │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
```

## Directory Structure

```
/home/ward/MCP/gemini_mcp_server/
├── README.md                 # This documentation
├── server.py                 # Original stdio server (for local use)
├── server_sse.py             # SSE transport server (for network use)
├── requirements.txt          # Python dependencies
├── pyproject.toml            # Project configuration
├── .gitignore                # Git ignore rules
└── venv/                     # Python virtual environment

/home/ward/.config/systemd/user/
└── gemini-mcp-server.service # Systemd service unit file
```

## Prerequisites

1. **Gemini CLI**: Ensure `gemini` is installed and in your PATH.
   ```bash
   npm install -g @google/gemini-cli
   ```

2. **Authentication**: You must be authenticated with Google/Gemini.
   ```bash
   gemini  # Follow the authentication prompts
   ```

3. **Python**: Python 3.10 or higher.

## Installation

### Quick Install

```bash
# Clone or navigate to the project directory
cd /home/ward/MCP/gemini_mcp_server

# Create virtual environment
python3 -m venv venv
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Test the installation
python -c "from server import gemini_version; print(gemini_version())"
```

### Full Installation with Systemd Service

```bash
# Step 1: Set up the project
cd /home/ward/MCP/gemini_mcp_server
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Step 2: Create systemd service file
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/gemini-mcp-server.service << 'EOF'
[Unit]
Description=Gemini CLI MCP Server (SSE)
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/ward/MCP/gemini_mcp_server
ExecStart=/home/ward/MCP/gemini_mcp_server/venv/bin/python server_sse.py
Restart=always
RestartSec=5
Environment=MCP_SERVER_HOST=0.0.0.0
Environment=MCP_SERVER_PORT=8601

[Install]
WantedBy=default.target
EOF

# Step 3: Enable and start the service
systemctl --user daemon-reload
systemctl --user enable gemini-mcp-server
systemctl --user start gemini-mcp-server

# Step 4: Verify it's running
systemctl --user status gemini-mcp-server
curl -I http://localhost:8601/sse
```

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `MCP_SERVER_HOST` | `0.0.0.0` | Host to bind to (SSE server only) |
| `MCP_SERVER_PORT` | `8601` | Port to listen on (SSE server only) |

### Network Settings

The SSE server is configured for external access:
- Binds to `0.0.0.0` (all interfaces)
- Port `8601`
- DNS rebinding protection disabled for external clients

## Usage

### Option 1: Local stdio Server

For direct MCP client integration (same machine):

```bash
python server.py
```

**MCP Client Configuration:**
```json
{
  "mcpServers": {
    "gemini-cli": {
      "command": "python",
      "args": ["/home/ward/MCP/gemini_mcp_server/server.py"]
    }
  }
}
```

### Option 2: Network SSE Server

For remote network access:

**Manual Start:**
```bash
cd /home/ward/MCP/gemini_mcp_server
source venv/bin/activate
python server_sse.py
```

**Background Start:**
```bash
venv/bin/python server_sse.py > /tmp/gemini-mcp.log 2>&1 &
```

### Option 3: Systemd Service (Recommended for SSE)

The SSE server can be configured as a systemd user service for automatic startup.

**Create the service file:**
```bash
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/gemini-mcp-server.service << 'EOF'
[Unit]
Description=Gemini CLI MCP Server (SSE)
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/ward/MCP/gemini_mcp_server
ExecStart=/home/ward/MCP/gemini_mcp_server/venv/bin/python server_sse.py
Restart=always
RestartSec=5
Environment=MCP_SERVER_HOST=0.0.0.0
Environment=MCP_SERVER_PORT=8601

[Install]
WantedBy=default.target
EOF
```

**Service Management:**
```bash
# Reload systemd
systemctl --user daemon-reload

# Start the service
systemctl --user start gemini-mcp-server

# Stop the service
systemctl --user stop gemini-mcp-server

# Restart the service
systemctl --user restart gemini-mcp-server

# Check status
systemctl --user status gemini-mcp-server

# View logs
journalctl --user -u gemini-mcp-server -f

# Enable auto-start on boot
systemctl --user enable gemini-mcp-server

# Disable auto-start
systemctl --user disable gemini-mcp-server
```

## API Reference

### Endpoints (SSE Server)

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/sse` | GET | SSE connection endpoint for MCP clients |
| `/messages/` | POST | Message posting endpoint |

### MCP Tools

#### `run_gemini`

Execute a command or query using the Gemini CLI.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `prompt` | string | Yes | - | The prompt or command to send to Gemini |
| `model` | string | No | `""` | Model to use (e.g., gemini-2.5-flash, gemini-2.0-flash-exp, gemini-1.5-pro) |
| `sandbox` | boolean | No | `false` | Run in sandbox mode (isolated environment for safety) |
| `yolo` | boolean | No | `true` | Auto-approve all actions (recommended for automated use) |
| `output_format` | string | No | `"text"` | Output format: 'text', 'json', or 'stream-json' |
| `debug` | boolean | No | `false` | Enable debug mode for verbose output |
| `include_directories` | string | No | `""` | Comma-separated list of additional directories to include |

**Returns:** String containing the Gemini CLI output with ANSI codes stripped.

**Example:**
```json
{
  "tool": "run_gemini",
  "arguments": {
    "prompt": "What is 2 + 2?",
    "model": "gemini-2.5-flash",
    "output_format": "text"
  }
}
```

#### `gemini_resume`

Resume a previous Gemini CLI session.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `session` | string | No | `"latest"` | Session to resume. Use "latest" or index number |
| `prompt` | string | No | `""` | Optional prompt to continue the conversation |

**Returns:** String containing the session response.

**Example:**
```json
{
  "tool": "gemini_resume",
  "arguments": {
    "session": "latest",
    "prompt": "Continue from where we left off"
  }
}
```

#### `gemini_list_sessions`

List available Gemini CLI sessions for the current project.

**Parameters:** None

**Returns:** String listing available sessions.

**Example:**
```json
{
  "tool": "gemini_list_sessions",
  "arguments": {}
}
```

#### `gemini_list_extensions`

List all available Gemini CLI extensions.

**Parameters:** None

**Returns:** String listing installed extensions.

**Example:**
```json
{
  "tool": "gemini_list_extensions",
  "arguments": {}
}
```

#### `gemini_version`

Get the Gemini CLI version information.

**Parameters:** None

**Returns:** String containing version information (e.g., "0.20.0").

**Example:**
```json
{
  "tool": "gemini_version",
  "arguments": {}
}
```

#### `gemini_delete_session`

Delete a Gemini CLI session by index number.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `session_index` | string | Yes | - | The index number of the session to delete |

**Returns:** String confirming deletion or error message.

**Example:**
```json
{
  "tool": "gemini_delete_session",
  "arguments": {
    "session_index": "1"
  }
}
```

#### `gemini_json`

Execute a Gemini prompt and return structured JSON output. Useful for programmatic parsing of responses.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `prompt` | string | Yes | - | The prompt or command to send to Gemini |
| `model` | string | No | `""` | Optional model to use |
| `sandbox` | boolean | No | `false` | Whether to run in sandbox mode |
| `yolo` | boolean | No | `true` | Whether to auto-approve all actions |

**Returns:** JSON-formatted response from Gemini.

**Example:**
```json
{
  "tool": "gemini_json",
  "arguments": {
    "prompt": "List 3 programming languages as JSON array"
  }
}
```

#### `gemini_with_context`

Execute a Gemini prompt with specific file or directory context. Uses @ syntax to include file contents in the prompt.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `prompt` | string | Yes | - | The prompt or command to send to Gemini |
| `files` | string | No | `""` | Comma-separated list of file paths to include (e.g., "src/main.py,README.md") |
| `directories` | string | No | `""` | Comma-separated list of directories to include |
| `model` | string | No | `""` | Optional model to use |
| `yolo` | boolean | No | `true` | Whether to auto-approve all actions |

**Returns:** String containing Gemini's response with file context.

**Example:**
```json
{
  "tool": "gemini_with_context",
  "arguments": {
    "prompt": "Explain this code",
    "files": "src/main.py,src/utils.py"
  }
}
```

#### `gemini_shell`

Execute a shell command through Gemini CLI using ! syntax. Gemini can observe the output and provide analysis.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `command` | string | Yes | - | Shell command to execute (without the ! prefix) |

**Returns:** String containing command output and Gemini's analysis.

**Example:**
```json
{
  "tool": "gemini_shell",
  "arguments": {
    "command": "ls -la"
  }
}
```

#### `gemini_chat_save`

Save the current Gemini chat session.

**Parameters:**

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `name` | string | No | `""` | Optional name for the saved session |

**Returns:** String confirming save status.

**Example:**
```json
{
  "tool": "gemini_chat_save",
  "arguments": {
    "name": "my-session"
  }
}
```

#### `gemini_help`

Get Gemini CLI help information and available commands.

**Parameters:** None

**Returns:** String containing CLI help output.

**Example:**
```json
{
  "tool": "gemini_help",
  "arguments": {}
}
```

## Client Configuration

### MCP Configuration File Locations

| Client | Configuration File Location |
|--------|----------------------------|
| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Claude Desktop (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
| Claude Desktop (Linux) | `~/.config/Claude/claude_desktop_config.json` |
| Claude Code | `~/.claude/settings.json` or project `.mcp.json` |
| Cline (VS Code) | VS Code settings or `~/.cline/mcp_settings.json` |

---

### Option 1: SSE Transport (Network/Remote Access) - RECOMMENDED

Use this for network access or when the server runs as a systemd service.

**Claude Desktop / Claude Code:**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "url": "http://localhost:8601/sse",
      "transport": "sse"
    }
  }
}
```

**Remote Server Access:**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "url": "http://192.168.1.100:8601/sse",
      "transport": "sse"
    }
  }
}
```

**Cline (VS Code Extension):**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "url": "http://localhost:8601/sse",
      "transport": "sse"
    }
  }
}
```

---

### Option 2: stdio Transport (Local/Direct)

Use this for local-only access without running a persistent service.

**Claude Desktop (with venv):**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "command": "/home/ward/MCP/gemini_mcp_server/venv/bin/python",
      "args": ["/home/ward/MCP/gemini_mcp_server/server.py"]
    }
  }
}
```

**Claude Desktop (system Python):**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "command": "python3",
      "args": ["/home/ward/MCP/gemini_mcp_server/server.py"],
      "cwd": "/home/ward/MCP/gemini_mcp_server"
    }
  }
}
```

**With Environment Variables:**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "command": "/home/ward/MCP/gemini_mcp_server/venv/bin/python",
      "args": ["/home/ward/MCP/gemini_mcp_server/server.py"],
      "env": {
        "PATH": "/usr/local/bin:/usr/bin:/bin"
      }
    }
  }
}
```

---

### Option 3: Project-Specific Configuration

Create a `.mcp.json` file in your project root:

```json
{
  "mcpServers": {
    "gemini-cli": {
      "url": "http://localhost:8601/sse",
      "transport": "sse"
    }
  }
}
```

---

### Complete Configuration Examples

**Full Claude Desktop config with multiple MCP servers:**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "url": "http://localhost:8601/sse",
      "transport": "sse"
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"]
    }
  }
}
```

**Claude Code settings.json:**

```json
{
  "mcpServers": {
    "gemini-cli": {
      "url": "http://localhost:8601/sse",
      "transport": "sse"
    }
  }
}
```

---

### Verifying the Configuration

After adding the configuration, verify the MCP server is accessible:

```bash
# Check if the server is running
systemctl --user status gemini-mcp-server

# Test the SSE endpoint
curl -I http://localhost:8601/sse

# Expected response:
# HTTP/1.1 200 OK
# content-type: text/event-stream
```

Restart your MCP client (Claude Desktop, Claude Code, etc.) after updating the configuration.

## Troubleshooting

### Server won't start

1. **Check if port is in use:**
   ```bash
   ss -tlnp | grep 8601
   ```

2. **Kill existing process:**
   ```bash
   lsof -i :8601 | awk 'NR>1 {print $2}' | xargs kill
   ```

3. **Check logs:**
   ```bash
   journalctl --user -u gemini-mcp-server -n 50
   ```

### Connection refused

1. **Verify server is running:**
   ```bash
   systemctl --user status gemini-mcp-server
   ```

2. **Check firewall:**
   ```bash
   sudo ufw status
   sudo ufw allow 8601/tcp
   ```

3. **Test locally:**
   ```bash
   curl -I http://localhost:8601/
   ```

### Gemini CLI errors

1. **Verify CLI is installed:**
   ```bash
   which gemini
   gemini --version
   ```

2. **Test CLI directly:**
   ```bash
   gemini "Hello" -o text -y
   ```

## Security Considerations

**Warning**: This server exposes Gemini CLI over the network.

- The server uses YOLO mode (`-y`) by default for automated use
- Consider using a firewall to restrict access
- Consider using a reverse proxy with authentication for production use
- Be mindful of API costs when exposing to network

### Recommended Security Measures

1. **Firewall rules:**
   ```bash
   # Allow only specific IPs
   sudo ufw allow from 192.168.1.0/24 to any port 8601
   ```

2. **Reverse proxy with auth** (nginx example):
   ```nginx
   location /mcp/ {
       auth_basic "MCP Server";
       auth_basic_user_file /etc/nginx/.htpasswd;
       proxy_pass http://localhost:8601/;
   }
   ```

## Files Reference

### server.py

Original stdio transport server for local MCP client integration.

### server_sse.py

SSE transport server for network access. Configured to:
- Listen on `0.0.0.0:8601`
- Disable DNS rebinding protection
- Allow all hosts and origins

### requirements.txt

```
mcp[cli]
uvicorn
starlette
```

### Systemd Service File

Location: `/home/ward/.config/systemd/user/gemini-mcp-server.service`

```ini
[Unit]
Description=Gemini CLI MCP Server (SSE)
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/ward/MCP/gemini_mcp_server
ExecStart=/home/ward/MCP/gemini_mcp_server/venv/bin/python server_sse.py
Restart=always
RestartSec=5
Environment=MCP_SERVER_HOST=0.0.0.0
Environment=MCP_SERVER_PORT=8601

[Install]
WantedBy=default.target
```

## Deployment & Management Commands

### Quick Reference

```bash
# Start the server
systemctl --user start gemini-mcp-server

# Stop the server
systemctl --user stop gemini-mcp-server

# Restart the server
systemctl --user restart gemini-mcp-server

# Check server status
systemctl --user status gemini-mcp-server

# View live logs
journalctl --user -u gemini-mcp-server -f

# View last 50 log entries
journalctl --user -u gemini-mcp-server -n 50

# Enable auto-start on boot
systemctl --user enable gemini-mcp-server

# Disable auto-start on boot
systemctl --user disable gemini-mcp-server

# Reload service configuration after changes
systemctl --user daemon-reload
```

### Health Check Commands

```bash
# Verify server is listening
ss -tlnp | grep 8601

# Test SSE endpoint
curl -I http://localhost:8601/sse

# Test from remote host
curl -I http://<server-ip>:8601/sse
```

### Process Management

```bash
# Find server process
pgrep -f "server_sse.py"

# Get process details
ps aux | grep server_sse.py

# Force kill if unresponsive
pkill -f "server_sse.py"

# Check port usage
lsof -i :8601
```

### Log Analysis

```bash
# View all logs
journalctl --user -u gemini-mcp-server --no-pager

# Filter by time
journalctl --user -u gemini-mcp-server --since "1 hour ago"

# Export logs to file
journalctl --user -u gemini-mcp-server > /tmp/gemini-mcp-server.log
```

### Service Configuration

```bash
# Edit service file
nano ~/.config/systemd/user/gemini-mcp-server.service

# After editing, reload and restart
systemctl --user daemon-reload
systemctl --user restart gemini-mcp-server
```

## Port Registration

This service is registered in the system port log (`~/.claude/PORT-LOG.md`):

| Port | Service | Description |
|------|---------|-------------|
| 8601 | MCP SSE | Gemini CLI MCP Server with SSE transport |

## Comparison with Claude Code MCP Server

| Feature | Claude Code MCP Server | Gemini CLI MCP Server |
|---------|------------------------|------------------------|
| Port | 8600 | 8601 |
| CLI Tool | `claude` | `gemini` |
| Primary Tool | `run_claude` | `run_gemini` |
| Auto-Approve Flag | `--dangerously-skip-permissions` | `-y` (yolo mode) |
| Session Support | No | Yes (`gemini_resume`, `gemini_list_sessions`) |
| Extensions | No | Yes (`gemini_list_extensions`) |
| Transport | stdio, SSE | stdio, SSE |

## License

MIT License

## Author

Created with Claude Code

## Changelog

### v1.1.0 (2025-12-10)

- Enhanced `run_gemini` with new parameters:
  - `output_format`: Choose between text, json, or stream-json
  - `debug`: Enable verbose debug output
  - `include_directories`: Include additional directories in context
- Added new tools based on official documentation:
  - `gemini_delete_session`: Delete sessions by index
  - `gemini_json`: Get structured JSON output
  - `gemini_with_context`: Include files/directories using @ syntax
  - `gemini_shell`: Execute shell commands with ! syntax
  - `gemini_chat_save`: Save chat sessions
  - `gemini_help`: Get CLI help information
- Now supports 12 MCP tools total
- Improved error handling and validation

### v1.0.0 (2025-12-10)

- Initial release
- stdio and SSE transport support
- Gemini CLI integration with `run_gemini` tool
- Session management with `gemini_resume` and `gemini_list_sessions` tools
- Extension listing with `gemini_list_extensions` tool
- Version info with `gemini_version` tool
- ANSI code stripping
- Comprehensive documentation
- Systemd service template