ai-cli-mcp 2.7.0 → 2.8.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## [2.8.1](https://github.com/mkXultra/ai-cli-mcp/compare/v2.8.0...v2.8.1) (2026-03-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * リポジトリ名変更に伴うURL・参照の更新 ([909cab7](https://github.com/mkXultra/ai-cli-mcp/commit/909cab77cc1e03f5880bd699ed680c32d990adb5))
7
+ * リポジトリ名変更に伴う再リリース ([c6a165b](https://github.com/mkXultra/ai-cli-mcp/commit/c6a165b101eae5cbc1b9d139227dfd074172a070))
8
+
9
+ # [2.8.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.7.0...v2.8.0) (2026-03-01)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * セッション再開時に--fork-sessionフラグを追加 ([44b359a](https://github.com/mkXultra/claude-code-mcp/commit/44b359a3acf6112339424efc703c1693df1ce1e9))
15
+
16
+
17
+ ### Features
18
+
19
+ * Gemini 3.1 Pro Previewモデルを追加 ([1c314bb](https://github.com/mkXultra/claude-code-mcp/commit/1c314bba3019aea791117a974bfc5ee809e15eee))
20
+
1
21
  # [2.7.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.6.0...v2.7.0) (2026-03-01)
2
22
 
3
23
 
package/CONTRIBUTING.md CHANGED
@@ -3,8 +3,8 @@
3
3
  ## Development Setup
4
4
 
5
5
  ```bash
6
- git clone https://github.com/mkXultra/claude-code-mcp.git
7
- cd claude-code-mcp
6
+ git clone https://github.com/mkXultra/ai-cli-mcp.git
7
+ cd ai-cli-mcp
8
8
  npm install
9
9
  npm run build
10
10
  ```
package/README.ja.md CHANGED
@@ -19,7 +19,7 @@ Cursorなどのエディタが、複雑な手順を伴う編集や操作に苦
19
19
  - 複数のAIモデルのサポート:
20
20
  - Claude (sonnet, sonnet[1m], opus, opusplan, haiku)
21
21
  - Codex (gpt-5.3-codex, gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, など)
22
- - Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview)
22
+ - Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3.1-pro-preview, gemini-3-pro-preview, gemini-3-flash-preview)
23
23
  - PID追跡によるバックグラウンドプロセスの管理
24
24
  - ツールからの構造化された出力の解析と返却
25
25
 
@@ -134,9 +134,9 @@ Claude CLI、Codex CLI、またはGemini CLIを使用してプロンプトを実
134
134
  - **Ultra エイリアス:** `claude-ultra`, `codex-ultra` (自動的に high-reasoning に設定), `gemini-ultra`
135
135
  - Claude: `sonnet`, `sonnet[1m]`, `opus`, `opusplan`, `haiku`
136
136
  - Codex: `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
137
- - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
137
+ - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3.1-pro-preview`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
138
138
  - `reasoning_effort` (string, 任意): Codex専用。`model_reasoning_effort` を設定します(許容値: "low", "medium", "high", "xhigh")。
139
- - `session_id` (string, 任意): 以前のセッションを再開するためのセッションID。対応モデル: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview。
139
+ - `session_id` (string, 任意): 以前のセッションを再開するためのセッションID。対応モデル: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3.1-pro-preview, gemini-3-pro-preview, gemini-3-flash-preview。
140
140
 
141
141
  ### `wait`
142
142
 
package/README.md CHANGED
@@ -18,7 +18,7 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
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, sonnet[1m], opus, opusplan, haiku), Codex (gpt-5.3-codex, gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, gpt-5.2, gpt-5.1, gpt-5.1-codex, gpt-5-codex, gpt-5-codex-mini, gpt-5), and Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview)
21
+ - Support multiple AI models: Claude (sonnet, sonnet[1m], opus, opusplan, haiku), Codex (gpt-5.3-codex, gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, gpt-5.2, gpt-5.1, gpt-5.1-codex, gpt-5-codex, gpt-5-codex-mini, gpt-5), and Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3.1-pro-preview, gemini-3-pro-preview, gemini-3-flash-preview)
22
22
  - Manage background processes with PID tracking
23
23
  - Parse and return structured outputs from both tools
24
24
 
@@ -133,9 +133,9 @@ Executes a prompt using Claude CLI, Codex CLI, or Gemini CLI. The appropriate CL
133
133
  - **Ultra Aliases:** `claude-ultra`, `codex-ultra` (defaults to high-reasoning), `gemini-ultra`
134
134
  - Claude: `sonnet`, `sonnet[1m]`, `opus`, `opusplan`, `haiku`
135
135
  - Codex: `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
136
- - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
136
+ - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3.1-pro-preview`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
137
137
  - `reasoning_effort` (string, optional): Codex only. Sets `model_reasoning_effort` (allowed: "low", "medium", "high", "xhigh").
138
- - `session_id` (string, optional): Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview.
138
+ - `session_id` (string, optional): Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3.1-pro-preview, gemini-3-pro-preview, gemini-3-flash-preview.
139
139
 
140
140
  ### `wait`
141
141
 
