ai-cli-mcp 2.4.0 → 2.6.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.
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "acm-dev": {
4
+ "command": "npm",
5
+ "args": [
6
+ "run",
7
+ "dev"
8
+ ]
9
+ }
10
+ }
11
+ }
package/.mcp.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "acm-dev": {
4
4
  "command": "npm",
5
5
  "args": [
6
- "start"
6
+ "run",
7
+ "dev"
7
8
  ]
8
9
  }
9
10
  }
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # [2.6.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.5.0...v2.6.0) (2026-02-09)
2
+
3
+
4
+ ### Features
5
+
6
+ * update model support (gpt-5.3-codex, sonnet[1m], opusplan) and refactor README ([eb6574d](https://github.com/mkXultra/claude-code-mcp/commit/eb6574d3760269d4be96cd934bc03d94ccb3801f))
7
+
8
+ # [2.5.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.4.0...v2.5.0) (2026-01-24)
9
+
10
+
11
+ ### Features
12
+
13
+ * enhance output parsers for Codex and Claude with tool usage extraction ([b6410a1](https://github.com/mkXultra/claude-code-mcp/commit/b6410a104666eca592735acea093b877c0f03f64))
14
+ * track command execution in Codex output and include .gemini config ([91f7f06](https://github.com/mkXultra/claude-code-mcp/commit/91f7f067a1d453fd8e3a5a95bb90f21b7df0af8a))
15
+ * update Claude CLI args to stream-json and add verbose option to get_result ([b7f9abc](https://github.com/mkXultra/claude-code-mcp/commit/b7f9abc11c56ad0c8c95e90a614d1d869d8a3bfa))
16
+
1
17
  # [2.4.0](https://github.com/mkXultra/claude-code-mcp/compare/v2.3.3...v2.4.0) (2026-01-24)
2
18
 
3
19
 
package/README.ja.md CHANGED
@@ -9,8 +9,6 @@ AI CLIツール(Claude, Codex, Gemini)をバックグラウンドプロセ
9
9
 
10
10
  Cursorなどのエディタが、複雑な手順を伴う編集や操作に苦戦していることに気づいたことはありませんか?このサーバーは、強力な統合 `run` ツールを提供し、複数のAIエージェントを活用してコーディングタスクをより効果的に処理できるようにします。
11
11
 
12
- <img src="assets/screenshot.png" width="300" alt="Screenshot">
13
-
14
12
  ## 概要
15
13
 
16
14
  このMCPサーバーは、LLMがAI CLIツールと対話するためのツールを提供します。MCPクライアントと統合することで、LLMは以下のことが可能になります:
@@ -19,8 +17,8 @@ Cursorなどのエディタが、複雑な手順を伴う編集や操作に苦
19
17
  - 自動承認モードでCodex CLIを実行(`--full-auto` を使用)
20
18
  - 自動承認モードでGemini CLIを実行(`-y` を使用)
21
19
  - 複数のAIモデルのサポート:
22
- - Claude (sonnet, opus, haiku)
23
- - Codex (gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, など)
20
+ - Claude (sonnet, sonnet[1m], opus, opusplan, haiku)
21
+ - Codex (gpt-5.3-codex, gpt-5.2-codex, gpt-5.1-codex-mini, gpt-5.1-codex-max, など)
24
22
  - Gemini (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview)
25
23
  - PID追跡によるバックグラウンドプロセスの管理
26
24
  - ツールからの構造化された出力の解析と返却
@@ -134,10 +132,10 @@ Claude CLI、Codex CLI、またはGemini CLIを使用してプロンプトを実
134
132
  - `workFolder` (string, 必須): CLIを実行する作業ディレクトリ。絶対パスである必要があります。
135
133
  - **モデル (Models):**
136
134
  - **Ultra エイリアス:** `claude-ultra`, `codex-ultra` (自動的に high-reasoning に設定), `gemini-ultra`
137
- - Claude: `sonnet`, `opus`, `haiku`
138
- - Codex: `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
135
+ - Claude: `sonnet`, `sonnet[1m]`, `opus`, `opusplan`, `haiku`
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`
139
137
  - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
140
- - `reasoning_effort` (string, 任意): Codex専用。`model_reasoning_effort` を設定します(許容値: "low", "medium", "high")。
138
+ - `reasoning_effort` (string, 任意): Codex専用。`model_reasoning_effort` を設定します(許容値: "low", "medium", "high", "xhigh")。
141
139
  - `session_id` (string, 任意): 以前のセッションを再開するためのセッションID。対応モデル: haiku, sonnet, opus, gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview, gemini-3-flash-preview。
142
140
 
143
141
  ### `wait`
package/README.md CHANGED
@@ -11,8 +11,6 @@ An MCP (Model Context Protocol) server that allows running AI CLI tools (Claude,
11
11
 
12
12
  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
13
 
14
- <img src="assets/screenshot.png" width="300" alt="Screenshot">
15
-
16
14
  ## Overview
17
15
 
18
16
  This MCP server provides tools that can be used by LLMs to interact with AI CLI tools. When integrated with MCP clients, it allows LLMs to:
@@ -20,7 +18,7 @@ This MCP server provides tools that can be used by LLMs to interact with AI CLI
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
20
  - Execute Gemini CLI with automatic approval mode (using `-y`)
23
- - Support multiple AI models: Claude (sonnet, opus, haiku), 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-pro-preview, gemini-3-flash-preview)
24
22
  - Manage background processes with PID tracking
25
23
  - Parse and return structured outputs from both tools
26
24
 
@@ -133,10 +131,10 @@ Executes a prompt using Claude CLI, Codex CLI, or Gemini CLI. The appropriate CL
133
131
  - `workFolder` (string, required): The working directory for the CLI execution. Must be an absolute path.
134
132
  **Models:**
135
133
  - **Ultra Aliases:** `claude-ultra`, `codex-ultra` (defaults to high-reasoning), `gemini-ultra`
136
- - Claude: `sonnet`, `opus`, `haiku`
137
- - Codex: `gpt-5.2-codex`, `gpt-5.1-codex-mini`, `gpt-5.1-codex-max`, `gpt-5.2`, `gpt-5.1`, `gpt-5`
134
+ - Claude: `sonnet`, `sonnet[1m]`, `opus`, `opusplan`, `haiku`
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`
138
136
  - Gemini: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
139
- - `reasoning_effort` (string, optional): Codex only. Sets `model_reasoning_effort` (allowed: "low", "medium", "high").
137
+ - `reasoning_effort` (string, optional): Codex only. Sets `model_reasoning_effort` (allowed: "low", "medium", "high", "xhigh").
140
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.
141
139
 
142
140
  ### `wait`
@@ -165,77 +163,6 @@ Terminates a running AI agent process by PID.
165
163
  **Arguments:**
166
164
  - `pid` (number, required): The process ID to terminate.
167
165
 
168
- ### Examples
169
-
170
- Here are some visual examples of the server in action:
171
-
172
- <img src="assets/claude_tool_git_example.png" alt="Claude Tool Git Example" width="50%">
173
-
174
- <img src="assets/additional_claude_screenshot.png" alt="Additional Claude Screenshot" width="50%">
175
-
176
- <img src="assets/cursor-screenshot.png" alt="Cursor Screenshot" width="50%">
177
-
178
- ### Fixing ESLint Setup
179
-
180
- Here's an example of using the Claude Code MCP tool to interactively fix an ESLint setup by deleting old configuration files and creating a new one:
181
-
182
- <img src="assets/eslint_example.png" alt="ESLint file operations example" width="50%">
183
-
184
- ### Listing Files Example
185
-
186
- Here's an example of the Claude Code tool listing files in a directory:
187
-
188
- <img src="assets/file_list_example.png" alt="File listing example" width="50%">
189
-
190
- ## Key Use Cases
191
-
192
- This server, through its unified `run` tool, unlocks a wide range of powerful capabilities by giving your AI direct access to both Claude and Codex CLI tools. Here are some examples of what you can achieve:
193
-
194
- 1. **Code Generation, Analysis & Refactoring:**
195
- - `"Generate a Python script to parse CSV data and output JSON."`
196
- - `"Analyze my_script.py for potential bugs and suggest improvements."`
197
-
198
- 2. **File System Operations (Create, Read, Edit, Manage):**
199
- - **Creating Files:** `"Your work folder is /Users/steipete/my_project\n\nCreate a new file named 'config.yml' in the 'app/settings' directory with the following content:\nport: 8080\ndatabase: main_db"`
200
- - **Editing Files:** `"Your work folder is /Users/steipete/my_project\n\nEdit file 'public/css/style.css': Add a new CSS rule at the end to make all 'h2' elements have a 'color: navy'."`
201
- - **Moving/Copying/Deleting:** `"Your work folder is /Users/steipete/my_project\n\nMove the file 'report.docx' from the 'drafts' folder to the 'final_reports' folder and rename it to 'Q1_Report_Final.docx'."`
202
-
203
- 3. **Version Control (Git):**
204
- - `"Your work folder is /Users/steipete/my_project\n\n1. Stage the file 'src/main.java'.\n2. Commit the changes with the message 'feat: Implement user authentication'.\n3. Push the commit to the 'develop' branch on origin."`
205
-
206
- 4. **Running Terminal Commands:**
207
- - `"Your work folder is /Users/steipete/my_project/frontend\n\nRun the command 'npm run build'."`
208
- - `"Open the URL https://developer.mozilla.org in my default web browser."`
209
-
210
- 5. **Web Search & Summarization:**
211
- - `"Search the web for 'benefits of server-side rendering' and provide a concise summary."`
212
-
213
- 6. **Complex Multi-Step Workflows:**
214
- - Automate version bumps, update changelogs, and tag releases: `"Your work folder is /Users/steipete/my_project\n\nFollow these steps: 1. Update the version in package.json to 2.5.0. 2. Add a new section to CHANGELOG.md for version 2.5.0 with the heading '### Added' and list 'New feature X'. 3. Stage package.json and CHANGELOG.md. 4. Commit with message 'release: version 2.5.0'. 5. Push the commit. 6. Create and push a git tag v2.5.0."`
215
-
216
- <img src="assets/multistep_example.png" alt="Complex multi-step operation example" width="50%">
217
-
218
- 7. **Repairing Files with Syntax Errors:**
219
- - `"Your work folder is /path/to/project\n\nThe file 'src/utils/parser.js' has syntax errors after a recent complex edit that broke its structure. Please analyze it, identify the syntax errors, and correct the file to make it valid JavaScript again, ensuring the original logic is preserved as much as possible."`
220
-
221
- 8. **Interacting with GitHub (e.g., Creating a Pull Request):**
222
- - `"Your work folder is /Users/steipete/my_project\n\nCreate a GitHub Pull Request in the repository 'owner/repo' from the 'feature-branch' to the 'main' branch. Title: 'feat: Implement new login flow'. Body: 'This PR adds a new and improved login experience for users.'"`
223
-
224
- 9. **Interacting with GitHub (e.g., Checking PR CI Status):**
225
- - `"Your work folder is /Users/steipete/my_project\n\nCheck the status of CI checks for Pull Request #42 in the GitHub repository 'owner/repo'. Report if they have passed, failed, or are still running."`
226
-
227
- ### Correcting GitHub Actions Workflow
228
-
229
- <img src="assets/github_actions_fix_example.png" alt="GitHub Actions workflow fix example" width="50%">
230
-
231
- ### Complex Multi-Step Operations
232
-
233
- This example illustrates the AI agent handling a more complex, multi-step task, such as preparing a release by creating a branch, updating multiple files (`package.json`, `CHANGELOG.md`), committing changes, and initiating a pull request, all within a single, coherent operation.
234
-
235
- <img src="assets/claude_code_multistep_example.png" alt="AI agent multi-step example" width="50%">
236
-
237
- **CRITICAL: Remember to provide Current Working Directory (CWD) context in your prompts for file system or git operations (e.g., `"Your work folder is /path/to/project\n\n...your command..."`).**
238
-
239
166
  ## Troubleshooting
240
167
 
241
168
  - **"Command not found" (claude-code-mcp):** If installed globally, ensure the npm global bin directory is in your system's PATH. If using `npx`, ensure `npx` itself is working.
@@ -244,76 +171,9 @@ This example illustrates the AI agent handling a more complex, multi-step task,
244
171
  - **JSON Errors from Server:** If `MCP_CLAUDE_DEBUG` is `true`, error messages or logs might interfere with MCP's JSON parsing. Set to `false` for normal operation.
245
172
  - **ESM/Import Errors:** Ensure you are using Node.js v20 or later.
246
173
 
247
- **For Developers: Local Setup & Contribution**
248
-
249
- If you want to develop or contribute to this server, or run it from a cloned repository for testing, please see our [Local Installation & Development Setup Guide](./docs/local_install.md).
250
-
251
- ## Testing
252
-
253
- The project includes comprehensive test suites:
254
-
255
- ```bash
256
- # Run all tests
257
- npm test
258
-
259
- # Run unit tests only
260
- npm run test:unit
261
-
262
- # Run e2e tests (with mocks)
263
- npm run test:e2e
264
-
265
- # Run e2e tests locally (requires Claude CLI)
266
- npm run test:e2e:local
267
-
268
- # Watch mode for development
269
- npm run test:watch
270
-
271
- # Coverage report
272
- npm run test:coverage
273
- ```
274
-
275
- For detailed testing documentation, see our [E2E Testing Guide](./docs/e2e-testing.md).
276
-
277
- ## Manual Testing with MCP Inspector
278
-
279
- You can manually test the MCP server using the Model Context Protocol Inspector:
280
-
281
- ```bash
282
- # Build the project first
283
- npm run build
284
-
285
- # Start the MCP Inspector with the server
286
- npx @modelcontextprotocol/inspector node dist/server.js
287
- ```
288
-
289
- This will open a web interface where you can:
290
- 1. View all available tools (`run`, `list_processes`, `get_result`, `kill_process`)
291
- 2. Test each tool with different parameters
292
- 3. Test different AI models including:
293
- - Claude models: `sonnet`, `opus`, `haiku`
294
- - Codex models: `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`
295
- - Gemini models: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-3-pro-preview`, `gemini-3-flash-preview`
296
-
297
- Example test: Select the `run` tool and provide:
298
- - `prompt`: "What is 2+2?"
299
- - `workFolder`: "/tmp"
300
- - `model`: "gemini-2.5-flash"
301
-
302
- ## Configuration via Environment Variables
303
-
304
- The server's behavior can be customized using these environment variables:
305
-
306
- - `CLAUDE_CLI_PATH`: Absolute path to the Claude CLI executable.
307
- - Default: Checks `~/.claude/local/claude`, then falls back to `claude` (expecting it in PATH).
308
- - `MCP_CLAUDE_DEBUG`: Set to `true` for verbose debug logging from this MCP server. Default: `false`.
309
-
310
- These can be set in your shell environment or within the `env` block of your `mcp.json` server configuration (though the `env` block in `mcp.json` examples was removed for simplicity, it's still a valid way to set them for the server process if needed).
311
-
312
174
  ## Contributing
313
175
 
314
- Contributions are welcome! Please refer to the [Local Installation & Development Setup Guide](./docs/local_install.md) for details on setting up your environment.
315
-
316
- Submit issues and pull requests to the [GitHub repository](https://github.com/mkXultra/claude-code-mcp).
176
+ For development setup, testing, and contribution guidelines, see the [Development Guide](./docs/development.md).
317
177
 
318
178
  ## Advanced Configuration (Optional)
319
179
 
@@ -0,0 +1,98 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseCodexOutput, parseClaudeOutput } from '../parsers.js';
3
+ describe('parseCodexOutput', () => {
4
+ it('should parse basic Codex output with message and session_id', () => {
5
+ const output = `
6
+ {"type":"thread.started","thread_id":"test-session-id"}
7
+ {"type":"turn.started"}
8
+ {"type":"item.completed","item":{"type":"agent_message","text":"Hello world"}}
9
+ {"type":"turn.completed"}
10
+ `;
11
+ const result = parseCodexOutput(output);
12
+ expect(result).toEqual({
13
+ message: "Hello world",
14
+ session_id: "test-session-id",
15
+ token_count: null,
16
+ tools: undefined
17
+ });
18
+ });
19
+ it('should extract MCP tool calls', () => {
20
+ const output = `
21
+ {"type":"thread.started","thread_id":"tool-test-id"}
22
+ {"type":"turn.started"}
23
+ {"type":"item.completed","item":{"id":"item_1","type":"mcp_tool_call","server":"acm","tool":"run","arguments":{"model":"gemini-2.5-flash","prompt":"hi"},"result":{"content":[{"text":"started","type":"text"}]},"status":"completed"}}
24
+ {"type":"item.completed","item":{"type":"agent_message","text":"Tool executed"}}
25
+ {"type":"turn.completed"}
26
+ `;
27
+ const result = parseCodexOutput(output);
28
+ expect(result.message).toBe("Tool executed");
29
+ expect(result.session_id).toBe("tool-test-id");
30
+ expect(result.tools).toHaveLength(1);
31
+ expect(result.tools[0]).toEqual({
32
+ tool: "run",
33
+ server: "acm",
34
+ input: { model: "gemini-2.5-flash", prompt: "hi" },
35
+ output: { content: [{ text: "started", type: "text" }] }
36
+ });
37
+ });
38
+ it('should handle multiple tool calls', () => {
39
+ const output = `
40
+ {"type":"item.completed","item":{"type":"mcp_tool_call","tool":"tool1","arguments":{"arg":1},"result":"res1"}}
41
+ {"type":"item.completed","item":{"type":"mcp_tool_call","tool":"tool2","arguments":{"arg":2},"result":"res2"}}
42
+ `;
43
+ const result = parseCodexOutput(output);
44
+ expect(result.tools).toHaveLength(2);
45
+ expect(result.tools[0].tool).toBe("tool1");
46
+ expect(result.tools[1].tool).toBe("tool2");
47
+ });
48
+ it('should return null for empty input', () => {
49
+ expect(parseCodexOutput("")).toBeNull();
50
+ });
51
+ it('should handle invalid JSON gracefully', () => {
52
+ const output = `
53
+ {"type":"valid"}
54
+ INVALID_JSON
55
+ {"type":"item.completed","item":{"type":"agent_message","text":"Still parses valid lines"}}
56
+ `;
57
+ const result = parseCodexOutput(output);
58
+ expect(result.message).toBe("Still parses valid lines");
59
+ });
60
+ });
61
+ describe('parseClaudeOutput', () => {
62
+ it('should parse legacy JSON output', () => {
63
+ const output = JSON.stringify({
64
+ content: [{ type: 'text', text: 'Hello' }]
65
+ });
66
+ const result = parseClaudeOutput(output);
67
+ expect(result).toEqual({
68
+ content: [{ type: 'text', text: 'Hello' }]
69
+ });
70
+ });
71
+ it('should parse stream-json (NDJSON) output', () => {
72
+ const output = `
73
+ {"type":"system","session_id":"test-claude-session"}
74
+ {"type":"assistant","message":{"content":[{"type":"text","text":"Thinking..."}]}}
75
+ {"type":"assistant","message":{"content":[{"type":"tool_use","id":"call_1","name":"mcp__acm__run","input":{"prompt":"hi"}}]}}
76
+ {"type":"user","message":{"content":[{"type":"tool_result","tool_use_id":"call_1","content":"done"}]}}
77
+ {"type":"result","result":"Final Answer","is_error":false}
78
+ `;
79
+ const result = parseClaudeOutput(output);
80
+ expect(result.message).toBe("Final Answer");
81
+ expect(result.session_id).toBe("test-claude-session");
82
+ expect(result.tools).toHaveLength(1);
83
+ expect(result.tools[0]).toEqual({
84
+ tool: "mcp__acm__run",
85
+ input: { prompt: "hi" },
86
+ output: "done"
87
+ });
88
+ });
89
+ it('should handle invalid NDJSON lines gracefully', () => {
90
+ const output = `
91
+ {"type":"system"}
92
+ INVALID_LINE
93
+ {"type":"result","result":"Success"}
94
+ `;
95
+ const result = parseClaudeOutput(output);
96
+ expect(result.message).toBe("Success");
97
+ });
98
+ });
@@ -652,7 +652,7 @@ describe('ClaudeCodeServer Unit Tests', () => {
652
652
  }
653
653
  });
654
654
  // Verify spawn was called with resolved model name
655
- expect(mockSpawn).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['--model', 'claude-3-5-haiku-20241022']), expect.any(Object));
655
+ expect(mockSpawn).toHaveBeenCalledWith(expect.any(String), expect.arrayContaining(['--model', 'haiku']), expect.any(Object));
656
656
  // Verify PID is returned
657
657
  expect(result.content[0].text).toContain('"pid": 12345');
658
658
  });
package/dist/parsers.js CHANGED
@@ -10,6 +10,7 @@ export function parseCodexOutput(stdout) {
10
10
  let lastMessage = null;
11
11
  let tokenCount = null;
12
12
  let threadId = null;
13
+ const tools = [];
13
14
  for (const line of lines) {
14
15
  if (line.trim()) {
15
16
  try {
@@ -29,6 +30,22 @@ export function parseCodexOutput(stdout) {
29
30
  else if (parsed.msg?.type === 'token_count') {
30
31
  tokenCount = parsed.msg;
31
32
  }
33
+ else if (parsed.type === 'item.completed' && parsed.item?.type === 'mcp_tool_call') {
34
+ tools.push({
35
+ server: parsed.item.server,
36
+ tool: parsed.item.tool,
37
+ input: parsed.item.arguments, // Map arguments to input to match common patterns
38
+ output: parsed.item.result
39
+ });
40
+ }
41
+ else if (parsed.type === 'item.completed' && parsed.item?.type === 'command_execution') {
42
+ tools.push({
43
+ tool: 'command_execution',
44
+ input: { command: parsed.item.command },
45
+ output: parsed.item.aggregated_output,
46
+ exit_code: parsed.item.exit_code
47
+ });
48
+ }
32
49
  }
33
50
  catch (e) {
34
51
  // Skip invalid JSON lines
@@ -36,11 +53,12 @@ export function parseCodexOutput(stdout) {
36
53
  }
37
54
  }
38
55
  }
39
- if (lastMessage || tokenCount || threadId) {
56
+ if (lastMessage || tokenCount || threadId || tools.length > 0) {
40
57
  return {
41
58
  message: lastMessage,
42
59
  token_count: tokenCount,
43
- session_id: threadId
60
+ session_id: threadId,
61
+ tools: tools.length > 0 ? tools : undefined
44
62
  };
45
63
  }
46
64
  }
@@ -50,18 +68,86 @@ export function parseCodexOutput(stdout) {
50
68
  return null;
51
69
  }
52
70
  /**
53
- * Parse Claude JSON output
71
+ * Parse Claude Output (supports both JSON and stream-json/NDJSON)
54
72
  */
55
73
  export function parseClaudeOutput(stdout) {
56
74
  if (!stdout)
57
75
  return null;
76
+ // First try parsing as a single JSON object (backward compatibility)
58
77
  try {
59
78
  return JSON.parse(stdout);
60
79
  }
61
80
  catch (e) {
62
- debugLog(`[Debug] Failed to parse Claude JSON output: ${e}`);
81
+ // If not valid single JSON, proceed to parse as NDJSON
82
+ }
83
+ try {
84
+ const lines = stdout.trim().split('\n');
85
+ let lastMessage = null;
86
+ let sessionId = null;
87
+ const toolsMap = new Map(); // Map by tool_use id for matching results
88
+ for (const line of lines) {
89
+ if (!line.trim())
90
+ continue;
91
+ try {
92
+ const parsed = JSON.parse(line);
93
+ // Extract session ID from any message that has it
94
+ if (parsed.session_id) {
95
+ sessionId = parsed.session_id;
96
+ }
97
+ // Extract final result message
98
+ if (parsed.type === 'result' && parsed.result) {
99
+ lastMessage = parsed.result;
100
+ }
101
+ // Extract tool usage from assistant messages
102
+ if (parsed.type === 'assistant' && parsed.message?.content) {
103
+ for (const content of parsed.message.content) {
104
+ if (content.type === 'tool_use') {
105
+ toolsMap.set(content.id, {
106
+ tool: content.name,
107
+ input: content.input,
108
+ output: null // Will be filled when tool_result is found
109
+ });
110
+ }
111
+ }
112
+ }
113
+ // Match tool results from user messages
114
+ if (parsed.type === 'user' && parsed.message?.content) {
115
+ for (const content of parsed.message.content) {
116
+ if (content.type === 'tool_result' && content.tool_use_id) {
117
+ const tool = toolsMap.get(content.tool_use_id);
118
+ if (tool) {
119
+ // Extract text from content array
120
+ if (Array.isArray(content.content)) {
121
+ const textContent = content.content.find((c) => c.type === 'text');
122
+ tool.output = textContent?.text || null;
123
+ }
124
+ else {
125
+ tool.output = content.content;
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ catch (e) {
133
+ debugLog(`[Debug] Skipping invalid JSON line in Claude output: ${line}`);
134
+ }
135
+ }
136
+ // Convert Map to array
137
+ const tools = Array.from(toolsMap.values());
138
+ if (lastMessage || sessionId || tools.length > 0) {
139
+ return {
140
+ message: lastMessage, // This is the final result text
141
+ session_id: sessionId,
142
+ tools: tools.length > 0 ? tools : undefined
143
+ };
144
+ }
145
+ }
146
+ catch (e) {
147
+ debugLog(`[Debug] Failed to parse Claude NDJSON output: ${e}`);
63
148
  return null;
64
149
  }
150
+ return null;
65
151
  }
66
152
  /**
67
153
  * Parse Gemini JSON output
package/dist/server.js CHANGED
@@ -12,12 +12,11 @@ import { parseCodexOutput, parseClaudeOutput, parseGeminiOutput } from './parser
12
12
  const SERVER_VERSION = "2.2.0";
13
13
  // Model alias mappings for user-friendly model names
14
14
  const MODEL_ALIASES = {
15
- 'haiku': 'claude-3-5-haiku-20241022',
16
15
  'claude-ultra': 'opus',
17
- 'codex-ultra': 'gpt-5.2-codex',
16
+ 'codex-ultra': 'gpt-5.3-codex',
18
17
  'gemini-ultra': 'gemini-3-pro-preview'
19
18
  };
20
- const ALLOWED_REASONING_EFFORTS = new Set(['low', 'medium', 'high']);
19
+ const ALLOWED_REASONING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh']);
21
20
  function getReasoningEffort(model, rawValue) {
22
21
  if (typeof rawValue !== 'string') {
23
22
  return '';
@@ -28,7 +27,7 @@ function getReasoningEffort(model, rawValue) {
28
27
  }
29
28
  const normalized = trimmed.toLowerCase();
30
29
  if (!ALLOWED_REASONING_EFFORTS.has(normalized)) {
31
- throw new McpError(ErrorCode.InvalidParams, `Invalid reasoning_effort: ${rawValue}. Allowed values: low, medium, high.`);
30
+ throw new McpError(ErrorCode.InvalidParams, `Invalid reasoning_effort: ${rawValue}. Allowed values: low, medium, high, xhigh.`);
32
31
  }
33
32
  if (!model.startsWith('gpt-')) {
34
33
  throw new McpError(ErrorCode.InvalidParams, 'reasoning_effort is only supported for Codex models (gpt-*).');
@@ -269,7 +268,7 @@ export class ClaudeCodeServer {
269
268
  **IMPORTANT**: This tool now returns immediately with a PID. Use other tools to check status and get results.
270
269
 
271
270
  **Supported models**:
272
- "claude-ultra", "codex-ultra", "gemini-ultra", "sonnet", "opus", "haiku", "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"
271
+ "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"
273
272
 
274
273
  **Prompt input**: You must provide EITHER prompt (string) OR prompt_file (file path), but not both.
275
274
 
@@ -297,11 +296,11 @@ export class ClaudeCodeServer {
297
296
  },
298
297
  model: {
299
298
  type: 'string',
300
- description: 'The model to use. Aliases: "claude-ultra", "codex-ultra" (auto high-reasoning), "gemini-ultra". Standard: "sonnet", "opus", "haiku", "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.',
299
+ 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.',
301
300
  },
302
301
  reasoning_effort: {
303
302
  type: 'string',
304
- description: 'Codex only. Sets model_reasoning_effort. Allowed: "low", "medium", "high".',
303
+ description: 'Codex only. Sets model_reasoning_effort. Allowed: "low", "medium", "high", "xhigh".',
305
304
  },
306
305
  session_id: {
307
306
  type: 'string',
@@ -329,6 +328,10 @@ export class ClaudeCodeServer {
329
328
  type: 'number',
330
329
  description: 'The process ID returned by run tool.',
331
330
  },
331
+ verbose: {
332
+ type: 'boolean',
333
+ description: 'Optional: If true, returns detailed execution information including tool usage history. Defaults to false.',
334
+ }
332
335
  },
333
336
  required: ['pid'],
334
337
  },
@@ -454,7 +457,7 @@ export class ClaudeCodeServer {
454
457
  // Special handling for codex-ultra: default to high reasoning effort if not specified
455
458
  let reasoningEffortArg = toolArguments.reasoning_effort;
456
459
  if (rawModel === 'codex-ultra' && !reasoningEffortArg) {
457
- reasoningEffortArg = 'high';
460
+ reasoningEffortArg = 'xhigh';
458
461
  }
459
462
  const reasoningEffort = getReasoningEffort(resolvedModel, reasoningEffortArg);
460
463
  let agent;
@@ -506,7 +509,7 @@ export class ClaudeCodeServer {
506
509
  else {
507
510
  // Handle Claude (default)
508
511
  cliPath = this.claudeCliPath;
509
- processArgs = ['--dangerously-skip-permissions', '--output-format', 'json'];
512
+ processArgs = ['--dangerously-skip-permissions', '--output-format', 'stream-json', '--verbose'];
510
513
  // Add session_id if provided (Claude only)
511
514
  if (toolArguments.session_id && typeof toolArguments.session_id === 'string') {
512
515
  processArgs.push('-r', toolArguments.session_id);
@@ -604,18 +607,20 @@ export class ClaudeCodeServer {
604
607
  /**
605
608
  * Helper to get process result object
606
609
  */
607
- getProcessResultHelper(pid) {
610
+ getProcessResultHelper(pid, verbose = false) {
608
611
  const process = processManager.get(pid);
609
612
  if (!process) {
610
613
  throw new McpError(ErrorCode.InvalidParams, `Process with PID ${pid} not found`);
611
614
  }
612
615
  // Parse output based on agent type
613
616
  let agentOutput = null;
614
- if (process.stdout) {
615
- if (process.toolType === 'codex') {
616
- agentOutput = parseCodexOutput(process.stdout);
617
- }
618
- else if (process.toolType === 'claude') {
617
+ if (process.toolType === 'codex') {
618
+ // Codex may output structured logs to stderr
619
+ const combinedOutput = (process.stdout || '') + '\n' + (process.stderr || '');
620
+ agentOutput = parseCodexOutput(combinedOutput);
621
+ }
622
+ else if (process.stdout) {
623
+ if (process.toolType === 'claude') {
619
624
  agentOutput = parseClaudeOutput(process.stdout);
620
625
  }
621
626
  else if (process.toolType === 'gemini') {
@@ -635,7 +640,14 @@ export class ClaudeCodeServer {
635
640
  };
636
641
  // If we have valid output from agent, include it
637
642
  if (agentOutput) {
638
- response.agentOutput = agentOutput;
643
+ // Filter out tools if not verbose
644
+ if (!verbose && agentOutput.tools) {
645
+ const { tools, ...rest } = agentOutput;
646
+ response.agentOutput = rest;
647
+ }
648
+ else {
649
+ response.agentOutput = agentOutput;
650
+ }
639
651
  // Extract session_id if available
640
652
  if (agentOutput.session_id) {
641
653
  response.session_id = agentOutput.session_id;
@@ -656,7 +668,8 @@ export class ClaudeCodeServer {
656
668
  throw new McpError(ErrorCode.InvalidParams, 'Missing or invalid required parameter: pid');
657
669
  }
658
670
  const pid = toolArguments.pid;
659
- const response = this.getProcessResultHelper(pid);
671
+ const verbose = !!toolArguments.verbose;
672
+ const response = this.getProcessResultHelper(pid, verbose);
660
673
  return {
661
674
  content: [{
662
675
  type: 'text',
@@ -706,8 +719,8 @@ export class ClaudeCodeServer {
706
719
  catch (error) {
707
720
  throw new McpError(ErrorCode.InternalError, error.message);
708
721
  }
709
- // Collect results
710
- const results = pids.map(pid => this.getProcessResultHelper(pid));
722
+ // Collect results (verbose=false for wait)
723
+ const results = pids.map(pid => this.getProcessResultHelper(pid, false));
711
724
  return {
712
725
  content: [{
713
726
  type: 'text',