From c2c938f10250a47d78ceac6c50e03f68eaa320ce Mon Sep 17 00:00:00 2001 From: Kirill Dubovitskiy Date: Thu, 9 Oct 2025 20:05:07 -0700 Subject: [PATCH] fix: auto-detect codex version and use correct MCP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes compatibility issues with codex versions 0.43.0-alpha.5 and later which introduced the new 'mcp-server' subcommand. The code now: - Detects the installed codex version at runtime - Uses 'mcp-server' for versions >= 0.43.0-alpha.5 - Falls back to 'mcp' for older versions - Defaults to 'mcp-server' if version detection fails This resolves MCP connection errors when using newer codex versions. Fixes #39 🤖 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- src/codex/codexMcpClient.ts | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/codex/codexMcpClient.ts b/src/codex/codexMcpClient.ts index 68bd7eb7..8a8c334d 100644 --- a/src/codex/codexMcpClient.ts +++ b/src/codex/codexMcpClient.ts @@ -9,9 +9,40 @@ import type { CodexSessionConfig, CodexToolResponse } from './types'; import { z } from 'zod'; import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js'; import { CodexPermissionHandler } from './utils/permissionHandler'; +import { execSync } from 'child_process'; const DEFAULT_TIMEOUT = 14 * 24 * 60 * 60 * 1000; // 14 days, which is the half of the maximum possible timeout (~28 days for int32 value in NodeJS) +/** + * Get the correct MCP subcommand based on installed codex version + * Versions >= 0.43.0-alpha.5 use 'mcp-server', older versions use 'mcp' + */ +function getCodexMcpCommand(): string { + try { + const version = execSync('codex --version', { encoding: 'utf8' }).trim(); + const match = version.match(/codex-cli\s+(\d+\.\d+\.\d+(?:-alpha\.\d+)?)/); + if (!match) return 'mcp-server'; // Default to newer command if we can't parse + + const versionStr = match[1]; + const [major, minor, patch] = versionStr.split(/[-.]/).map(Number); + + // Version >= 0.43.0-alpha.5 has mcp-server + if (major > 0 || minor > 43) return 'mcp-server'; + if (minor === 43 && patch === 0) { + // Check for alpha version + if (versionStr.includes('-alpha.')) { + const alphaNum = parseInt(versionStr.split('-alpha.')[1]); + return alphaNum >= 5 ? 'mcp-server' : 'mcp'; + } + return 'mcp-server'; // 0.43.0 stable has mcp-server + } + return 'mcp'; // Older versions use mcp + } catch (error) { + logger.debug('[CodexMCP] Error detecting codex version, defaulting to mcp-server:', error); + return 'mcp-server'; // Default to newer command + } +} + export class CodexMcpClient { private client: Client; private transport: StdioClientTransport | null = null; @@ -53,11 +84,12 @@ export class CodexMcpClient { async connect(): Promise { if (this.connected) return; - logger.debug('[CodexMCP] Connecting to Codex MCP server...'); + const mcpCommand = getCodexMcpCommand(); + logger.debug(`[CodexMCP] Connecting to Codex MCP server using command: codex ${mcpCommand}`); this.transport = new StdioClientTransport({ command: 'codex', - args: ['mcp'] + args: [mcpCommand] }); // Register request handlers for Codex permission methods