@@ -28,8 +28,8 @@ describe('cli-builder', () => {
28
28
  it('should resolve codex-ultra to gpt-5.3-codex', () => {
29
29
  expect(resolveModelAlias('codex-ultra')).toBe('gpt-5.3-codex');
30
30
  });
31
- it('should resolve gemini-ultra to gemini-3-pro-preview', () => {
32
- expect(resolveModelAlias('gemini-ultra')).toBe('gemini-3-pro-preview');
31
+ it('should resolve gemini-ultra to gemini-3.1-pro-preview', () => {
32
+ expect(resolveModelAlias('gemini-ultra')).toBe('gemini-3.1-pro-preview');
33
33
  });
34
34
  it('should pass through non-alias model names', () => {
35
35
  expect(resolveModelAlias('sonnet')).toBe('sonnet');
@@ -160,6 +160,7 @@ describe('cli-builder', () => {
160
160
  });
161
161
  expect(cmd.args).toContain('-r');
162
162
  expect(cmd.args).toContain('ses-123');
163
+ expect(cmd.args).toContain('--fork-session');
163
164
  });
164
165
  it('should resolve claude-ultra alias to opus', () => {
165
166
  const cmd = buildCliCommand({
@@ -271,7 +272,7 @@ describe('cli-builder', () => {
271
272
  cliPaths: DEFAULT_CLI_PATHS,
272
273
  });
273
274
  expect(cmd.agent).toBe('gemini');
274
- expect(cmd.resolvedModel).toBe('gemini-3-pro-preview');
275
+ expect(cmd.resolvedModel).toBe('gemini-3.1-pro-preview');
275
276
  });
276
277
  });
277
278
  });
@@ -499,7 +499,7 @@ describe('ClaudeCodeServer Unit Tests', () => {
499
499
  }
500
500
  });
501
501
  // Verify spawn was called with -r flag
502
- expect(mockSpawn).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['-r', 'test-session-123', '-p', 'test prompt']), expect.any(Object));
502
+ expect(mockSpawn).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['-r', 'test-session-123', '--fork-session', '-p', 'test prompt']), expect.any(Object));
503
503
  });
