VibeCoding 365 로고 VibeCoding 365

Codex 앱 서버를 직접 다뤄야 할 때 | ChatGPT Remote로는 안 되는 것들

ChatGPT Remote와 codex app-server의 차이부터 initialize, 승인 핸들러, 백프레셔, 원격 접근 제약까지 한 번에 정리한 Codex 통합 실전 가이드입니다.

심층 학습 가이드

Codex 앱 서버를 직접 다뤄야 할 때 | ChatGPT Remote로는 안 되는 것들

심층 학습 가이드

Codex 앱 서버를 직접 다뤄야 할 때 | ChatGPT Remote로는 안 되는 것들

완제품이 있는데 왜 프로토콜을 만지나 - 판단 기준부터 통합 실전까지

핵심 주제
Codex app-server vs ChatGPT Remote
예상 시간
14분
업데이트
2026.05.15
키워드
Codex app-server · ChatGPT Remote · JSON-RPC

휴대폰으로 데스크톱 Codex를 조종하고 싶은데, 누군가는 QR 코드만 찍으라 하고 누군가는 JSON-RPC를 구현하라고 말합니다. 여기서 많은 사람이 시간을 버립니다. 사람의 작업을 멀리서 이어 보고 승인하는 게 목적이면 완제품을 써야 하고, 프로그램이 Codex를 호출하고 중간에 개입해야 한다면 프로토콜까지 내려가야 합니다.

문제는 둘 다 "원격"처럼 보인다는 점입니다. ChatGPT Remote는 사람이 앱으로 쓰는 완제품이고, codex app-server는 그 완제품이 내부에서 쓰는 인터페이스에 가깝습니다. 이 차이를 놓치면, 앱으로 끝날 일을 굳이 클라이언트 구현으로 키우거나 반대로 프로덕션 통합을 QR 스캔 수준으로 오해하게 됩니다.

이 글은 "둘 중 무엇이 더 고급인가"를 따지는 글이 아닙니다. 여러분 작업이 어느 쪽 문제인지 가르는 글입니다. 먼저 Remote로 끝나는 경우를 잘라내고, app-server를 직접 다뤄야 하는 네 가지 경우, initialize 핸드셰이크, 승인 대기, -32001 백프레셔, 원격 접근 제약까지 한 번에 남깁니다.

그리고 중요한 기준을 하나 더 붙입니다. 사람이 버튼을 눌러도 충분한 문제를 프로그램 설계 문제로 키우지 않는 것, 반대로 프로그램이 개입해야 하는데 앱 기능으로 버티지 않는 것입니다. 이 경계만 제대로 잡아도 문서 읽는 시간과 구현 시간이 같이 줄어듭니다.

먼저, 여러분에게 이 글이 필요 없을 가능성

"휴대폰으로 데스크톱 Codex를 조종하고 싶다"가 목적이라면 이 글을 닫고 ChatGPT Remote를 쓰는 편이 맞습니다. 데스크톱 앱에서 Remote를 켜고 QR 코드를 폰으로 찍고 같은 계정과 워크스페이스를 확인하면, 폰에서 기존 작업을 이어 가고 승인하고 diff와 테스트 결과를 보는 흐름이 이미 갖춰져 있습니다.

필요한 준비물도 단순합니다. 최신 ChatGPT 모바일 앱, 최신 데스크톱 앱, 같은 계정/워크스페이스, 그리고 깨어 있고 온라인인 호스트 머신이면 됩니다. 회사 워크스페이스라면 관리자가 Remote 접근을 열어 두었는지도 확인해야 합니다.

즉 먼저 물어볼 질문은 이것입니다. "내가 만들려는 게 ChatGPT Remote로 이미 되는 일인가?" 열에 아홉은 여기서 끝납니다.

💡 Tip: 사람 한 명이 폰에서 작업 상태를 보고 승인하는 게 목표라면 프로토콜을 배우는 시간보다 Remote를 붙이는 30분이 훨씬 싸게 먹힙니다.

app-server가 따로 존재하는 이유 ChatGPT Remote가 완제품이라면 codex app-server그 완제품이 내부에서 쓰는 프로토콜 인터페이스입니다. Codex 데스크톱 앱이나 관련 클라이언트가 사람 대신 여러분 코드가 되어야 할 때 등장합니다.

Codex app-server와 운영 레이어 연결 구조
Codex는 실행 엔진이 되고, Hermes(또는 운영 UI)는 승인/메모리/도구 운영 레이어를 감싸는 구조
구분ChatGPT Remotecodex app-server
정체사람이 쓰는 완제품프로그램이 붙는 인터페이스
조작 주체사람여러분 코드
설정 비용앱 설정, QR 스캔JSON-RPC 클라이언트 구현
승인앱 버튼승인 핸들러 직접 구현
전송OpenAI 측 원격 제어 흐름기본 stdio, 선택적 로컬 리스너
적합한 일이동 중 감독/승인자동화/임베딩/커스텀 UI

