Codex chạy ngầm trong Claude Code
Khi Codex có thể chạy headless bên trong Claude Code, điều đáng chú ý không chỉ là thêm một công cụ mới, mà là một cách chia việc nhẹ hơn giữa các agent.
Codex chạy ngầm trong Claude Code
Một xưởng làm việc tốt không bắt người thợ chính tự cầm mọi dụng cụ trong tay cùng lúc. Nó quan trọng ở chỗ dụng cụ nào nằm đúng chỗ, bật lên đúng lúc, trả lại kết quả đủ sạch để người thợ tiếp tục quyết định. Với AI coding, mình thấy chuyển động đáng chú ý nhất không phải là thêm một cửa sổ chat mới, mà là làm cho một agent (tác nhân AI có thể nhận nhiệm vụ, thao tác công cụ và trả kết quả) chạy như một phần hạ tầng phía sau một agent khác.
codex mcp-server làm đúng việc đó. Nó biến Codex thành một MCP (Model Context Protocol, giao thức mở để các ứng dụng AI gọi công cụ và dịch vụ theo cùng một chuẩn) server chạy qua stdio, không cần giao diện đồ họa, không cần một tab riêng để nhìn. Claude Code, Cursor, hoặc các môi trường hỗ trợ MCP có thể gọi Codex như gọi một tool trong lúc đang làm việc. Ở bề mặt, chuyện này nghe như “Claude gọi Codex”, nhưng ở tầng workflow, nó giống việc đặt một bàn phụ trong xưởng: khi có phần việc nặng, lặp lại, hoặc cần một năng lực khác, Claude Code giao sang Codex rồi nhận lại kết quả.
Điểm làm mình quan tâm không phải là cảm giác có hai chatbot cùng tham gia. Nếu chỉ thêm một màn hình nữa để mình phải prompt thêm, copy thêm, dán thêm, thì workflow sẽ nặng hơn chứ không nhẹ hơn. Giá trị thật nằm ở chỗ Claude Code vẫn là nơi mình đang làm việc, còn Codex chỉ hiện diện như một khả năng gọi được giữa chừng. Khi ranh giới này rõ, mình không bị kéo vào việc điều phối bằng tay quá nhiều.