504
504
  it('should handle session_id parameter for Codex using exec resume', async () => {
505
505
  mockHomedir.mockReturnValue('/home/user');
@@ -4,7 +4,7 @@ import { resolve as pathResolve, isAbsolute } from 'node:path';
4
4
  export const MODEL_ALIASES = {
5
5
  'claude-ultra': 'opus',
6
6
  'codex-ultra': 'gpt-5.3-codex',
7
- 'gemini-ultra': 'gemini-3-pro-preview'
7
+ 'gemini-ultra': 'gemini-3.1-pro-preview'
8
8
  };
9
9
  export const ALLOWED_REASONING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh']);
10
10
  /**
@@ -134,7 +134,7 @@ export function buildCliCommand(options) {
134
134
  cliPath = options.cliPaths.claude;
135
135
  args = ['--dangerously-skip-permissions', '--output-format', 'stream-json', '--verbose'];
136
136
  if (options.session_id && typeof options.session_id === 'string') {
137
- args.push('-r', options.session_id);
137
+ args.push('-r', options.session_id, '--fork-session');
138
138
  }
139
139
  args.push('-p', prompt);
140
140
  if (resolvedModel) {
@@ -0,0 +1,125 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import * as path from 'path';
5
+ // Define debugMode globally using const
6
+ const debugMode = process.env.MCP_CLAUDE_DEBUG === 'true';
7
+ // Dedicated debug logging function
8
+ export function debugLog(message, ...optionalParams) {
9
+ if (debugMode) {
10
+ console.error(message, ...optionalParams);
11
+ }
12
+ }
13
+ /**
14
+ * Determine the Gemini CLI command/path.
15
+ * Similar to findClaudeCli but for Gemini
16
+ */
17
+ export function findGeminiCli() {
18
+ debugLog('[Debug] Attempting to find Gemini CLI...');
19
+ // Check for custom CLI name from environment variable
20
+ const customCliName = process.env.GEMINI_CLI_NAME;
21
+ if (customCliName) {
22
+ debugLog(`[Debug] Using custom Gemini CLI name from GEMINI_CLI_NAME: ${customCliName}`);
23
+ // If it's an absolute path, use it directly
24
+ if (path.isAbsolute(customCliName)) {
25
+ debugLog(`[Debug] GEMINI_CLI_NAME is an absolute path: ${customCliName}`);
26
+ return customCliName;
27
+ }
28
+ // If it starts with ~ or ./, reject as relative paths are not allowed
29
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
30
+ 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')`);
31
+ }
32
+ }
33
+ const cliName = customCliName || 'gemini';
34
+ // Try local install path: ~/.gemini/local/gemini
35
+ const userPath = join(homedir(), '.gemini', 'local', 'gemini');
36
+ debugLog(`[Debug] Checking for Gemini CLI at local user path: ${userPath}`);
37
+ if (existsSync(userPath)) {
38
+ debugLog(`[Debug] Found Gemini CLI at local user path: ${userPath}. Using this path.`);
39
+ return userPath;
40
+ }
41
+ else {
42
+ debugLog(`[Debug] Gemini CLI not found at local user path: ${userPath}.`);
43
+ }
44
+ // Fallback to CLI name (PATH lookup)
45
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
46
+ console.warn(`[Warning] Gemini CLI not found at ~/.gemini/local/gemini. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
47
+ return cliName;
48
+ }
49
+ /**
50
+ * Determine the Codex CLI command/path.
51
+ * Similar to findClaudeCli but for Codex
52
+ */
53
+ export function findCodexCli() {
54
+ debugLog('[Debug] Attempting to find Codex CLI...');
55
+ // Check for custom CLI name from environment variable
56
+ const customCliName = process.env.CODEX_CLI_NAME;
57
+ if (customCliName) {
58
+ debugLog(`[Debug] Using custom Codex CLI name from CODEX_CLI_NAME: ${customCliName}`);
59
+ // If it's an absolute path, use it directly
60
+ if (path.isAbsolute(customCliName)) {
61
+ debugLog(`[Debug] CODEX_CLI_NAME is an absolute path: ${customCliName}`);
62
+ return customCliName;
63
+ }
64
+ // If it starts with ~ or ./, reject as relative paths are not allowed
65
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
66
+ throw new Error(`Invalid CODEX_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'codex') or an absolute path (e.g., '/tmp/codex-test')`);
67
+ }
68
+ }
69
+ const cliName = customCliName || 'codex';
70
+ // Try local install path: ~/.codex/local/codex
71
+ const userPath = join(homedir(), '.codex', 'local', 'codex');
72
+ debugLog(`[Debug] Checking for Codex CLI at local user path: ${userPath}`);
73
+ if (existsSync(userPath)) {
74
+ debugLog(`[Debug] Found Codex CLI at local user path: ${userPath}. Using this path.`);
75
+ return userPath;
76
+ }
77
+ else {
78
+ debugLog(`[Debug] Codex CLI not found at local user path: ${userPath}.`);
79
+ }
80
+ // Fallback to CLI name (PATH lookup)
81
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
82
+ console.warn(`[Warning] Codex CLI not found at ~/.codex/local/codex. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
83
+ return cliName;
84
+ }
85
+ /**
86
+ * Determine the Claude CLI command/path.
87
+ * 1. Checks for CLAUDE_CLI_NAME environment variable:
88
+ * - If absolute path, uses it directly
89
+ * - If relative path, throws error
90
+ * - If simple name, continues with path resolution
91
+ * 2. Checks for Claude CLI at the local user path: ~/.claude/local/claude.
92
+ * 3. If not found, defaults to the CLI name (or 'claude'), relying on the system's PATH for lookup.
93
+ */
94
+ export function findClaudeCli() {
95
+ debugLog('[Debug] Attempting to find Claude CLI...');
96
+ // Check for custom CLI name from environment variable
97
+ const customCliName = process.env.CLAUDE_CLI_NAME;
98
+ if (customCliName) {
99
+ debugLog(`[Debug] Using custom Claude CLI name from CLAUDE_CLI_NAME: ${customCliName}`);
100
+ // If it's an absolute path, use it directly
101
+ if (path.isAbsolute(customCliName)) {
102
+ debugLog(`[Debug] CLAUDE_CLI_NAME is an absolute path: ${customCliName}`);
103
+ return customCliName;
104
+ }
105
+ // If it starts with ~ or ./, reject as relative paths are not allowed
106
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
107
+ throw new Error(`Invalid CLAUDE_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'claude') or an absolute path (e.g., '/tmp/claude-test')`);
108
+ }
109
+ }
110
+ const cliName = customCliName || 'claude';
111
+ // Try local install path: ~/.claude/local/claude (using the original name for local installs)
112
+ const userPath = join(homedir(), '.claude', 'local', 'claude');
113
+ debugLog(`[Debug] Checking for Claude CLI at local user path: ${userPath}`);
114
+ if (existsSync(userPath)) {
115
+ debugLog(`[Debug] Found Claude CLI at local user path: ${userPath}. Using this path.`);
116
+ return userPath;
117
+ }
118
+ else {
119
+ debugLog(`[Debug] Claude CLI not found at local user path: ${userPath}.`);
120
+ }
121
+ // 3. Fallback to CLI name (PATH lookup)
122
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
123
+ console.warn(`[Warning] Claude CLI not found at ~/.claude/local/claude. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
124
+ return cliName;
125
+ }
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from 'node:child_process';
3
3
  import { buildCliCommand } from './cli-builder.js';
4
- import { findClaudeCli, findCodexCli, findGeminiCli } from './server.js';
4
+ import { findClaudeCli, findCodexCli, findGeminiCli } from './cli-utils.js';
5
5
  /**
6
6
  * Minimal argv parser. No external dependencies.
7
7
  * Supports: --key value, --key=value
package/dist/parsers.js CHANGED
@@ -1,4 +1,4 @@
1
- import { debugLog } from './server.js';
1
+ import { debugLog } from './cli-utils.js';
2
2
  /**
3
3
  * Parse Codex NDJSON output to extract the last agent message and token count
4
4
  */
package/dist/server.js CHANGED
@@ -3,143 +3,20 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { spawn } from 'node:child_process';
6
- import { existsSync } from 'node:fs';
7
- import { homedir } from 'node:os';
8
- import { join } from 'node:path';
9
- import * as path from 'path';
10
6
  import { parseCodexOutput, parseClaudeOutput, parseGeminiOutput } from './parsers.js';
11
7
  import { buildCliCommand } from './cli-builder.js';
8
+ import { debugLog, findClaudeCli, findCodexCli, findGeminiCli } from './cli-utils.js';
9
+ // Re-export for backward compatibility
10
+ export { debugLog, findClaudeCli, findCodexCli, findGeminiCli } from './cli-utils.js';
11
+ export { resolveModelAlias } from './cli-builder.js';
12
12
  // Server version - update this when releasing new versions
13
13
  const SERVER_VERSION = "2.2.0";
14
- // Define debugMode globally using const
15
- const debugMode = process.env.MCP_CLAUDE_DEBUG === 'true';
16
14
  // Track if this is the first tool use for version printing
17
15
  let isFirstToolUse = true;
18
16
  // Capture server startup time when the module loads
19
17
  const serverStartupTime = new Date().toISOString();
20
18
  // Global process manager
21
19
  const processManager = new Map();
22
- // Dedicated debug logging function
23
- export function debugLog(message, ...optionalParams) {
24
- if (debugMode) {
25
- console.error(message, ...optionalParams);
26
- }
27
- }
28
- /**
29
- * Determine the Gemini CLI command/path.
30
- * Similar to findClaudeCli but for Gemini
31
- */
32
- export function findGeminiCli() {
33
- debugLog('[Debug] Attempting to find Gemini CLI...');
34
- // Check for custom CLI name from environment variable
35
- const customCliName = process.env.GEMINI_CLI_NAME;
36
- if (customCliName) {
37
- debugLog(`[Debug] Using custom Gemini CLI name from GEMINI_CLI_NAME: ${customCliName}`);
38
- // If it's an absolute path, use it directly
39
- if (path.isAbsolute(customCliName)) {
40
- debugLog(`[Debug] GEMINI_CLI_NAME is an absolute path: ${customCliName}`);
41
- return customCliName;
42
- }
43
- // If it starts with ~ or ./, reject as relative paths are not allowed
44
- if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
45
- 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')`);
46
- }
47
- }
48
- const cliName = customCliName || 'gemini';
49
- // Try local install path: ~/.gemini/local/gemini
50
- const userPath = join(homedir(), '.gemini', 'local', 'gemini');
51
- debugLog(`[Debug] Checking for Gemini CLI at local user path: ${userPath}`);
52
- if (existsSync(userPath)) {
53
- debugLog(`[Debug] Found Gemini CLI at local user path: ${userPath}. Using this path.`);
54
- return userPath;
55
- }
56
- else {
57
- debugLog(`[Debug] Gemini CLI not found at local user path: ${userPath}.`);
58
- }
59
- // Fallback to CLI name (PATH lookup)
60
- debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
61
- console.warn(`[Warning] Gemini CLI not found at ~/.gemini/local/gemini. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
62
- return cliName;
63
- }
64
- /**
65
- * Determine the Codex CLI command/path.
66
- * Similar to findClaudeCli but for Codex
67
- */
68
- export function findCodexCli() {
69
- debugLog('[Debug] Attempting to find Codex CLI...');
70
- // Check for custom CLI name from environment variable
71
- const customCliName = process.env.CODEX_CLI_NAME;
72
- if (customCliName) {
73
- debugLog(`[Debug] Using custom Codex CLI name from CODEX_CLI_NAME: ${customCliName}`);
74
- // If it's an absolute path, use it directly
75
- if (path.isAbsolute(customCliName)) {
76
- debugLog(`[Debug] CODEX_CLI_NAME is an absolute path: ${customCliName}`);
77
- return customCliName;
78
- }
79
- // If it starts with ~ or ./, reject as relative paths are not allowed
80
- if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
81
- throw new Error(`Invalid CODEX_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'codex') or an absolute path (e.g., '/tmp/codex-test')`);
82
- }
83
- }
84
- const cliName = customCliName || 'codex';
85
- // Try local install path: ~/.codex/local/codex
86
- const userPath = join(homedir(), '.codex', 'local', 'codex');
87
- debugLog(`[Debug] Checking for Codex CLI at local user path: ${userPath}`);
88
- if (existsSync(userPath)) {
89
- debugLog(`[Debug] Found Codex CLI at local user path: ${userPath}. Using this path.`);
90
- return userPath;
91
- }
92
- else {
93
- debugLog(`[Debug] Codex CLI not found at local user path: ${userPath}.`);
94
- }
95
- // Fallback to CLI name (PATH lookup)
96
- debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
97
- console.warn(`[Warning] Codex CLI not found at ~/.codex/local/codex. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
98
- return cliName;
99
- }
100
- /**
101
- * Determine the Claude CLI command/path.
102
- * 1. Checks for CLAUDE_CLI_NAME environment variable:
103
- * - If absolute path, uses it directly
104
- * - If relative path, throws error
105
- * - If simple name, continues with path resolution
106
- * 2. Checks for Claude CLI at the local user path: ~/.claude/local/claude.
107
- * 3. If not found, defaults to the CLI name (or 'claude'), relying on the system's PATH for lookup.
108
- */
109
- export function findClaudeCli() {
110
- debugLog('[Debug] Attempting to find Claude CLI...');
111
- // Check for custom CLI name from environment variable
112
- const customCliName = process.env.CLAUDE_CLI_NAME;
113
- if (customCliName) {
114
- debugLog(`[Debug] Using custom Claude CLI name from CLAUDE_CLI_NAME: ${customCliName}`);
115
- // If it's an absolute path, use it directly
116
- if (path.isAbsolute(customCliName)) {
117
- debugLog(`[Debug] CLAUDE_CLI_NAME is an absolute path: ${customCliName}`);
118
- return customCliName;
119
- }
120
- // If it starts with ~ or ./, reject as relative paths are not allowed
121
- if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
122
- throw new Error(`Invalid CLAUDE_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'claude') or an absolute path (e.g., '/tmp/claude-test')`);
123
- }
124
- }
125
- const cliName = customCliName || 'claude';
126
- // Try local install path: ~/.claude/local/claude (using the original name for local installs)
127
- const userPath = join(homedir(), '.claude', 'local', 'claude');
128
- debugLog(`[Debug] Checking for Claude CLI at local user path: ${userPath}`);
129
- if (existsSync(userPath)) {
130
- debugLog(`[Debug] Found Claude CLI at local user path: ${userPath}. Using this path.`);
131
- return userPath;
132
- }
133
- else {
134
- debugLog(`[Debug] Claude CLI not found at local user path: ${userPath}.`);
135
- }
136
- // 3. Fallback to CLI name (PATH lookup)
137
- debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
138
- console.warn(`[Warning] Claude CLI not found at ~/.claude/local/claude. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
139
- return cliName;
140
- }
141
- // Re-export resolveModelAlias for backward compatibility
142
- export { resolveModelAlias } from './cli-builder.js';
143
20
  // Ensure spawnAsync is defined correctly *before* the class
144
21
  export async function spawnAsync(command, args, options) {
145
22
  return new Promise((resolve, reject) => {
@@ -239,7 +116,7 @@ export class ClaudeCodeServer {
239
116
  **IMPORTANT**: This tool now returns immediately with a PID. Use other tools to check status and get results.
240
117
 
241
118
  **Supported models**:
242
- "claude-ultra", "codex-ultra", "gemini-ultra", "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1-codex-max", "gpt-5.2", "gpt-5.1", "gpt-5.1-codex", "gpt-5-codex", "gpt-5-codex-mini", "gpt-5", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-3-pro-preview", "gemini-3-flash-preview"
119
+ "claude-ultra", "codex-ultra", "gemini-ultra", "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1-codex-max", "gpt-5.2", "gpt-5.1", "gpt-5.1-codex", "gpt-5-codex", "gpt-5-codex-mini", "gpt-5", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview"
243
120
 
244
121
  **Prompt input**: You must provide EITHER prompt (string) OR prompt_file (file path), but not both.
245
122
 
@@ -267,7 +144,7 @@ export class ClaudeCodeServer {
267
144
  },
268
145
  model: {
269
146
  type: 'string',
270
- description: 'The model to use. Aliases: "claude-ultra", "codex-ultra" (auto high-reasoning), "gemini-ultra". Standard: "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1", "gemini-2.5-pro", "gemini-3-pro-preview", "gemini-3-flash-preview", etc.',
147
+ description: 'The model to use. Aliases: "claude-ultra", "codex-ultra" (auto high-reasoning), "gemini-ultra". Standard: "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1", "gemini-2.5-pro", "gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview", etc.',
271
148
  },
272
149
  reasoning_effort: {
273
150
  type: 'string',
@@ -275,7 +152,7 @@ export class ClaudeCodeServer {
275
152
  },
276
153
  session_id: {
277
154
  type: 'string',
278
- description: 'Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview.',
155
+ description: 'Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3.1-pro-preview, gemini-3-pro-preview, gemini-3-flash-preview.',
279
156
  },
280
157
  },
281
158
  required: ['workFolder'],
@@ -61,5 +61,5 @@ This project uses OIDC trusted publishing (no npm token required).
61
61
 
62
62
  Configuration on npmjs.com:
63
63
  - Organization/user: `mkXultra`
64
- - Repository: `claude-code-mcp`
64
+ - Repository: `ai-cli-mcp`
65
65
  - Workflow filename: `publish.yml`
@@ -4,8 +4,8 @@
4
4
 
5
5
  ```bash
6
6
  # Clone the repository
7
- git clone https://github.com/mkXultra/claude-code-mcp.git
8
- cd claude-code-mcp
7
+ git clone https://github.com/mkXultra/ai-cli-mcp.git
8
+ cd ai-cli-mcp
9
9
 
10
10
  # Install dependencies
11
11
  npm install
@@ -153,4 +153,4 @@ These can be set in your shell environment or within the `env` block of your `mc
153
153
 
154
154
  Contributions are welcome!
155
155
 
156
- Submit issues and pull requests to the [GitHub repository](https://github.com/mkXultra/claude-code-mcp).
156
+ Submit issues and pull requests to the [GitHub repository](https://github.com/mkXultra/ai-cli-mcp).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-cli-mcp",
3
- "version": "2.7.0",
3
+ "version": "2.8.1",
4
4
  "description": "MCP server for AI CLI tools (Claude, Codex, and Gemini) with background process management",
5
5
  "author": "mkXultra",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "repository": {
41
41
  "type": "git",
42
- "url": "git+https://github.com/mkXultra/claude-code-mcp.git"
42
+ "url": "git+https://github.com/mkXultra/ai-cli-mcp.git"
43
43
  },
44
44
  "keywords": [
45
45
  "mcp",
@@ -52,7 +52,7 @@
52
52
  "gpt5"
53
53
  ],
54
54
  "bugs": {
55
- "url": "https://github.com/mkXultra/claude-code-mcp/issues"
55
+ "url": "https://github.com/mkXultra/ai-cli-mcp/issues"
56
56
  },
57
- "homepage": "https://github.com/mkXultra/claude-code-mcp#readme"
57
+ "homepage": "https://github.com/mkXultra/ai-cli-mcp#readme"
58
58
  }
@@ -40,8 +40,8 @@ describe('cli-builder', () => {
40
40
  expect(resolveModelAlias('codex-ultra')).toBe('gpt-5.3-codex');
41
41
  });
42
42
 
43
- it('should resolve gemini-ultra to gemini-3-pro-preview', () => {
44
- expect(resolveModelAlias('gemini-ultra')).toBe('gemini-3-pro-preview');
43
+ it('should resolve gemini-ultra to gemini-3.1-pro-preview', () => {
44
+ expect(resolveModelAlias('gemini-ultra')).toBe('gemini-3.1-pro-preview');
45
45
  });
46
46
 
47
47
  it('should pass through non-alias model names', () => {
@@ -209,6 +209,7 @@ describe('cli-builder', () => {
209
209
 
210
210
  expect(cmd.args).toContain('-r');
211
211
  expect(cmd.args).toContain('ses-123');
212
+ expect(cmd.args).toContain('--fork-session');
212
213
  });
213
214
 
214
215
  it('should resolve claude-ultra alias to opus', () => {
@@ -338,7 +339,7 @@ describe('cli-builder', () => {
338
339
  });
339
340
 
340
341
  expect(cmd.agent).toBe('gemini');
341
- expect(cmd.resolvedModel).toBe('gemini-3-pro-preview');
342
+ expect(cmd.resolvedModel).toBe('gemini-3.1-pro-preview');
342
343
  });
343
344
  });
344
345
  });
@@ -624,7 +624,7 @@ describe('ClaudeCodeServer Unit Tests', () => {
624
624
  // Verify spawn was called with -r flag
625
625
  expect(mockSpawn).toHaveBeenCalledWith(
626
626
  expect.any(String),
627
- expect.arrayContaining(['-r', 'test-session-123', '-p', 'test prompt']),
627
+ expect.arrayContaining(['-r', 'test-session-123', '--fork-session', '-p', 'test prompt']),
628
628
  expect.any(Object)
629
629
  );
630
630
  });
@@ -5,7 +5,7 @@ import { resolve as pathResolve, isAbsolute } from 'node:path';
5
5
  export const MODEL_ALIASES: Record<string, string> = {
6
6
  'claude-ultra': 'opus',
7
7
  'codex-ultra': 'gpt-5.3-codex',
8
- 'gemini-ultra': 'gemini-3-pro-preview'
8
+ 'gemini-ultra': 'gemini-3.1-pro-preview'
9
9
  };
10
10
 
11
11
  export const ALLOWED_REASONING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh']);
@@ -177,7 +177,7 @@ export function buildCliCommand(options: BuildCliCommandOptions): CliCommand {
177
177
  args = ['--dangerously-skip-permissions', '--output-format', 'stream-json', '--verbose'];
178
178
 
179
179
  if (options.session_id && typeof options.session_id === 'string') {
180
- args.push('-r', options.session_id);
180
+ args.push('-r', options.session_id, '--fork-session');
181
181
  }
182
182
 
183
183
  args.push('-p', prompt);
@@ -0,0 +1,148 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import * as path from 'path';
5
+
6
+ // Define debugMode globally using const
7
+ const debugMode = process.env.MCP_CLAUDE_DEBUG === 'true';
8
+
9
+ // Dedicated debug logging function
10
+ export function debugLog(message?: any, ...optionalParams: any[]): void {
11
+ if (debugMode) {
12
+ console.error(message, ...optionalParams);
13
+ }
14
+ }
15
+
16
+ /**
17
+ * Determine the Gemini CLI command/path.
18
+ * Similar to findClaudeCli but for Gemini
19
+ */
20
+ export function findGeminiCli(): string {
21
+ debugLog('[Debug] Attempting to find Gemini CLI...');
22
+
23
+ // Check for custom CLI name from environment variable
24
+ const customCliName = process.env.GEMINI_CLI_NAME;
25
+ if (customCliName) {
26
+ debugLog(`[Debug] Using custom Gemini CLI name from GEMINI_CLI_NAME: ${customCliName}`);
27
+
28
+ // If it's an absolute path, use it directly
29
+ if (path.isAbsolute(customCliName)) {
30
+ debugLog(`[Debug] GEMINI_CLI_NAME is an absolute path: ${customCliName}`);
31
+ return customCliName;
32
+ }
33
+
34
+ // If it starts with ~ or ./, reject as relative paths are not allowed
35
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
36
+ 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')`);
37
+ }
38
+ }
39
+
40
+ const cliName = customCliName || 'gemini';
41
+
42
+ // Try local install path: ~/.gemini/local/gemini
43
+ const userPath = join(homedir(), '.gemini', 'local', 'gemini');
44
+ debugLog(`[Debug] Checking for Gemini CLI at local user path: ${userPath}`);
45
+
46
+ if (existsSync(userPath)) {
47
+ debugLog(`[Debug] Found Gemini CLI at local user path: ${userPath}. Using this path.`);
48
+ return userPath;
49
+ } else {
50
+ debugLog(`[Debug] Gemini CLI not found at local user path: ${userPath}.`);
51
+ }
52
+
53
+ // Fallback to CLI name (PATH lookup)
54
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
55
+ console.warn(`[Warning] Gemini CLI not found at ~/.gemini/local/gemini. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
56
+ return cliName;
57
+ }
58
+
59
+ /**
60
+ * Determine the Codex CLI command/path.
61
+ * Similar to findClaudeCli but for Codex
62
+ */
63
+ export function findCodexCli(): string {
64
+ debugLog('[Debug] Attempting to find Codex CLI...');
65
+
66
+ // Check for custom CLI name from environment variable
67
+ const customCliName = process.env.CODEX_CLI_NAME;
68
+ if (customCliName) {
69
+ debugLog(`[Debug] Using custom Codex CLI name from CODEX_CLI_NAME: ${customCliName}`);
70
+
71
+ // If it's an absolute path, use it directly
72
+ if (path.isAbsolute(customCliName)) {
73
+ debugLog(`[Debug] CODEX_CLI_NAME is an absolute path: ${customCliName}`);
74
+ return customCliName;
75
+ }
76
+
77
+ // If it starts with ~ or ./, reject as relative paths are not allowed
78
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
79
+ throw new Error(`Invalid CODEX_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'codex') or an absolute path (e.g., '/tmp/codex-test')`);
80
+ }
81
+ }
82
+
83
+ const cliName = customCliName || 'codex';
84
+
85
+ // Try local install path: ~/.codex/local/codex
86
+ const userPath = join(homedir(), '.codex', 'local', 'codex');
87
+ debugLog(`[Debug] Checking for Codex CLI at local user path: ${userPath}`);
88
+
89
+ if (existsSync(userPath)) {
90
+ debugLog(`[Debug] Found Codex CLI at local user path: ${userPath}. Using this path.`);
91
+ return userPath;
92
+ } else {
93
+ debugLog(`[Debug] Codex CLI not found at local user path: ${userPath}.`);
94
+ }
95
+
96
+ // Fallback to CLI name (PATH lookup)
97
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
98
+ console.warn(`[Warning] Codex CLI not found at ~/.codex/local/codex. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
99
+ return cliName;
100
+ }
101
+
102
+ /**
103
+ * Determine the Claude CLI command/path.
104
+ * 1. Checks for CLAUDE_CLI_NAME environment variable:
105
+ * - If absolute path, uses it directly
106
+ * - If relative path, throws error
107
+ * - If simple name, continues with path resolution
108
+ * 2. Checks for Claude CLI at the local user path: ~/.claude/local/claude.
109
+ * 3. If not found, defaults to the CLI name (or 'claude'), relying on the system's PATH for lookup.
110
+ */
111
+ export function findClaudeCli(): string {
112
+ debugLog('[Debug] Attempting to find Claude CLI...');
113
+
114
+ // Check for custom CLI name from environment variable
115
+ const customCliName = process.env.CLAUDE_CLI_NAME;
116
+ if (customCliName) {
117
+ debugLog(`[Debug] Using custom Claude CLI name from CLAUDE_CLI_NAME: ${customCliName}`);
118
+
119
+ // If it's an absolute path, use it directly
120
+ if (path.isAbsolute(customCliName)) {
121
+ debugLog(`[Debug] CLAUDE_CLI_NAME is an absolute path: ${customCliName}`);
122
+ return customCliName;
123
+ }
124
+
125
+ // If it starts with ~ or ./, reject as relative paths are not allowed
126
+ if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
127
+ throw new Error(`Invalid CLAUDE_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'claude') or an absolute path (e.g., '/tmp/claude-test')`);
128
+ }
129
+ }
130
+
131
+ const cliName = customCliName || 'claude';
132
+
133
+ // Try local install path: ~/.claude/local/claude (using the original name for local installs)
134
+ const userPath = join(homedir(), '.claude', 'local', 'claude');
135
+ debugLog(`[Debug] Checking for Claude CLI at local user path: ${userPath}`);
136
+
137
+ if (existsSync(userPath)) {
138
+ debugLog(`[Debug] Found Claude CLI at local user path: ${userPath}. Using this path.`);
139
+ return userPath;
140
+ } else {
141
+ debugLog(`[Debug] Claude CLI not found at local user path: ${userPath}.`);
142
+ }
143
+
144
+ // 3. Fallback to CLI name (PATH lookup)
145
+ debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
146
+ console.warn(`[Warning] Claude CLI not found at ~/.claude/local/claude. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
147
+ return cliName;
148
+ }
package/src/cli.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from 'node:child_process';
3
3
  import { buildCliCommand } from './cli-builder.js';
4
- import { findClaudeCli, findCodexCli, findGeminiCli } from './server.js';
4
+ import { findClaudeCli, findCodexCli, findGeminiCli } from './cli-utils.js';
5
5
 
6
6
  /**
7
7
  * Minimal argv parser. No external dependencies.
package/src/parsers.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { debugLog } from './server.js';
1
+ import { debugLog } from './cli-utils.js';
2
2
 
3
3
  /**
4
4
  * Parse Codex NDJSON output to extract the last agent message and token count
package/src/server.ts CHANGED
@@ -9,19 +9,17 @@ import {
9
9
  type ServerResult,
10
10
  } from '@modelcontextprotocol/sdk/types.js';
11
11
  import { spawn, ChildProcess } from 'node:child_process';
12
- import { existsSync } from 'node:fs';
13
- import { homedir } from 'node:os';
14
- import { join } from 'node:path';
15
- import * as path from 'path';
16
12
  import { parseCodexOutput, parseClaudeOutput, parseGeminiOutput } from './parsers.js';
17
13
  import { buildCliCommand } from './cli-builder.js';
14
+ import { debugLog, findClaudeCli, findCodexCli, findGeminiCli } from './cli-utils.js';
15
+
16
+ // Re-export for backward compatibility
17
+ export { debugLog, findClaudeCli, findCodexCli, findGeminiCli } from './cli-utils.js';
18
+ export { resolveModelAlias } from './cli-builder.js';
18
19
 
19
20
  // Server version - update this when releasing new versions
20
21
  const SERVER_VERSION = "2.2.0";
21
22
 
22
- // Define debugMode globally using const
23
- const debugMode = process.env.MCP_CLAUDE_DEBUG === 'true';
24
-
25
23
  // Track if this is the first tool use for version printing
26
24
  let isFirstToolUse = true;
27
25
 
@@ -53,150 +51,6 @@ interface ProcessListItem {
53
51
  // Global process manager
54
52
  const processManager = new Map<number, ClaudeProcess>();
55
53
 
56
- // Dedicated debug logging function
57
- export function debugLog(message?: any, ...optionalParams: any[]): void {
58
- if (debugMode) {
59
- console.error(message, ...optionalParams);
60
- }
61
- }
62
-
63
- /**
64
- * Determine the Gemini CLI command/path.
65
- * Similar to findClaudeCli but for Gemini
66
- */
67
- export function findGeminiCli(): string {
68
- debugLog('[Debug] Attempting to find Gemini CLI...');
69
-
70
- // Check for custom CLI name from environment variable
71
- const customCliName = process.env.GEMINI_CLI_NAME;
72
- if (customCliName) {
73
- debugLog(`[Debug] Using custom Gemini CLI name from GEMINI_CLI_NAME: ${customCliName}`);
74
-
75
- // If it's an absolute path, use it directly
76
- if (path.isAbsolute(customCliName)) {
77
- debugLog(`[Debug] GEMINI_CLI_NAME is an absolute path: ${customCliName}`);
78
- return customCliName;
79
- }
80
-
81
- // If it starts with ~ or ./, reject as relative paths are not allowed
82
- if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
83
- 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')`);
84
- }
85
- }
86
-
87
- const cliName = customCliName || 'gemini';
88
-
89
- // Try local install path: ~/.gemini/local/gemini
90
- const userPath = join(homedir(), '.gemini', 'local', 'gemini');
91
- debugLog(`[Debug] Checking for Gemini CLI at local user path: ${userPath}`);
92
-
93
- if (existsSync(userPath)) {
94
- debugLog(`[Debug] Found Gemini CLI at local user path: ${userPath}. Using this path.`);
95
- return userPath;
96
- } else {
97
- debugLog(`[Debug] Gemini CLI not found at local user path: ${userPath}.`);
98
- }
99
-
100
- // Fallback to CLI name (PATH lookup)
101
- debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
102
- console.warn(`[Warning] Gemini CLI not found at ~/.gemini/local/gemini. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
103
- return cliName;
104
- }
105
-
106
- /**
107
- * Determine the Codex CLI command/path.
108
- * Similar to findClaudeCli but for Codex
109
- */
110
- export function findCodexCli(): string {
111
- debugLog('[Debug] Attempting to find Codex CLI...');
112
-
113
- // Check for custom CLI name from environment variable
114
- const customCliName = process.env.CODEX_CLI_NAME;
115
- if (customCliName) {
116
- debugLog(`[Debug] Using custom Codex CLI name from CODEX_CLI_NAME: ${customCliName}`);
117
-
118
- // If it's an absolute path, use it directly
119
- if (path.isAbsolute(customCliName)) {
120
- debugLog(`[Debug] CODEX_CLI_NAME is an absolute path: ${customCliName}`);
121
- return customCliName;
122
- }
123
-
124
- // If it starts with ~ or ./, reject as relative paths are not allowed
125
- if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
126
- throw new Error(`Invalid CODEX_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'codex') or an absolute path (e.g., '/tmp/codex-test')`);
127
- }
128
- }
129
-
130
- const cliName = customCliName || 'codex';
131
-
132
- // Try local install path: ~/.codex/local/codex
133
- const userPath = join(homedir(), '.codex', 'local', 'codex');
134
- debugLog(`[Debug] Checking for Codex CLI at local user path: ${userPath}`);
135
-
136
- if (existsSync(userPath)) {
137
- debugLog(`[Debug] Found Codex CLI at local user path: ${userPath}. Using this path.`);
138
- return userPath;
139
- } else {
140
- debugLog(`[Debug] Codex CLI not found at local user path: ${userPath}.`);
141
- }
142
-
143
- // Fallback to CLI name (PATH lookup)
144
- debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
145
- console.warn(`[Warning] Codex CLI not found at ~/.codex/local/codex. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
146
- return cliName;
147
- }
148
-
149
- /**
150
- * Determine the Claude CLI command/path.
151
- * 1. Checks for CLAUDE_CLI_NAME environment variable:
152
- * - If absolute path, uses it directly
153
- * - If relative path, throws error
154
- * - If simple name, continues with path resolution
155
- * 2. Checks for Claude CLI at the local user path: ~/.claude/local/claude.
156
- * 3. If not found, defaults to the CLI name (or 'claude'), relying on the system's PATH for lookup.
157
- */
158
- export function findClaudeCli(): string {
159
- debugLog('[Debug] Attempting to find Claude CLI...');
160
-
161
- // Check for custom CLI name from environment variable
162
- const customCliName = process.env.CLAUDE_CLI_NAME;
163
- if (customCliName) {
164
- debugLog(`[Debug] Using custom Claude CLI name from CLAUDE_CLI_NAME: ${customCliName}`);
165
-
166
- // If it's an absolute path, use it directly
167
- if (path.isAbsolute(customCliName)) {
168
- debugLog(`[Debug] CLAUDE_CLI_NAME is an absolute path: ${customCliName}`);
169
- return customCliName;
170
- }
171
-
172
- // If it starts with ~ or ./, reject as relative paths are not allowed
173
- if (customCliName.startsWith('./') || customCliName.startsWith('../') || customCliName.includes('/')) {
174
- throw new Error(`Invalid CLAUDE_CLI_NAME: Relative paths are not allowed. Use either a simple name (e.g., 'claude') or an absolute path (e.g., '/tmp/claude-test')`);
175
- }
176
- }
177
-
178
- const cliName = customCliName || 'claude';
179
-
180
- // Try local install path: ~/.claude/local/claude (using the original name for local installs)
181
- const userPath = join(homedir(), '.claude', 'local', 'claude');
182
- debugLog(`[Debug] Checking for Claude CLI at local user path: ${userPath}`);
183
-
184
- if (existsSync(userPath)) {
185
- debugLog(`[Debug] Found Claude CLI at local user path: ${userPath}. Using this path.`);
186
- return userPath;
187
- } else {
188
- debugLog(`[Debug] Claude CLI not found at local user path: ${userPath}.`);
189
- }
190
-
191
- // 3. Fallback to CLI name (PATH lookup)
192
- debugLog(`[Debug] Falling back to "${cliName}" command name, relying on spawn/PATH lookup.`);
193
- console.warn(`[Warning] Claude CLI not found at ~/.claude/local/claude. Falling back to "${cliName}" in PATH. Ensure it is installed and accessible.`);
194
- return cliName;
195
- }
196
-
197
- // Re-export resolveModelAlias for backward compatibility
198
- export { resolveModelAlias } from './cli-builder.js';
199
-
200
54
  // Ensure spawnAsync is defined correctly *before* the class
