---
title: "Claude Code 휴대폰 알림: 훅으로 간단 설정"
description: "Claude Code가 권한을 요청하거나 작업을 마치면 휴대폰으로 알림을 받으세요. Notification·Stop 훅과 웹훅을 쓰는 복사해 붙여넣기용 설정을 소개합니다."
date: 2026-10-02
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - Claude Code
  - AI 코딩 에이전트
  - 훅
  - 휴대폰 알림
  - 웹훅
  - 개발자 생산성
---

# Claude Code 휴대폰 알림: 내가 필요할 때, 작업이 끝났을 때 바로 알기

Claude Code가 멈추는 중요한 순간은 두 가지입니다. 권한 요청이나 질문처럼 여러분의 응답을 기다리며 막혀 있을 때, 그리고 작업을 끝냈을 때입니다. 터미널을 보고 있지 않으면 두 상황은 똑같아 보입니다. 아무 일도 일어나지 않고, 여러분이 돌아올 때까지 세션은 그대로 멈춰 있습니다. 해결책은 훅입니다. `settings.json`에 몇 줄만 추가하면, 둘 중 하나가 발생하는 즉시 휴대폰으로 웹훅이 날아갑니다.

이 글에서는 복사해서 쓸 수 있는 설정을 드리고, 상황별로 어떤 훅 이벤트를 써야 하는지 설명합니다. 또 안정적으로 동작시키는 데 필요한 세부 사항, 즉 훅 입력 읽기, 셸 따옴표 처리, 알림 폭주 막기까지 다룹니다.

## 상황별로 어떤 훅을 쓸까