Cài Codex như một MCP server trong Claude Code
Trước khi đi tiếp vào lý do dùng pattern này, mình ghi lại đúng các bước để wire Codex thành một MCP server mà Claude Code có thể gọi. Điều kiện cần là máy đã có Codex CLI cài rồi (codex --version chạy được) và đã codex login ít nhất một lần để token nằm ở ~/.codex/auth.json. Cách đăng ký với Claude Code thì có sẵn lệnh, không phải sửa file tay.
Lệnh cài trong scope user (áp dụng cho mọi project) là:
claude mcp add -s user codex -- env -u OPENAI_API_KEY codex mcp-server
Cú pháp tách thành ba phần: tên server (codex), dấu -- để Claude Code biết phần còn lại là lệnh subprocess thật sự, và lệnh env -u OPENAI_API_KEY codex mcp-server. Phần env -u OPENAI_API_KEY cố tình xóa biến môi trường OPENAI_API_KEY trước khi chạy, vì như phần sau bài này sẽ nói rõ, nếu biến đó tồn tại Codex sẽ âm thầm tính phí qua API key thay vì ChatGPT subscription. Đặt cờ này lúc cài là cách tốt nhất để workflow MCP luôn đi qua đường subscription mà mình đã codex login.
Tùy mục đích, có ba scope khác nhau. -s local là mặc định, chỉ có hiệu lực trong thư mục hiện tại. -s user (cách trên) lưu vào cấu hình toàn cục của Claude Code, áp dụng cho mọi project trên máy. -s project ghi vào file .mcp.json ngay trong repo, nên khi push lên Git cả team cùng có Codex MCP mà không phải tự cài lại. Với workflow cá nhân, user thường là lựa chọn sạch nhất; với repo dùng chung, project đáng cân nhắc.
Sau khi cài xong, kiểm tra bằng:
claude mcp list
Nếu thành công, dòng codex sẽ hiện kèm ký hiệu kết nối tốt, đại loại là codex: env -u OPENAI_API_KEY codex mcp-server - ✓ Connected. Nếu không thấy ✓, hai thứ cần check là codex có trong PATH không, và codex login đã chạy thành công chưa. Mở session Claude Code mới, MCP server codex sẽ xuất hiện như một tool có thể gọi giữa workflow, không cần thêm prompt đặc biệt nào.
Nếu muốn gỡ ra, lệnh tương ứng là:
claude mcp remove codex
Hai agent, hai đường đi
Hai agent không dư thừa nếu mỗi bên có đường đi riêng. Claude Code mạnh ở reasoning, giữ kế hoạch, đọc codebase dài, quản lý ngữ cảnh và ra quyết định tích hợp. Codex lại có đường auth riêng qua codex login, lưu ở ~/.codex/auth.json, có thể dùng ChatGPT subscription, và trong nhiều việc cụ thể như code, multimodal, image hoặc tác vụ cần chạy lệnh sạch, nó là một worker rất hợp. Mỗi bên còn có sandbox (vùng thực thi bị giới hạn để giảm rủi ro khi chạy lệnh hoặc sửa file), quyền truy cập, cách tính phí, và kiểu output khác nhau. Interop qua MCP giúp mình không phải chọn một bên như chọn hệ sinh thái duy nhất; mình có thể orchestration (điều phối nhiều tác nhân/công cụ theo kế hoạch chung) chúng theo vai trò.
Một lợi ích khá thực tế là context window (cửa sổ ngữ cảnh, tức lượng thông tin model có thể giữ trong một lượt làm việc) của Claude Code không bị phình vì các việc phụ. Trong một refactor, chẳng hạn, Claude cần giữ kiến trúc, trade-off, test strategy, và trạng thái repo. Nếu cũng bắt nó đọc toàn bộ log phụ, tạo biến thể ảnh, rà một danh sách lỗi lặp lại, hoặc trích xuất dữ liệu từ một đống note, phần ngữ cảnh chính sẽ đuối dần. Khi Codex làm phần phụ và trả lại output đã nén, Claude giữ được vai trò người tích hợp thay vì thành nơi chứa mọi mẩu vụn.
Headless là nền móng, không phải MCP
Nhưng nếu chỉ nhìn codex mcp-server, mình nghĩ ta mới thấy phần cửa. Nền móng sâu hơn là codex exec. Đây là chế độ headless (chạy không cần giao diện tương tác, phù hợp cho script, cron, CI/CD hoặc Docker) của Codex. Nó cho phép chạy Codex như một lệnh CLI (command-line interface, giao diện dòng lệnh), nghĩa là có thể nằm trong bash script, pipeline, job tự động, hoặc một quy trình deploy (đưa thay đổi lên môi trường chạy thật) mà không cần ai ngồi trước màn hình để bấm.
Sự khác biệt giữa một AI tool “có CLI” và một AI tool “thật sự headless” rất lớn. CLI có thể vẫn chỉ là một cách mở chat từ terminal. Headless đúng nghĩa phải chạy được không tương tác, nhận input từ file hoặc pipe, xuất kết quả có cấu trúc, và trả mã thoát đủ rõ để hệ thống khác hiểu. Với codex exec --json, Codex phát ra một dòng sự kiện JSONL có thể đọc bằng máy. Các event như thread.started, turn.started, item.completed, turn.completed cho phép một script biết tiến trình đang ở đâu, thay vì chỉ nhìn một đoạn văn trôi qua terminal.

