Gå direkt till huvudinnehåll
OpenAI

4 februari 2026

Teknik

Låsa upp Codex-ramverket: hur vi byggde App Server

Av Celia Chen, medlem i den tekniska personalen

Laddar …

OpenAI:s Agent Codex finns på många olika plattformar: webbappen(öppnas i ett nytt fönster), CLI(öppnas i ett nytt fönster), IDE-tillägget(öppnas i ett nytt fönster) och den nya Codex-appen för macOS. Under huven drivs de alla av samma Codex-ramverk – agentloopen och logiken som ligger till grund för alla Codex-upplevelser. Den avgörande länken mellan dem? Codex App Server(öppnas i ett nytt fönster), en användarvänlig, dubbelriktad JSON-RPC1-API.

I det här inlägget kommer vi att introducera Codex App Server och vi kommer att dela med oss av våra lärdomar hittills om de bästa sätten att integrera Codex funktioner i din produkt för att hjälpa dina användare att effektivisera sina arbetsflöden. Vi kommer att gå igenom App Serverns arkitektur och protokoll och hur den integreras med olika Codex-ytor, samt ge tips om hur man kan utnyttja Codex, oavsett om man vill göra Codex till en kodgranskare, en SRE-agent eller en kodassistent.

App Serverns bakgrund

Innan du dyker ner i arkitekturen är det bra att känna till App Serverns bakgrund. Inledningsvis var App Server ett praktiskt sätt att återanvända Codex-ramverket mellan produkter, vilket gradvis utvecklades till vårt standardprotokoll.

Codex CLI började som ett TUI (terminalanvändargränssnitt), vilket innebär att Codex nås via terminalen. När vi byggde VS Code-tillägget (ett mer IDE-vänligt sätt att interagera med Codex-agenter) behövde vi ett sätt att använda samma ramverk för att driva samma agentloop från ett IDE-gränssnitt utan att implementera det på nytt. Det innebar att stödja rika interaktionsmönster bortom begäran/svar, som att utforska arbetsytan och strömma förlopp medan agenten resonerar och generera diffar. Vi experimenterade först med att exponera Codex som en MCP-server(öppnas i ett nytt fönster), men att upprätthålla MCP-semantik på ett sätt som var meningsfullt för VS Code visade sig vara svårt. Istället introducerade vi ett JSON-RPC-protokoll som speglade TUI-loopen, vilket blev den inofficiella första versionen(öppnas i ett nytt fönster) av App Servern. Då förväntade vi oss inte att andra klienter skulle vara beroende av App Server, så den var inte designad som ett stabilt API.

När Codex-användningen ökade under de kommande månaderna ville interna team och externa partners kunna integrera samma ramverk i sina egna produkter för att påskynda sina användares arbetsflöden för mjukvaruutveckling. Till exempel ville JetBrains och Xcode ha en agentupplevelse av IDE-kvalitet, medan Codex-skrivbordsappen behövde samordna många Codex-agenter parallellt. Dessa krav drev oss att utforma en plattformsyta som både våra produkter och partnerintegrationer kunde lita på över tid. Det behövde vara enkelt att integrera och bakåtkompatibelt, vilket innebar att vi kunde utveckla protokollet utan att påverka befintliga klienter.

Härnäst går vi igenom hur vi utformade arkitekturen och protokollet så att olika klienter kan använda samma ramverk.

Inuti Codex-ramverket

Först ska vi fokusera på vad som finns inuti Codex-ramverket och hur Codex App Server exponerar det för klienter. I vår senaste Codex-blogg bröt vi ned den centrala agentloopen som orkestrerar interaktionen mellan användaren, modellen och verktygen. Det här är kärnlogiken i Codex-ramverket, men det finns mer i den fullständiga agentupplevelsen:

1. Trådens livscykel och persistens En tråd är en Codex-konversation mellan en användare och en Codex-agent. Codex skapar, återupptar, kopierar och arkiverar trådar och bevarar händelsehistoriken så att klienter kan återansluta och rendera en konsekvent tidslinje.

2. Konfiguration och autentisering Codex läser in konfigurationer, hanterar standardinställningar och kör autentiseringsflöden som ”Logga in med ChatGPT”, inklusive status för autentiseringsuppgifter.

3. Verktygsanvändning och tillägg Codex kör shell-/filverktyg i en sandlåda och kopplar integrationer som MCP-servrar och färdigheter så att de kan delta i agent-loopen under en konsekvent policymodell.