따라서 app-server를 직접 다룬다는 말은, ChatGPT 앱 자리에 여러분 프로그램을 앉히겠다는 뜻입니다. 이 구분이 잡히면 뒤 판단이 쉬워집니다.

직접 다뤄야 하는 경우는 네 가지뿐입니다

실제로 app-server가 필요한 경우는 생각보다 좁습니다.

첫째, Codex를 여러분 제품 안에 넣을 때입니다. 사내 개발 포털, CI 대시보드, 이슈 화면에서 "이 실패를 고쳐줘" 버튼을 누르면 그 자리에서 스트리밍 출력을 보여 주고 승인도 거기서 받아야 하는 경우입니다.

둘째, 실행 중간에 프로그램이 개입해야 할 때입니다. 진행 중인 턴에 메시지를 주입하거나 끊어야 한다면 앱 UI만으로는 안 됩니다.

셋째, 승인 정책을 코드로 결정해야 할 때입니다. 특정 디렉터리만 자동 승인하거나, 무응답 5분이면 거부하는 규칙을 코드로 적어야 하는 경우입니다.

넷째, 다른 프레임워크와 섞을 때입니다. 예를 들어 AI SDK 계층에서 Codex를 하나의 제공자로 감싸고 싶다면 프로토콜 수준 접근이 필요합니다.

이 넷 중 하나도 아니면 완제품이 낫습니다. 프로토콜을 직접 다루는 비용은 작지 않고, 그 비용이 어디서 생기는지는 다음 섹션에서 드러납니다.

시작 전에 알아야 할 세 가지 전제

HTTP 서버처럼 생각하면 처음부터 틀립니다. codex app-server는 데몬을 띄워 리버스 프록시 뒤에 두는 웹 서버가 아닙니다. 기본 전송은 stdio이고, 줄 단위 JSON 형태의 양방향 JSON-RPC 2.0에 가깝게 동작합니다. 여러분 앱이 자식 프로세스로 띄우고 stdin/stdout으로 대화한다고 생각하는 편이 맞습니다.

전송플래그상태
stdio--stdio (기본)안정
unix socket--listen unix://...로컬 제어용
websocket--listen ws://...실험적, 미지원
off--listen off로컬 전송 비노출

공개 네트워크에 직접 노출하면 안 됩니다. 공식 문서는 원격 연결에 SSH를 쓰라고 설명하고, 공유/공개 네트워크에 app-server 전송을 직접 노출하지 말라고 못 박습니다. 외부 네트워크에서 접근해야 하면 VPN이나 메시 네트워킹 계층으로 해결하고, 원격 개발 환경이 필요하면 데스크톱 앱의 SSH 호스트 연결을 쓰는 편이 안전합니다.

API 표면은 빠르게 움직입니다. deprecated 메서드, 실험 메서드, 개발 중인 플러그인 계열이 혼재합니다. README를 읽고 타입을 손으로 적기 시작하면 버전이 한 번만 바뀌어도 바로 어긋납니다. 그래서 생성된 타입과 스키마를 버전에 고정하는 습관이 사실상 필수입니다.

thread, turn, item을 먼저 이해해야 합니다

thread/turn/item로 나뉘는 Codex 실행 계층
Codex 기본 도구, 플러그인, 그리고 MCP callback이 서로 다른 책임을 맡는 실행 계층

API 전체는 이 세 계층 위에서 움직입니다.

Thread는 사용자와 Codex 사이의 대화 하나입니다. 여러 턴을 담고, 저장되며, resume이나 fork의 대상이 됩니다.

Turn은 대화의 한 차례입니다. 보통 사용자 입력으로 시작해 에이전트 메시지나 작업 종료로 닫힙니다.

Item은 턴 안의 개별 요소입니다. 사용자 메시지, 에이전트 메시지, 셸 실행, 파일 편집, 추론 조각 같은 것들이 여기에 들어갑니다.

메서드 이름이 thread/start, turn/start, item/completed 형태로 보이는 이유가 여기 있습니다. 이걸 먼저 이해하면 문서가 갑자기 읽히기 시작합니다.

initialize와 첫 대화 흐름에서 가장 자주 멈춥니다

연결 하나당 정확히 한 번, 다른 어떤 메서드보다 먼저 initialize를 보내야 합니다. 그리고 initialized 알림까지 보내고 나서야 나머지 요청이 유효해집니다.

