An MCP (Model Context Protocol) server that wraps the Gemini CLI, exposing it over both stdio and SSE (Server-Sent Events) transports.
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
- 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.0for external access - Session Management: Resume previous sessions, list sessions
- Extension Support: List available Gemini CLI extensions
- YOLO Mode: Auto-approve actions for automated use
┌─────────────────────────────────────────────────────────────┐
│ 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] │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
/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
-
Gemini CLI: Ensure
geminiis installed and in your PATH.npm install -g @google/gemini-cli
-
Authentication: You must be authenticated with Google/Gemini.
gemini # Follow the authentication prompts -
Python: Python 3.10 or higher.
# 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())"# 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| 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) |
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
For direct MCP client integration (same machine):
python server.pyMCP Client Configuration:
{
"mcpServers": {
"gemini-cli": {
"command": "python",
"args": ["/home/ward/MCP/gemini_mcp_server/server.py"]
}
}
}For remote network access:
Manual Start:
cd /home/ward/MCP/gemini_mcp_server
source venv/bin/activate
python server_sse.pyBackground Start:
venv/bin/python server_sse.py > /tmp/gemini-mcp.log 2>&1 &The SSE server can be configured as a systemd user service for automatic startup.
Create the 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
EOFService Management:
# 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| Endpoint | Method | Description |
|---|---|---|
/sse |
GET | SSE connection endpoint for MCP clients |
/messages/ |
POST | Message posting endpoint |
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:
{
"tool": "run_gemini",
"arguments": {
"prompt": "What is 2 + 2?",
"model": "gemini-2.5-flash",
"output_format": "text"
}
}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:
{
"tool": "gemini_resume",
"arguments": {
"session": "latest",
"prompt": "Continue from where we left off"
}
}List available Gemini CLI sessions for the current project.
Parameters: None
Returns: String listing available sessions.
Example:
{
"tool": "gemini_list_sessions",
"arguments": {}
}List all available Gemini CLI extensions.
Parameters: None
Returns: String listing installed extensions.
Example:
{
"tool": "gemini_list_extensions",
"arguments": {}
}Get the Gemini CLI version information.
Parameters: None
Returns: String containing version information (e.g., "0.20.0").
Example:
{
"tool": "gemini_version",
"arguments": {}
}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:
{
"tool": "gemini_delete_session",
"arguments": {
"session_index": "1"
}
}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:
{
"tool": "gemini_json",
"arguments": {
"prompt": "List 3 programming languages as JSON array"
}
}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:
{
"tool": "gemini_with_context",
"arguments": {
"prompt": "Explain this code",
"files": "src/main.py,src/utils.py"
}
}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:
{
"tool": "gemini_shell",
"arguments": {
"command": "ls -la"
}
}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:
{
"tool": "gemini_chat_save",
"arguments": {
"name": "my-session"
}
}Get Gemini CLI help information and available commands.
Parameters: None
Returns: String containing CLI help output.
Example:
{
"tool": "gemini_help",
"arguments": {}
}| 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 |
Use this for network access or when the server runs as a systemd service.
Claude Desktop / Claude Code:
{
"mcpServers": {
"gemini-cli": {
"url": "http://localhost:8601/sse",
"transport": "sse"
}
}
}Remote Server Access:
{
"mcpServers": {
"gemini-cli": {
"url": "http://192.168.1.100:8601/sse",
"transport": "sse"
}
}
}Cline (VS Code Extension):
{
"mcpServers": {
"gemini-cli": {
"url": "http://localhost:8601/sse",
"transport": "sse"
}
}
}Use this for local-only access without running a persistent service.
Claude Desktop (with venv):
{
"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):
{
"mcpServers": {
"gemini-cli": {
"command": "python3",
"args": ["/home/ward/MCP/gemini_mcp_server/server.py"],
"cwd": "/home/ward/MCP/gemini_mcp_server"
}
}
}With Environment Variables:
{
"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"
}
}
}
}Create a .mcp.json file in your project root:
{
"mcpServers": {
"gemini-cli": {
"url": "http://localhost:8601/sse",
"transport": "sse"
}
}
}Full Claude Desktop config with multiple MCP servers:
{
"mcpServers": {
"gemini-cli": {
"url": "http://localhost:8601/sse",
"transport": "sse"
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"]
}
}
}Claude Code settings.json:
{
"mcpServers": {
"gemini-cli": {
"url": "http://localhost:8601/sse",
"transport": "sse"
}
}
}After adding the configuration, verify the MCP server is accessible:
# 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-streamRestart your MCP client (Claude Desktop, Claude Code, etc.) after updating the configuration.
-
Check if port is in use:
ss -tlnp | grep 8601 -
Kill existing process:
lsof -i :8601 | awk 'NR>1 {print $2}' | xargs kill
-
Check logs:
journalctl --user -u gemini-mcp-server -n 50
-
Verify server is running:
systemctl --user status gemini-mcp-server
-
Check firewall:
sudo ufw status sudo ufw allow 8601/tcp
-
Test locally:
curl -I http://localhost:8601/
-
Verify CLI is installed:
which gemini gemini --version
-
Test CLI directly:
gemini "Hello" -o text -y
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
-
Firewall rules:
# Allow only specific IPs sudo ufw allow from 192.168.1.0/24 to any port 8601 -
Reverse proxy with auth (nginx example):
location /mcp/ { auth_basic "MCP Server"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://localhost:8601/; }
Original stdio transport server for local MCP client integration.
SSE transport server for network access. Configured to:
- Listen on
0.0.0.0:8601 - Disable DNS rebinding protection
- Allow all hosts and origins
mcp[cli]
uvicorn
starlette
Location: /home/ward/.config/systemd/user/gemini-mcp-server.service
[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# 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# 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# 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# 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# 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-serverThis 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 |
| 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 |
MIT License
Created with Claude Code
- Enhanced
run_geminiwith new parameters:output_format: Choose between text, json, or stream-jsondebug: Enable verbose debug outputinclude_directories: Include additional directories in context
- Added new tools based on official documentation:
gemini_delete_session: Delete sessions by indexgemini_json: Get structured JSON outputgemini_with_context: Include files/directories using @ syntaxgemini_shell: Execute shell commands with ! syntaxgemini_chat_save: Save chat sessionsgemini_help: Get CLI help information
- Now supports 12 MCP tools total
- Improved error handling and validation
- Initial release
- stdio and SSE transport support
- Gemini CLI integration with
run_geminitool - Session management with
gemini_resumeandgemini_list_sessionstools - Extension listing with
gemini_list_extensionstool - Version info with
gemini_versiontool - ANSI code stripping
- Comprehensive documentation
- Systemd service template