All Agentlogik som vi nämnde här, inklusive den centrala agentloopen, finns i en del av Codex CLI-kodbasen som kallas “Codex-kärna(öppnas i ett nytt fönster).” Codex-kärnan är både ett bibliotek där all agentkod finns och en körmiljö som kan startas för att köra agentloopen och hantera persistensen för en Codex-tråd (konversation).

För att vara användbar måste Codex-ramverket vara tillgänglig för klienter. Det är här App Server kommer in i bilden.

Diagram med titeln ”Appserverns processflöde”. En klient skickar JSON-RPC-meddelanden till en stdio-läsare, som vidarebefordrar förfrågningar till en Codex-meddelandeprocessor. Processorn interagerar med en trådhanterare och en kärntråd genom uppslagstrådar, trådhandtag, inskickade begäranden och händelser/uppdateringar, och returnerar sedan svar till klienten.

App Server är både JSON-RPC-protokollet mellan klienten och servern och en långlivad process som hyser Codex-kärntrådar. Som vi kan se från diagrammet ovan har en App Server-process fyra huvudkomponenter: stdio-läsaren, Codex-meddelandeprocessorn, trådhanteraren och kärntrådarna. Trådhanteraren startar en kärnsession för varje tråd, och Codex-meddelandeprocessorn kommunicerar sedan direkt med varje kärnsession för att skicka klientförfrågningar och ta emot uppdateringar.

En klientbegäran kan resultera i många händelseuppdateringar, och dessa detaljerade händelser möjliggör att vi kan bygga ett rikt användargränssnitt ovanpå App Server. Dessutom fungerar stdio-läsaren och Codex-meddelandeprocessorn som översättningslagret mellan klienten och Codex-kärntrådarna. De översätter klientens JSON-RPC-begäranden till Codex-kärnoperationer, lyssnar på Codex-kärnans interna händelseström och omvandlar sedan dessa lågnivåhändelser till en liten uppsättning stabila, UI-klara JSON-RPC-notifieringar.

JSON-RPC-protokollet mellan klienten och App Server är helt dubbelriktat. En typisk tråd innehåller en klientförfrågan och många servermeddelanden. Dessutom kan servern initiera förfrågningar när agenten behöver indata, som ett godkännande, och sedan pausa processen tills klienten svarar.

Samtalsprimitiverna

Nästa steg är att bryta ner konversationsprimitiverna, som är byggstenarna i App Server-protokollet. Att utforma ett API för en agentloop är knepigt eftersom interaktionen mellan användare och agent inte är en enkel begäran/svar. En användarförfrågan kan utvecklas till en strukturerad sekvens av åtgärder som klienten behöver återge korrekt: användarens indata, agentens stegvisa framsteg, och artefakter som produceras längs vägen (t.ex. diffar). För att göra den interaktionsströmmen enkel att integrera och motståndskraftig i olika användargränssnitt, kom vi fram till tre kärnprimitiver med tydliga gränser och livscykler:

