ntfy로 Claude Code push 알림을 받으려면 휴대폰에 ntfy 앱을 설치하고, 추측하기 어려운 이름의 topic을 구독한 뒤, curl -d "message" https://ntfy.sh/your-topic을 실행하는 Claude Code hook을 추가하면 돼요. Notification hook은 Claude가 권한을 요청하거나 입력을 기다릴 때 알려 주고, Stop hook은 턴이 끝나는 즉시 알려 줘요. 무료이고, 10분 정도면 설정할 수 있으며, Mac, Windows, Linux에서 모두 동작해요.
011단계: topic을 정하고 구독하기
ntfy는 가입이 필요 없어요. topic은 누군가 처음 publish하거나 구독할 때 생성되고, 이름을 아는 사람은 누구나 읽을 수 있어요. ntfy 공식 문서에서도 topic이 사실상 비밀번호라고 설명하니, claude-7f3k9q2xw4mz처럼 길고 무작위로 만드세요. topic 이름에는 영문자, 숫자, 밑줄, 대시를 최대 64자까지 쓸 수 있어요.
ntfy 앱(App Store, Google Play 또는 F-Droid)을 설치하고 +를 눌러 ntfy.sh에서 내 topic을 구독하세요.
terminal에서 잘 동작하는지 확인해 보세요:
curl -H "Title: Test" -d "Hello from my computer" https://ntfy.sh/claude-7f3k9q2xw4mz
1~2초 안에 휴대폰이 울려야 해요. Windows에서는 Windows 10과 11에 기본 포함된 curl.exe로 같은 명령을 실행할 수 있어요.
022단계: hook 스크립트 (Mac 및 Linux)
Claude Code는 각 hook에 표준 입력으로 JSON 객체를 전달해요. 두 이벤트 모두 cwd, hook_event_name 같은 필드를 공통으로 가져요. Notification에는 message와 notification_type이 추가되고, Stop에는 Claude의 마지막 답변 텍스트인 last_assistant_message가 추가돼요. 이 스크립트는 두 경우 모두 읽기 좋은 push로 바꿔 줘요. jq가 필요해요(brew install jq, Debian과 Ubuntu에서는 apt install jq).
~/.claude/ntfy-notify.sh로 저장하고 chmod +x ~/.claude/ntfy-notify.sh를 실행하세요:
#!/bin/sh
TOPIC_URL="https://ntfy.sh/claude-7f3k9q2xw4mz"
input=$(cat)
event=$(printf '%s' "$input" | jq -r '.hook_event_name')
project=$(basename "$(printf '%s' "$input" | jq -r '.cwd')")
if [ "$event" = "Stop" ]; then
title="Claude finished: $project"
body=$(printf '%s' "$input" | jq -r '(.last_assistant_message // "Done") | .[0:300]')
priority=3
else
title="Claude needs you: $project"
body=$(printf '%s' "$input" | jq -r '.message // "Needs your attention"')
priority=4
fi
curl -s -H "Title: $title" -H "Priority: $priority" -H "Tags: robot" \
-d "$body" "$TOPIC_URL" > /dev/null
exit 0
우선순위는 1(최저)부터 5(긴급)까지예요. Tags는 알림에 이모지를 붙여 주는데, robot은 로봇 얼굴을 표시해요.
033단계: settings.json에 연결하기
~/.claude/settings.json에 hook을 추가하세요. 파일에 이미 hooks 객체가 있다면 덮어쓰지 말고 그 안에 이벤트를 추가하세요.
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{ "type": "command", "command": "~/.claude/ntfy-notify.sh" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "~/.claude/ntfy-notify.sh", "async": true }
]
}
]
}
}
"async": true를 설정하면 Stop hook이 백그라운드에서 전송되므로 네트워크가 느려도 Claude가 지연되지 않아요. hook은 세션 시작 시 로드되니 새 Claude Code 세션을 시작하세요.
Stop과 idle_prompt 중 무엇을 쓸까요?
Stop은 키보드 앞에 있더라도 Claude가 끝나는 즉시 실행돼요. 너무 잦다면 Stop 블록을 빼고 matcher로 permission_prompt|idle_prompt를 쓰세요. Anthropic 문서에 따르면 idle_prompt는 Claude가 끝난 뒤 약 60초 동안 입력이 없을 때만 실행되고, permission_prompt는 권한 prompt가 약 6초간 키 입력 없이 대기하면 실행돼요. 덕분에 별도 작업 없이 '자리를 비웠을 때만' 알림을 받는 대략적인 필터가 생기는 셈이에요. 모든 필드와 타이밍은 Notification hook 가이드와 Stop hook 가이드에서 다뤄요.
04Windows (PowerShell)
Windows에서는 다음을 %USERPROFILE%\.claude\ntfy-notify.ps1로 저장하세요. 따로 설치할 건 없어요:
$in = [Console]::In.ReadToEnd() | ConvertFrom-Json
$project = Split-Path $in.cwd -Leaf
if ($in.hook_event_name -eq 'Stop') {
$title = "Claude finished: $project"
$body = [string]$in.last_assistant_message
if ($body.Length -gt 300) { $body = $body.Substring(0, 300) }
$priority = '3'
} else {
$title = "Claude needs you: $project"
$body = [string]$in.message
$priority = '4'
}
Invoke-RestMethod -Method Post -Uri 'https://ntfy.sh/claude-7f3k9q2xw4mz' `
-Headers @{ Title = $title; Priority = $priority } `
-Body ([Text.Encoding]::UTF8.GetBytes($body)) | Out-Null
그다음 위의 command 줄 대신 이 hook 항목을 사용하세요:
{
"type": "command",
"shell": "powershell",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\ntfy-notify.ps1\""
}
WSL 안에서 Claude Code를 실행한다면 Mac 및 Linux용 스크립트를 쓰세요. hook 입장에서 WSL은 Linux예요.
05비공개로 유지하기
push 내용은 모두 ntfy 서버를 거치고, ntfy.sh에서는 topic 이름을 아는 누구나 읽을 수 있어요. 위의 Stop 메시지에는 Claude 답변의 앞부분이 포함되는데, 여기에 코드나 파일 이름이 들어 있을 수 있어요. 보안을 강화하는 방법은 세 가지예요:
- 덜 보내기.
Stop본문을"Done"같은 고정 문자열로 바꾸고 제목에는 프로젝트 이름만 남기세요. - 액세스 토큰 사용하기. ntfy는 모든 publish에서
-H "Authorization: Bearer tk_..."를 받아요. 자체 서버라면auth-default-access: "deny-all"을 설정하고,ntfy user add로 사용자를,ntfy token add로 토큰을 만드세요. - 자체 서버 운영하기. ntfy는 셀프 호스팅이 가능해요. iPhone 앱으로 즉시 전달하려면 ntfy 문서대로
upstream-base-url: "https://ntfy.sh"를 설정하세요. 그러면 휴대폰을 깨우기 위해 메시지 ID와 topic 해시만 ntfy.sh로 전달되고, 앱은 실제 메시지를 내 서버에서 가져와요.
Claude Code를 원격 서버에서 실행해도 같은 hook이 그대로 동작하므로, ntfy는 SSH 환경의 알림에도 잘 맞아요.
06Claude Code Notifier의 역할
단방향 알림이라면 위 설정으로 충분하고, 굳이 말릴 생각도 없어요. 다만 알려 주는 데서 끝나요. Claude가 권한이 필요하다는 push가 와도, 키보드 앞으로 돌아갈 때까지 세션은 계속 기다려요.
ntfy는 HTTP 요청을 보내는 액션 버튼을 지원하니 응답 경로를 직접 만들 수도 있어요. 요청을 publish하고, 두 번째 topic에서 응답을 기다렸다가 결정을 반환하는 PermissionRequest hook을 만드는 식이죠. 실제로 이렇게 하는 오픈 소스 프로젝트도 있어요(비교 글 참고).
Claude Code Notifier는 이 경로를 패키지로 제공해요. 휴대폰을 페어링하면 권한을 한 번 허용, 세션 동안 허용, 거부할 수 있고, Claude가 질문하면 답을 고르고, Claude가 끝나면 다음 지시를 보내는 것까지 모두 휴대폰에서 할 수 있어요. 자리에 있는지도 확인해요. 최근 30초 안에 입력했다면 terminal이 평소처럼 묻고 휴대폰 쪽은 기다리지 않아요. 자리를 비웠다면 terminal은 설정한 최대 시간까지 답을 기다리다가, 키보드를 건드리는 순간 기다림을 멈춰요. ccn은 Mac, Windows, Linux에서 동작해요. 휴대폰 앱은 ccn 페이지와 요금제를 참고하세요.
07FAQ
Claude Code 알림에 ntfy는 무료인가요?
ntfy.sh에 publish하거나 구독할 때는 계정이 필요 없고, 서버는 누구에게나 열려 있어요. ntfy는 유료 요금제도 있고 셀프 호스팅도 가능해요. 현재 제한은 ntfy 공식 사이트에서 확인하세요.
ntfy hook이 실행되지 않는 이유는 뭔가요?
hook은 시작 시 로드되므로 settings.json을 수정한 뒤에는 새 Claude Code 세션을 시작하세요. 그다음 curl 테스트 명령을 직접 실행해 보고, echo '{"hook_event_name":"Stop","cwd":"/tmp/x"}' | ~/.claude/ntfy-notify.sh처럼 샘플 JSON을 스크립트에 파이프로 넣어 보세요. 나머지는 문제 해결 체크리스트에서 다뤄요.
ntfy 알림에서 Claude Code에 답장할 수 있나요?
단순 publish로는 안 돼요. ntfy의 HTTP 액션 버튼으로 요청을 보낼 수는 있지만, 답을 기다렸다가 Claude Code가 이해하는 결정으로 바꿔 주는 hook이 필요해요.
모든 알림 유형마다 push를 받나요?
지정한 matcher에 대해서만 받아요. 인증 및 MCP 대화 상자를 포함한 모든 유형을 받으려면 Notification 항목에서 matcher를 빼세요.