환경변수로 붙인 MCP가 cron에서만 조용히 죽는 이유
대화형에선 잘 되던 MCP 연결이 무인 자동화에서만 조용히 실패하는 세션 스코프 인증 함정과 해결법을 정리했어요.
터미널에서 손으로 돌릴 땐 멀쩡했어요. AI 에이전트에 MCP 서버를 붙이고, 붙자마자 "연결됨"까지 확인했죠. 그런데 같은 파이프라인을 cron에 얹어 밤에 무인으로 돌리니 그 서버만 "연결 실패"로 조용히 죽어 있더라고요. 에러도 요란하지 않아서, 아침에 결과물이 비어 있고 나서야 알았어요. 혹시 비슷한 경험 없나요?
대화형에선 되고, 무인에선 죽는다
원인을 파보니 인증 방식이 문제였어요. export KEY=... && (mcp 붙이기) 식으로 환경변수에 토큰을 넣어 연결하면, 설정 파일에는 서버 항목만 남고 토큰 값은 그 셸 세션에서만 살아 있어요. 새 터미널 하나만 열어도 값이 사라지는 이유가 이거예요.
직접 재현해 봤더니 규칙이 선명했어요. 값을 .zshrc 같은 셸 프로필에 넣어 두면 대화형에선 잘 붙습니다. 문제는 cron이나 launchd 같은 무인 실행 경로는 인터랙티브 셸 프로필을 아예 읽지 않는다는 점이에요. 최소한의 환경변수만 상속받고 시작하거든요. 그러니 대화형에서 되던 인증이 무인 경로에서만 골라서 죽습니다.
가장 나쁜 실패 모드: false green
이게 특히 성가신 건 실패가 조용해서예요. 워크플로우 상태는 "성공"으로 뜨는데 정작 그 도구만 안 붙은 채 지나가요. 저는 이걸 겉만 초록색인 가짜 성공이라고 불러요. 라이프케어로그의 플랜 시리즈를 1인 개발로 운영하면서 이런 자동화를 여럿 돌리는데, 무인 파이프라인이 24시간 넘게 빈 결과만 쌓다가 뒤늦게 발견되면 그 시간이 통째로 날아가요.
해결은 두 가지가 전부
테스트해 보면서 정리한 방법은 단순해요.
첫째, 토큰을 셸 프로필이 아니라 스케줄러 자체에 직접 박기예요. launchd라면 plist의 환경변수 항목에, cron이라면 실행 스크립트 상단에, 혹은 MCP 설정 파일의 env 블록에 직접 넣습니다. 무인 경로가 실제로 읽는 자리에 두는 게 핵심이에요.
둘째, 배선한 뒤 무인 경로에서 딱 한 번 실제로 돌려 보기예요. 대화형에서 됐다는 건 증거가 안 돼요. cron 트리거 그대로 1회 실증해서 그 도구가 붙는지를 눈으로 확인해야 false green을 걸러낼 수 있어요.
- 프로필 대신 스케줄러에 직접 배선
- 값이 실토큰인지 참조인지 먼저 확인
- 무인 경로에서 1회 실증
한 가지 더. 설정에 들어간 값이 진짜 토큰인지, 다른 변수를 가리키는 참조인지 먼저 구분하세요. ${...} 같은 참조는 그 변수가 무인 환경에 없으면 똑같이 빈손이 됩니다.
마무리
무인 자동화일수록 "대화형에서 됐으니 되겠지"라는 가정이 제일 위험해요. 사람이 안 보는 경로일수록 한 번은 그 경로 그대로 돌려 보고 넘어가면, 밤새 조용히 죽는 파이프라인 하나는 확실히 줄일 수 있어요.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.