├── requirements.txt ├── .gitignore ├── LICENSE ├── install.sh ├── EXAMPLES.md ├── setup.sh ├── README.md └── server.py /requirements.txt: -------------------------------------------------------------------------------- 1 | google-generativeai>=0.8.5 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | env/ 8 | venv/ 9 | .env 10 | 11 | # IDE 12 | .vscode/ 13 | .idea/ 14 | *.swp 15 | *.swo 16 | 17 | # OS 18 | .DS_Store 19 | Thumbs.db 20 | 21 | # Project specific 22 | *.log 23 | .claude/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Rai Ansar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # One-line installer for Claude-Gemini MCP Server 3 | 4 | set -e 5 | 6 | # Colors 7 | GREEN='\033[0;32m' 8 | RED='\033[0;31m' 9 | BLUE='\033[0;34m' 10 | NC='\033[0m' 11 | 12 | echo -e "${BLUE}🚀 Claude-Gemini MCP Server Installer${NC}" 13 | echo "" 14 | 15 | # Check requirements 16 | if ! command -v python3 &> /dev/null; then 17 | echo -e "${RED}❌ Python 3 is required. Please install it first.${NC}" 18 | exit 1 19 | fi 20 | 21 | if ! command -v claude &> /dev/null; then 22 | echo -e "${RED}❌ Claude Code CLI not found. Please install it first:${NC}" 23 | echo "npm install -g @anthropic-ai/claude-code" 24 | exit 1 25 | fi 26 | 27 | # Clone the repository 28 | echo "📥 Downloading Claude-Gemini MCP Server..." 29 | TEMP_DIR=$(mktemp -d) 30 | cd "$TEMP_DIR" 31 | git clone https://github.com/RaiAnsar/claude_code-gemini-mcp.git 32 | 33 | # Get API key 34 | echo "" 35 | echo "🔑 Please enter your Gemini API key:" 36 | echo " (Get one free at https://aistudio.google.com/apikey)" 37 | read -p "API Key: " API_KEY 38 | 39 | if [ -z "$API_KEY" ]; then 40 | echo -e "${RED}❌ API key is required${NC}" 41 | rm -rf "$TEMP_DIR" 42 | exit 1 43 | fi 44 | 45 | # Run setup 46 | cd claude_code-gemini-mcp 47 | chmod +x setup.sh 48 | ./setup.sh "$API_KEY" 49 | 50 | # Cleanup 51 | cd ~ 52 | rm -rf "$TEMP_DIR" 53 | 54 | echo "" 55 | echo -e "${GREEN}✨ Installation complete!${NC}" -------------------------------------------------------------------------------- /EXAMPLES.md: -------------------------------------------------------------------------------- 1 | # Claude-Gemini MCP Usage Examples 2 | 3 | ## Basic Conversation 4 | 5 | ```bash 6 | # Start Claude Code 7 | claude 8 | 9 | # Ask Gemini a simple question 10 | mcp__gemini-collab__ask_gemini 11 | prompt: "What is the capital of France?" 12 | 13 | # Gemini responds directly in Claude's context! 14 | ``` 15 | 16 | ## Code Review Example 17 | 18 | ```bash 19 | # Have Gemini review your authentication code 20 | mcp__gemini-collab__gemini_code_review 21 | code: | 22 | def authenticate(username, password): 23 | if username == "admin" and password == "password123": 24 | return True 25 | return False 26 | focus: "security" 27 | 28 | # Gemini will point out security issues like: 29 | # - Hardcoded credentials 30 | # - Plain text password 31 | # - No hashing 32 | # - etc. 33 | ``` 34 | 35 | ## Brainstorming Session 36 | 37 | ```bash 38 | # Brainstorm startup ideas 39 | mcp__gemini-collab__gemini_brainstorm 40 | topic: "AI-powered tools for developers" 41 | context: "Looking for B2B SaaS ideas that solve real developer pain points" 42 | 43 | # Gemini provides creative suggestions 44 | ``` 45 | 46 | ## Advanced: Collaborative Problem Solving 47 | 48 | ```bash 49 | # Claude writes code 50 | > Write a Python function to calculate fibonacci numbers 51 | 52 | # Claude creates the function... 53 | 54 | # Then get Gemini's optimization suggestions 55 | mcp__gemini-collab__gemini_code_review 56 | code: "[paste Claude's code here]" 57 | focus: "performance" 58 | 59 | # Claude can then incorporate Gemini's feedback! 60 | ``` 61 | 62 | ## Temperature Control 63 | 64 | ```bash 65 | # Low temperature (0.2) for factual, consistent responses 66 | mcp__gemini-collab__ask_gemini 67 | prompt: "Explain the HTTP protocol" 68 | temperature: 0.2 69 | 70 | # High temperature (0.8) for creative responses 71 | mcp__gemini-collab__ask_gemini 72 | prompt: "Write a haiku about debugging" 73 | temperature: 0.8 74 | ``` 75 | 76 | ## Real-World Workflow 77 | 78 | 1. **Claude writes initial code** 79 | 2. **Gemini reviews for security/performance** 80 | 3. **Claude implements improvements** 81 | 4. **Both AIs brainstorm edge cases** 82 | 5. **Final optimized solution!** 83 | 84 | This creates a powerful AI pair programming experience where both models complement each other's strengths. -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Easy setup script for Claude-Gemini MCP Server 3 | 4 | set -e 5 | 6 | # Colors for output 7 | GREEN='\033[0;32m' 8 | RED='\033[0;31m' 9 | BLUE='\033[0;34m' 10 | NC='\033[0m' # No Color 11 | 12 | echo -e "${BLUE}🚀 Claude-Gemini MCP Server Setup${NC}" 13 | echo "" 14 | 15 | # Check if API key was provided 16 | API_KEY="$1" 17 | if [ -z "$API_KEY" ]; then 18 | echo -e "${RED}❌ Please provide your Gemini API key${NC}" 19 | echo "Usage: ./setup.sh YOUR_GEMINI_API_KEY" 20 | echo "" 21 | echo "Get a free API key at: https://aistudio.google.com/apikey" 22 | exit 1 23 | fi 24 | 25 | # Check Python version 26 | echo "📋 Checking requirements..." 27 | if ! command -v python3 &> /dev/null; then 28 | echo -e "${RED}❌ Python 3 is required but not installed.${NC}" 29 | exit 1 30 | fi 31 | 32 | PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') 33 | echo "✅ Python $PYTHON_VERSION found" 34 | 35 | # Check Claude Code 36 | if ! command -v claude &> /dev/null; then 37 | echo -e "${RED}❌ Claude Code CLI not found. Please install it first:${NC}" 38 | echo "npm install -g @anthropic-ai/claude-code" 39 | exit 1 40 | fi 41 | echo "✅ Claude Code CLI found" 42 | 43 | # Create directory 44 | echo "" 45 | echo "📁 Creating MCP server directory..." 46 | mkdir -p ~/.claude-mcp-servers/gemini-collab 47 | 48 | # Copy server file 49 | echo "📋 Installing server..." 50 | cp server.py ~/.claude-mcp-servers/gemini-collab/ 51 | 52 | # Replace API key in server 53 | sed -i.bak "s/YOUR_API_KEY_HERE/$API_KEY/g" ~/.claude-mcp-servers/gemini-collab/server.py 54 | rm ~/.claude-mcp-servers/gemini-collab/server.py.bak 55 | 56 | # Install Python dependencies 57 | echo "" 58 | echo "📦 Installing Python dependencies..." 59 | pip3 install google-generativeai --quiet 60 | 61 | # Remove any existing MCP configuration 62 | echo "" 63 | echo "🔧 Configuring Claude Code..." 64 | claude mcp remove gemini-collab 2>/dev/null || true 65 | 66 | # Add MCP server with global scope 67 | claude mcp add --scope user gemini-collab python3 ~/.claude-mcp-servers/gemini-collab/server.py 68 | 69 | echo "" 70 | echo -e "${GREEN}✅ Setup complete!${NC}" 71 | echo "" 72 | echo "🎉 You can now use Gemini in Claude Code from any directory!" 73 | echo "" 74 | echo "Try it out:" 75 | echo " 1. Run: claude" 76 | echo " 2. Type: /mcp (should show gemini-collab connected)" 77 | echo " 3. Use: mcp__gemini-collab__ask_gemini" 78 | echo " prompt: \"Hello Gemini!\"" 79 | echo "" 80 | echo "Available tools:" 81 | echo " • mcp__gemini-collab__ask_gemini" 82 | echo " • mcp__gemini-collab__gemini_code_review" 83 | echo " • mcp__gemini-collab__gemini_brainstorm" 84 | echo "" 85 | echo "Enjoy! 🚀" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Claude Code + Gemini MCP Server 2 | 3 | Connect Claude Code with Google's Gemini AI for powerful AI collaboration. Ask Gemini questions, get code reviews, and brainstorm ideas - all within Claude Code! 4 | 5 | ## 🚀 Quick Start (2 minutes) 6 | 7 | ### Prerequisites 8 | - Python 3.8+ installed 9 | - Claude Code CLI installed 10 | - Google Gemini API key ([Get one free](https://aistudio.google.com/apikey)) 11 | 12 | ### One-Line Install 13 | 14 | ```bash 15 | curl -sSL https://raw.githubusercontent.com/RaiAnsar/claude_code-gemini-mcp/main/install.sh | bash 16 | ``` 17 | 18 | ### Manual Install 19 | 20 | 1. **Clone this repo:** 21 | ```bash 22 | git clone https://github.com/RaiAnsar/claude_code-gemini-mcp.git 23 | cd claude_code-gemini-mcp 24 | ``` 25 | 26 | 2. **Run setup with your API key:** 27 | ```bash 28 | ./setup.sh YOUR_GEMINI_API_KEY 29 | ``` 30 | 31 | That's it! 🎉 32 | 33 | ## 📖 Usage 34 | 35 | Start Claude Code anywhere and use these commands: 36 | 37 | ```bash 38 | claude 39 | 40 | # Ask Gemini anything 41 | 42 | mcp__gemini-collab__ask_gemini 43 | prompt: "Explain quantum computing in simple terms" 44 | 45 | # Get code reviews 46 | mcp__gemini-collab__gemini_code_review 47 | code: "def auth(u): return u.pwd == 'admin'" 48 | focus: "security" 49 | 50 | # Brainstorm ideas 51 | mcp__gemini-collab__gemini_brainstorm 52 | topic: "How to scale a web app to 1M users" 53 | 54 | Or simply ask claude code to correlate with Gemini, it is not a rocket sciene... (Author's note) 55 | ``` 56 | 57 | ## 🛠️ What This Does 58 | 59 | 1. Installs the Google Gemini Python SDK 60 | 2. Sets up an MCP server that bridges Claude Code and Gemini 61 | 3. Configures it globally (works in any directory) 62 | 4. Provides tools for collaboration between Claude and Gemini 63 | 64 | ## 🔧 Available Tools 65 | 66 | - **ask_gemini** - Ask Gemini any question 67 | - **gemini_code_review** - Get security/performance code reviews 68 | - **gemini_brainstorm** - Brainstorm ideas and solutions 69 | 70 | ## 📁 Installation Location 71 | 72 | The server is installed at: `~/.claude-mcp-servers/gemini-collab/` 73 | 74 | ## 🐛 Troubleshooting 75 | 76 | **MCP not showing up?** 77 | ```bash 78 | # Check if it's installed 79 | claude mcp list 80 | 81 | # Reinstall with global scope 82 | claude mcp remove gemini-collab 83 | claude mcp add --scope user gemini-collab python3 ~/.claude-mcp-servers/gemini-collab/server.py 84 | ``` 85 | 86 | **Connection errors?** 87 | - Check your API key is valid 88 | - Ensure Python has `google-generativeai` installed: `pip install google-generativeai` 89 | 90 | ## 🔑 Update API Key 91 | 92 | Edit `~/.claude-mcp-servers/gemini-collab/server.py` and replace the API key. 93 | 94 | ## 🤝 Contributing 95 | 96 | Pull requests welcome! Please keep it simple and beginner-friendly. 97 | 98 | ## 📜 License 99 | 100 | MIT - Use freely! 101 | 102 | --- 103 | 104 | Made with ❤️ for the Claude Code community 105 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Claude-Gemini MCP Server 4 | Enables Claude Code to collaborate with Google's Gemini AI 5 | """ 6 | 7 | import json 8 | import sys 9 | import os 10 | from typing import Dict, Any, Optional 11 | 12 | # Ensure unbuffered output 13 | sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1) 14 | sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 1) 15 | 16 | # Server version 17 | __version__ = "1.0.0" 18 | 19 | # Initialize Gemini 20 | try: 21 | import google.generativeai as genai 22 | 23 | # Get API key from environment or use the one provided during setup 24 | API_KEY = os.environ.get("GEMINI_API_KEY", "YOUR_API_KEY_HERE") 25 | if API_KEY == "YOUR_API_KEY_HERE": 26 | print(json.dumps({ 27 | "jsonrpc": "2.0", 28 | "error": { 29 | "code": -32603, 30 | "message": "Please set your Gemini API key in the server.py file or GEMINI_API_KEY environment variable" 31 | } 32 | }), file=sys.stdout, flush=True) 33 | sys.exit(1) 34 | 35 | genai.configure(api_key=API_KEY) 36 | model = genai.GenerativeModel('gemini-2.0-flash') 37 | GEMINI_AVAILABLE = True 38 | except Exception as e: 39 | GEMINI_AVAILABLE = False 40 | GEMINI_ERROR = str(e) 41 | 42 | def send_response(response: Dict[str, Any]): 43 | """Send a JSON-RPC response""" 44 | print(json.dumps(response), flush=True) 45 | 46 | def handle_initialize(request_id: Any) -> Dict[str, Any]: 47 | """Handle initialization""" 48 | return { 49 | "jsonrpc": "2.0", 50 | "id": request_id, 51 | "result": { 52 | "protocolVersion": "2024-11-05", 53 | "capabilities": { 54 | "tools": {} 55 | }, 56 | "serverInfo": { 57 | "name": "claude-gemini-mcp", 58 | "version": __version__ 59 | } 60 | } 61 | } 62 | 63 | def handle_tools_list(request_id: Any) -> Dict[str, Any]: 64 | """List available tools""" 65 | tools = [] 66 | 67 | if GEMINI_AVAILABLE: 68 | tools = [ 69 | { 70 | "name": "ask_gemini", 71 | "description": "Ask Gemini a question and get the response directly in Claude's context", 72 | "inputSchema": { 73 | "type": "object", 74 | "properties": { 75 | "prompt": { 76 | "type": "string", 77 | "description": "The question or prompt for Gemini" 78 | }, 79 | "temperature": { 80 | "type": "number", 81 | "description": "Temperature for response (0.0-1.0)", 82 | "default": 0.5 83 | } 84 | }, 85 | "required": ["prompt"] 86 | } 87 | }, 88 | { 89 | "name": "gemini_code_review", 90 | "description": "Have Gemini review code and return feedback directly to Claude", 91 | "inputSchema": { 92 | "type": "object", 93 | "properties": { 94 | "code": { 95 | "type": "string", 96 | "description": "The code to review" 97 | }, 98 | "focus": { 99 | "type": "string", 100 | "description": "Specific focus area (security, performance, etc.)", 101 | "default": "general" 102 | } 103 | }, 104 | "required": ["code"] 105 | } 106 | }, 107 | { 108 | "name": "gemini_brainstorm", 109 | "description": "Brainstorm solutions with Gemini, response visible to Claude", 110 | "inputSchema": { 111 | "type": "object", 112 | "properties": { 113 | "topic": { 114 | "type": "string", 115 | "description": "The topic to brainstorm about" 116 | }, 117 | "context": { 118 | "type": "string", 119 | "description": "Additional context", 120 | "default": "" 121 | } 122 | }, 123 | "required": ["topic"] 124 | } 125 | } 126 | ] 127 | else: 128 | tools = [ 129 | { 130 | "name": "server_info", 131 | "description": "Get server status and error information", 132 | "inputSchema": { 133 | "type": "object", 134 | "properties": {} 135 | } 136 | } 137 | ] 138 | 139 | return { 140 | "jsonrpc": "2.0", 141 | "id": request_id, 142 | "result": { 143 | "tools": tools 144 | } 145 | } 146 | 147 | def call_gemini(prompt: str, temperature: float = 0.5) -> str: 148 | """Call Gemini and return response""" 149 | try: 150 | response = model.generate_content( 151 | prompt, 152 | generation_config=genai.GenerationConfig( 153 | temperature=temperature, 154 | max_output_tokens=8192, 155 | ) 156 | ) 157 | return response.text 158 | except Exception as e: 159 | return f"Error calling Gemini: {str(e)}" 160 | 161 | def handle_tool_call(request_id: Any, params: Dict[str, Any]) -> Dict[str, Any]: 162 | """Handle tool execution""" 163 | tool_name = params.get("name") 164 | arguments = params.get("arguments", {}) 165 | 166 | try: 167 | result = "" 168 | 169 | if tool_name == "server_info": 170 | if GEMINI_AVAILABLE: 171 | result = f"Server v{__version__} - Gemini connected and ready!" 172 | else: 173 | result = f"Server v{__version__} - Gemini error: {GEMINI_ERROR}" 174 | 175 | elif tool_name == "ask_gemini": 176 | if not GEMINI_AVAILABLE: 177 | result = f"Gemini not available: {GEMINI_ERROR}" 178 | else: 179 | prompt = arguments.get("prompt", "") 180 | temperature = arguments.get("temperature", 0.5) 181 | result = call_gemini(prompt, temperature) 182 | 183 | elif tool_name == "gemini_code_review": 184 | if not GEMINI_AVAILABLE: 185 | result = f"Gemini not available: {GEMINI_ERROR}" 186 | else: 187 | code = arguments.get("code", "") 188 | focus = arguments.get("focus", "general") 189 | prompt = f"""Please review this code with a focus on {focus}: 190 | 191 | ``` 192 | {code} 193 | ``` 194 | 195 | Provide specific, actionable feedback on: 196 | 1. Potential issues or bugs 197 | 2. Security concerns 198 | 3. Performance optimizations 199 | 4. Best practices 200 | 5. Code clarity and maintainability""" 201 | result = call_gemini(prompt, 0.2) 202 | 203 | elif tool_name == "gemini_brainstorm": 204 | if not GEMINI_AVAILABLE: 205 | result = f"Gemini not available: {GEMINI_ERROR}" 206 | else: 207 | topic = arguments.get("topic", "") 208 | context = arguments.get("context", "") 209 | prompt = f"Let's brainstorm about: {topic}" 210 | if context: 211 | prompt += f"\n\nContext: {context}" 212 | prompt += "\n\nProvide creative ideas, alternatives, and considerations." 213 | result = call_gemini(prompt, 0.7) 214 | 215 | else: 216 | raise ValueError(f"Unknown tool: {tool_name}") 217 | 218 | return { 219 | "jsonrpc": "2.0", 220 | "id": request_id, 221 | "result": { 222 | "content": [ 223 | { 224 | "type": "text", 225 | "text": f"🤖 GEMINI RESPONSE:\n\n{result}" 226 | } 227 | ] 228 | } 229 | } 230 | except Exception as e: 231 | return { 232 | "jsonrpc": "2.0", 233 | "id": request_id, 234 | "error": { 235 | "code": -32603, 236 | "message": str(e) 237 | } 238 | } 239 | 240 | def main(): 241 | """Main server loop""" 242 | while True: 243 | try: 244 | line = sys.stdin.readline() 245 | if not line: 246 | break 247 | 248 | request = json.loads(line.strip()) 249 | method = request.get("method") 250 | request_id = request.get("id") 251 | params = request.get("params", {}) 252 | 253 | if method == "initialize": 254 | response = handle_initialize(request_id) 255 | elif method == "tools/list": 256 | response = handle_tools_list(request_id) 257 | elif method == "tools/call": 258 | response = handle_tool_call(request_id, params) 259 | else: 260 | response = { 261 | "jsonrpc": "2.0", 262 | "id": request_id, 263 | "error": { 264 | "code": -32601, 265 | "message": f"Method not found: {method}" 266 | } 267 | } 268 | 269 | send_response(response) 270 | 271 | except json.JSONDecodeError: 272 | continue 273 | except EOFError: 274 | break 275 | except Exception as e: 276 | if 'request_id' in locals(): 277 | send_response({ 278 | "jsonrpc": "2.0", 279 | "id": request_id, 280 | "error": { 281 | "code": -32603, 282 | "message": f"Internal error: {str(e)}" 283 | } 284 | }) 285 | 286 | if __name__ == "__main__": 287 | main() --------------------------------------------------------------------------------