Skip to main content
Glama

consult_codex

Process prompts with OpenAI's Codex AI to generate structured text, JSON, or code responses for batch processing and analysis tasks.

Instructions

Consult Codex in non-interactive mode with structured output. Processes prompt and returns formatted response. Supports text, JSON, and code extraction formats. Args: query: The prompt to send to Codex directory: Working directory (required) format: Output format - "text", "json", or "code" (default: "json") timeout: Optional timeout in seconds (overrides env var, recommended: 60-120) Returns: Formatted response based on format parameter

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
directoryYes
formatNojson
timeoutNo

Implementation Reference

  • The primary handler for the 'consult_codex' MCP tool. Decorated with @mcp.tool() for automatic registration and schema inference. Runs 'codex exec' CLI subprocess with query, supports JSON/text/code formats, Windows compatibility, timeouts (default 90s), git check skip, full error handling with structured JSON errors.
    @mcp.tool() def consult_codex( query: str, directory: str, format: str = "json", timeout: Optional[int] = None ) -> str: """ Consult Codex in non-interactive mode with structured output. Processes prompt and returns formatted response. Supports text, JSON, and code extraction formats. Args: query: The prompt to send to Codex directory: Working directory (required) format: Output format - "text", "json", or "code" (default: "json") timeout: Optional timeout in seconds (overrides env var, recommended: 60-120) Returns: Formatted response based on format parameter """ # Check if codex CLI is available if not _get_codex_command(): error_response = "Error: Codex CLI not found. Install from OpenAI" if format == "json": return json.dumps({"status": "error", "error": error_response}, indent=2) return error_response # Validate directory if not os.path.isdir(directory): error_response = f"Error: Directory does not exist: {directory}" if format == "json": return json.dumps({"status": "error", "error": error_response}, indent=2) return error_response # Validate format if format not in ["text", "json", "code"]: error_response = f"Error: Invalid format '{format}'. Must be 'text', 'json', or 'code'" # Always return JSON for invalid format errors for consistency return json.dumps({"status": "error", "error": error_response}, indent=2) # Prepare query based on format if format == "json": processed_query = _format_prompt_for_json(query) else: processed_query = query # Setup command and timeout cmd = _build_codex_exec_command() if _should_skip_git_check(): cmd.append("--skip-git-repo-check") timeout_value = timeout or _get_timeout() # Execute with timing start_time = time.time() try: result = _run_codex_command(cmd, directory, timeout_value, processed_query) execution_time = time.time() - start_time if result.returncode == 0: cleaned_output = _clean_codex_output(result.stdout) raw_response = cleaned_output if cleaned_output else "No output from Codex CLI" return _format_response(raw_response, format, execution_time, directory) else: error_response = f"Codex CLI Error: {result.stderr.strip()}" if format == "json": return json.dumps({ "status": "error", "error": error_response, "metadata": { "execution_time": execution_time, "directory": directory, "format": format } }, indent=2) return error_response except subprocess.TimeoutExpired: error_response = f"Error: Codex CLI command timed out after {timeout_value} seconds" if format == "json": return json.dumps({ "status": "error", "error": error_response, "metadata": { "timeout": timeout_value, "directory": directory, "format": format } }, indent=2) return error_response except FileNotFoundError as e: # More specific error for when codex command is not found codex_path = _get_codex_command() if _is_windows(): error_response = ( f"Error: Codex CLI not found or not executable. " f"Detected path: {codex_path or 'None'}. " f"Please ensure 'codex' is installed and in your PATH. " f"Try running 'codex --version' in Command Prompt to verify." ) else: error_response = f"Error: Codex CLI not found: {str(e)}" if format == "json": return json.dumps({ "status": "error", "error": error_response, "metadata": { "directory": directory, "format": format, "platform": platform.system() } }, indent=2) return error_response except Exception as e: error_response = f"Error executing Codex CLI: {str(e)}" if format == "json": return json.dumps({ "status": "error", "error": error_response, "metadata": { "directory": directory, "format": format, "platform": platform.system(), "exception_type": type(e).__name__ } }, indent=2) return error_response
  • Input schema defined by function parameters and comprehensive docstring. query (str): prompt; directory (str): cwd; format (str='json'): output type; timeout (int=None): seconds. Returns str (formatted response or JSON). FastMCP infers Pydantic schema automatically.
    def consult_codex( query: str, directory: str, format: str = "json", timeout: Optional[int] = None ) -> str: """ Consult Codex in non-interactive mode with structured output. Processes prompt and returns formatted response. Supports text, JSON, and code extraction formats. Args: query: The prompt to send to Codex directory: Working directory (required) format: Output format - "text", "json", or "code" (default: "json") timeout: Optional timeout in seconds (overrides env var, recommended: 60-120) Returns: Formatted response based on format parameter """
  • Key helper function that executes the 'codex exec' subprocess. Handles Windows UTF-8 I/O issues, timeouts, stdin piping, cross-platform env vars, and safe output decoding. Central to all consult_codex variants.
    def _run_codex_command(cmd: List[str], directory: str, timeout_value: int, input_text: str) -> subprocess.CompletedProcess: """Execute codex command with platform-specific handling. Args: cmd: Command list to execute directory: Working directory timeout_value: Timeout in seconds input_text: Input text to pipe to the command Returns: CompletedProcess result with stdout/stderr as strings """ # Windows-specific handling with UTF-8 encoding support if _is_windows(): # On Windows, we need to: # 1. Use encoding='utf-8' instead of text=True to avoid code page issues # 2. Set PYTHONUTF8=1 and PYTHONIOENCODING=utf-8 for consistent encoding # 3. Don't use start_new_session as it's not supported on Windows env = os.environ.copy() env['PYTHONUTF8'] = '1' env['PYTHONIOENCODING'] = 'utf-8' # Encode input as UTF-8 bytes input_bytes = input_text.encode('utf-8') if input_text else None result = subprocess.run( cmd, cwd=directory, capture_output=True, timeout=timeout_value, input=input_bytes, shell=False, env=env ) # Decode output as UTF-8 with error handling return subprocess.CompletedProcess( args=result.args, returncode=result.returncode, stdout=result.stdout.decode('utf-8', errors='replace') if result.stdout else '', stderr=result.stderr.decode('utf-8', errors='replace') if result.stderr else '' ) else: # Unix/macOS handling (original behavior) return subprocess.run( cmd, cwd=directory, capture_output=True, text=True, timeout=timeout_value, input=input_text, start_new_session=True )
  • Formats tool output per user request: extracts JSON from Codex response, wraps with metadata (time, dir), parses code blocks. Ensures structured MCP-compliant responses.
    def _format_response(raw_response: str, format_type: str, execution_time: float, directory: str) -> str: """Format response according to specified output format.""" if format_type == "text": return raw_response elif format_type == "json": # Try to extract JSON from response first extracted_json = _extract_json_from_response(raw_response) if extracted_json: # Wrap extracted JSON in standard structure return json.dumps({ "status": "success", "response": extracted_json, "metadata": { "execution_time": execution_time, "directory": directory, "format": "json" } }, indent=2) else: # Fallback: wrap raw response return json.dumps({ "status": "success", "response": raw_response, "metadata": { "execution_time": execution_time, "directory": directory, "format": "json" } }, indent=2) elif format_type == "code": # Extract code blocks code_blocks = re.findall(r'```(\w+)?\n(.*?)\n```', raw_response, re.DOTALL) return json.dumps({ "status": "success", "response": raw_response, "code_blocks": [{"language": lang or "text", "code": code.strip()} for lang, code in code_blocks], "metadata": { "execution_time": execution_time, "directory": directory, "format": "code" } }, indent=2) else: return raw_response
  • Extracts structured JSON from raw Codex CLI output by filtering noise and regex-parsing JSON blocks. Validates structure before returning.
    def _extract_json_from_response(response: str) -> Optional[Dict]: """Extract JSON from mixed text response using regex.""" # Clean the response to remove CLI noise lines = response.split('\n') clean_lines = [] json_started = False for line in lines: # Skip CLI headers and metadata if (line.startswith('[') and ']' in line and ('OpenAI' in line or 'workdir:' in line or 'model:' in line)): continue if line.startswith('--------'): continue if 'tokens used:' in line: continue if 'thinking' in line and line.startswith('['): continue if 'codex' in line and line.startswith('['): continue # Look for JSON content if '{' in line: json_started = True if json_started: clean_lines.append(line) clean_response = '\n'.join(clean_lines) # Try to find complete JSON objects json_pattern = r'\{(?:[^{}]|{[^{}]*})*\}' matches = re.findall(json_pattern, clean_response, re.DOTALL) for match in matches: try: parsed = json.loads(match.strip()) # Validate it has expected structure if isinstance(parsed, dict) and any(key in parsed for key in ['result', 'response', 'answer']): return parsed except json.JSONDecodeError: continue return None

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/eLyiN/codex-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server