ai-cli-mcp 2.0.0 → 2.1.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.
@@ -12,7 +12,8 @@
12
12
  "mcp__ccm__get_claude_result",
13
13
  "mcp__chat__agent_communication_list_rooms",
14
14
  "mcp__chat__agent_communication_get_messages",
15
- "mcp__ccm__list_claude_processes"
15
+ "mcp__ccm__list_claude_processes",
16
+ "Bash(gemini:*)"
16
17
  ],
17
18
  "deny": []
18
19
  }
package/README.md CHANGED
@@ -1,13 +1,11 @@
1
1
  # AI CLI MCP Server
2
2
 
3
- <img src="assets/claude_code_mcp_logo.png" alt="AI CLI MCP Logo">
4
-
5
3
  [![npm package](https://img.shields.io/npm/v/ai-cli-mcp)](https://www.npmjs.com/package/ai-cli-mcp)
6
4
  [![View changelog](https://img.shields.io/badge/Explore%20Changelog-brightgreen)](/CHANGELOG.md)
7
5
 
8
6
  > **📦 Package Migration Notice**: This package was formerly `@mkxultra/claude-code-mcp` and has been renamed to `ai-cli-mcp` to reflect its expanded support for multiple AI CLI tools.
9
7
 
10
- An MCP (Model Context Protocol) server that allows running AI CLI tools (Claude and Codex) in background processes with automatic permission handling.
8
+ An MCP (Model Context Protocol) server that allows running AI CLI tools (Claude, Codex, and Gemini) in background processes with automatic permission handling.
11
9
 
12
10
  Did you notice that Cursor sometimes struggles with complex, multi-step edits or operations? This server, with its powerful unified `run` tool, enables multiple AI agents to handle your coding tasks more effectively.
13
11
 
@@ -19,7 +17,8 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
19
17
 
20
18
  - Run Claude CLI with all permissions bypassed (using `--dangerously-skip-permissions`)
21
19
  - Execute Codex CLI with automatic approval mode (using `--full-auto`)
22
- - Support multiple AI models: Claude (sonnet, opus, haiku) and Codex (gpt-5-low, gpt-5-medium, gpt-5-high)
20
+ - Execute Gemini CLI with automatic approval mode (using `-y`)
21
+ - Support multiple AI models: Claude (sonnet, opus, haiku), Codex (gpt-5-low, gpt-5-medium, gpt-5-high), and Gemini (gemini-2.5-pro, gemini-2.5-flash)
23
22
  - Manage background processes with PID tracking
24
23
  - Parse and return structured outputs from both tools
25
24
 
@@ -31,13 +30,12 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
31
30
  - Claude has wider system access and can do things that Cursor/Windsurf can't do (or believe they can't), so whenever they are stuck just ask them "use claude code" and it will usually un-stuck them.
32
31
  - Agents in Agents rules.
33
32
 
34
- <img src="assets/agents_in_agents_meme.jpg" alt="Agents in Agents Meme">
35
-
36
33
  ## Prerequisites
37
34
 
38
35
  - Node.js v20 or later (Use fnm or nvm to install)
39
36
  - Claude CLI installed locally (run it and call /doctor) and `--dangerously-skip-permissions` accepted
40
37
  - Codex CLI installed (optional, for Codex support)
38
+ - Gemini CLI installed (optional, for Gemini support)
41
39
 
42
40
  ## Configuration
43
41
 
@@ -45,9 +43,10 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
45
43
 
46
44
  - `CLAUDE_CLI_NAME`: Override the Claude CLI binary name or provide an absolute path (default: `claude`)
47
45
  - `CODEX_CLI_NAME`: Override the Codex CLI binary name or provide an absolute path (default: `codex`)
46
+ - `GEMINI_CLI_NAME`: Override the Gemini CLI binary name or provide an absolute path (default: `gemini`)
48
47
  - `MCP_CLAUDE_DEBUG`: Enable debug logging (set to `true` for verbose output)
49
48
 
50
- Both CLI name variables support:
49
+ All CLI name variables support:
51
50
  - Simple name: `CLAUDE_CLI_NAME=claude-custom` or `CODEX_CLI_NAME=codex-v2`
52
51
  - Absolute path: `CLAUDE_CLI_NAME=/path/to/custom/claude`
53
52
 
@@ -112,7 +111,15 @@ Follow the prompts to accept. Once this is done, the MCP server will be able to
112
111
  codex login
113
112
  ```
114
113
 
115
- macOS might ask for folder permissions the first time either tool runs. If the first run fails, subsequent runs should work.
114
+ ### For Gemini CLI:
115
+
116
+ **For Gemini, ensure you're logged in and have configured your credentials:**
117
+
118
+ ```bash
119
+ gemini auth login
120
+ ```
121
+
122
+ macOS might ask for folder permissions the first time any of these tools run. If the first run fails, subsequent runs should work.
116
123
 
117
124
  ## Connecting to Your MCP Client
118
125
 
@@ -155,6 +162,7 @@ Executes a prompt using either Claude CLI or Codex CLI. The appropriate CLI is a
155
162
  - `model` (string, optional): The model to use:
156
163
  - Claude models: "sonnet", "opus", "haiku"
157
164
  - Codex models: "gpt-5-low", "gpt-5-medium", "gpt-5-high"
165
+ - Gemini models: "gemini-2.5-pro", "gemini-2.5-flash"
158
166
  - `session_id` (string, optional): Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus.
159
167
 
160
168
  ### `list_processes`
@@ -199,6 +207,18 @@ Terminates a running AI agent process by PID.
199
207
  }
200
208
  ```
201
209
 
210
+ **Example with Gemini:**
211
+ ```json
212
+ {
213
+ "toolName": "run",
214
+ "arguments": {
215
+ "prompt": "Generate unit tests for the Calculator class",
216
+ "workFolder": "/Users/username/my_project",
217
+ "model": "gemini-2.5-pro"
218
+ }
219
+ }
220
+ ```
221
+
202
222
  ### Examples
203
223
 
204
224
  Here are some visual examples of the server in action:
@@ -308,6 +328,31 @@ npm run test:coverage
308
328
 
309
329
  For detailed testing documentation, see our [E2E Testing Guide](./docs/e2e-testing.md).
310
330
 
331
+ ## Manual Testing with MCP Inspector
332
+
333
+ You can manually test the MCP server using the Model Context Protocol Inspector:
334
+
335
+ ```bash
336
+ # Build the project first
337
+ npm run build
338
+
339
+ # Start the MCP Inspector with the server
340
+ npx @modelcontextprotocol/inspector node dist/server.js
341
+ ```
342
+
343
+ This will open a web interface where you can:
344
+ 1. View all available tools (`run`, `list_processes`, `get_result`, `kill_process`)
345
+ 2. Test each tool with different parameters
346
+ 3. Test different AI models including:
347
+ - Claude models: `sonnet`, `opus`, `haiku`
348
+ - Codex models: `gpt-5-low`, `gpt-5-medium`, `gpt-5-high`
349
+ - Gemini models: `gemini-2.5-pro`, `gemini-2.5-flash`
350
+
351
+ Example test: Select the `run` tool and provide:
352
+ - `prompt`: "What is 2+2?"
353
+ - `workFolder`: "/tmp"
354
+ - `model`: "gemini-2.5-flash"
355
+
311
356
  ## Configuration via Environment Variables
312
357
 
313
358
  The server's behavior can be customized using these environment variables:
package/dist/parsers.js CHANGED
@@ -52,3 +52,17 @@ export function parseClaudeOutput(stdout) {
52
52
  return null;
53
53
  }
54
54
  }
55
+ /**
56
+ * Parse Gemini JSON output
57
+ */
58
+ export function parseGeminiOutput(stdout) {
59
+ if (!stdout)
60
+ return null;
61
+ try {
62
+ return JSON.parse(stdout);
63
+ }
64
+ catch (e) {
65
+ debugLog(`[Debug] Failed to parse Gemini JSON output: ${e}`);
66
+ return null;
67
+ }
68
+ }
package/dist/server.js CHANGED
@@ -7,9 +7,9 @@ import { existsSync, readFileSync } from 'node:fs';
7
7
  import { homedir } from 'node:os';
8
8
  import { join, resolve as pathResolve } from 'node:path';
9
9
  import * as path from 'path';
10
- import { parseCodexOutput, parseClaudeOutput } from './parsers.js';
10
+ import { parseCodexOutput, parseClaudeOutput, parseGeminiOutput } from './parsers.js';
11
11
  // Server version - update this when releasing new versions
12
- const SERVER_VERSION = "2.0.0";
12
+ const SERVER_VERSION = "2.0.1";
13
13
  // Model alias mappings for user-friendly model names
14
14
  const MODEL_ALIASES = {
15
15
  'haiku': 'claude-3-5-haiku-20241022'
@@ -28,6 +28,42 @@ export function debugLog(message, ...optionalParams) {
28
28
  console.error(message, ...optionalParams);
29
29
  }
30
30
  }
31
+ /**
32
+ * Determine the Gemini CLI command/path.
33
+ * Similar to findClaudeCli but for Gemini
34
+ */
35
+ export function findGeminiCli() {
36
+ debugLog('[Debug] Attempting to find Gemini CLI...');
37
+ // Check for custom CLI name from environment variable
38
+ const customCliName = process.env.GEMINI_CLI_NAME;
39
+ if (customCliName) {
40
+ debugLog(`[Debug] Using custom Gemini CLI name from GEMINI_CLI_NAME: ${customCliName}`);
41
+ // If it's an absolute path, use it directly
42
+ if (path.isAbsolute(customCliName)) {
43
+ debugLog(`[Debug] GEMINI_CLI_NAME is an absolute path: ${customCliName}`);
44
+ return customCliName;
45
+ }
46
+ // If it starts with ~ or ./, reject as relative paths are not allowed
47
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
48
+ throw new Error(`Invalid GEMINI_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'gemini') or an absolute path (e.g., '/tmp/gemini-test')`);
49
+ }
50
+ }
51
+ const cliName = customCliName || 'gemini';
52
+ // Try local install path: ~/.gemini/local/gemini
53
+ const userPath = join(homedir(), '.gemini', 'local', 'gemini');
54
+ debugLog(`[Debug] Checking for Gemini CLI at local user path: ${userPath}`);
55
+ if (existsSync(userPath)) {
56
+ debugLog(`[Debug] Found Gemini CLI at local user path: ${userPath}. Using this path.`);
57
+ return userPath;
58
+ }
59
+ else {
60
+ debugLog(`[Debug] Gemini CLI not found at local user path: ${userPath}.`);
61
+ }
62
+ // Fallback to CLI name (PATH lookup)
63
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
64
+ console.warn(`[Warning] Gemini CLI not found at ~/.gemini/local/gemini. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
65
+ return cliName;
66
+ }
31
67
  /**
32
68
  * Determine the Codex CLI command/path.
33
69
  * Similar to findClaudeCli but for Codex
@@ -163,14 +199,17 @@ export class ClaudeCodeServer {
163
199
  server;
164
200
  claudeCliPath;
165
201
  codexCliPath;
202
+ geminiCliPath;
166
203
  sigintHandler;
167
204
  packageVersion;
168
205
  constructor() {
169
206
  // Use the simplified findClaudeCli function
170
207
  this.claudeCliPath = findClaudeCli(); // Removed debugMode argument
171
208
  this.codexCliPath = findCodexCli();
209
+ this.geminiCliPath = findGeminiCli();
172
210
  console.error(`[Setup] Using Claude CLI command/path: ${this.claudeCliPath}`);
173
211
  console.error(`[Setup] Using Codex CLI command/path: ${this.codexCliPath}`);
212
+ console.error(`[Setup] Using Gemini CLI command/path: ${this.geminiCliPath}`);
174
213
  this.packageVersion = SERVER_VERSION;
175
214
  this.server = new Server({
176
215
  name: 'ai_cli_mcp',
@@ -197,7 +236,7 @@ export class ClaudeCodeServer {
197
236
  tools: [
198
237
  {
199
238
  name: 'run',
200
- description: `AI Agent Runner: Starts a Claude or Codex CLI process in the background and returns a PID immediately. Use list_processes and get_result to monitor progress.
239
+ description: `AI Agent Runner: Starts a Claude, Codex, or Gemini CLI process in the background and returns a PID immediately. Use list_processes and get_result to monitor progress.
201
240
 
202
241
  • File ops: Create, read, (fuzzy) edit, move, copy, delete, list files, analyze/ocr images, file content analysis
203
242
  • Code: Generate / analyse / refactor / fix
@@ -208,8 +247,8 @@ export class ClaudeCodeServer {
208
247
 
209
248
  **IMPORTANT**: This tool now returns immediately with a PID. Use other tools to check status and get results.
210
249
 
211
- **Supported models**:
212
- "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high"
250
+ **Supported models**:
251
+ "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high", "gemini-2.5-pro", "gemini-2.5-flash"
213
252
 
214
253
  **Prompt input**: You must provide EITHER prompt (string) OR prompt_file (file path), but not both.
215
254
 
@@ -223,11 +262,6 @@ export class ClaudeCodeServer {
223
262
  inputSchema: {
224
263
  type: 'object',
225
264
  properties: {
226
- agent: {
227
- type: 'string',
228
- description: 'The agent to use: "claude" or "codex". Defaults to "claude".',
229
- enum: ['claude', 'codex'],
230
- },
231
265
  prompt: {
232
266
  type: 'string',
233
267
  description: 'The detailed natural language prompt for the agent to execute. Either this or prompt_file is required.',
@@ -242,7 +276,7 @@ export class ClaudeCodeServer {
242
276
  },
243
277
  model: {
244
278
  type: 'string',
245
- description: 'The model to use: "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high".',
279
+ description: 'The model to use: "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high", "gemini-2.5-pro", "gemini-2.5-flash".',
246
280
  },
247
281
  session_id: {
248
282
  type: 'string',
@@ -360,7 +394,16 @@ export class ClaudeCodeServer {
360
394
  }
361
395
  // Determine which agent to use based on model name
362
396
  const model = toolArguments.model || '';
363
- const agent = model.startsWith('gpt-') ? 'codex' : 'claude';
397
+ let agent;
398
+ if (model.startsWith('gpt-')) {
399
+ agent = 'codex';
400
+ }
401
+ else if (model.startsWith('gemini')) {
402
+ agent = 'gemini';
403
+ }
404
+ else {
405
+ agent = 'claude';
406
+ }
364
407
  let cliPath;
365
408
  let processArgs;
366
409
  if (agent === 'codex') {
@@ -378,6 +421,17 @@ export class ClaudeCodeServer {
378
421
  }
379
422
  processArgs.push('--full-auto', '--json', prompt);
380
423
  }
424
+ else if (agent === 'gemini') {
425
+ // Handle Gemini
426
+ cliPath = this.geminiCliPath;
427
+ processArgs = ['-y', '--output-format', 'json'];
428
+ // Add model if specified
429
+ if (toolArguments.model) {
430
+ processArgs.push('--model', toolArguments.model);
431
+ }
432
+ // Add prompt as positional argument
433
+ processArgs.push(prompt);
434
+ }
381
435
  else {
382
436
  // Handle Claude (default)
383
437
  cliPath = this.claudeCliPath;
@@ -515,6 +569,9 @@ export class ClaudeCodeServer {
515
569
  else if (process.toolType === 'claude') {
516
570
  agentOutput = parseClaudeOutput(process.stdout);
517
571
  }
572
+ else if (process.toolType === 'gemini') {
573
+ agentOutput = parseGeminiOutput(process.stdout);
574
+ }
518
575
  }
519
576
  // Construct response with agent's output and process metadata
520
577
  const response = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-cli-mcp",
3
- "version": "2.0.0",
4
- "description": "MCP server for AI CLI tools (Claude and Codex) with background process management",
3
+ "version": "2.1.0",
4
+ "description": "MCP server for AI CLI tools (Claude, Codex, and Gemini) with background process management",
5
5
  "author": "mkXultra",
6
6
  "license": "MIT",
7
7
  "main": "dist/server.js",
package/src/parsers.ts CHANGED
@@ -45,11 +45,25 @@ export function parseCodexOutput(stdout: string): any {
45
45
  */
46
46
  export function parseClaudeOutput(stdout: string): any {
47
47
  if (!stdout) return null;
48
-
48
+
49
49
  try {
50
50
  return JSON.parse(stdout);
51
51
  } catch (e) {
52
52
  debugLog(`[Debug] Failed to parse Claude JSON output: ${e}`);
53
53
  return null;
54
54
  }
55
+ }
56
+
57
+ /**
58
+ * Parse Gemini JSON output
59
+ */
60
+ export function parseGeminiOutput(stdout: string): any {
61
+ if (!stdout) return null;
62
+
63
+ try {
64
+ return JSON.parse(stdout);
65
+ } catch (e) {
66
+ debugLog(`[Debug] Failed to parse Gemini JSON output: ${e}`);
67
+ return null;
68
+ }
55
69
  }
package/src/server.ts CHANGED
@@ -13,10 +13,10 @@ import { existsSync, readFileSync } from 'node:fs';
13
13
  import { homedir } from 'node:os';
14
14
  import { join, resolve as pathResolve } from 'node:path';
15
15
  import * as path from 'path';
16
- import { parseCodexOutput, parseClaudeOutput } from './parsers.js';
16
+ import { parseCodexOutput, parseClaudeOutput, parseGeminiOutput } from './parsers.js';
17
17
 
18
18
  // Server version - update this when releasing new versions
19
- const SERVER_VERSION = "2.0.0";
19
+ const SERVER_VERSION = "2.1.0";
20
20
 
21
21
  // Model alias mappings for user-friendly model names
22
22
  const MODEL_ALIASES: Record<string, string> = {
@@ -39,7 +39,7 @@ interface ClaudeProcess {
39
39
  prompt: string;
40
40
  workFolder: string;
41
41
  model?: string;
42
- toolType: 'claude' | 'codex'; // Identify which CLI tool
42
+ toolType: 'claude' | 'codex' | 'gemini'; // Identify which CLI tool
43
43
  startTime: string;
44
44
  stdout: string;
45
45
  stderr: string;
@@ -57,6 +57,49 @@ export function debugLog(message?: any, ...optionalParams: any[]): void {
57
57
  }
58
58
  }
59
59
 
60
+ /**
61
+ * Determine the Gemini CLI command/path.
62
+ * Similar to findClaudeCli but for Gemini
63
+ */
64
+ export function findGeminiCli(): string {
65
+ debugLog('[Debug] Attempting to find Gemini CLI...');
66
+
67
+ // Check for custom CLI name from environment variable
68
+ const customCliName = process.env.GEMINI_CLI_NAME;
69
+ if (customCliName) {
70
+ debugLog(`[Debug] Using custom Gemini CLI name from GEMINI_CLI_NAME: ${customCliName}`);
71
+
72
+ // If it's an absolute path, use it directly
73
+ if (path.isAbsolute(customCliName)) {
74
+ debugLog(`[Debug] GEMINI_CLI_NAME is an absolute path: ${customCliName}`);
75
+ return customCliName;
76
+ }
77
+
78
+ // If it starts with ~ or ./, reject as relative paths are not allowed
79
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
80
+ throw new Error(`Invalid GEMINI_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'gemini') or an absolute path (e.g., '/tmp/gemini-test')`);
81
+ }
82
+ }
83
+
84
+ const cliName = customCliName || 'gemini';
85
+
86
+ // Try local install path: ~/.gemini/local/gemini
87
+ const userPath = join(homedir(), '.gemini', 'local', 'gemini');
88
+ debugLog(`[Debug] Checking for Gemini CLI at local user path: ${userPath}`);
89
+
90
+ if (existsSync(userPath)) {
91
+ debugLog(`[Debug] Found Gemini CLI at local user path: ${userPath}. Using this path.`);
92
+ return userPath;
93
+ } else {
94
+ debugLog(`[Debug] Gemini CLI not found at local user path: ${userPath}.`);
95
+ }
96
+
97
+ // Fallback to CLI name (PATH lookup)
98
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
99
+ console.warn(`[Warning] Gemini CLI not found at ~/.gemini/local/gemini. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
100
+ return cliName;
101
+ }
102
+
60
103
  /**
61
104
  * Determine the Codex CLI command/path.
62
105
  * Similar to findClaudeCli but for Codex
@@ -232,6 +275,7 @@ export class ClaudeCodeServer {
232
275
  private server: Server;
233
276
  private claudeCliPath: string;
234
277
  private codexCliPath: string;
278
+ private geminiCliPath: string;
235
279
  private sigintHandler?: () => Promise<void>;
236
280
  private packageVersion: string;
237
281
 
@@ -239,8 +283,10 @@ export class ClaudeCodeServer {
239
283
  // Use the simplified findClaudeCli function
240
284
  this.claudeCliPath = findClaudeCli(); // Removed debugMode argument
241
285
  this.codexCliPath = findCodexCli();
286
+ this.geminiCliPath = findGeminiCli();
242
287
  console.error(`[Setup] Using Claude CLI command/path: ${this.claudeCliPath}`);
243
288
  console.error(`[Setup] Using Codex CLI command/path: ${this.codexCliPath}`);
289
+ console.error(`[Setup] Using Gemini CLI command/path: ${this.geminiCliPath}`);
244
290
  this.packageVersion = SERVER_VERSION;
245
291
 
246
292
  this.server = new Server(
@@ -274,7 +320,7 @@ export class ClaudeCodeServer {
274
320
  tools: [
275
321
  {
276
322
  name: 'run',
277
- description: `AI Agent Runner: Starts a Claude or Codex CLI process in the background and returns a PID immediately. Use list_processes and get_result to monitor progress.
323
+ description: `AI Agent Runner: Starts a Claude, Codex, or Gemini CLI process in the background and returns a PID immediately. Use list_processes and get_result to monitor progress.
278
324
 
279
325
  • File ops: Create, read, (fuzzy) edit, move, copy, delete, list files, analyze/ocr images, file content analysis
280
326
  • Code: Generate / analyse / refactor / fix
@@ -285,8 +331,8 @@ export class ClaudeCodeServer {
285
331
 
286
332
  **IMPORTANT**: This tool now returns immediately with a PID. Use other tools to check status and get results.
287
333
 
288
- **Supported models**:
289
- "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high"
334
+ **Supported models**:
335
+ "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high", "gemini-2.5-pro", "gemini-2.5-flash"
290
336
 
291
337
  **Prompt input**: You must provide EITHER prompt (string) OR prompt_file (file path), but not both.
292
338
 
@@ -300,11 +346,6 @@ export class ClaudeCodeServer {
300
346
  inputSchema: {
301
347
  type: 'object',
302
348
  properties: {
303
- agent: {
304
- type: 'string',
305
- description: 'The agent to use: "claude" or "codex". Defaults to "claude".',
306
- enum: ['claude', 'codex'],
307
- },
308
349
  prompt: {
309
350
  type: 'string',
310
351
  description: 'The detailed natural language prompt for the agent to execute. Either this or prompt_file is required.',
@@ -319,7 +360,7 @@ export class ClaudeCodeServer {
319
360
  },
320
361
  model: {
321
362
  type: 'string',
322
- description: 'The model to use: "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high".',
363
+ description: 'The model to use: "sonnet", "opus", "haiku", "gpt-5-low", "gpt-5-medium", "gpt-5-high", "gemini-2.5-pro", "gemini-2.5-flash".',
323
364
  },
324
365
  session_id: {
325
366
  type: 'string',
@@ -449,16 +490,24 @@ export class ClaudeCodeServer {
449
490
 
450
491
  // Determine which agent to use based on model name
451
492
  const model = toolArguments.model || '';
452
- const agent = model.startsWith('gpt-') ? 'codex' : 'claude';
453
-
493
+ let agent: 'codex' | 'claude' | 'gemini';
494
+
495
+ if (model.startsWith('gpt-')) {
496
+ agent = 'codex';
497
+ } else if (model.startsWith('gemini')) {
498
+ agent = 'gemini';
499
+ } else {
500
+ agent = 'claude';
501
+ }
502
+
454
503
  let cliPath: string;
455
504
  let processArgs: string[];
456
-
505
+
457
506
  if (agent === 'codex') {
458
507
  // Handle Codex
459
508
  cliPath = this.codexCliPath;
460
509
  processArgs = ['exec'];
461
-
510
+
462
511
  // Parse model format for Codex (e.g., gpt-5-low -> model: gpt-5, effort: low)
463
512
  if (toolArguments.model) {
464
513
  // Split by "gpt-5-" to get the effort level
@@ -468,19 +517,32 @@ export class ClaudeCodeServer {
468
517
  }
469
518
  processArgs.push('--model', 'gpt-5');
470
519
  }
471
-
520
+
472
521
  processArgs.push('--full-auto', '--json', prompt);
473
-
522
+
523
+ } else if (agent === 'gemini') {
524
+ // Handle Gemini
525
+ cliPath = this.geminiCliPath;
526
+ processArgs = ['-y', '--output-format', 'json'];
527
+
528
+ // Add model if specified
529
+ if (toolArguments.model) {
530
+ processArgs.push('--model', toolArguments.model);
531
+ }
532
+
533
+ // Add prompt as positional argument
534
+ processArgs.push(prompt);
535
+
474
536
  } else {
475
537
  // Handle Claude (default)
476
538
  cliPath = this.claudeCliPath;
477
539
  processArgs = ['--dangerously-skip-permissions', '--output-format', 'json'];
478
-
540
+
479
541
  // Add session_id if provided (Claude only)
480
542
  if (toolArguments.session_id && typeof toolArguments.session_id === 'string') {
481
543
  processArgs.push('-r', toolArguments.session_id);
482
544
  }
483
-
545
+
484
546
  processArgs.push('-p', prompt);
485
547
  if (toolArguments.model && typeof toolArguments.model === 'string') {
486
548
  const resolvedModel = resolveModelAlias(toolArguments.model);
@@ -507,7 +569,7 @@ export class ClaudeCodeServer {
507
569
  prompt,
508
570
  workFolder: effectiveCwd,
509
571
  model: toolArguments.model,
510
- toolType: agent as 'claude' | 'codex',
572
+ toolType: agent,
511
573
  startTime: new Date().toISOString(),
512
574
  stdout: '',
513
575
  stderr: '',
@@ -625,6 +687,8 @@ export class ClaudeCodeServer {
625
687
  agentOutput = parseCodexOutput(process.stdout);
626
688
  } else if (process.toolType === 'claude') {
627
689
  agentOutput = parseClaudeOutput(process.stdout);
690
+ } else if (process.toolType === 'gemini') {
691
+ agentOutput = parseGeminiOutput(process.stdout);
628
692
  }
629
693
  }
630
694