Codex는 MCP(영어)를 통해 내 서버에 연결합니다. ~/.codex/config.toml의 mcp_servers 섹션에 Termalin 서버 항목 하나를 추가하면, Codex가 키를 전혀 쥐지 않고도 내 호스트에서 명령을 실행하고 파일을 읽고 씁니다. 설정은 20분쯤 걸립니다. (이미 SSH로 접속하는 서버 한 대에서만 Codex를 쓰고 싶다면, Codex 앱 자체의 원격 연결이 내 키와 원격에 설치된 codex 명령으로 그 일을 해 줍니다 — MCP는 필요 없습니다.)
왜 뻔한 방법이 아니라 MCP 경로일까요? Codex는 리포지토리 안에서는 잘 지냅니다. 서버 액세스를 찾아 나서게 만드는 작업은 리포지토리를 벗어나는 일입니다 — 배포가 실패했거나, 마이그레이션이 멈췄거나, 서비스가 실제 서버에서 다시 올라오지 않을 때 말입니다. 솔깃한 해법은 Codex가 직접 ssh를 실행하게 하는 것입니다. Codex는 이미 내 머신에서 셸 명령을 실행하므로, ~/.ssh나 실행 중인 ssh-agent에 키가 잠금 해제된 채 있으면 내가 아무것도 결정하지 않아도 Codex에게 ssh prod가 그냥 됩니다. 그것은 “Codex에게 액세스를 주는” 것이 아니라, 기본값으로 이미 내줬다는 사실을 뒤늦게 발견하는 것입니다.
이것은 Claude Code(영어)와 Cursor 설정과 같은 구조입니다. 아래는 Codex에 특화된 버전을 단계별로 담았습니다.
Codex가 샌드박스에서 SSH가 허용되지 않는다고 하는 이유
Codex에게 서버로 ssh 하라고 하면 대개 하지 않습니다. 명령이 차단된 채 돌아오거나, Codex가 멈춰서 승인을 요청하는데 무인 실행에서는 그 승인을 내줄 수 없습니다. 이는 설계대로 동작하는 것입니다. Codex는 네트워크와 쓰기 액세스를 차단한 샌드박스 안에서 명령을 실행하는데, 바로 혼란에 빠지거나 주입 공격을 당한 에이전트가 스스로 내 인프라에 손을 뻗지 못하게 하기 위해서입니다 — 그리고 아웃바운드 SSH 연결은 바로 그 울타리가 막으려는 종류의 일입니다.
이리저리 돌아다니는 우회법들은 울타리와 함께 일하기보다 울타리를 치워 버립니다.
- 우회 플래그.
codex --dangerously-bypass-approvals-and-sandbox(그리고--full-auto)는 샌드박스를 꺼서ssh가 통과하게 합니다. 하지만 이 플래그는 SSH에만 한정되지 않습니다 — 그 실행의 모든 명령에서 승인과 샌드박스를 없앱니다. 하나를 열려다 전부의 보호 난간을 치운 셈입니다. sshpass.sshpass -p 'hunter2' ssh user@host는 비밀번호를 비대화식으로 넣어 줍니다. 비밀번호를 명령줄에 평문으로 올려 — 프로세스 목록과 셸 기록에 드러납니다 — 에이전트에게 서버 자격 증명을 들고 다니도록 가르치는데, 이는 바로 피해야 할 습관입니다.- 샌드박스 안의 키.
~/.ssh를 마운트하거나 키를 Codex 환경으로 내보내는 방법도 되긴 하지만, 키가 에이전트의 컨텍스트를 한 번 거치고 나면 유출되지 않았음을 증명할 수 없습니다. 영향 범위 순위(영어)가 이 방법을 맨 아래에 두는 데는 이유가 있고, 그 뒤 유일하게 정직한 해결책은 그 키를 신뢰하는 모든 곳에서 교체하는 것입니다.
세 가지 모두 “샌드박스를 지나 SSH를 어떻게 통과시키나”에 답하지만, 더 나은 질문은 “에이전트가 키를 쥐거나 샌드박스를 끄지 않고 어떻게 내 서버에서 명령을 실행하나”입니다. 그것이 아래의 MCP 경로입니다. SSH 연결은 Termalin이 맺고, Codex는 도구를 호출합니다. Codex가 하는 그 밖의 모든 일에서 샌드박스는 켜진 채로 유지되며, session_open / session_exec가 지속 세션을 유지하므로 에이전트는 상태가 있는 진짜 셸을 얻습니다 — cd, 내보낸 변수, 오래 실행되는 프로세스가 모두 호출 사이에서 살아남습니다 — 끊긴 일회성 명령의 나열이 아니라요.
필요한 것
- Termalin — 데스크톱 앱이며, Free 요금제로 충분합니다. 거기 내장된 MCP 서버가 Codex가 대화할 상대입니다.
- Codex CLI — 같은 머신에 있어야 합니다.
- 호스트 하나 — Termalin에 저장해 두세요. 첫 실행에서는 에이전트가 들쑤셔도 괜찮은 것을 고르세요 — 스테이징이나 버려도 되는 VPS 같은 것.
1단계 — 에이전트 액세스를 켜고 정책을 정하기
에이전트 액세스는 기본적으로 꺼져 있습니다. Termalin에서 **설정 → 에이전트 액세스 (MCP)**를 열어 켠 다음, Codex가 닿아도 되는 호스트를 체크하세요. 그 목록 밖의 것은 에이전트에게는 존재하지 않습니다. 호스트를 추가하는 것은 앱에서 내가 내리는 결정이지, Codex가 말솜씨로 끌어낼 수 있는 일이 아닙니다.
그 아래에서 두 가지 일이 일어납니다. Termalin은 MCP 서버를 위한 호스트 인벤토리를 에이전트 전용 인증 항목으로 기록합니다 — 비밀번호나 키는 그 파일에 들어가지 않습니다. 그리고 인증은 앱의 키 커스터디언(사용자 대신 키를 보관하고 서명하는 구성 요소)이 맡습니다. 한 번 잠금을 해제하면 Termalin이 에이전트 대신 서명합니다. Codex가 읽을 키 파일이 없으니 유출될 것도 없고 — 이로써 앞서 말한 ~/.ssh 뒷문도 닫힙니다.
그 김에 각 호스트의 에이전트 정책도 정하세요. 전체 액세스, 명령 허용 목록, 또는 차단입니다. 신경 쓰이는 대상이라면 허용 목록으로 시작하세요 — 머릿속에 둔 일을 Codex가 해내게 하는 가장 짧은 목록으로요.
2단계 — config.toml에 서버 등록하기
Codex는 ~/.codex/config.toml의 mcp_servers 섹션에서 MCP 서버를 읽습니다. 번들된 termalin-mcp 바이너리를 가리키는 항목 하나를 추가하세요:
[mcp_servers.termalin]
command = "<path>/termalin-mcp"
최근 Codex 빌드에서는 명령줄로 추가할 수도 있습니다 — 결과는 같습니다:
codex mcp add termalin -- <path>/termalin-mcp
이게 통합의 전부이며, 같은 설정이 IDE의 Codex도 구동합니다. Codex를 재시작하고 서버가 연결됨으로 표시되는지 확인하면, 에이전트에게 도구가 나타납니다. hosts_list, ssh_exec, 지속 세션(session_open / session_exec), SFTP 읽기·쓰기, 그리고 포트 포워딩입니다. 전체 도구 목록(영어)에 하나하나 정리돼 있습니다.
처음 몇 세션 동안 지켜 둘 만한 Codex 습관 하나: 명령 승인을 켜 두세요. Codex는 그러지 말라고 하기 전까지는 행동하기 전에 묻습니다 — 아직은 그러지 말라고 하지 마세요. 그 범위는 호스트 목록을 넓히는 방식 그대로 넓히세요. 동작을 지켜본 뒤에, 한 번에 지루한 것 하나씩.
3단계 — 진짜 잡일을 맡기기
데모 명령은 건너뛰세요. 실제로 할 법한 일을 맡기세요:
staging-1 배포는 끝났는데 헬스 체크가 깜빡거립니다. 원인을 찾아 고쳐 주세요.
Codex는 hosts_list를 호출해 staging-1을 확인하고, 세션을 열어 실마리를 당기기 시작합니다 — 서비스 상태, 마지막 로그 100줄, 실행 중인 것과의 설정 diff. 수정안을 제안하고, 내가 정한 정책 안에서 적용한 뒤, 체크가 초록색으로 바뀌는지 확인합니다.
이것이 조마조마하지 않고 편안한 이유는, 그 무엇도 보이지 않는 곳에서 일어나지 않기 때문입니다. Codex가 여는 모든 세션은 Termalin에 실시간 터미널 탭으로 나타나고, **워치 그리드(영어)**는 열린 모든 세션을 나란히 놓고 에이전트가 조작하는 타일을 빛나게 합니다. 나중에 요약을 읽는 게 아니라 명령이 실행되는 대로 지켜보며 — 세션 도중 언제든 끼어들 수 있습니다.
경계는 어디에 있나
중요한 대상에 Codex를 들이대기 전에 알아 둘 만한 기본값들:
- 내 키는 Codex 환경에 절대 들어가지 않습니다. 커스터디언이 서명하고, 에이전트는 요청합니다. 액세스 해지는 전체 서버에 걸친 키 교체가 아니라 설정의 토글 하나입니다.
- 에이전트의 범위는 1단계에서 체크한 호스트 목록이고, 각 호스트의 명령 정책이 거기서 실행할 수 있는 것을 제한합니다. 프로덕션에 “전체”를 주면 여전히 완전한 셸입니다 — 신중하게 정하세요.
- 내 세션에 입력하는 것은 별개입니다. 기본적으로 Codex는 자기 세션을 엽니다. 이미 열어 둔 세션에 합류하는 것은 별도의 동의 토글입니다. 조용히 묻어 타는 일은 결코 없습니다.
- 모든 명령이 기록으로 남습니다. 세션 녹화는 출력만 담고 — 키 입력은 절대 담지 않으며 — 각 에이전트 명령은 감사 로그에 출처 기기와 IP와 함께 에이전트의 것으로 태그됩니다(영어). “에이전트가 이걸 했다”는 재구성하는 이야기가 아니라 적용하는 필터입니다.
Codex가 내 데스크톱이 없는 곳에서 실행될 때
Codex가 내 노트북이 아니라 CI나 클라우드 샌드박스에서 실행된다면 로컬 stdio 바이너리에는 닿을 수 없습니다 — 하지만 Termalin의 호스팅 MCP 엔드포인트에는 닿습니다. 누군가 로그인할 수 있는 상황이라면, Codex에 https://termal.in/mcp를 원격 MCP 서버로 추가하고 Termalin 로그인 페이지에서 한 번 승인하세요(OAuth, 붙여 넣을 키 없음). 무인 실행이라면 웹 캐비닛에서 API 키를 만들어, 그 작업이 건드릴 서버로 범위를 제한하고, 읽기 전용이나 허용 목록으로 설정한 뒤, 만료 기간을 두세요. 엔드포인트는 Connector로 등록한 서버에 키 없이 닿으며, 실행마다 단기 인증서로 인증합니다 — 넘겨주는 키도, 상주하는 것도 없습니다. 복사해 붙여 넣을 파이프라인 예시를 포함한 전체 패턴은 CI/CD에서 에이전트에 SSH 액세스 주기(영어)에 있습니다.
습관으로 자리 잡게 하는 법
첫 주는 타자가 빠른 동료를 온보딩하듯 대하세요. 워치 그리드를 열어 두세요. Codex에게 완료 상태가 분명한 잡일을 주고 — “헬스 체크를 통과시켜라”, “인증서를 갱신해라” — 거기에 어떻게 도달하는지 읽어 보세요. 지루한 도구에 대해 자동 승인을 얻기 전까지는 승인을 켜 두고, 호스트 목록은 심심한 서버 하나씩 넓히세요.
이 비대칭이 핵심입니다. Codex는 진짜 도달 범위를 얻고, 나는 한번 나가면 되돌려받을 수 없는 그 하나를 쥐고 있습니다.
Termalin은 내장 MCP 서버, 키 커스터디언, 호스트별 에이전트 정책을 갖춘 크로스 플랫폼 SSH 클라이언트입니다. Codex SSH 페이지에서 시작하거나, MCP 레퍼런스를 읽거나, 앱을 다운로드하세요 — Free 요금제는 호스트 수 제한이 없습니다.