@rlabs-inc/gemini-mcp 0.6.3 → 0.7.0

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.
Files changed (39) hide show
  1. package/README.md +46 -43
  2. package/dist/cli/commands/config.d.ts +8 -0
  3. package/dist/cli/commands/config.js +147 -0
  4. package/dist/cli/commands/image.d.ts +7 -0
  5. package/dist/cli/commands/image.js +133 -0
  6. package/dist/cli/commands/query.d.ts +7 -0
  7. package/dist/cli/commands/query.js +94 -0
  8. package/dist/cli/commands/research.d.ts +7 -0
  9. package/dist/cli/commands/research.js +147 -0
  10. package/dist/cli/commands/search.d.ts +7 -0
  11. package/dist/cli/commands/search.js +152 -0
  12. package/dist/cli/commands/speak.d.ts +7 -0
  13. package/dist/cli/commands/speak.js +168 -0
  14. package/dist/cli/commands/tokens.d.ts +8 -0
  15. package/dist/cli/commands/tokens.js +105 -0
  16. package/dist/cli/commands/video.d.ts +7 -0
  17. package/dist/cli/commands/video.js +154 -0
  18. package/dist/cli/config.d.ts +23 -0
  19. package/dist/cli/config.js +89 -0
  20. package/dist/cli/index.d.ts +6 -0
  21. package/dist/cli/index.js +180 -0
  22. package/dist/cli/ui/box.d.ts +20 -0
  23. package/dist/cli/ui/box.js +112 -0
  24. package/dist/cli/ui/colors.d.ts +46 -0
  25. package/dist/cli/ui/colors.js +106 -0
  26. package/dist/cli/ui/index.d.ts +21 -0
  27. package/dist/cli/ui/index.js +42 -0
  28. package/dist/cli/ui/progress.d.ts +37 -0
  29. package/dist/cli/ui/progress.js +125 -0
  30. package/dist/cli/ui/spinner.d.ts +42 -0
  31. package/dist/cli/ui/spinner.js +96 -0
  32. package/dist/cli/ui/theme.d.ts +48 -0
  33. package/dist/cli/ui/theme.js +200 -0
  34. package/dist/index.d.ts +6 -3
  35. package/dist/index.js +26 -218
  36. package/dist/server.d.ts +7 -0
  37. package/dist/server.js +221 -0
  38. package/dist/tools/deep-research.js +2 -2
  39. package/package.json +9 -3
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Theme System for Gemini CLI
3
+ *
4
+ * Provides beautiful, consistent styling across all CLI output.
5
+ * Default theme adapts to terminal colors.
6
+ */
7
+ import { cyan, magenta, green, red, yellow, blue, brightBlack, white, brightCyan, hex, dim, bold, } from './colors.js';
8
+ // Terminal theme - adapts to user's terminal colors
9
+ export const terminalTheme = {
10
+ name: 'terminal',
11
+ colors: {
12
+ primary: cyan,
13
+ secondary: magenta,
14
+ success: green,
15
+ error: red,
16
+ warning: yellow,
17
+ info: blue,
18
+ muted: brightBlack,
19
+ text: white,
20
+ highlight: brightCyan,
21
+ },
22
+ symbols: {
23
+ success: '✓',
24
+ error: '✗',
25
+ warning: '⚠',
26
+ info: 'ℹ',
27
+ spinner: ['◐', '◓', '◑', '◒'],
28
+ arrow: '→',
29
+ bullet: '•',
30
+ pointer: '❯',
31
+ star: '★',
32
+ },
33
+ box: {
34
+ topLeft: '┌',
35
+ topRight: '┐',
36
+ bottomLeft: '└',
37
+ bottomRight: '┘',
38
+ horizontal: '─',
39
+ vertical: '│',
40
+ },
41
+ };
42
+ // Neon theme - cyberpunk vibes
43
+ export const neonTheme = {
44
+ name: 'neon',
45
+ colors: {
46
+ primary: hex('#ff00ff'), // Hot pink
47
+ secondary: hex('#00ffff'), // Cyan
48
+ success: hex('#39ff14'), // Neon green
49
+ error: hex('#ff3131'), // Neon red
50
+ warning: hex('#ffff00'), // Neon yellow
51
+ info: hex('#00bfff'), // Deep sky blue
52
+ muted: hex('#666666'),
53
+ text: hex('#ffffff'),
54
+ highlight: hex('#ff6ec7'), // Pink
55
+ },
56
+ symbols: {
57
+ success: '◆',
58
+ error: '◆',
59
+ warning: '◆',
60
+ info: '◆',
61
+ spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
62
+ arrow: '▸',
63
+ bullet: '▪',
64
+ pointer: '▶',
65
+ star: '✦',
66
+ },
67
+ box: {
68
+ topLeft: '╔',
69
+ topRight: '╗',
70
+ bottomLeft: '╚',
71
+ bottomRight: '╝',
72
+ horizontal: '═',
73
+ vertical: '║',
74
+ },
75
+ };
76
+ // Minimal theme - subtle, mostly monochrome
77
+ export const minimalTheme = {
78
+ name: 'minimal',
79
+ colors: {
80
+ primary: white,
81
+ secondary: brightBlack,
82
+ success: green,
83
+ error: red,
84
+ warning: yellow,
85
+ info: brightBlack,
86
+ muted: dim,
87
+ text: white,
88
+ highlight: bold,
89
+ },
90
+ symbols: {
91
+ success: '+',
92
+ error: 'x',
93
+ warning: '!',
94
+ info: '-',
95
+ spinner: ['-', '\\', '|', '/'],
96
+ arrow: '>',
97
+ bullet: '-',
98
+ pointer: '>',
99
+ star: '*',
100
+ },
101
+ box: {
102
+ topLeft: '+',
103
+ topRight: '+',
104
+ bottomLeft: '+',
105
+ bottomRight: '+',
106
+ horizontal: '-',
107
+ vertical: '|',
108
+ },
109
+ };
110
+ // Ocean theme - blues and teals
111
+ export const oceanTheme = {
112
+ name: 'ocean',
113
+ colors: {
114
+ primary: hex('#00ced1'), // Dark turquoise
115
+ secondary: hex('#4682b4'), // Steel blue
116
+ success: hex('#20b2aa'), // Light sea green
117
+ error: hex('#ff6347'), // Tomato
118
+ warning: hex('#ffa500'), // Orange
119
+ info: hex('#87ceeb'), // Sky blue
120
+ muted: hex('#708090'), // Slate gray
121
+ text: hex('#e0ffff'), // Light cyan
122
+ highlight: hex('#00ffff'), // Aqua
123
+ },
124
+ symbols: {
125
+ success: '●',
126
+ error: '●',
127
+ warning: '●',
128
+ info: '●',
129
+ spinner: ['∙∙∙', '●∙∙', '∙●∙', '∙∙●', '∙●∙', '●∙∙'],
130
+ arrow: '➜',
131
+ bullet: '○',
132
+ pointer: '➤',
133
+ star: '✧',
134
+ },
135
+ box: {
136
+ topLeft: '╭',
137
+ topRight: '╮',
138
+ bottomLeft: '╰',
139
+ bottomRight: '╯',
140
+ horizontal: '─',
141
+ vertical: '│',
142
+ },
143
+ };
144
+ // Forest theme - greens and earth tones
145
+ export const forestTheme = {
146
+ name: 'forest',
147
+ colors: {
148
+ primary: hex('#228b22'), // Forest green
149
+ secondary: hex('#8b4513'), // Saddle brown
150
+ success: hex('#32cd32'), // Lime green
151
+ error: hex('#dc143c'), // Crimson
152
+ warning: hex('#daa520'), // Goldenrod
153
+ info: hex('#6b8e23'), // Olive drab
154
+ muted: hex('#696969'), // Dim gray
155
+ text: hex('#f5f5dc'), // Beige
156
+ highlight: hex('#98fb98'), // Pale green
157
+ },
158
+ symbols: {
159
+ success: '✓',
160
+ error: '✗',
161
+ warning: '⚡',
162
+ info: '❧',
163
+ spinner: ['🌱', '🌿', '🌳', '🌲'],
164
+ arrow: '➔',
165
+ bullet: '❀',
166
+ pointer: '➣',
167
+ star: '❁',
168
+ },
169
+ box: {
170
+ topLeft: '┏',
171
+ topRight: '┓',
172
+ bottomLeft: '┗',
173
+ bottomRight: '┛',
174
+ horizontal: '━',
175
+ vertical: '┃',
176
+ },
177
+ };
178
+ // All available themes
179
+ export const themes = {
180
+ terminal: terminalTheme,
181
+ neon: neonTheme,
182
+ minimal: minimalTheme,
183
+ ocean: oceanTheme,
184
+ forest: forestTheme,
185
+ };
186
+ // Current active theme (default to terminal)
187
+ let currentTheme = terminalTheme;
188
+ export function setTheme(themeName) {
189
+ const theme = themes[themeName];
190
+ if (theme) {
191
+ currentTheme = theme;
192
+ }
193
+ }
194
+ export function getTheme() {
195
+ return currentTheme;
196
+ }
197
+ // Convenience function to get themed colors
198
+ export function t() {
199
+ return currentTheme;
200
+ }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * MCP Server Gemini - Integrates Google's Gemini models with Claude Code
3
+ * Gemini - Dual Mode Entry Point
4
4
  *