{
  "method": "initialize",
  "id": 0,
  "params": {
    "clientInfo": {
      "name": "my_app",
      "title": "My Application",
      "version": "0.1.0"
    }
  }
}

이 단계를 빼먹으면 "Not initialized" 에러가 나고, 두 번 호출하면 "Already initialized"가 옵니다. 실제 통합 초기에 제일 자주 보는 실패입니다.

그다음 흐름은 보통 이 순서입니다.

initialize -> initialized
thread/start
turn/start
item/started / item/.../delta / item/completed
turn/completed

thread/start에서 cwd, 승인 정책, 샌드박스, 퍼스낼리티 같은 설정이 걸립니다. 여기서 놓치기 쉬운 점이 두 개 있습니다. cwd는 신뢰된 프로젝트 상태 같은 부수 효과를 만들 수 있고, 레거시 sandbox와 실험적 permissions를 한 요청에 같이 보내면 거부될 수 있다는 점입니다.

승인과 권한이 통합을 가장 자주 멈추게 만듭니다

에이전트가 샌드박스 밖 명령을 실행하거나 워크스페이스 밖 파일을 건드리려 하면, app-server는 클라이언트에게 역방향 승인 요청을 보냅니다. 여기서 승인 핸들러를 구현하지 않으면 턴이 그냥 멈춘 것처럼 보입니다.

그래서 설계 시 세 가지를 먼저 정해야 합니다.

  1. 어떤 작업을 자동 승인할지
  2. 사람 승인 대기 시간을 얼마나 둘지
  3. 승인 요청과 응답을 어떤 로그 포맷으로 남길지

무인 자동화라면 approvalPolicy: "never"처럼 아예 승인 없는 범위로 좁히는 편이 낫고, 사람 승인 UI라면 타임아웃 후 거부를 기본값으로 두는 편이 안전합니다.

여기서 더 위험한 지점이 두 개 있습니다. thread/shellCommandprocess/spawn은 설계에 따라 사실상 별도 실행 창구가 될 수 있습니다. 최종 사용자에게 노출되는 제품이라면 기본으로 감추고, 정말 필요한 관리자 흐름에서만 열어 두는 편이 맞습니다.

⚠️ 주의: "승인 UI는 나중에 붙이자"는 생각으로 시작하면, 실제로는 가장 먼저 막힙니다. 턴이 시작됐는데 아무 반응이 없는 경우 대부분이 여기입니다.

버전 고정, 백프레셔, 운영 로그는 프로덕션에서 같이 봐야 합니다

스키마와 큐 처리, 운영 지표를 묶어 비용을 추적하는 흐름
비용/토큰/실행 병목을 로그에서 연결해 운영 라우팅을 만드는 방식

가장 실무적인 습관 하나를 꼽으라면, 타입과 스키마를 app-server 버전에 맞춰 직접 생성해서 고정하는 것입니다.

codex app-server generate-ts --out ./src/generated
codex app-server generate-json-schema --out ./schema

이 산출물을 CI에 넣고 diff가 생기면 리뷰 없이 넘어가지 않게 막아야 합니다. 바이너리 버전도 latest 대신 고정하는 편이 안전합니다.

또 하나는 백프레셔 처리입니다. app-server는 경계가 있는 큐를 쓰고, 포화되면 -32001 같은 과부하 에러로 새 요청을 거절할 수 있습니다. 이때는 즉시 재시도 루프가 아니라 지수 백오프 + 지터가 기본입니다. 이 에러가 자주 보인다면 요청을 너무 빠르게 밀고 있다는 뜻입니다.

운영 로그와 비용 추적도 함께 설계하세요.

  • LOG_FORMAT=json 같은 구조화 로그를 기본으로 둔다
  • turn/completed에서 토큰 사용량을 잡아 비용 추적에 연결한다
  • serviceName 같은 태그로 어떤 통합에서 발생한 턴인지 구분한다
  • resume 직후 복원되는 사용량 이벤트가 있다면 UI에 같이 반영한다

문서만 읽고 넘기기 쉬운 부분이지만, 실제로는 이 셋이 없으면 프로토콜 통합이 운영 단계에서 가장 빨리 흐려집니다.

원격 접근이 정말 필요하다면 셋 중 하나를 고르세요

원격이라는 말을 보고 app-server 전송을 밖으로 직접 열 생각부터 하면 안 됩니다. 선택지는 세 가지뿐입니다.

첫째, 사람이 조종하는 원격이면 ChatGPT Remote입니다.

둘째, 원격 개발 머신에서 Codex를 돌려야 하면 데스크톱 앱의 SSH 호스트 연결입니다. 앱이 SSH를 통해 원격 app-server를 시작하고 관리합니다.

