Негізгі мазмұнға өту
OpenAI

2026 ж. 4 ақпан

Инженерия

Unlocking the Codex harness: how we built the App Server

By Celia Chen, Member of the Technical Staff

Жүктелуде…

OpenAI’s coding agent Codex exists across many different surfaces: the web app(жаңа терезеде ашылады), the CLI(жаңа терезеде ашылады), the IDE extension(жаңа терезеде ашылады), and the new Codex macOS app. Under the hood, they’re all powered by the same Codex harness—the agent loop and logic that underlies all Codex experiences. The critical link between them? The Codex App Server(жаңа терезеде ашылады), a client-friendly, bidirectional JSON-RPC1 API.

In this post, we’ll introduce the Codex App Server; we’ll share our learnings so far on the best ways to bring Codex’s capabilities into your product to help your users supercharge their workflows. We’ll cover the App Server’s architecture and protocol and how it integrates with different Codex surfaces, as well as tips on leveraging Codex, whether you want to turn Codex into a code reviewer, an SRE agent, or a coding assistant.

Origin of the App Server

Before diving into architecture, it’s helpful to know the App Server’s backstory. Initially, the App Server was a practical way to reuse the Codex harness across products that gradually evolved into our standard protocol.

Codex CLI started as a TUI (terminal user interface), meaning Codex is accessed through the terminal. When we built the VS Code extension (a more IDE-friendly way to interact with Codex agents), we needed a way to use the same harness so as to drive the same agent loop from an IDE UI without re-implementing it. That meant supporting rich interaction patterns beyond request/response, such as exploring the workspace, streaming progress as the agent reasons, and emitting diffs. We first experimented with exposing Codex as an MCP server(жаңа терезеде ашылады), but maintaining MCP semantics in a way that made sense for VS Code proved difficult. Instead, we introduced a JSON-RPC protocol that mirrored the TUI loop, which became the unofficial first version(жаңа терезеде ашылады) of the App Server. At the time, we didn’t expect other clients to depend on the App Server, so it wasn’t designed as a stable API.

As Codex adoption grew over the next few months, internal teams and external partners wanted the ability to embed the same harness in their own products in order to accelerate their users’ software development workflows. For example, JetBrains and Xcode wanted an IDE-grade agent experience, while the Codex desktop app needed to orchestrate many Codex agents in parallel. Those demands pushed us to design a platform surface that both our products and partner integrations could safely depend on over time. It needed to be easy to integrate and backward compatible, meaning we could evolve the protocol without breaking existing clients.

Next, we’ll walk through how we designed the architecture and protocol so different clients can use the same harness.

Inside the Codex harness

First, let’s zoom in on what’s inside the Codex harness and how the Codex App Server exposes it to clients. In our last Codex blog, we broke down the core agent loop that orchestrates the interaction between the user, the model, and the tools. This is the core logic of the Codex harness, but there’s more to the full agent experience:

1. Thread lifecycle and persistence. A thread is a Codex conversation between a user and an agent. Codex creates, resumes, forks, and archives threads, and persists the event history so clients can reconnect and render a consistent timeline.

2. Config and auth. Codex loads configuration, manages defaults, and runs authentication flows like “Sign in with ChatGPT,” including credential state.

3. Tool execution and extensions. Codex executes shell/file tools in a sandbox and wires up integrations like MCP servers and skills so they can participate in the agent loop under a consistent policy model.

All the agent logic we mentioned here, including the core agent loop, lives in a part of the Codex CLI codebase called “Codex core(жаңа терезеде ашылады).” Codex core is both a library where all the agent code lives and a runtime that can be spun up to run the agent loop and manage the persistence of one Codex thread (conversation).

To be useful, the Codex harness needs to be accessible to clients. That’s where the App Server comes in.

«App server процесінің ағыны» атты диаграмма. Клиент stdio reader-ге JSON-RPC хабарламаларын жібереді, ол сұрауларды Codex message processor-ға бағыттайды. Processor lookup threads, thread handles, submitted requests және events/updates арқылы thread manager және core thread-пен өзара әрекеттеседі, содан кейін жауаптарды клиентке қайтарады.

The App Server is both the JSON-RPC protocol between the client and the server and a long-lived process that hosts the Codex core threads. As we can see from the diagram above, an App Server process has four main components: the stdio reader, the Codex message processor, the thread manager, and core threads. The thread manager spins up one core session for each thread, and the Codex message processor then communicates with each core session directly to submit client requests and receive updates.