5
- * This MCP server provides access to Gemini models for use in Claude Code.
6
- * Features include direct queries, brainstorming, and analysis tools.
5
+ * 1. MCP Server Mode (default): `gemini-mcp` or `gemini serve`
6
+ * 2. CLI Mode: `gemini <command> [options]`
7
+ *
8
+ * This integrates Google's Gemini models with Claude Code (MCP)
9
+ * and provides a beautiful standalone CLI experience.
7
10
  */
8
11
  export {};
package/dist/index.js CHANGED
@@ -1,224 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * MCP Server Gemini - Integrates Google's Gemini models with Claude Code
3
+ * Gemini - Dual Mode Entry Point
4
4
  *
5
- * This MCP server provides access to Gemini models for use in Claude Code.
6
- * Features include direct queries, brainstorming, and analysis tools.
5
+ * 1. MCP Server Mode (default): `gemini-mcp` or `gemini serve`
6
+ * 2. CLI Mode: `gemini <command> [options]`
7
+ *
8
+ * This integrates Google's Gemini models with Claude Code (MCP)
9
+ * and provides a beautiful standalone CLI experience.
7
10
  */
8
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
- import { parseArgs } from 'node:util';
11
- // Import tools
12
- import { registerQueryTool } from './tools/query.js';
13
- import { registerBrainstormTool } from './tools/brainstorm.js';
14
- import { registerAnalyzeTool } from './tools/analyze.js';
15
- import { registerSummarizeTool } from './tools/summarize.js';
16
- import { registerImageGenTool } from './tools/image-gen.js';
17
- import { registerImageEditTool } from './tools/image-edit.js';
18
- import { registerVideoGenTool } from './tools/video-gen.js';
19
- import { registerCodeExecTool } from './tools/code-exec.js';
20
- import { registerSearchTool } from './tools/search.js';
21
- import { registerStructuredTool } from './tools/structured.js';
22
- import { registerYouTubeTool } from './tools/youtube.js';
23
- import { registerDocumentTool } from './tools/document.js';
24
- import { registerUrlContextTool } from './tools/url-context.js';
25
- import { registerCacheTool } from './tools/cache.js';
26
- import { registerSpeechTool } from './tools/speech.js';
27
- import { registerTokenCountTool } from './tools/token-count.js';
28
- import { registerDeepResearchTool } from './tools/deep-research.js';
29
- // Import Gemini client and logger
30
- import { initGeminiClient } from './gemini-client.js';
31
- import { setupLogger, logger } from './utils/logger.js';
32
- // Parse command line arguments
33
- const { values } = parseArgs({
34
- options: {
35
- verbose: {
36
- type: 'boolean',
37
- short: 'v',
38
- default: false,
39
- },
40
- quiet: {
41
- type: 'boolean',
42
- short: 'q',
43
- default: false,
44
- },
45
- help: {
46
- type: 'boolean',
47
- short: 'h',
48
- default: false,
49
- },
50
- },
51
- });
52
- // Show help if requested
53
- if (values.help) {
54
- console.log(`
55
- MCP Server Gemini - Integrates Google's Gemini models with Claude Code
56
-
57
- Usage:
58
- gemini-mcp [options]
59
-
60
- Options:
61
- -v, --verbose Enable verbose logging (shows all prompts and responses)
62
- -q, --quiet Run in quiet mode (minimal logging)
63
- -h, --help Show this help message
64
-
65
- Environment Variables:
66
- GEMINI_API_KEY (required) Your Google Gemini API key
67
- VERBOSE (optional) Set to "true" to enable verbose logging
68
- QUIET (optional) Set to "true" to enable quiet mode
69
- GEMINI_MODEL (optional) Default Gemini model to use
70
- GEMINI_PRO_MODEL (optional) Specify Pro model variant
71
- GEMINI_FLASH_MODEL (optional) Specify Flash model variant
72
- `);
73
- process.exit(0);
74
- }
75
- // Configure logging mode based on command line args or environment variables
76
- let logLevel = 'normal';
77
- if (values.verbose || process.env.VERBOSE === 'true') {
78
- logLevel = 'verbose';
79
- }
80
- else if (values.quiet || process.env.QUIET === 'true') {
81
- logLevel = 'quiet';
82
- }
83
- setupLogger(logLevel);
84
- // Check for required API key
85
- if (!process.env.GEMINI_API_KEY) {
86
- logger.error('Error: GEMINI_API_KEY environment variable is required');
87
- process.exit(1);
11
+ import { runCli } from './cli/index.js';
12
+ import { startMcpServer } from './server.js';
13
+ // Get command line arguments
14
+ const args = process.argv.slice(2);
15
+ // Determine mode based on first argument
16
+ const firstArg = args[0];
17
+ // MCP server mode conditions:
18
+ // 1. No arguments (default behavior for MCP)
19
+ // 2. Explicit 'serve' command
20
+ // 3. Legacy flags that were for MCP server
21
+ const mcpServerFlags = ['--verbose', '-v', '--quiet', '-q', '--help', '-h'];
22
+ const isMcpMode = args.length === 0 ||
23
+ firstArg === 'serve' ||
24
+ (args.length === 1 && mcpServerFlags.includes(firstArg));
25
+ if (isMcpMode) {
26
+ // Start MCP server (existing behavior)
27
+ startMcpServer(args);
88
28
  }
89
- // Get model name from environment or use default
90
- // Use Gemini 3 as default (latest frontier model)
91
- const defaultModel = 'gemini-3-pro-preview';
92
- const geminiModel = process.env.GEMINI_MODEL || defaultModel;
93
- // Log model configuration for debugging
94
- logger.debug(`Model configuration:
95
- - GEMINI_MODEL: ${process.env.GEMINI_MODEL || '(not set, using default)'}
96
- - GEMINI_PRO_MODEL: ${process.env.GEMINI_PRO_MODEL || '(not set, using default)'}
97
- - GEMINI_FLASH_MODEL: ${process.env.GEMINI_FLASH_MODEL || '(not set, using default)'}`);
98
- async function main() {
99
- logger.info(`Starting MCP Gemini Server with model: ${geminiModel}`);
100
- logger.info(`Logging mode: ${logLevel}`);
101
- // Handle unexpected stdio errors
102
- process.stdin.on('error', (err) => {
103
- logger.error('STDIN error:', err);
104
- // Don't exit, just log
105
- });
106
- process.stdout.on('error', (err) => {
107
- logger.error('STDOUT error:', err);
108
- // Don't exit, just log
109
- });
110
- try {
111
- // Initialize Gemini client
112
- await initGeminiClient();
113
- // Create MCP server
114
- const server = new McpServer({
115
- name: 'Gemini',
116
- version: '0.6.3',
117
- });
118
- // Register tools
119
- registerQueryTool(server);
120
- registerBrainstormTool(server);
121
- registerAnalyzeTool(server);
122
- registerSummarizeTool(server);
123
- registerImageGenTool(server);
124
- registerImageEditTool(server);
125
- registerVideoGenTool(server);
126
- registerCodeExecTool(server);
127
- registerSearchTool(server);
128
- registerStructuredTool(server);
129
- registerYouTubeTool(server);
130
- registerDocumentTool(server);
131
- registerUrlContextTool(server);
132
- registerCacheTool(server);
133
- registerSpeechTool(server);
134
- registerTokenCountTool(server);
135
- registerDeepResearchTool(server);
136
- // Start server with stdio transport with enhanced error handling
137
- const transport = new StdioServerTransport();
138
- // Set up error handling for transport with improved error recovery
139
- transport.onclose = () => {
140
- logger.warn('MCP transport connection closed');
141
- logger.debug('Connection closed event triggered');
142
- // Attempt to recover connection after brief delay with backoff strategy
143
- let reconnectAttempts = 0;
144
- const maxReconnectAttempts = 5;
145
- const attemptReconnect = () => {
146
- if (reconnectAttempts >= maxReconnectAttempts) {
147
- logger.error(`Failed to reconnect after ${maxReconnectAttempts} attempts`);
148
- return;
149
- }
150
- reconnectAttempts++;
151
- const delay = Math.min(1000 * Math.pow(1.5, reconnectAttempts - 1), 10000);
152
- logger.info(`Attempting to reconnect (${reconnectAttempts}/${maxReconnectAttempts}) after ${delay}ms...`);
153
- setTimeout(() => {
154
- try {
155
- // Check if stdin/stdout are still available
156
- if (process.stdin.destroyed || process.stdout.destroyed) {
157
- logger.error('Cannot reconnect: stdin or stdout is destroyed');
158
- return;
159
- }
160
- server.connect(transport)
161
- .then(() => {
162
- logger.info('Successfully reconnected to MCP transport');
163
- reconnectAttempts = 0;
164
- })
165
- .catch(e => {
166
- logger.error('Reconnection failed:', e);
167
- attemptReconnect(); // Try again with backoff
168
- });
169
- }
170
- catch (e) {
171
- logger.error('Error during reconnection attempt:', e);
172
- attemptReconnect(); // Try again with backoff
173
- }
174
- }, delay);
175
- };
176
- attemptReconnect();
177
- };
178
- transport.onerror = (error) => {
179
- logger.error('MCP transport error:', error);
180
- // Log detailed error information for debugging
181
- if (error instanceof Error) {
182
- logger.debug(`Error name: ${error.name}, message: ${error.message}`);
183
- logger.debug(`Stack trace: ${error.stack}`);
184
- }
185
- };
186
- // Set up error handling for the connection with more diagnostics
187
- try {
188
- // Log environment diagnostic info before connecting
189
- logger.debug(`Process details - PID: ${process.pid}, Node version: ${process.version}`);
190
- logger.debug(`Environment variables: API_KEY=${process.env.GEMINI_API_KEY ? 'SET' : 'NOT_SET'}, VERBOSE=${process.env.VERBOSE || 'not set'}`);
191
- logger.debug(`Process stdin/stdout state - isTTY: ${process.stdin.isTTY}, ${process.stdout.isTTY}`);
192
- await server.connect(transport);
193
- logger.info('MCP Gemini Server running');
194
- }
195
- catch (err) {
196
- logger.error('Failed to connect MCP server transport:', err);
197
- // More detailed error logging
198
- if (err instanceof Error) {
199
- logger.debug(`Error stack: ${err.stack}`);
200
- logger.debug(`Error details: name=${err.name}, message=${err.message}`);
201
- }
202
- else {
203
- logger.debug(`Non-Error object thrown: ${JSON.stringify(err)}`);
204
- }
205
- logger.warn('Server will attempt to continue running despite connection error');
206
- }
207
- // Handle process termination
208
- process.on('SIGINT', async () => {
209
- logger.info('Shutting down MCP Gemini Server');
210
- await server.close();
211
- process.exit(0);
212
- });
213
- process.on('SIGTERM', async () => {
214
- logger.info('Shutting down MCP Gemini Server');
215
- await server.close();
216
- process.exit(0);
217
- });
218
- }
219
- catch (error) {
220
- logger.error('Failed to start MCP Gemini Server:', error);
221
- process.exit(1);
222
- }
29
+ else {
30
+ // Run CLI
31
+ runCli(args);
223
32
  }
224
- main();
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP Server for Gemini
3
+ *
4
+ * Provides Gemini models as MCP tools for Claude Code integration.
5
+ * This is the original MCP server functionality, now modularized.
6
+ */
7
+ export declare function startMcpServer(argv: string[]): Promise<void>;