1. Objekt: Ett objekt är den atomära enheten för indata/utdata i Codex. Objekt är kategoriserade (t.ex., användarmeddelande, agentmeddelande, verktygskörning, godkännandebegäran, diff) och varje har en tydlig livscykel:

  • item/started när objektet börjar
  • valfria item/*/delta-händelser som innehållsströmmar (för streamande objekttyper)
  • item/completed när objektet avslutas med sin slutliga nyttolast

Den här livscykeln gör det möjligt för klienter att börja rendera omedelbart vid started, strömma inkrementella uppdateringar vid delta och avsluta vid completed.

2. Omgång: En omgång är en enhet av agentarbete som initieras av användarindata. Det börjar när klienten skickar in en indata (till exempel ”kör tester och sammanfatta fel”) och slutar när agenten har slutfört att producera utdata för den indatan. En omgång innehåller en sekvens av objekt som representerar de mellanliggande stegen och resultaten som produceras längs vägen.

3. Tråd: En tråd är en hållbar behållare för en pågående Codex-session mellan en användare och en agent. Den innehåller flera omgångar. Trådar kan skapas, återupptas, delas och arkiveras. Trådhistoriken bevaras så att klienter kan återansluta och visa en konsekvent tidslinje.

Nu ska vi titta på en förenklad konversation mellan en klient och en agent, där konversationen representeras av primitiva element:

Diagram märkt ”Klient-serverprotokoll: meddelandeflöde: initieringshandskakning”. En klient skickar en initieringsbegäran med klientinformation till servern. Servern svarar med en resultathändelse som innehåller userAgent-strängen “my_client/1.0”.

I början av konversationen måste klienten och servern etablera initialize-handskakningen. Klienten måste skicka en enda initialize-begäran innan någon annan metod, och servern bekräftar med ett svar. Detta ger servern en möjlighet att presentera sina funktioner och låter båda parter komma överens om protokollversionering, funktionsflaggor och standardinställningar innan det verkliga arbetet börjar. Här är ett exempel på en nyttolast från OpenAI:s VS Code-tillägg:

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
}

Detta är vad servern returnerar:

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
}
Diagram med titeln ”Klient-serverprotokoll: Meddelandeflöde för livscykel för thread och turn.” Klienten skickar förfrågningar om thread/start och turn/start till servern. Servern sänder ut händelser – thread/started, turn/started, item/started och item/completed – som visar en omgång där användarmeddelandet är ”kör tester och sammanfatta fel.”

När en klient gör en ny begäran skapar den först en tråd och sedan en omgång. Servern kommer att skicka tillbaka aviseringar om framsteg (thread/started och turn/started). Den kommer också att skicka tillbaka indata som den registrerar som objekt, såsom användarmeddelandet här.

Diagram med titeln ”Klient-serverprotokoll meddelandeflöde: Verktygskörning med valfritt godkännande.” Under ett verktygsanrop skickar servern item/started och sedan item/commandExecution/requestApproval med anledningen “kör tester”. Klienten returnerar en godkännandehändelse (allow/deny). Servern skickar sedan item/completed som visar att kommandot ("pnpm test") har körts.

Verktygsanrop skickas också tillbaka till klienten som objekt. Dessutom kan servern begära klientens godkännande innan den kan utföra en åtgärd genom att skicka en serverförfrågan. Godkännandet kommer att pausa omgången tills klienten svarar med antingen ”tillåt” eller ”neka”. Så här ser godkännandeflödet ut i VS Code-tillägget:

Prompt i ett gränssnitt med mörkt tema som frågar: ”Vill du tillåta mig att köra pnpm-test för den här arbetsytan?” Den listar alternativ: 1) Ja, 2) Ja, och fråga inte igen för kommandon som börjar med pnpm-test, och 3) Nej, med en Skicka-knapp längst ned.
Diagram med titeln ”Klient-serverprotokoll: Meddelandeflöde för strömmande agent.” Servern strömmar ett assistentmeddelande i delar: item/started, två agentMessage/delta-händelser (”körde 3 tester.”, ”alla godkända”), sedan objekt/completed. Omgången avslutas med turn/completed.

Till slut skickar servern ett agentmeddelande och avslutar sedan omgången med turn/completed. Agentens meddelandedelta-händelser strömmar tillbaka delar av meddelandet tills det är slutfört med item/completed.

Meddelandena i diagrammet har förenklats för att vara lättlästa. Om du vill se JSON för en hel omgång kan du köra testklienten från Codex CLI-förvaret:

Bash

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

Integration med kunder

Nu ska vi titta på hur olika klientgränssnitt bäddar in Codex via App Servern. Vi kommer att gå igenom tre mönster: lokala appar och IDE:er, Codex web runtime och TUI.

Diagram med titeln ”Codex-klienter integrerade med Codex-ramverket via appservern.” Förstapartsklienter (Codex Desktop App, TUI/CLI, Web Runtime) och tredjepartsintegrationer (JetBrains IDEs, VS Code, Xcode) kommunicerar med Codex-ramverket via JSON-RPC-anrop.

För alla tre är transporten JSON-RPC över stdio (JSONL). JSON-RPC gör det enkelt att skapa klientbindningar på det språk du väljer. Codex-ytor och partnerintegrationer har implementerat App Server-klienter i språk som Go, Python, TypeScript, Swift och Kotlin. För TypeScript kan du generera definitioner direkt från Rust-protokollet genom att köra:

Bash

1
codex app-server generate-ts

För andra språk kan du skapa ett JSON-schema-paket och mata in det i din valda kodgenerator genom att köra:

Bash

1
codex app-server generate-json-schema
Lokala appar och IDE:er
Skärmdump av VS Code med Codex-tillägget aktivt. En Rust-testfil är öppen, och under den beskriver Codex-panelen att endast fmt och cargo test -p codex-app-server körs, och rapporterar att formatering och tester pågår medan ett slutligt godkänt/underkänt resultat väntas.

Lokala klienter brukar paketera eller hämta en plattformsspecifik App Server-binär, starta den som en långvarig underprocess och hålla en dubbelriktad stdio-kanal öppen för JSON-RPC. I vårt VS Code-tillägg och vår skrivbordsapp, till exempel, innehåller den levererade artefakten den plattformsspecifika Codex-binären och är fastlåst till en testad version så att klienten alltid kör exakt de bitar vi har validerat.

Inte alla integrationer kan leverera klientuppdateringar ofta. Vissa partners, som Xcode, frikopplar releasecykler genom att hålla klienten stabil och låta den peka på en nyare App Server-binär vid behov. På så sätt kan de införa förbättringar på serversidan (till exempel bättre automatisk komprimering i Codex-kärnan eller nyligen stödda konfigurationsnycklar) och distribuera buggfixar utan att behöva vänta på en klientutgåva. App Serverns JSON-RPC-gränssnitt är utformat för att vara bakåtkompatibelt, så att äldre klienter kan kommunicera säkert med nya servrar.

Codex Web
Skärmdump av ett Codex-webbgränssnitt som visar en uppdatering med titeln ”Uppdatera meddelande om genomförd inloggning.” Den vänstra panelen sammanfattar ändringar, tester och modifierade filer, medan den högra panelen visar en kod-diff för login.rs med uppdaterad formulering av meddelandet om genomförd inloggning.

Codex Web använder Codex-ramverket, men kör det i en container-miljö. En arbetare etablerar en container med den utcheckade arbetsytan, startar App Server-binärfilen inuti den och underhåller en långlivad JSON-RPC över kanalen stdio2. Webbappen (som körs i användarens webbläsarflik) kommunicerar med Codex-backend via HTTP och SSE, vilka strömmar uppgiftshändelser som genereras av arbetaren. Detta håller användargränssnittet på webbläsarsidan lättviktigt samtidigt som det fortfarande ger oss en konsekvent körningsmiljö på dator och webben.

Eftersom webbsessioner är kortlivade (flikar stängs, nätverk bryts) kan webbappen inte vara den enda sanningskällan för långvariga uppgifter. Att förvara tillstånd och framsteg på servern innebär att arbetet fortsätter även om fliken försvinner. Strömningsprotokollet och sparade trådsessioner gör det enkelt för en ny session att återansluta, fortsätta där den slutade och komma ikapp utan att bygga om tillståndet i klienten.

TUI/Codex CLI
Skärmbild av en terminal som kör Codex CLI. Den visar OpenAI Codex-bannern med modellen GPT-5.2-Codex, ett användarkommando “förklara appservern för mig,” och en “Arbetar”-status. Nedan visas ett förslag: ”skriv tester för @filename” med alternativ för genvägar.

Historiskt sett var TUI en “native“-klient som kördes i samma process som agentloopen och kommunicerade direkt med Rust-kärntyper istället för app-serverprotokollet. Det gjorde tidig iteration snabb, men det gjorde också TUI till en specialfallsyta.

Nu när App Server finns planerar vi att refaktorera TUI(öppnas i ett nytt fönster) för att använda den så att den beter sig som vilken annan klient som helst: starta en underprocess för App Server, kommunicera JSON-RPC över stdio och rendera samma strömmande händelser och godkännanden. Detta möjliggör arbetsflöden där TUI kan ansluta till en Codex-server som körs på en fjärrmaskin, vilket håller agenten nära beräkningsresurserna och låter arbetet fortsätta även om den bärbara datorn går i viloläge eller kopplas från, samtidigt som den levererar liveuppdateringar och kontroller lokalt.

Välja rätt protokoll

Codex App Server kommer att vara den främsta integrationsmetoden vi underhåller framöver, men det finns också andra metoder med mer begränsad funktionalitet. Som standard rekommenderar vi att kunder använder Codex App Server för att integrera med Codex, men det är värt att överväga olika integrationsmetoder och förstå deras för- och nackdelar. Nedan följer de vanligaste sätten att använda Codex och när vart och ett kan vara lämpligt.

JSON-RPC-protokoll

Codex som en MCP-server

Kör codex mcp-server(öppnas i ett nytt fönster) och anslut från valfri MCP-klient som stöder stdio-servrar (t.ex. OpenAI Agents SDK(öppnas i ett nytt fönster)). Det här passar bra om du redan har ett MCP-baserat arbetsflöde och vill använda Codex som ett anropbart verktyg. Nackdelen är att du bara får det som MCP exponerar, så Codex-specifika interaktioner som förlitar sig på rikare sessionssemantik (t.ex., diff-uppdateringar) kanske inte mappas tydligt via MCP-slutpunkter.

Protokoll för agentramverk mellan leverantörer

Vissa ekosystem erbjuder ett portabelt gränssnitt som kan rikta sig mot flera modelleverantörer och körtider. Detta kan vara en bra lösning om du vill ha en abstraktion som samordnar flera agenter. Nackdelen är att dessa protokoll ofta konvergerar mot en gemensam delmängd av funktioner, vilket kan göra det svårare att representera mer komplexa interaktioner, särskilt när leverantörsspecifika verktyg och sessionssemantik är viktiga. Detta område utvecklas snabbt, och vi förväntar oss att mer allmänt vedertagna standarder kommer att uppstå när vi identifierar de bästa grundläggande byggstenarna för att representera verkliga agentarbetsflöden (skills(öppnas i ett nytt fönster) är ett bra exempel på detta).

Codex App Server

Välj App Server när du vill att hela Codex-ramverket ska exponeras som ett stabilt och användarvänligt händelseflöde. Du får både agentloopens fulla funktionalitet och andra stödfunktioner som Logga in med ChatGPT, modellidentifiering och konfigurationshantering. Den största kostnaden är integrationsarbete, eftersom du behöver bygga klientsidans JSON-RPC-bindning på ditt språk. I praktiken kan Codex dock utföra en stor del av det tunga arbetet om du förser den med JSON-schemat och dokumentationen. Många team vi arbetade med kunde snabbt skapa en fungerande integration med Codex.

Andra sätt att integrera Codex

Ett lätt, skriptbart CLI-läge för engångsuppgifter och CI-körningar. Det är väl lämpat för automatisering och pipelines där du vill att ett enda kommando ska köras till slut utan interaktion, strömma strukturerad utdata för loggar och avsluta med en tydlig signal om genomförande eller misslyckande.

Ett TypeScript-bibliotek för att programmera styrning av lokala Codex-agenter från din egen applikation. Det är bäst när du vill ha ett inbyggt biblioteksgränssnitt för serververktyg och arbetsflöden utan att behöva bygga en separat JSON-RPC-klient. Eftersom den skickades tidigare än App Server, stöder den för närvarande färre språk och har ett mindre omfång. Om det finns intresse från utvecklare kan vi lägga till fler SDK:er som omsluter App Server-protokollet så att team kan täcka mer av ramverkets yta utan att behöva skriva JSON-RPC-bindningar.

Ta detta framåt

I det här inlägget berättade vi hur det går till när man utformar en ny standard för interaktion med agenter och hur man omvandlar Codex-ramverket till ett stabilt och klientvänligt protokoll. Vi gick igenom hur App Server exponerar Codex-kärnan, låter klienter styra hela agent-loopen och driver en mängd olika gränssnitt, inklusive TUI, lokala IDE-integrationer och webbkörmiljön.

Om detta väckte idéer om att integrera Codex i dina egna arbetsflöden, är det värt att prova App Server. All källkod finns i Codex CLI repo(öppnas i ett nytt fönster) för öppen källkod. Känn dig fri att dela med dig av din feedback och dina funktionsönskemål. Vi är glada över att höra från dig och att fortsätta göra agenter mer tillgängliga för alla.

Författare

Celia Chen

Tack

Ett särskilt tack till Michael Bolin, Owen Lin, Eric Traut och Rasmus Rygaard, som bidrog till det här inlägget, och till hela Codex-teamet som arbetade med App Server.

Fotnoter

  1. 1

    Vi använder en ”JSON-RPC lite”-variant: den behåller formen för request/response/notification, men utelämnar rubriken "jsonrpc": "2.0" och är formaterad som JSONL över stdio istället för strikt JSON-RPC 2.0.

  2. 2

     “stdio” avser app-serverns stdin/stdout inuti containern. I värdbaserade konfigurationer tunnlas dessa strömmar ofta över en beständig nätverksanslutning (t.ex. WebSocket-liknande) till containerns körtid – så att den beter sig som stdio även om det inte är en lokal pipe.