Claude Code는 여러 선택지 중 하나를 골라야 할 때 AskUserQuestion이라는 도구를 호출하고 사용자의 선택을 기다려요. AskUserQuestion에 매칭되는 PreToolUse hook은 answers 필드를 채운 질문을 반환해서 대신 답할 수 있어요. 휴대폰에서 Claude Code의 질문에 답하는 원리가 바로 이거예요. hook이 질문과 선택지를 휴대폰으로 보내고, 선택을 기다렸다가 그 결과를 돌려주는 거죠. Claude Code Notifier는 ccn 도구와 휴대폰 앱으로 Mac, Windows, Linux에서 이 작업을 해 줘요.
01AskUserQuestion이란
Claude는 가끔 혼자 결정하면 안 되는 갈림길을 만나요. 어떤 프레임워크를 쓸지, 기존 API를 유지할지 제거할지, 테스트를 고칠지 코드를 고칠지 같은 것들이요. 이럴 때는 추측하는 대신 짧은 객관식 질문을 해요. terminal에는 질문과 설명이 붙은 몇 가지 선택지가 표시되고, 키보드로 하나를 고르면 돼요.
다른 도구 호출과 마찬가지로 AskUserQuestion도 먼저 Claude Code의 hook을 거쳐요. 원격으로 답할 수 있는 틈이 바로 여기예요.
질문은 권한 prompt와 달라요. 권한 prompt는 하나의 작업에 대해 예/아니요를 묻고, PermissionRequest hook이 여기에 응답해요(휴대폰에서 Claude Code 권한 요청 승인하기 참고). 질문은 선택을 요구하고, 답은 '예'가 아니라 레이블이에요.
02hook이 답을 넣는 방법
PreToolUse hook은 도구의 입력을 표준 입력으로 JSON 형태로 받아요. AskUserQuestion의 경우 입력에 questions 배열이 들어 있어요. 각 질문에는 question(본문), header(짧은 레이블), options(각각 label과 description 포함), multiSelect가 있어요.
이 도구는 "allow"만 반환해서는 안 돼요. 답이 어딘가에서 와야 하니까요. Anthropic의 hooks 레퍼런스에 따르면 hook은 updatedInput에 questions를 그대로 돌려주고, 각 질문의 본문을 선택한 레이블에 매핑하는 answers 객체를 추가해야 해요.
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": {
"questions": [
{
"question": "Which framework?",
"header": "Framework",
"options": [
{ "label": "React", "description": "Component library" },
{ "label": "Vue", "description": "Progressive framework" }
],
"multiSelect": false
}
],
"answers": { "Which framework?": "React" }
}
}
}
복수 선택 질문이라면 선택한 레이블을 쉼표로 이어 주세요. hook이 아무것도 출력하지 않으면 질문은 평소처럼 terminal에 표시돼요.
등록하기
{
"hooks": {
"PreToolUse": [
{
"matcher": "AskUserQuestion",
"hooks": [
{ "type": "command", "command": "/path/to/your-answer-script" }
]
}
]
}
}
모든 프로젝트에 적용하려면 ~/.claude/settings.json에 넣으세요. 모든 hook 이벤트와 각각의 쓰임새는 Claude Code hooks 설명에서 확인하세요.
비대화형 실행 참고 사항
Anthropic 문서에 따르면 claude -p 실행에서는 Agent SDK의 canUseTool 콜백처럼 prompt를 받을 권한 호스트가 있을 때만 AskUserQuestion이 제공돼요. 일반 스크립트 실행에서는 Claude가 아예 질문하지 않을 수도 있어요. 이 가이드는 대화형 세션을 기준으로 해요.
03휴대폰 응답을 잘 만들려면
JSON은 쉬운 부분이에요. 설계상 고민할 점은 권한 prompt 때와 같아요.
- 질문 전체를 보여 주세요. header, 질문, 각 선택지의 설명이 모두 중요해요. 잠금 화면에 레이블("Option B")만 떠서는 아무 도움이 안 돼요.
- terminal을 계속 쓸 수 있게 하세요. 컴퓨터 앞에 있다면 휴대폰을 기다리는 hook 때문에 막히지 않고 바로 거기서 답할 수 있어야 해요.
- 깔끔하게 물러나세요. 답이 오지 않으면 hook은 타임아웃 전에 아무것도 반환하지 않아서 terminal prompt가 뜨게 해야 해요.
- 텍스트를 정확히 맞추세요.
answers의 키는 Claude가 작성한 질문 본문 그대로여야 하고, 값은 선택지 레이블이어야 해요.
04Claude Code Notifier 사용하기
Claude Code Notifier는 TouchTap Ltd가 만든 독립 도구로, Anthropic이 만든 제품이 아니에요. 커맨드라인 도구인 ccn은 다른 hook과 함께 AskUserQuestion용 PreToolUse hook을 설치해요. 자리를 비운 사이 Claude가 질문하면 휴대폰에 질문과 선택지가 표시돼요. 하나를 탭하면 hook이 답을 넣어 주고 Claude는 작업을 이어가요.
Mac 또는 Linux에서 설치하기:
curl -fsSL https://claudecodenotifier.com/install.sh | sh
Windows에서는 PowerShell로 설치하세요(베타):
irm https://claudecodenotifier.com/install.ps1 | iex
그다음 QR 코드를 스캔하거나 앱의 6자리 코드를 입력해서 휴대폰을 페어링하세요. 운영체제별 방법은 휴대폰을 Claude Code에 연결하기에서 안내해요.
자리에 있는지에 따라 답하는 곳이 정해져요
ccn은 질문에도 권한 요청과 같은 presence 규칙을 적용해요. 최근 30초 안에 입력한 적이 있으면 terminal이 평소처럼 묻고, 휴대폰에는 기껏해야 알림만 가요. 자리를 비웠다면 terminal은 직접 정한 상한(hold_ceiling_seconds, 30~3600, 기본값 600)까지 휴대폰 응답을 기다리고, 키보드를 건드리는 순간 대기를 멈춰요.
휴대폰으로 받을 항목 선택하기
질문 알림은 notify_on_permission, notify_on_done와 별도로 notify_on_question 설정을 따로 가지고 있어서, 원하는 종류만 켜 두고 나머지는 끌 수 있어요. ccn config show로 현재 적용된 설정을 확인할 수 있고, 대부분의 설정은 폰 앱에서 컴퓨터별로 바꿀 수도 있어요.
방해 금지 시간도 똑같이 적용돼요. 예를 들면 ccn config set quiet_hours 22:00-08:00처럼 설정해요. 자세한 내용은 방해 금지 시간과 방해 금지 모드를 참고하세요.
폰을 페어링하지 않아도 Claude가 질문하면 ccn이 컴퓨터에 무료 데스크톱 알림을 띄워 주니까, 돌아와야 할 때를 알 수 있어요. 폰에서 답하려면 앱이 필요한데, 앱은 무료로 다운로드할 수 있고 사용하려면 구독이나 평생 이용권 구매가 필요해요. 가격을 참고하세요.
05질문, 후속 지시, 작업 완료
질문은 Claude가 사용자를 기다리는 세 가지 순간 중 하나예요. 나머지 두 가지는 권한 prompt와 턴 종료예요. Claude가 작업을 마친 직후에는 Claude Code Notifier로 폰에서 다음 지시를 보낼 수도 있는데, 이 지시는 Stop hook을 통해 Claude에게 다음 지시로 전달돼요. 이 세 가지만 챙기면 긴 작업이 멈춰 있는 대부분의 상황을 해결할 수 있어요. Claude Code를 실행해 두고 자리 비우기에서 이걸 하나의 루틴으로 정리했어요.
06FAQ
옵션을 고르는 대신 자유롭게 답을 입력할 수 있나요?
문서화된 hook 방식은 answers 필드에 옵션 라벨을 담아 답해요. Claude Code Notifier에서는 폰에서 옵션 중 하나를 고르면 돼요. 맞는 옵션이 없으면 질문을 terminal에서 답하도록 남겨 두거나, 작업이 끝난 뒤 후속 지시로 Claude의 방향을 잡아 주세요.
PreToolUse hook에서 "allow"를 반환해도 질문에 답이 안 되는 이유는 뭔가요?
AskUserQuestion은 권한이 아니라 답이 필요하기 때문이에요. 위 예시처럼 원래의 questions와 answers 객체를 담은 updatedInput을 반환하세요.
Claude가 한 번에 여러 질문을 하면 어떻게 되나요?
questions 배열에는 질문이 여러 개 들어갈 수 있어요. answers 객체에는 질문마다 항목이 있어야 하고, 키는 질문의 정확한 텍스트를 써야 해요.
VS Code, Cursor, JetBrains에서도 작동하나요?
hook은 terminal이 아니라 Claude Code에 속한 기능이라 IDE 내장 terminal에서도 작동해요. VS Code, Cursor, JetBrains terminal에서 Claude Code 알림 받기를 참고하세요.