셋째, 네트워크 밖 머신에 안전하게 접근해야 하면 VPN 또는 메시 네트워킹입니다. app-server를 공개 주소로 여는 대신 네트워크 계층에서 묶는 방식입니다.

remoteControl/* 계열 메서드는 ChatGPT 앱을 대체하는 자체 클라이언트를 만드는 경우에만 의미가 있습니다. 이것도 실험적 범주로 보는 편이 안전합니다. 그리고 원격 제어를 끈다고 이미 등록된 기기 권한까지 자동으로 사라지는 것은 아니므로, 등록된 컨트롤러 목록 점검과 revoke 흐름을 별도로 관리해야 합니다.

통합 체크리스트

원격 vs 프로토콜 통합 선택 기준 매트릭스
Remote로 끝낼지 app-server 통합이 필요한지, 그리고 실패 지점을 최소화하는 선택 기준

시작 전 판단

  • [ ] ChatGPT Remote로 끝나는 일이 아닌지 먼저 확인했다
  • [ ] 제품 안 임베딩/중간 개입/승인 정책/프레임워크 연동 중 해당 이유가 있다
  • [ ] 사용 주체가 사람인지 프로그램인지 분명하다

프로토콜 기본

  • [ ] 연결당 initialize 1회 후에만 다른 요청을 보낸다
  • [ ] 알림과 응답을 구분해 처리한다
  • [ ] 승인 요청 핸들러와 타임아웃 정책이 있다
  • [ ] -32001 과부하를 재시도 가능한 에러로 본다

버전/운영

  • [ ] generate-ts, generate-json-schema를 CI에 넣었다
  • [ ] app-server 바이너리 버전을 고정했다
  • [ ] turn/completed 사용량을 비용 추적에 연결했다
  • [ ] 구조화 로그와 서비스 태그를 정했다

안전

  • [ ] cwd에 사용자 입력을 그대로 넘기지 않는다
  • [ ] sandboxpermissions를 무심코 같이 보내지 않는다
  • [ ] thread/shellCommand, process/spawn 노출 여부를 명시적으로 결정했다
  • [ ] app-server 전송을 공개 네트워크에 직접 노출하지 않는다

출처와 링크

조사 기준: 2026년 7월. app-server API는 매우 빠르게 변하므로, 문서 문장을 베껴 타입을 손으로 적지 말고 반드시 여러분 버전의 generate-ts 결과와 대조하세요.

자주 묻는 질문

ChatGPT Remote가 이미 되는데 왜 app-server를 배워야 하나요?

사람이 폰이나 데스크톱 앱으로 Codex를 쓰는 것만이 목적이라면 Remote로 충분합니다. 반대로 여러분 제품 안에 Codex를 넣거나, 승인 정책과 실행 중 개입을 코드로 제어해야 하면 app-server 쪽이 필요해집니다.

app-server를 서버처럼 띄워 여러 사용자가 붙게 만들 수 있나요?

그 방향은 공식 권장과 거리가 있습니다. 기본 전송이 stdio이고, 공개 네트워크 노출을 피하라는 지침이 분명하기 때문입니다. 멀티유저 서비스를 만들려면 사용자별 격리와 상위 서버 계층을 따로 두는 편이 안전합니다.

MCP와 app-server는 무엇이 다른가요?

둘 다 양방향 JSON-RPC라는 점은 비슷하지만, 역할은 다릅니다. MCP는 모델에게 도구를 건네는 규격이고, app-server는 스레드, 승인, 샌드박스, 실행 흐름까지 포함해 Codex 에이전트 전체를 구동하는 인터페이스에 가깝습니다.

SDK를 쓰면 프로토콜 세부를 몰라도 되나요?

일상적인 사용에서는 많이 가려집니다. 다만 모든 기능이 SDK에 바로 노출되는 것은 아니어서, 실행 중 개입 같은 세밀한 제어가 필요하면 결국 프로토콜 수준 이해가 다시 필요해질 수 있습니다.

턴이 시작됐는데 아무 반응이 없는 이유는 무엇인가요?

대부분은 승인 요청을 받아 놓고 응답하지 않는 경우입니다. 그다음으로는 initialize/initialized 순서를 잘못 처리했거나, 델타 알림을 꺼 두고 최종 메시지만 기다리는 경우가 있습니다. 이벤트 로그를 먼저 보는 편이 빠릅니다.

폰에서 Remote 메뉴가 안 보이면 무엇부터 봐야 하나요?

모바일 앱과 데스크톱 앱의 최신 버전 여부, 같은 계정과 워크스페이스 로그인 상태, 그리고 회사 워크스페이스라면 관리자 쪽 Remote 허용 상태를 먼저 확인하세요. 설정 시작점이 앱 안이라는 점도 자주 놓칩니다.