Claude Code는 라이프사이클 이벤트마다 훅을 실행합니다. 이 문제는 그중 두 가지로 해결됩니다([훅 레퍼런스](https://code.claude.com/docs/en/hooks)).

| 알고 싶은 상황 | 훅 이벤트 | Matcher / 필터 |
| --- | --- | --- |
| Claude가 권한 결정을 기다릴 때 | `Notification` | `permission_prompt` |
| Claude가 한동안 대기하며 여러분의 입력을 기다릴 때 | `Notification` | `idle_prompt` |
| Claude가 응답을 마쳤을 때 | `Stop` | 필요 없음 |

`Notification` 훅의 `matcher`는 알림 유형으로 걸러 주므로, 어떤 알림을 휴대폰까지 보낼지 정확히 고를 수 있습니다. 입력은 stdin으로 JSON 형태로 들어오며 `notification_type`, `message`, `cwd`, `session_id`가 들어 있습니다. `Notification` 훅은 아무것도 막거나 바꿀 수 없는 관찰자일 뿐이고, 이번 목적에는 오히려 그게 딱 맞습니다.

`Stop` 입력에는 Claude가 마지막으로 작성한 텍스트인 `last_assistant_message`가 들어 있습니다. 알림에 쓸 요약 한 줄이 공짜로 생기는 셈입니다.

## 준비물

- 휴대폰에 설치된 Echobell ([App Store](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-claude-code-phone-notifications-ko&mt=8) / [Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid))
- Claude Code를 실행하는 머신의 `curl`과 `jq`
- 2분

## 1단계 — 채널 두 개 만들기

모든 알림을 한 채널로 보내고 싶은 유혹을 참으세요. Echobell에서 다음 두 채널을 만듭니다.

- **Claude Blocked**, 유형은 **시간 민감** 또는 **전화** — 권한 요청용입니다. 에이전트가 멈춰 있으면 1분마다 컴퓨팅 자원과 시간이 낭비됩니다.
- **Claude Done**, 유형은 **일반** — 평범한 푸시라서 언제 봐도 괜찮습니다.

각 채널의 웹훅 URL을 복사하세요. `https://hook.echobell.one/t/<channel-token>` 같은 형태입니다. 비밀번호처럼 다루세요. 이 URL을 아는 사람은 누구나 여러분의 휴대폰을 울릴 수 있습니다.

두 URL을 환경 변수로 저장해 두면 커밋되는 설정 파일에 들어가지 않습니다.

```bash
export ECHOBELL_CLAUDE_BLOCKED_URL="https://hook.echobell.one/t/<blocked-token>"
export ECHOBELL_CLAUDE_DONE_URL="https://hook.echobell.one/t/<done-token>"
```

Claude Code가 상속받을 수 있도록 셸 프로필에 넣어 두세요.

## 2단계 — 훅 추가하기

모든 프로젝트에 적용하려면 `~/.claude/settings.json`에, 한 저장소에만 적용하려면 `.claude/settings.local.json`에 다음을 추가합니다.

```json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{title: \"Claude 권한 요청\", body: .message, project: (.cwd | split(\"/\") | last)}' | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_CLAUDE_BLOCKED_URL\""
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{title: \"Claude 작업 완료\", body: (.last_assistant_message // \"완료\" | .[0:200]), project: (.cwd | split(\"/\") | last)}' | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_CLAUDE_DONE_URL\""
          }
        ]
      }
    ]
  }
}
```

각 부분이 하는 일은 다음과 같습니다.

- `jq -c '{...}'`는 훅의 JSON을 stdin으로 읽어 작은 페이로드를 만듭니다. 그래서 Echobell은 훅 문서 전체가 아니라 원하는 필드만 받습니다.
- `.cwd | split("/") | last`는 `/home/me/code/api`를 `api`로 바꿔 주므로, 어느 프로젝트에서 보낸 알림인지 바로 알 수 있습니다.
- `.[0:200]`은 마지막 메시지를 잘라 줍니다. Echobell 워커는 알림 본문을 1500바이트로 제한하고, 잠금 화면에는 어차피 훨씬 적게 표시됩니다.
- `-m 10`은 `curl`에 10초 타임아웃을 줍니다. 네트워크에 문제가 생겨도 Claude Code가 훅을 기다리며 멈추는 일이 없습니다.

Echobell은 보낸 키를 채널 템플릿으로 렌더링하는데, 새 채널에는 이 키를 읽는 템플릿이 없습니다. 채널 설정에서 제목 템플릿을 `{{title}}`, 본문 템플릿을 `{{body}}`로 지정하세요. 프로젝트 이름도 보이게 하려면 `{{title}} ({{project}})`처럼 둘 중 하나에 `{{project}}`를 추가하면 됩니다.

## 3단계 — 실제 요청을 기다리지 않고 테스트하기

가짜 훅 페이로드로 같은 파이프라인을 직접 실행해 보세요.

```bash
echo '{"message":"Claude에게 Bash 사용 권한이 필요합니다","cwd":"/home/me/code/api","notification_type":"permission_prompt"}' \
  | jq -c '{title: "Claude 권한 요청", body: .message, project: (.cwd | split("/") | last)}' \
  | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- "$ECHOBELL_CLAUDE_BLOCKED_URL"
```

휴대폰이 울린다면 Echobell 쪽은 정상이며, 남은 문제는 Claude Code가 설정을 읽는 방식에 있습니다. Claude Code에서 `/hooks`를 실행해 훅이 로드되었는지 확인하세요. 세션이 실행 중일 때 바꾼 설정은 hooks 메뉴를 거치거나 재시작해야 적용될 수 있습니다.

## 4단계 — 차단 알림 채널을 울리게 만들기

푸시 알림은 방해 금지 모드를 이기지 못합니다. **전화** 채널은 걸려 오는 전화처럼 동작해서 iOS 집중 모드를 뚫고 들어오며, 긴 작업을 맡기고 저녁에 자리를 비울 때 특히 중요합니다. 일부 요청에만 방해받고 싶다면 훅을 고치지 말고, 보내는 변수에 대해 Echobell 채널 조건(예: `project == "api"`)으로 필터링하세요. 사용 가능한 변수 전체는 [조건 레퍼런스](/ko/docs/conditions)에서 확인할 수 있습니다.

## 알림 과부하 피하기

바쁜 세션에서는 `Stop` 이벤트가 아주 많이 발생합니다. 응답이 끝날 때마다 하나씩 발생하니까요. 신호만 남기는 방법은 세 가지입니다.

- **`Stop`을 울리는 채널로 보내지 마세요.** 완료는 급한 일이 아닙니다. 일반 채널에 두세요.
- **`Stop` 대신 `idle_prompt`를 쓰세요.** 응답이 끝날 때마다가 아니라, Claude가 멈추고 여러분을 기다릴 때만 알고 싶다면 이쪽이 맞습니다.
- **조건으로 프로젝트를 좁히세요.** 임시로 쓰는 저장소는 아예 알림이 오지 않게 할 수 있습니다.

## 원격 환경이나 CI에서 Claude Code 실행하기

클라우드나 원격 환경에서도 같은 방식이 통합니다. 훅은 그저 바깥으로 나가는 HTTPS 요청이기 때문입니다. 인터넷에서 접근 가능해야 하는 것은 아무것도 없습니다. 셸 프로필 대신 해당 환경의 시크릿에 두 환경 변수를 설정하면, 세션이 어디서 실행되든 알림이 휴대폰에 도착합니다.

## 문제 해결

**아무것도 도착하지 않고 수동 테스트도 실패합니다.** Claude Code를 실행하는 셸에 URL 변수가 설정되어 있는지 확인하세요: `echo "$ECHOBELL_CLAUDE_BLOCKED_URL"`. 변수가 비어 있으면 `curl`이 조용히 실패합니다.

**수동 테스트는 되는데 훅이 실행되지 않습니다.** matcher를 확인하세요. `permission_prompt`와 `idle_prompt`는 서로 다르며, 일치하지 않는 matcher는 그냥 실행되지 않습니다. `/hooks`를 실행해 JSON이 올바른지 확인하세요. 끝에 쉼표가 하나만 남아 있어도 해당 설정 파일의 훅이 전부 비활성화됩니다.

**알림 본문이 비어 있습니다.** `jq` 필터가 해당 이벤트에 없는 필드를 참조한 경우입니다. `message`는 `Notification` 입력에, `last_assistant_message`는 `Stop` 입력에 있습니다. 위 설정처럼 `//`로 기본값을 지정하세요.

**너무 자주 울립니다.** 위 섹션을 참고하세요. `Stop`에서 `idle_prompt`로 바꾸거나 조건을 추가하세요.

## 자주 묻는 질문

### Claude Code가 권한을 요청할 때 알림을 받으려면 어떻게 하나요?

matcher가 `permission_prompt`인 `Notification` 훅을 추가해서 채널로 웹훅을 보내세요. Echobell이 그 요청을 휴대폰의 푸시 또는 전화형 알림으로 바꿔 줍니다.

### Claude Code가 작업을 끝낸 걸 어떻게 알 수 있나요?

`Stop` 훅을 추가하세요. Claude가 응답을 마치면 실행되고, 입력에 들어 있는 `last_assistant_message`를 알림 본문으로 쓸 수 있습니다.

### 방해 금지 모드를 뚫고 알림이 올 수 있나요?

네, 받는 채널이 전화 채널이라면 가능합니다. 걸려 오는 전화처럼 동작하기 때문에 iOS 집중 모드도 통과합니다. 다른 앱의 일반 푸시는 그렇지 못합니다.

### 웹에서 쓰는 Claude Code나 원격 세션에서도 되나요?

네. 훅은 바깥으로 나가는 HTTPS 요청만 보내므로, 세션이 인터넷에 연결되는 곳이라면 어디서든 동작합니다. 채널 URL은 환경의 시크릿으로 전달하세요.

### 웹훅 URL을 settings.json에 넣어도 안전한가요?

위에서 본 것처럼 환경 변수를 쓰는 편이 좋습니다. 토큰이 저장소에 커밋되지 않기 때문입니다. 유출되었다면 새 채널을 만들고 기존 채널은 폐기하세요.

## 마무리

채널 두 개, 훅 두 개, 그리고 `jq | curl` 파이프라인이면 충분합니다. `permission_prompt`에는 **전화** 또는 시간 민감 채널을, `Stop`에는 일반 채널을 연결하세요. 이제 긴 에이전트 작업을 시작해 놓고 자리를 떠나도, 에이전트가 정말 여러분을 필요로 할 때만 불려 오게 됩니다.

[iPhone용 Echobell 다운로드](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-claude-code-phone-notifications-ko&mt=8) 또는 [Google Play에서 받기](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid) 후, 긴 작업을 맡기기 전에 위의 수동 테스트부터 실행해 보세요.

## 관련 글

- [에이전트 승인 단계를 전화로 바꾸기](/ko/blog/ai-agent-human-in-the-loop-alerts)
- [오래 걸리는 터미널 명령이 끝나면 알림 받기](/ko/blog/notify-when-terminal-command-finishes)
- [웹훅 연동 가이드](/ko/docs/webhook)
- [채널 조건 레퍼런스](/ko/docs/conditions)
- [중요한 알림으로 iOS 집중 모드 뚫기](/ko/blog/how-to-bypass-ios-focus-mode-for-critical-alerts)