--output-schema còn quan trọng hơn trong các pipeline nghiêm túc. Schema (khuôn dạng dữ liệu mô tả trường, kiểu và ràng buộc của output) giúp mình ép phản hồi về JSON theo cấu trúc đã định, thay vì hy vọng model viết đúng một đoạn markdown rồi dùng regex để móc dữ liệu. Regex trên văn bản AI sinh ra thường là một thói quen mỏng, vì chỉ cần model đổi cách xuống dòng hoặc thêm một câu lịch sự là pipeline có thể gãy. Khi output bị ràng buộc bởi JSON Schema, AI bắt đầu giống một thành phần trong hệ thống phần mềm hơn là một hộp thoại.
Ba use case headless trong workflow thật
Một use case rõ là tạo batch ảnh cho workshop. Thay vì mở từng prompt, chờ từng ảnh, lưu từng file, mình có thể viết script đọc danh sách chủ đề, gọi codex exec, yêu cầu tạo prompt ảnh theo một format nhất định, rồi đưa sang bước tạo asset. Codex lúc này không phải “người bạn chat”, mà là một công đoạn trong dây chuyền sản xuất học liệu. Claude Code vẫn có thể thiết kế cấu trúc workshop, còn Codex chạy phần lặp lại theo hàng.
Use case thứ hai là review PR tự động. codex exec review có thể nằm trong một CI job, đọc diff, kiểm tra một số tiêu chí, và trả lại nhận xét có cấu trúc. Mình không xem đây là thay thế review của người hoặc review sâu của Claude Code trong repo lớn. Nó giống một lớp lọc phụ: bắt các lỗi hiển nhiên, nhắc test thiếu, phát hiện pattern chưa nhất quán. Khi đặt trong CI/CD, giá trị nằm ở tính đều đặn, không phải ở việc nó phán quyết cuối cùng.
Use case thứ ba là trích xuất có cấu trúc từ nội dung lộn xộn. Email, meeting note, brief khách hàng, comment dài trong issue, tất cả thường có thông tin hữu ích nhưng không nằm trong bảng. Nếu pipe nội dung qua codex exec --output-schema, mình có thể lấy ra fields như stakeholders, deadlines, risks, action_items, unknowns. Phần này đặc biệt hợp với các knowledge workflow, vì nó biến văn bản mềm thành dữ liệu đủ sạch để lưu vào database, Notion, docs, hoặc một dashboard nhỏ.
Bẫy OPENAI_API_KEY cần biết trước
Có một bẫy vận hành cần nói thẳng. Nếu biến môi trường OPENAI_API_KEY đang tồn tại, Codex có thể dùng API key đó và tính phí qua API thay vì đi qua ChatGPT subscription, mà không cảnh báo đủ rõ. Với người dùng đã quen để key trong shell profile, đây là loại chi tiết dễ bị bỏ qua. Cách gọn là chạy env -u OPENAI_API_KEY codex ... khi muốn chắc chắn Codex không dùng key trong môi trường, hoặc tạo alias riêng cho Codex subscription. Đây không phải vấn đề triết lý, chỉ là kỷ luật shell rất thực tế.

Ranh giới giữa tool và agent đang mờ đi
Khi nhìn toàn bộ, mình thấy MCP là lớp bắt tay, còn headless mới là lớp móng. MCP giúp Claude Code gọi Codex trong một workflow tương tác. codex exec giúp Codex bước ra khỏi cửa sổ chat và đi vào script, cron, CI, Docker, hoặc bất kỳ chỗ nào một lệnh Unix có thể sống. Một thứ có thể chạy không người trông coi sẽ thay đổi cách ta thiết kế công việc nhiều hơn một thứ chỉ có thêm giao diện đẹp.
Điều này cũng làm mờ ranh giới giữa tool và agent. Nếu Claude Code gọi Codex qua MCP, Codex là tool hay worker agent? Nếu Codex chạy exec trong CI và tự review PR, nó còn là tool bị động không? Nếu một ngày Codex lại gọi ngược một dịch vụ khác qua MCP, vai trò “ai điều phối ai” sẽ không còn cố định theo tên sản phẩm. Có thể câu hỏi đúng hơn không phải là chọn agent nào mạnh nhất, mà là thiết kế sao cho không agent nào phải giữ tất cả mọi thứ trong đầu.
Ở đây mình thiên về một nguyên tắc đơn giản: nơi nào cần toàn cảnh thì để một orchestrator giữ, nơi nào có thể đóng gói thành việc nhỏ thì chuyển cho worker. Claude Code có thể là nơi giữ repo, kế hoạch, và quyết định cuối. Codex có thể là cánh tay chạy ngầm, xử lý phần việc nặng hoặc lặp lại, rồi trả về output đủ sạch. Sự phối hợp này không làm AI “thông minh thần kỳ” hơn, nhưng làm workflow bớt chật.
Mình nghĩ đây là hướng thiết kế đáng theo dõi cho AI workflow cá nhân: ít cửa sổ hơn, nhiều capability chạy ngầm hơn, output có cấu trúc hơn, và một điểm điều phối đủ tỉnh để nói “việc này không đáng nhét vào context chính”. Khi hai agent có thể gọi nhau bằng MCP, câu hỏi không còn chỉ là “dùng Claude hay Codex”, mà là “mình muốn công việc chảy qua hệ thống như thế nào”. Nếu phải chia việc trong workflow của bạn hôm nay, phần nào bạn vẫn muốn agent chính giữ trong đầu, và phần nào nên được thả cho một worker chạy ngầm?