# 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