gemini-bridge 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.4
2
+ Name: gemini-bridge
3
+ Version: 1.0.0
4
+ Summary: Lightweight MCP server bridging Claude Code to Google's Gemini AI via official CLI
5
+ Author-email: Shelakh <info@shelakh.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/shelakh/gemini-bridge
8
+ Project-URL: Repository, https://github.com/shelakh/gemini-bridge
9
+ Project-URL: Issues, https://github.com/shelakh/gemini-bridge/issues
10
+ Keywords: mcp,gemini,ai,coding,assistant
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: mcp>=1.0.0
23
+ Dynamic: license-file
24
+
25
+ # Gemini Bridge
26
+
27
+ ![PyPI Version](https://img.shields.io/pypi/v/gemini-bridge)
28
+ ![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)
29
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)
30
+ ![MCP Compatible](https://img.shields.io/badge/MCP-compatible-green.svg)
31
+ ![CI Status](https://github.com/shelakh/gemini-bridge/actions/workflows/ci.yml/badge.svg)
32
+
33
+ A lightweight MCP (Model Context Protocol) server that enables Claude Code to interact with Google's Gemini AI through the official CLI. Designed for simplicity, reliability, and seamless integration.
34
+
35
+ ## ✨ Features
36
+
37
+ - **Direct Gemini CLI Integration**: Zero API costs using official Gemini CLI
38
+ - **Simple MCP Tools**: Two core functions for basic queries and file analysis
39
+ - **Stateless Operation**: No sessions, caching, or complex state management
40
+ - **Production Ready**: Robust error handling with configurable 60-second timeouts
41
+ - **Minimal Dependencies**: Only requires `mcp>=1.0.0` and Gemini CLI
42
+ - **Easy Deployment**: Support for both uvx and traditional pip installation
43
+
44
+ ## 🚀 Quick Start
45
+
46
+ ### Prerequisites
47
+
48
+ 1. **Install Gemini CLI**:
49
+ ```bash
50
+ npm install -g @google/gemini-cli
51
+ ```
52
+
53
+ 2. **Authenticate with Gemini**:
54
+ ```bash
55
+ gemini auth login
56
+ ```
57
+
58
+ 3. **Verify installation**:
59
+ ```bash
60
+ gemini --version
61
+ ```
62
+
63
+ ### Installation
64
+
65
+ **🎯 Recommended: PyPI Installation**
66
+ ```bash
67
+ # Install from PyPI
68
+ pip install gemini-bridge
69
+
70
+ # Add to Claude Code with uvx (recommended)
71
+ claude mcp add gemini-bridge -s user -- uvx gemini-bridge
72
+ ```
73
+
74
+ **Alternative: From Source**
75
+ ```bash
76
+ # Clone the repository
77
+ git clone https://github.com/shelakh/gemini-bridge.git
78
+ cd gemini-bridge
79
+
80
+ # Build and install locally
81
+ uvx --from build pyproject-build
82
+ pip install dist/*.whl
83
+
84
+ # Add to Claude Code
85
+ claude mcp add gemini-bridge -s user -- uvx gemini-bridge
86
+ ```
87
+
88
+ **Development Installation**
89
+ ```bash
90
+ # Clone and install in development mode
91
+ git clone https://github.com/shelakh/gemini-bridge.git
92
+ cd gemini-bridge
93
+ pip install -e .
94
+
95
+ # Add to Claude Code (development)
96
+ claude mcp add gemini-bridge-dev -s user -- python -m src
97
+ ```
98
+
99
+ ## 🛠️ Available Tools
100
+
101
+ ### `consult_gemini`
102
+ Direct CLI bridge for simple queries.
103
+
104
+ **Parameters:**
105
+ - `query` (string): The question or prompt to send to Gemini
106
+ - `directory` (string): Working directory for the query (default: current directory)
107
+ - `model` (string, optional): Model to use - "flash" or "pro" (default: "flash")
108
+
109
+ **Example:**
110
+ ```python
111
+ consult_gemini(
112
+ query="Find authentication patterns in this codebase",
113
+ directory="/path/to/project",
114
+ model="flash"
115
+ )
116
+ ```
117
+
118
+ ### `consult_gemini_with_files`
119
+ CLI bridge with file attachments for detailed analysis.
120
+
121
+ **Parameters:**
122
+ - `query` (string): The question or prompt to send to Gemini
123
+ - `directory` (string): Working directory for the query
124
+ - `files` (list): List of file paths relative to the directory
125
+ - `model` (string, optional): Model to use - "flash" or "pro" (default: "flash")
126
+
127
+ **Example:**
128
+ ```python
129
+ consult_gemini_with_files(
130
+ query="Analyze these auth files and suggest improvements",
131
+ directory="/path/to/project",
132
+ files=["src/auth.py", "src/models.py"],
133
+ model="pro"
134
+ )
135
+ ```
136
+
137
+ ## 📋 Usage Examples
138
+
139
+ ### Basic Code Analysis
140
+ ```python
141
+ # Simple research query
142
+ consult_gemini(
143
+ query="What authentication patterns are used in this project?",
144
+ directory="/Users/dev/my-project"
145
+ )
146
+ ```
147
+
148
+ ### Detailed File Review
149
+ ```python
150
+ # Analyze specific files
151
+ consult_gemini_with_files(
152
+ query="Review these files and suggest security improvements",
153
+ directory="/Users/dev/my-project",
154
+ files=["src/auth.py", "src/middleware.py"],
155
+ model="pro"
156
+ )
157
+ ```
158
+
159
+ ### Multi-file Analysis
160
+ ```python
161
+ # Compare multiple implementation files
162
+ consult_gemini_with_files(
163
+ query="Compare these database implementations and recommend the best approach",
164
+ directory="/Users/dev/my-project",
165
+ files=["src/db/postgres.py", "src/db/sqlite.py", "src/db/redis.py"]
166
+ )
167
+ ```
168
+
169
+ ## 🏗️ Architecture
170
+
171
+ ### Core Design
172
+ - **CLI-First**: Direct subprocess calls to `gemini` command
173
+ - **Stateless**: Each tool call is independent with no session state
174
+ - **Fixed Timeout**: 60-second maximum execution time
175
+ - **Simple Error Handling**: Clear error messages with fail-fast approach
176
+
177
+ ### Project Structure
178
+ ```
179
+ gemini-bridge/
180
+ ├── src/
181
+ │ ├── __init__.py # Entry point
182
+ │ ├── __main__.py # Module execution entry point
183
+ │ └── mcp_server.py # Main MCP server implementation
184
+ ├── .github/ # GitHub templates and workflows
185
+ ├── start_server_uvx.sh # Production startup script
186
+ ├── start_server_dev.sh # Development startup script
187
+ ├── pyproject.toml # Python package configuration
188
+ ├── README.md # This file
189
+ ├── CONTRIBUTING.md # Contribution guidelines
190
+ ├── CODE_OF_CONDUCT.md # Community standards
191
+ ├── SECURITY.md # Security policies
192
+ ├── CHANGELOG.md # Version history
193
+ └── LICENSE # MIT license
194
+ ```
195
+
196
+ ## 🔧 Development
197
+
198
+ ### Local Testing
199
+ ```bash
200
+ # Install in development mode
201
+ pip install -e .
202
+
203
+ # Run directly
204
+ python -m src
205
+
206
+ # Test CLI availability
207
+ gemini --version
208
+ ```
209
+
210
+ ### Integration with Claude Code
211
+ The server automatically integrates with Claude Code when properly configured through the MCP protocol.
212
+
213
+ ## 🔍 Troubleshooting
214
+
215
+ ### CLI Not Available
216
+ ```bash
217
+ # Install Gemini CLI
218
+ npm install -g @google/gemini-cli
219
+
220
+ # Authenticate
221
+ gemini auth login
222
+
223
+ # Test
224
+ gemini --version
225
+ ```
226
+
227
+ ### Connection Issues
228
+ - Verify Gemini CLI is properly authenticated
229
+ - Check network connectivity
230
+ - Ensure Claude Code MCP configuration is correct
231
+ - Check that the `gemini` command is in your PATH
232
+
233
+ ### Common Error Messages
234
+ - **"CLI not available"**: Gemini CLI is not installed or not in PATH
235
+ - **"Authentication required"**: Run `gemini auth login`
236
+ - **"Timeout after 60 seconds"**: Query took too long, try breaking it into smaller parts
237
+
238
+ ## 🤝 Contributing
239
+
240
+ We welcome contributions from the community! Please read our [Contributing Guidelines](CONTRIBUTING.md) for details on how to get started.
241
+
242
+ ### Quick Contributing Guide
243
+ 1. Fork the repository
244
+ 2. Create a feature branch
245
+ 3. Make your changes
246
+ 4. Add tests if applicable
247
+ 5. Submit a pull request
248
+
249
+ ## 📄 License
250
+
251
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
252
+
253
+ ## 🔄 Version History
254
+
255
+ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
256
+
257
+ ## 🆘 Support
258
+
259
+ - **Issues**: Report bugs or request features via [GitHub Issues](https://github.com/shelakh/gemini-bridge/issues)
260
+ - **Discussions**: Join the community discussion
261
+ - **Documentation**: Additional docs available in the `docs/` directory
262
+
263
+ ---
264
+
265
+ **Focus**: A simple, reliable bridge between Claude Code and Gemini AI through the official CLI.
@@ -0,0 +1,9 @@
1
+ gemini_bridge-1.0.0.dist-info/licenses/LICENSE,sha256=yTz_R8ocWu64Eubxr6vdZCKRS0dB_Pi3RbjUNn4qPxQ,1063
2
+ src/__init__.py,sha256=FYM7cJkOKgimwO1wUNk3wgQPKz6_Kn8kuYQR6IR_e9k,190
3
+ src/__main__.py,sha256=12FoIYCXYYKu2_BYX1GS_h9E9qO41Q26B8zedRIDPBs,149
4
+ src/mcp_server.py,sha256=SGdrmNMvpCvJseSvvMlBGvDS71RkwWS7yM4JnSPg_Yg,6871
5
+ gemini_bridge-1.0.0.dist-info/METADATA,sha256=B7tBEvl0NmOdeXZ9k1jtQYJPModC0DRNXO0JQj6x8sY,7962
6
+ gemini_bridge-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ gemini_bridge-1.0.0.dist-info/entry_points.txt,sha256=ygWf0B23Gygq8mW_GzPx8rxIA19RR_RH4RG2I15lU3E,43
8
+ gemini_bridge-1.0.0.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
9
+ gemini_bridge-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ gemini-bridge = src:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Shelakh
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.
@@ -0,0 +1 @@
1
+ src
src/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ """
2
+ MCP Gemini Assistant - Simple CLI bridge to Gemini AI.
3
+ Version 1.0.0 - Production ready, radically simplified.
4
+ """
5
+
6
+ from .mcp_server import main
7
+
8
+ __version__ = "1.0.0"
9
+ __all__ = ["main"]
src/__main__.py ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python3
2
+ """Entry point for running the MCP server as a module."""
3
+
4
+ from .mcp_server import main
5
+
6
+ if __name__ == "__main__":
7
+ main()
src/mcp_server.py ADDED
@@ -0,0 +1,215 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Gemini MCP Server - Simple CLI Bridge
4
+ Version 1.0.0
5
+ A minimal MCP server to interface with Gemini AI via the gemini CLI.
6
+ Created by @shelakh/elyin
7
+ """
8
+
9
+ import os
10
+ import shutil
11
+ import subprocess
12
+ from typing import List, Optional
13
+
14
+ from mcp.server.fastmcp import FastMCP
15
+
16
+ mcp = FastMCP("gemini-assistant")
17
+
18
+
19
+ def _normalize_model_name(model: Optional[str]) -> str:
20
+ """
21
+ Normalize user-provided model identifiers to canonical Gemini CLI model names.
22
+ Defaults to gemini-2.5-flash when not provided or unrecognized.
23
+
24
+ Accepted forms:
25
+ - "flash", "2.5-flash", "gemini-2.5-flash"
26
+ - "pro", "2.5-pro", "gemini-2.5-pro"
27
+ """
28
+ if not model:
29
+ return "gemini-2.5-flash"
30
+ value = model.strip().lower()
31
+ # Common short aliases
32
+ if value in {"flash", "2.5-flash", "gemini-2.5-flash"}:
33
+ return "gemini-2.5-flash"
34
+ if value in {"pro", "2.5-pro", "gemini-2.5-pro"}:
35
+ return "gemini-2.5-pro"
36
+ # If the caller passed a full model name, keep it
37
+ if value.startswith("gemini-"):
38
+ return value
39
+ # Fallback to flash for anything else
40
+ return "gemini-2.5-flash"
41
+
42
+
43
+ def execute_gemini_simple(query: str, directory: str = ".", model: Optional[str] = None) -> str:
44
+ """
45
+ Execute gemini CLI command for simple queries without file attachments.
46
+
47
+ Args:
48
+ query: The prompt to send to Gemini
49
+ directory: Working directory for the command
50
+ model: Optional model name (flash, pro, etc.)
51
+
52
+ Returns:
53
+ CLI output or error message
54
+ """
55
+ # Check if gemini CLI is available
56
+ if not shutil.which("gemini"):
57
+ return "Error: Gemini CLI not found. Install with: npm install -g @google/gemini-cli"
58
+
59
+ # Validate directory
60
+ if not os.path.isdir(directory):
61
+ return f"Error: Directory does not exist: {directory}"
62
+
63
+ # Build command - use stdin for input to avoid hanging
64
+ selected_model = _normalize_model_name(model)
65
+ cmd = ["gemini", "-m", selected_model]
66
+
67
+ # Execute CLI command - simple timeout, no retries
68
+ try:
69
+ result = subprocess.run(
70
+ cmd,
71
+ cwd=directory,
72
+ capture_output=True,
73
+ text=True,
74
+ timeout=60,
75
+ input=query
76
+ )
77
+
78
+ if result.returncode == 0:
79
+ return result.stdout.strip() if result.stdout.strip() else "No output from Gemini CLI"
80
+ else:
81
+ return f"Gemini CLI Error: {result.stderr.strip()}"
82
+
83
+ except subprocess.TimeoutExpired:
84
+ return "Error: Gemini CLI command timed out after 60 seconds"
85
+ except Exception as e:
86
+ return f"Error executing Gemini CLI: {str(e)}"
87
+
88
+
89
+ def execute_gemini_with_files(query: str, directory: str = ".", files: Optional[List[str]] = None, model: Optional[str] = None) -> str:
90
+ """
91
+ Execute gemini CLI command with file attachments.
92
+
93
+ Args:
94
+ query: The prompt to send to Gemini
95
+ directory: Working directory for the command
96
+ files: List of file paths to attach (relative to directory)
97
+ model: Optional model name (flash, pro, etc.)
98
+
99
+ Returns:
100
+ CLI output or error message
101
+ """
102
+ # Check if gemini CLI is available
103
+ if not shutil.which("gemini"):
104
+ return "Error: Gemini CLI not found. Install with: npm install -g @google/gemini-cli"
105
+
106
+ # Validate directory
107
+ if not os.path.isdir(directory):
108
+ return f"Error: Directory does not exist: {directory}"
109
+
110
+ # Validate files parameter
111
+ if not files:
112
+ return "Error: No files provided for file attachment mode"
113
+
114
+ # Build command - use stdin for input to avoid hanging
115
+ selected_model = _normalize_model_name(model)
116
+ cmd = ["gemini", "-m", selected_model]
117
+
118
+ # Read and concatenate file contents
119
+ file_contents = []
120
+ for file_path in files:
121
+ try:
122
+ # Convert relative paths to absolute based on directory
123
+ if not os.path.isabs(file_path):
124
+ file_path = os.path.join(directory, file_path)
125
+
126
+ if os.path.isfile(file_path):
127
+ with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
128
+ content = f.read()
129
+ file_contents.append(f"=== {os.path.basename(file_path)} ===\n{content}")
130
+ else:
131
+ file_contents.append(f"=== {os.path.basename(file_path)} ===\n[File not found]")
132
+ except Exception as e:
133
+ file_contents.append(f"=== {os.path.basename(file_path)} ===\n[Error reading file: {str(e)}]")
134
+
135
+ # Combine file contents with query
136
+ stdin_content = "\n\n".join(file_contents) + "\n\n" + query
137
+
138
+ # Execute CLI command - simple timeout, no retries
139
+ try:
140
+ result = subprocess.run(
141
+ cmd,
142
+ cwd=directory,
143
+ capture_output=True,
144
+ text=True,
145
+ timeout=60,
146
+ input=stdin_content
147
+ )
148
+
149
+ if result.returncode == 0:
150
+ return result.stdout.strip() if result.stdout.strip() else "No output from Gemini CLI"
151
+ else:
152
+ return f"Gemini CLI Error: {result.stderr.strip()}"
153
+
154
+ except subprocess.TimeoutExpired:
155
+ return "Error: Gemini CLI command timed out after 60 seconds"
156
+ except Exception as e:
157
+ return f"Error executing Gemini CLI: {str(e)}"
158
+
159
+
160
+ @mcp.tool()
161
+ def consult_gemini(
162
+ query: str,
163
+ directory: str,
164
+ model: Optional[str] = None
165
+ ) -> str:
166
+ """
167
+ Send a query directly to Gemini CLI.
168
+
169
+ This is the core function - a direct bridge between Claude and Gemini.
170
+ No caching, no sessions, no complexity. Just execute and return.
171
+
172
+ Args:
173
+ query: The question or prompt to send to Gemini
174
+ directory: Working directory (required)
175
+ model: Optional model name (flash, pro, etc.)
176
+
177
+ Returns:
178
+ Gemini's response
179
+ """
180
+ return execute_gemini_simple(query, directory, model)
181
+
182
+
183
+ @mcp.tool()
184
+ def consult_gemini_with_files(
185
+ query: str,
186
+ directory: str,
187
+ files: Optional[List[str]] = None,
188
+ model: Optional[str] = None
189
+ ) -> str:
190
+ """
191
+ Send a query to Gemini CLI with file attachments.
192
+
193
+ Files are read and concatenated into the prompt. Simple and direct.
194
+
195
+ Args:
196
+ query: The question or prompt to send to Gemini
197
+ directory: Working directory (required)
198
+ files: List of file paths to attach (relative to directory)
199
+ model: Optional model name (flash, pro, etc.)
200
+
201
+ Returns:
202
+ Gemini's response with file context
203
+ """
204
+ if not files:
205
+ return "Error: files parameter is required for consult_gemini_with_files"
206
+ return execute_gemini_with_files(query, directory, files, model)
207
+
208
+
209
+ def main():
210
+ """Entry point for the MCP server."""
211
+ mcp.run()
212
+
213
+
214
+ if __name__ == "__main__":
215
+ main()