201
55
  export async function spawnAsync(command: string, args: string[], options?: { timeout?: number, cwd?: string }): Promise<{ stdout: string; stderr: string }> {
202
56
  return new Promise((resolve, reject) => {
@@ -308,7 +162,7 @@ export class ClaudeCodeServer {
308
162
  **IMPORTANT**: This tool now returns immediately with a PID. Use other tools to check status and get results.
309
163
 
310
164
  **Supported models**:
311
- "claude-ultra", "codex-ultra", "gemini-ultra", "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1-codex-max", "gpt-5.2", "gpt-5.1", "gpt-5.1-codex", "gpt-5-codex", "gpt-5-codex-mini", "gpt-5", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-3-pro-preview", "gemini-3-flash-preview"
165
+ "claude-ultra", "codex-ultra", "gemini-ultra", "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1-codex-max", "gpt-5.2", "gpt-5.1", "gpt-5.1-codex", "gpt-5-codex", "gpt-5-codex-mini", "gpt-5", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview"
312
166
 
313
167
  **Prompt input**: You must provide EITHER prompt (string) OR prompt_file (file path), but not both.
314
168
 
@@ -336,7 +190,7 @@ export class ClaudeCodeServer {
336
190
  },
337
191
  model: {
338
192
  type: 'string',
339
- description: 'The model to use. Aliases: "claude-ultra", "codex-ultra" (auto high-reasoning), "gemini-ultra". Standard: "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1", "gemini-2.5-pro", "gemini-3-pro-preview", "gemini-3-flash-preview", etc.',
193
+ description: 'The model to use. Aliases: "claude-ultra", "codex-ultra" (auto high-reasoning), "gemini-ultra". Standard: "sonnet", "sonnet[1m]", "opus", "opusplan", "haiku", "gpt-5.3-codex", "gpt-5.2-codex", "gpt-5.1-codex-mini", "gpt-5.1", "gemini-2.5-pro", "gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview", etc.',
340
194
  },
341
195
  reasoning_effort: {
342
196
  type: 'string',
@@ -344,7 +198,7 @@ export class ClaudeCodeServer {
344
198
  },
345
199
  session_id: {
346
200
  type: 'string',
347
- description: 'Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview.',
201
+ description: 'Optional session ID to resume a previous session. Supported for: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3.1-pro-preview, gemini-3-pro-preview, gemini-3-flash-preview.',
348
202
  },
349
203
  },
350
204
  required: ['workFolder'],