
Claude Code로 매일 아침 정기 업무 자동화하기 (Windows 편) — 작업 스케줄러 × headless 모드에서 빠진 3가지 함정
요약
Windows 작업 스케줄러를 사용하여 Claude Code의 headless 모드를 정기적으로 자동화할 때 발생하는 3가지 주요 문제점과 해결 방법을 다룹니다. PowerShell 버전 차이로 인한 실행 실패, MCP 도구 권한 문제, 그리고 실행 결과 관측성 확보 방안을 제시합니다.
핵심 포인트
- PowerShell 5.1 대신 pwsh.exe(7계열)를 사용하여 경로 인코딩 문제를 회피하세요.
- 무인 실행 시 MCP 도구 사용을 위해 --allowedTools 플래그를 설정해야 합니다.
- 실행 결과를 로그 파일로 남겨 사후 리뷰가 가능한 관측성 체계를 구축하세요.
- headless 모드는 완전 자동화가 아닌 '무인 실행 후 인간의 확인' 프로세스로 접근해야 합니다.
Claude Code의 headless 모드(claude -p)를 알고, "이걸 매일 아침 자동으로 실행하면 아침 첫 정기 작업이 사라지지 않을까?"라고 생각한 사람이 가장 먼저 맞닥뜨리는 지점은 바로 여기입니다.
- 수동으로 입력하면 작동하는 명령어가 작업 스케줄러를 통하면 아무 일도 일어나지 않고 종료됨 (에러조차 발생하지 않음)
- MCP 도구를 사용하게 하고 싶은데, 무인 실행 시에는 허가 프롬프트(permission prompt)를 띄울 수 없어 거기서 막힘
- 애초에 "오늘 아침에 제대로 작동했는지"를 확인할 수단을 만들어두지 않았다는 사실을 며칠 뒤에 깨달음
이 기사에서는 Windows의 작업 스케줄러(Task Scheduler)로부터 claude -p를 매일 아침 정해진 시간에 실행하는 운영 체계를 구축했을 때, 제가 실제로 빠졌던 3가지 함정과 그 회피책을 정리합니다. headless 모드 자체의 기본( -p 사용법, 출력 포맷 등)은 이 기사에서 깊게 다루지 않습니다. "작동하는 명령어는 있는데, 정기 실행 운영에 태울 수 없는" 부분에 집중합니다.
참고: Claude Code의 플래그나 동작은 집필 시점의 것입니다. 사양은 업데이트되므로, 최신 정보는 공식 문서(https://code.claude.com/docs/)에서 확인해 주세요.
- 작업 스케줄러 ×
claude -p의 기본 구성 (스크립트 + 로그 + 인간의 사후 확인) - 함정 ①: powershell.exe (5.1)를 사용하면 일본어 경로에서 무언으로 실패하는 문제와 pwsh.exe 지정으로 인한 회피
- 함정 ②: headless 실행에서 MCP 도구를 사용하게 하기 위한
--allowedTools작성법 - 함정 ③: "작동하지 않고 있음"을 알아챌 수 있는 관측성(Observability) 구축 방법
- 작업 스케줄러의 구체적인 설정값과 자동 실행에 부여하는 권한의 보안 주의사항
해야 할 일은 심플하며, 다음의 3종 세트입니다.
claude -p "프롬프트"를 작성한 ps1 스크립트 준비- 작업 스케줄러로 매일 아침 정해진 시간에 해당 스크립트를 기동
- 결과는 날짜가 포함된 로그 파일에 기록해 두고, 인간(본인)이 나중에 육안으로 확인
포인트는 3번입니다. headless 실행은 "Claude에게 완전히 맡기고 끝"내는 것이 아니라, 결과를 파일로 남겨서 인간이 사후 리뷰를 한다는 전제로 구성합니다. LLM의 출력은 실행할 때마다 흔들리기 때문에, 무인 실행과 수동 확인을 한 세트로 만드는 것이 안전합니다.
스크립트의 틀은 다음과 같습니다.
# daily-claude.ps1
$ErrorActionPreference = "Stop"
$workDir = "C:\work\myrepo" # Claude에게 작업을 시킬 디렉토리
...
*>는 PowerShell 7계열에서 모든 스트림(표준 출력, 에러 등)을 한꺼번에 리다이렉션(redirection)하는 작성법입니다. 성공 시의 출력도 에러도 전부 그날의 로그에 담깁니다.
여기까지는 순조롭습니다. 문제는 이것을 작업 스케줄러에 올리는 순간 시작됩니다.
처음에 빠졌던 것이 이것입니다. 작업 스케줄러의 "프로그램/스크립트"에 powershell.exe(Windows 표준 PowerShell 5.1)를 지정하고, 인수로 일본어가 포함된 경로의 스크립트를 -File로 지정했더니, 작업은 "정상 종료" 처리되었는데 스크립트의 내용은 아무것도 실행되지 않는 상태가 되었습니다.
- 에러 다이얼로그 없음
- 이벤트 로그에도 실마리라고 할 만한 흔적 없음
- 작업 스케줄러상으로는 성공으로 보임
제 환경(Windows 11)에서는 pwsh.exe (PowerShell 7계열)를 명시적으로 지정했더니 동일한 인수로 그대로 작동했습니다. 일본어가 포함된 경로 + -File 지정의 조합에서 5.1과 7계열의 동작이 갈린 형태입니다. 교훈은 두 가지입니다.
첫 번째: 작업 스케줄러에서는 pwsh.exe를 풀 경로(full path)로 지정할 것. PowerShell 7계열은 별도로 설치가 필요합니다 (winget install Microsoft.PowerShell 등). 기본 설치 경로는 C:\Program Files\PowerShell\7\pwsh.exe입니다.
두 번째: 스케줄러에 등록하기 전에, 동일한 커맨드라인을 수동으로 입력하여 검증할 것. 정기 실행은 "실패를 알아차리기 어렵다"는 것이 본질적인 약점입니다. 등록하는 것과 완전히 동일한 실행 파일, 동일한 인수를 먼저 커맨드라인에서 직접 실행하여 동작을 확인합니다.
# 작업 스케줄러에 등록하기 전에, 이를 직접 실행하여 확인합니다
& "C:\Program Files\PowerShell\7\pwsh.exe" -NoProfile -File "C:\work\scripts\daily-claude.ps1"
이렇게 해서 동작하지 않는다면, 스케줄러에 등록해도 동작하지 않습니다. 문제 원인을 분리하는 단계가 한결 간단해집니다.
대화형 모드의 Claude Code에서는 MCP 도구를 처음 사용할 때 "허용하시겠습니까?"라는 프롬프트가 나타나며 사람이 승인합니다. 하지만 headless 실행(claude -p)은 무인(unattended) 상태입니다. 허가 프롬프트를 받아줄 대상이 없기 때문에, MCP 도구를 사용하는 처리 단계에서 더 이상 진행되지 않습니다.
회피 방법은 호출 시 --allowedTools 플래그를 사용하여 사용하고자 하는 도구를 명시적으로 허용하는 것입니다. MCP 도구의 이름은 다음 형식을 따릅니다.
mcp__<서버명>__<도구명>
예를 들어 MCP 서버 myserver의 search 도구를 허용하려면 다음과 같이 작성합니다.
claude -p "MCP의 검색 도구로 어제의 기록을 조사하여 요약해줘" `
--allowedTools "mcp__myserver__search" `
*> $logFile
"매번 플래그를 쓰는 것은 번거로우니, settings.json의 허용 리스트에 작성하여 영구화하자"라고 생각하는 것이 자연스럽지만, 제 환경에서는 Claude Code 스스로 settings.json을 편집하여 허용 항목을 추가하도록 시도했을 때, 안전 장치에 걸려 편집이 통과되지 않는 케이스가 있었습니다. 설정 파일의 수정 자체가 민감한 작업으로 취급되기 때문인 것으로 보입니다 (이 판단 기준의 상세 내용은 확인하지 못했습니다).
결과적으로, 호출할 때마다 --allowedTools로 명시 지정하는 것이 확실했습니다. 정기 실행의 경우, 커맨드라인은 스크립트에 고정되어 작성되므로 매번 지정하더라도 수고는 한 번뿐입니다. 오히려 "이 작업(job)에 부여된 권한이 스크립트를 보면 전부 파악된다"라는 감사(audit) 측면의 이점도 있습니다.
정기 실행에서 가장 무서운 고장 모드는 화려한 에러가 아니라 **"어느샌가 동작하지 않고 있는데, 아무도 눈치채지 못하는 것"**입니다. 함정 ①과 같은 무언의 실패도 있으므로, 관측성(observability)은 처음부터 준비해 두어야 합니다.
해야 할 일은 두 가지입니다.
첫 번째: 표준 출력(standard output)을 날짜가 포함된 로그 파일로 리다이렉트합니다. 서두의 템플릿에서 했던 것처럼, yyyy-MM-dd.log 형식으로 파일을 나눕니다. "오늘 아침 분량"이 파일로서 존재하는지 여부 자체가 생존 확인이 됩니다.
두 번째: 로그 파일의 수정 시간을 확인하는 습관(또는 명령어)을 갖습니다. 저는 다음의 원라이너(one-liner)로 최근 로그를 확인합니다.
Get-ChildItem C:\work\logs\claude-daily |
Sort-Object LastWriteTime -Descending |
Select-Object -First 3 Name, LastWriteTime
오늘 날짜의 파일이 맨 위에 오지 않는다면, 오늘 아침의 작업은 실행되지 않은 것입니다. "결과 내용의 본문"을 읽기 전에 "애초에 실행되었는가"를 몇 초 만에 판정할 수 있습니다.
작업 스케줄러 측에서도 "작업 상태", "이전 실행 결과" 열을 볼 수 있지만, 앞서 언급했듯이 내용이 실행되지 않았더라도 정상 종료된 것처럼 보이는 패턴이 있으므로, 결과물(로그 파일) 측면에서 확인하는 것이 확실합니다.
함정을 고려한 설정값을 정리합니다. 작업 스케줄러에서 "기본 작업 만들기" $\rightarrow$ "프로그램 시작"을 선택하고 다음과 같이 입력합니다.
| 설정 항목 | 값 |
|---|---|
| 프로그램/스크립트 | C:\Program Files\PowerShell\7\pwsh.exe |
보충 설명입니다.
-NoProfile을 붙이면 사용자 프로필($PROFILE)을 읽지 않고 실행합니다. 프로필에 작성한 설정이나 모듈 로드가 정기 실행의 동작을 바꾸는 것을 방지하고, 환경 차이를 줄일 수 있습니다.- "시작(옵션)"(작업 디렉터리)은 잊지 말고 지정합니다. 공란으로 두면 예상치 못한 디렉터리에서 실행되어, 상대 경로를 사용하는 처리가 망가집니다. 스크립트 내부에서
Set-Location을 호출하더라도, 실행 직후의 현재 디렉터리(current directory)를 고정해 두면 사고를 줄일 수 있습니다. - 스크립트 경로에 공백이나 일본어(또는 한글 등 비영어권 문자)가 포함된 경우, 인수 내의 큰따옴표(double quotes)는 필수입니다.
무인 실행(Unattended execution)은 "인간의 확인이 개입되지 않는" 실행입니다. 그렇기에 부여하는 권한은 의식적으로 제한해야 합니다.
읽기 전용 작업이라면 --allowedTools를 사용하여 해당 작업에 필요한 도구만 나열합니다. "Read"만 필요하다면, MCP 도구가 하나 필요할 경우 "mcp__myserver__search"만 지정합니다. 무인 실행에서는 "귀찮으니까 넓게 설정하자"는 방식은 오히려 독이 됩니다.
이름 그대로 권한 확인을 건너뛰는 플래그로, 이를 정기 실행에 추가하면 "매일 아침, 권한 체크 없이 LLM이 동작하는" 상태가 됩니다. 프롬프트에서 멈추는 문제는 --dangerously-skip-permissions를 안일하게 사용하지 마세요. --allowedTools를 명시함으로써 해결할 수 있으므로, 먼저 그 방법을 사용해야 합니다.
만일의 폭주나 예상치 못한 출력에 대비하여, 파괴적인 작업(커밋, 삭제, 외부 전송 등)은 자동 작업에 포함하지 말고, 생성 결과를 파일로 쓰는 단계까지만 수행한 뒤, 적용은 인간의 확인 후에 수동으로 진행하는 구성을 권장합니다.
Windows에서 claude -p를 매일 아침 정기 실행에 올릴 때의 체크리스트입니다.
실행 엔진은 pwsh.exe (PowerShell 7계열)를 풀 경로(full path)로 지정하세요. powershell.exe (5.1)는 일본어 경로 + -File 조합에서 아무런 메시지 없이 실패할 수 있습니다.
등록 전에 동일한 커맨드라인을 수동으로 실행하여 검증하세요. 정기 실행은 실패를 알아차리기 어렵습니다.
MCP 도구는 settings.json 편집을 통한 영구 설정이 거부되는 경우가 있으므로, --allowedTools "mcp__<서버명>__<도구명>"를 통해 호출 시마다 명시적으로 허용하세요.
**출력은 날짜가 포함된 로그 파일로 리다이렉트(redirect)**하여, 업데이트 일시를 확인함으로써 "애초에 실행되었는지"를 판단할 수 있도록 합니다.
작업 스케줄러에서는 -NoProfile -File "…"와 작업 디렉토리(working directory) 지정을 잊지 마세요.
권한은 최소한으로. --dangerously-skip-permissions는 정기 실행에 추가하지 마세요.
3가지 함정은 모두 "수동이라면 알아챌 수 있지만, 무인 상태라면 알아챌 수 없는" 성질의 것이었습니다. 역으로 말하면, **수동 검증 → 최소 권한 → 관측성(Observability)**의 세 가지 포인트를 처음에 잡아둔다면, 매일 아침의 정형 업무는 안심하고 Claude Code에 맡길 수 있습니다.
반복해서 말씀드리지만, Claude Code의 플래그 및 동작은 집필 시점의 정보입니다. 도입 시에는 공식 문서(https://code.claude.com/docs/ )에서 최신 사양을 확인하시기 바랍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기