One client request can result in many event updates, and these detailed events are what allow us to build a rich UI on top of the App Server. Furthermore, the stdio reader and the Codex message processor serve as the translation layer between the client and Codex core threads. They translate client JSON-RPC requests into Codex core operations, listen to Codex core’s internal event stream, and then transform those low-level events into a small set of stable, UI-ready JSON-RPC notifications.

The JSON-RPC protocol between the client and the App Server is fully bidirectional. A typical thread has a client request and many server notifications. In addition, the server can initiate requests when the agent needs input, like an approval, and then pause the turn until the client responds.

The conversation primitives

Next, we’ll break down the conversation primitives, the building blocks of the App Server protocol. Designing an API for an agent loop is tricky because the user/agent interaction is not a simple request/response. One user request can unfold into a structured sequence of actions that the client needs to represent faithfully: the user’s input, the agent’s incremental progress, artifacts produced along the way (e.g., diffs). To make that interaction stream easy to integrate and resilient across UIs, we landed on three core primitives with clear boundaries and lifecycles:

1. Item: An item is the atomic unit of input/output in Codex. Items are typed (e.g., user message, agent message, tool execution, approval request, diff) and each has an explicit lifecycle:

  • item/started when the item begins
  • optional item/*/delta events as content streams in (for streaming item types)
  • item/completed when the item finalizes with its terminal payload

This lifecycle lets clients start rendering immediately on started, stream incremental updates on delta, and finalize on completed.

2. Turn: A turn is one unit of agent work initiated by user input. It begins when the client submits an input (for example, “run tests and summarize failures”) and ends when the agent finishes producing outputs for that input. A turn contains a sequence of items that represent the intermediate steps and outputs produced along the way.

3. Thread: A thread is the durable container for an ongoing Codex session between a user and an agent. It contains multiple turns. Threads can be created, resumed, forked, and archived. Thread history is persisted so clients can reconnect and render a consistent timeline.

Now, we’ll look at a simplified conversation between a client and an agent, where the conversation is represented by primitives:

«Клиент–сервер хаттама хабарламаларының ағыны: инициализациямен қол алысу» деп белгіленген диаграмма. Клиент серверге clientInfo бар initialize сұрауын жібереді. Сервер жауап ретінде «my_client/1.0» userAgent жолын қамтитын result оқиғасын қайтарады.

At the beginning of the conversation, the client and the server need to establish the initialize handshake. The client must send a single initialize request before any other method, and the server acknowledges with a response. This gives the server a chance to advertise capabilities and lets both sides agree on protocol versioning, feature flags, and defaults before the real work begins. Here’s an example payload from OpenAI’s VS Code extension:

JSON

1
{
2
"method": "initialize",
3
"id": 0,
4
"params": {
5
"clientInfo": {
6
"name": "codex_vscode",
7
"title": "Codex VS Code Extension",
8
"version": "0.1.0"
9
}
10
}
11
}

This is what the server returns:

JSON

1
{
2
"id": 0,
3
"result": {
4
"userAgent": "codex_vscode/0.94.0-alpha.7 (Mac OS 26.2.0; arm64) vscode/2.4.22 (codex_vscode; 0.1.0)"
5
}
6
}
«Клиент–сервер хаттама хабарламаларының ағыны: ағым мен қадамның өмірлік циклі» атты диаграмма. Клиент серверге thread/start және turn/start сұрауларын жібереді. Сервер thread/started, turn/started, item/started және item/completed оқиғаларын жібереді, мұнда пайдаланушы хабарламасы «тесттерді іске қосып, қателерді қорытындыла» деп көрсетілген қадам бейнеленген.

When a client makes a new request, it will first create a thread and then a turn. The server will send back notifications for progress (thread/started and turn/started). It will also send back inputs it registers as items, like the user message here.

«Клиент–сервер хаттама хабарламаларының ағыны: қосымша мақұлдауы бар құралды орындау» атты диаграмма. Құрал шақыруы кезінде сервер item/started жібереді, содан кейін себеппен («run tests») item/commandExecution/requestApproval жібереді. Клиент мақұлдау оқиғасын қайтарады (allow/deny). Одан кейін сервер пәрменнің орындалуын («pnpm test») көрсететін item/completed жібереді.

Tool calls are also sent back to the client as items. Additionally, the server may ask for client approval before it can run an action by sending a server request. The approval will pause the turn until the client replies with either “allow” or “deny.” This is what the approval flow looks like in the VS Code extension:

Қараңғы тақырыптағы интерфейстегі рұқсат сұрауы: «Осы жұмыс кеңістігі үшін pnpm test іске қосуыма рұқсат бересіз бе?» Опциялар: 1) Иә, 2) Иә, әрі pnpm test деп басталатын пәрмендер үшін енді сұрамау, 3) Жоқ. Төменгі жағында Submit түймесі бар.
«Клиент–сервер хаттама хабарламаларының ағыны: агент хабарламасының ағындық ағыны» атты диаграмма. Сервер assistant хабарын бөліктермен жібереді: item/started, екі agentMessage/delta оқиғасы («ran 3 tests.», «all passed»), содан кейін item/completed. Қадам turn/completed арқылы аяқталады.

In the end, the server sends an agent message and then ends the turn with turn/completed. The agent message delta events stream pieces of the message back until the message is finalized with item/completed.

Диаграммадағы хабарламалар оқуға жеңіл болуы үшін ықшамдалған. Толық бір қадамның JSON нұсқасын көргіңіз келсе, Codex CLI репозиторийіндегі тест клиентін іске қоса аласыз:

Bash

1
codex debug app-server send-message-v2 "run tests and summarize failures"

Клиенттермен біріктіру

Енді әртүрлі клиент беттері Codex-ті App Server арқылы қалай ендіретінін қарастырайық. Біз үш үлгіні қамтимыз: жергілікті қолданбалар мен IDE-лер, Codex веб орындалу ортасы және TUI.

«App server арқылы Codex harness-пен біріктірілген Codex клиенттері» атты диаграмма. Бірінші тарап клиенттері (Codex Desktop App, TUI/CLI, Web Runtime) және үшінші тарап интеграциялары (JetBrains IDE-лері, VS Code, Xcode) Codex harness-пен JSON-RPC шақырулары арқылы байланысады.

Үшеуінде де тасымалдау тәсілі — stdio (JSONL) арқылы JSON-RPC. JSON-RPC таңдаған тіліңізде клиенттік байламдар жасауды жеңілдетеді. Codex беттері мен серіктес интеграциялары Go, Python, TypeScript, Swift және Kotlin тілдерінде App Server клиенттерін іске асырды. TypeScript үшін анықтамаларды Rust хаттамасынан тікелей мына пәрменмен жасай аласыз:

Bash

1
codex app-server generate-ts

Басқа тілдер үшін JSON схема жиынтығын жасап, оны өзіңіз қалаған код генераторына мына пәрменмен бере аласыз:

Bash

1
codex app-server generate-json-schema
Жергілікті қолданбалар мен IDE-лер
Іске қосылған Codex кеңейтімі бар VS Code скриншоты. Rust тест файлы ашық, ал төмендегі Codex панелі тек fmt және cargo test -p codex-app-server іске қосылып жатқанын сипаттайды және пішімдеу мен тесттер жүріп жатқанын, соңғы өтті/өтпеді нәтижесін күтіп тұрғанын хабарлайды.

Жергілікті клиенттер әдетте платформаға тән App Server бинарын бірге жеткізеді немесе жүктеп алады, оны ұзақ жұмыс істейтін еншілес процесс ретінде іске қосады және JSON-RPC үшін екіжақты stdio арнасын ашық ұстайды. Мысалы, біздің VS Code кеңейтімі мен Desktop App-та жеткізілетін артефакт платформаға тән Codex бинарын қамтиды және сыналған нұсқаға бекітіледі, сондықтан клиент әрдайым біз тексерген нақты биттерді іске қосады.

Әрбір интеграция клиент жаңартуларын жиі шығара алмайды. Xcode сияқты кей серіктестер шығару циклдерін клиентті тұрақты күйде қалдырып, қажет болса оны жаңарақ App Server бинарына бағыттауға мүмкіндік беру арқылы бөледі. Осылайша олар сервер жақсартуларын (мысалы, Codex core-тағы жақсырақ автоықшамдау немесе жаңадан қолдау тапқан config кілттері) қабылдап, клиент релизін күтпей-ақ қате түзетулерін шығара алады. App Server-дің JSON-RPC беті кері үйлесімді болатындай жасалған, сондықтан ескі клиенттер жаңа серверлермен қауіпсіз сөйлесе алады.

Codex Web
«Update login success message» атты жаңарту көрсетілген Codex веб интерфейсінің скриншоты. Сол жақ панель өзгерістерді, тесттерді және өзгертілген файлдарды қорытындылайды, ал оң жақ панель login.rs файлы үшін жаңартылған кіру сәттілігі хабарламасының тұжырымын көрсететін код diff-ін бейнелейді.

Codex Web Codex harness-ті қолданады, бірақ оны контейнерлік ортада іске қосады. Worker тексеріліп алынған жұмыс кеңістігі бар контейнерді дайындайды, оның ішінде App Server бинарын іске қосады және stdio2 арқылы ұзақ өмір сүретін JSON-RPC арнасын ұстап тұрады. Веб қолданба (пайдаланушының браузер қойындысында жұмыс істейді) Codex бэкендімен HTTP және SSE арқылы сөйлеседі, ол worker жасаған тапсырма оқиғаларын ағынмен жібереді. Бұл браузер жақ UI-ды жеңіл күйде сақтай отырып, десктоп пен веб арасында бірізді орындалу ортасын береді.

Веб сеанстар өткінші болғандықтан (қойындылар жабылады, желі үзіледі), веб қолданба ұзақ жүретін тапсырмалар үшін ақиқат көзі бола алмайды. Күй мен ілгерілеуді серверде сақтау, қойынды жоғалып кетсе де, жұмыстың жалғасуын қамтамасыз етеді. Ағындық хаттама мен сақталған ағым сеанстары жаңа сеансқа қайта қосылуды, тоқтаған жерінен жалғастыруды және клиентте күйді қайта құрмай-ақ қалып қойған жерін қуып жетуді жеңілдетеді.

TUI/Codex CLI
Codex CLI іске қосылған терминал скриншоты. Онда gpt-5.2-codex medium моделі бар OpenAI Codex баннері, пайдаланушының «explain app server to me» пәрмені және «Working» күйі көрсетілген. Төменде «write tests for @filename» деген ұсыныс және жарлық опциялары бар.

Тарихи түрде TUI агент циклімен бір процесте жұмыс істейтін және app-server хаттамасы емес, Rust core түрлерімен тікелей сөйлесетін «жергілікті» клиент болды. Бұл бастапқы итерацияны жылдамдатты, бірақ TUI-ды ерекше жағдайдағы бетке айналдырды.

Енді App Server бар болғандықтан, біз TUI-ды қайта құрылымдауды(жаңа терезеде ашылады) жоспарлап отырмыз, сонда ол кез келген басқа клиент сияқты әрекет етеді: App Server еншілес процесін іске қосады, stdio арқылы JSON-RPC-пен сөйлеседі және дәл сол ағындық оқиғалар мен мақұлдауларды көрсетеді. Бұл TUI-ға қашықтағы машинада жұмыс істеп тұрған Codex серверіне қосылу сияқты жұмыс ағындарын ашады, агентті есептеу қуатына жақын ұстап, ноутбук ұйқы режиміне өтсе не ажыратылса да жұмысты жалғастыруға мүмкіндік береді, сонымен бірге жергілікті жерде тірі жаңартулар мен басқару құралдарын береді.

Дұрыс хаттаманы таңдау

Codex App Server бұдан былай біз қолдайтын негізгі интеграция әдісі болады, бірақ функционалдығы шектеулі басқа әдістер де бар. Әдепкі бойынша, клиенттерге Codex-пен бірігу үшін Codex App Server пайдалануды ұсынар едік, бірақ әртүрлі интеграция әдістерін қарап, олардың артықшылықтары мен кемшіліктерін түсінген жөн. Төменде Codex-ті басқарудың ең жиі қолданылатын жолдары және әрқайсысы қай кезде қолайлы болуы мүмкін екені берілген.

JSON-RPC хаттамалары

MCP сервері ретіндегі Codex

codex mcp-server(жаңа терезеде ашылады) пәрменін іске қосып, stdio серверлерін қолдайтын кез келген MCP клиентінен қосылыңыз (мысалы, OpenAI Agents SDK(жаңа терезеде ашылады)). Бұл сізде MCP-ке негізделген жұмыс ағыны бұрыннан болса және Codex-ті шақырылатын құрал ретінде пайдаланғыңыз келсе, қолайлы. Кемшілігі — тек MCP ашатын мүмкіндіктерді ғана аласыз, сондықтан байырақ сеанс семантикасына сүйенетін Codex-ке тән өзара әрекеттер (мысалы, diff жаңартулары) MCP соңғы нүктелері арқылы таза бейнеленбеуі мүмкін.

Провайдерлер арасында ортақ агент harness хаттамалары

Кейбір экожүйелер бірнеше модель провайдері мен орындалу ортасына бағыттала алатын тасымалды интерфейс ұсынады. Егер бірнеше агентті үйлестіретін бір абстракцияны қаласаңыз, бұл жақсы таңдау болуы мүмкін. Алайда мұндай хаттамалар көбіне мүмкіндіктердің ортақ жиынтығына тоғысады, сондықтан байырақ өзара әрекеттерді көрсету қиындайды, әсіресе провайдерге тән құрал мен сеанс семантикасы маңызды болғанда. Бұл кеңістік жылдам дамып жатыр, және нақты әлемдегі агент жұмыс ағындарын бейнелеуге ең дұрыс примитивтерді анықтаған сайын ортақ стандарттар көбірек пайда болады деп күтеміз (skills(жаңа терезеде ашылады) — соның жақсы мысалы).

Codex App Server

Толық Codex harness тұрақты, UI-ға ыңғайлы оқиғалар ағыны ретінде ашылсын десеңіз, App Server таңдаңыз. Сонда агент циклінің толық функционалдығын және ChatGPT арқылы кіру, модельдерді табу, конфигурацияны басқару сияқты қосымша мүмкіндіктерді аласыз. Негізгі шығын — интеграция жұмысы, өйткені тіліңізде клиент жақ JSON-RPC байламын құруыңыз керек. Алайда тәжірибеде JSON схемасы мен құжаттаманы берсеңіз, ауыр жұмыстың көп бөлігін Codex өзі атқара алады. Біз жұмыс істеген көптеген командалар Codex көмегімен жұмыс істейтін интеграцияны тез жасай алды.

Codex-ті ендірудің басқа жолдары

Бір реттік тапсырмалар мен CI іске қосударына арналған жеңіл, сценарийленетін CLI режимі. Бұл автоматтандыру мен құбырлар үшін қолайлы, онда бір пәрменнің интерактивсіз толық орындалуын, журналдар үшін құрылымды шығысты ағынмен беруін және табыс не сәтсіздік туралы анық белгімен аяқталуын қалайсыз.

Өз қолданбаңыздың ішінде жергілікті Codex агенттерін бағдарламалық түрде басқаруға арналған TypeScript кітапханасы. Бұл бөлек JSON-RPC клиентін құрмай-ақ, сервер жақ құралдар мен жұмыс ағындары үшін жергілікті кітапхана интерфейсін қалағанда ең қолайлы. Ол App Server-ден ертерек шыққандықтан, қазір азырақ тілді және кішірек бетті қолдайды. Егер әзірлеушілер тарапынан қызығушылық болса, командалар JSON-RPC байламдарын жазбай-ақ harness бетінің көбірек бөлігін қамтуы үшін App Server хаттамасын қаптайтын қосымша SDK-лар қосуымыз мүмкін.

Мұны ары қарай дамыту

Бұл жазбада агенттермен өзара әрекеттесудің жаңа стандартын жобалауға қалай қарайтынымызды және Codex harness-ті тұрақты, клиентке қолайлы хаттамаға қалай айналдыратынымызды бөлістік. Біз App Server Codex core-ды қалай ашатынын, клиенттерге толық агент циклін басқаруға қалай мүмкіндік беретінін және TUI, жергілікті IDE интеграциялары мен веб орындалу ортасын қоса алғанда, кең ауқымды беттерді қалай қуаттандыратынын қарастырдық.

Егер бұл сіздің жеке жұмыс ағындарыңызға Codex-ті біріктіру туралы ой тудырса, App Server-ді байқап көруге тұрарлық. Барлық бастапқы код Codex CLI-дің ашық бастапқы кодты репозиторийінде(жаңа терезеде ашылады) орналасқан. Пікірлеріңіз бен функция сұраныстарыңызды бөлісе беріңіз. Сізден хабар алуға және агенттерді баршаға қолжетімді етуді жалғастыруға қуаныштымыз.

Автор

Celia Chen

Алғыс

Осы жазбаға үлес қосқан Майкл Болинге, Оуэн Линге, Эрик Траутқа және Расмус Рюгордқа, сондай-ақ App Server-де жұмыс істеген бүкіл Codex командасына ерекше алғыс.

Ескертпелер

  1. 1

    Біз «JSON‑RPC lite» нұсқасын қолданамыз: ол сұрау/жауап/хабарландыру пішінін сақтайды, бірақ "jsonrpc": "2.0" тақырыбын алып тастайды және қатаң JSON‑RPC 2.0 орнына stdio арқылы JSONL ретінде жақтауланады.

  2. 2

    «stdio» контейнер ішіндегі app-server-дің stdin/stdout ағындарын білдіреді. Хостинг конфигурацияларында бұл ағындар контейнердің орындалу ортасына тұрақты желілік қосылым арқылы (мысалы, WebSocket тәрізді) жиі туннельденеді, сондықтан ол нақты жергілікті құбыр болмаса да, stdio сияқты жұмыс істейді.