ai-cli-mcp 2.0.1 → 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.
- package/.claude/settings.local.json +2 -1
- package/README.md +53 -4
- package/dist/parsers.js +14 -0
- package/dist/server.js +68 -6
- package/package.json +2 -2
- package/src/parsers.ts +15 -1
- package/src/server.ts +85 -16
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
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.
|
|
7
7
|
|
|
8
|
-
An MCP (Model Context Protocol) server that allows running AI CLI tools (Claude and
|
|
8
|
+
An MCP (Model Context Protocol) server that allows running AI CLI tools (Claude, Codex, and Gemini) in background processes with automatic permission handling.
|
|
9
9
|
|
|
10
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.
|
|
11
11
|
|
|
@@ -17,7 +17,8 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
|
|
|
17
17
|
|
|
18
18
|
- Run Claude CLI with all permissions bypassed (using `--dangerously-skip-permissions`)
|
|
19
19
|
- Execute Codex CLI with automatic approval mode (using `--full-auto`)
|
|
20
|
-
-
|
|
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)
|
|
21
22
|
- Manage background processes with PID tracking
|
|
22
23
|
- Parse and return structured outputs from both tools
|
|
23
24
|
|
|
@@ -34,6 +35,7 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
|
|
|
34
35
|
- Node.js v20 or later (Use fnm or nvm to install)
|
|
35
36
|
- Claude CLI installed locally (run it and call /doctor) and `--dangerously-skip-permissions` accepted
|
|
36
37
|
- Codex CLI installed (optional, for Codex support)
|
|
38
|
+
- Gemini CLI installed (optional, for Gemini support)
|
|
37
39
|
|
|
38
40
|
## Configuration
|
|
39
41
|
|
|
@@ -41,9 +43,10 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
|
|
|
41
43
|
|
|
42
44
|
- `CLAUDE_CLI_NAME`: Override the Claude CLI binary name or provide an absolute path (default: `claude`)
|
|
43
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`)
|
|
44
47
|
- `MCP_CLAUDE_DEBUG`: Enable debug logging (set to `true` for verbose output)
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
All CLI name variables support:
|
|
47
50
|
- Simple name: `CLAUDE_CLI_NAME=claude-custom` or `CODEX_CLI_NAME=codex-v2`
|
|
48
51
|
- Absolute path: `CLAUDE_CLI_NAME=/path/to/custom/claude`
|
|
49
52
|
|
|
@@ -108,7 +111,15 @@ Follow the prompts to accept. Once this is done, the MCP server will be able to
|
|
|
108
111
|
codex login
|
|
109
112
|
```
|
|
110
113
|
|
|
111
|
-
|
|
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.
|
|
112
123
|
|
|
113
124
|
## Connecting to Your MCP Client
|
|
114
125
|
|
|
@@ -151,6 +162,7 @@ Executes a prompt using either Claude CLI or Codex CLI. The appropriate CLI is a
|
|
|
151
162
|
- `model` (string, optional): The model to use:
|
|
152
163
|
- Claude models: "sonnet", "opus", "haiku"
|
|
153
164
|
- Codex models: "gpt-5-low", "gpt-5-medium", "gpt-5-high"
|
|
165
|
+
- Gemini models: "gemini-2.5-pro", "gemini-2.5-flash"
|
|
154
166
|
- `session_id` (string, optional): Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus.
|
|
155
167
|
|
|
156
168
|
### `list_processes`
|
|
@@ -195,6 +207,18 @@ Terminates a running AI agent process by PID.
|
|
|
195
207
|
}
|
|
196
208
|
```
|
|
197
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
|
+
|
|
198
222
|
### Examples
|
|
199
223
|
|
|
200
224
|
Here are some visual examples of the server in action:
|
|
@@ -304,6 +328,31 @@ npm run test:coverage
|
|
|
304
328
|
|
|
305
329
|
For detailed testing documentation, see our [E2E Testing Guide](./docs/e2e-testing.md).
|
|
306
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
|
+
|
|
307
356
|
## Configuration via Environment Variables
|
|
308
357
|
|
|
309
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,7 +7,7 @@ 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
12
|
const SERVER_VERSION = "2.0.1";
|
|
13
13
|
// Model alias mappings for user-friendly model names
|
|
@@ -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
|
|
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
|
|
|
@@ -237,7 +276,7 @@ export class ClaudeCodeServer {
|
|
|
237
276
|
},
|
|
238
277
|
model: {
|
|
239
278
|
type: 'string',
|
|
240
|
-
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".',
|
|
241
280
|
},
|
|
242
281
|
session_id: {
|
|
243
282
|
type: 'string',
|
|
@@ -355,7 +394,16 @@ export class ClaudeCodeServer {
|
|
|
355
394
|
}
|
|
356
395
|
// Determine which agent to use based on model name
|
|
357
396
|
const model = toolArguments.model || '';
|
|
358
|
-
|
|
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
|
+
}
|
|
359
407
|
let cliPath;
|
|
360
408
|
let processArgs;
|
|
361
409
|
if (agent === 'codex') {
|
|
@@ -373,6 +421,17 @@ export class ClaudeCodeServer {
|
|
|
373
421
|
}
|
|
374
422
|
processArgs.push('--full-auto', '--json', prompt);
|
|
375
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
|
+
}
|
|
376
435
|
else {
|
|
377
436
|
// Handle Claude (default)
|
|
378
437
|
cliPath = this.claudeCliPath;
|
|
@@ -510,6 +569,9 @@ export class ClaudeCodeServer {
|
|
|
510
569
|
else if (process.toolType === 'claude') {
|
|
511
570
|
agentOutput = parseClaudeOutput(process.stdout);
|
|
512
571
|
}
|
|
572
|
+
else if (process.toolType === 'gemini') {
|
|
573
|
+
agentOutput = parseGeminiOutput(process.stdout);
|
|
574
|
+
}
|
|
513
575
|
}
|
|
514
576
|
// Construct response with agent's output and process metadata
|
|
515
577
|
const response = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-cli-mcp",
|
|
3
|
-
"version": "2.0
|
|
4
|
-
"description": "MCP server for AI CLI tools (Claude and
|
|
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
|
|
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
|
|
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
|
|
|
@@ -314,7 +360,7 @@ export class ClaudeCodeServer {
|
|
|
314
360
|
},
|
|
315
361
|
model: {
|
|
316
362
|
type: 'string',
|
|
317
|
-
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".',
|
|
318
364
|
},
|
|
319
365
|
session_id: {
|
|
320
366
|
type: 'string',
|
|
@@ -444,16 +490,24 @@ export class ClaudeCodeServer {
|
|
|
444
490
|
|
|
445
491
|
// Determine which agent to use based on model name
|
|
446
492
|
const model = toolArguments.model || '';
|
|
447
|
-
|
|
448
|
-
|
|
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
|
+
|
|
449
503
|
let cliPath: string;
|
|
450
504
|
let processArgs: string[];
|
|
451
|
-
|
|
505
|
+
|
|
452
506
|
if (agent === 'codex') {
|
|
453
507
|
// Handle Codex
|
|
454
508
|
cliPath = this.codexCliPath;
|
|
455
509
|
processArgs = ['exec'];
|
|
456
|
-
|
|
510
|
+
|
|
457
511
|
// Parse model format for Codex (e.g., gpt-5-low -> model: gpt-5, effort: low)
|
|
458
512
|
if (toolArguments.model) {
|
|
459
513
|
// Split by "gpt-5-" to get the effort level
|
|
@@ -463,19 +517,32 @@ export class ClaudeCodeServer {
|
|
|
463
517
|
}
|
|
464
518
|
processArgs.push('--model', 'gpt-5');
|
|
465
519
|
}
|
|
466
|
-
|
|
520
|
+
|
|
467
521
|
processArgs.push('--full-auto', '--json', prompt);
|
|
468
|
-
|
|
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
|
+
|
|
469
536
|
} else {
|
|
470
537
|
// Handle Claude (default)
|
|
471
538
|
cliPath = this.claudeCliPath;
|
|
472
539
|
processArgs = ['--dangerously-skip-permissions', '--output-format', 'json'];
|
|
473
|
-
|
|
540
|
+
|
|
474
541
|
// Add session_id if provided (Claude only)
|
|
475
542
|
if (toolArguments.session_id && typeof toolArguments.session_id === 'string') {
|
|
476
543
|
processArgs.push('-r', toolArguments.session_id);
|
|
477
544
|
}
|
|
478
|
-
|
|
545
|
+
|
|
479
546
|
processArgs.push('-p', prompt);
|
|
480
547
|
if (toolArguments.model && typeof toolArguments.model === 'string') {
|
|
481
548
|
const resolvedModel = resolveModelAlias(toolArguments.model);
|
|
@@ -502,7 +569,7 @@ export class ClaudeCodeServer {
|
|
|
502
569
|
prompt,
|
|
503
570
|
workFolder: effectiveCwd,
|
|
504
571
|
model: toolArguments.model,
|
|
505
|
-
toolType: agent
|
|
572
|
+
toolType: agent,
|
|
506
573
|
startTime: new Date().toISOString(),
|
|
507
574
|
stdout: '',
|
|
508
575
|
stderr: '',
|
|
@@ -620,6 +687,8 @@ export class ClaudeCodeServer {
|
|
|
620
687
|
agentOutput = parseCodexOutput(process.stdout);
|
|
621
688
|
} else if (process.toolType === 'claude') {
|
|
622
689
|
agentOutput = parseClaudeOutput(process.stdout);
|
|
690
|
+
} else if (process.toolType === 'gemini') {
|
|
691
|
+
agentOutput = parseGeminiOutput(process.stdout);
|
|
623
692
|
}
|
|
624
693
|
}
|
|
625
694
|
|