Claude Code HTTP Hooks: 웹앱으로 AI 에이전트 제어하기
Claude CodeAI개발도구Hook웹앱
안녕하세요, Tom입니다.
Claude Code 쓰면서 "이 작업 승인 여부를 웹 대시보드에서 관리할 수 있으면 좋겠는데..."라고 생각해본 적 있으세요?
이제 가능합니다. Claude Code에 HTTP Hook 기능이 추가되었습니다.
HTTP Hook이 뭔가요?
기존 **커맨드 훅(Command Hook)**은 강력하지만 복잡했습니다:
- 쉘 스크립트 작성 필요
- 보안 관리 까다로움
- 상태 공유 어려움
HTTP Hook은 이걸 완전히 바꿉니다:
Claude Code 이벤트 발생
↓
HTTP POST → 웹 서버 (localhost도 가능)
↓
웹 서버가 응답 (승인/거부/수정)
↓
Claude Code가 응답에 따라 행동
왜 이게 중요한가?
1. 웹앱으로 제어 가능
// Express.js 예시
app.post('/claude-hook', (req, res) => {
const { event, context } = req.body;
if (event.type === 'file_write') {
// 파일 쓰기 승인 여부를 웹 대시보드에서 확인
if (isDangerousPath(event.path)) {
res.json({ approved: false, reason: 'Sensitive file' });
} else {
res.json({ approved: true });
}
}
});이제 브라우저에서 실시간으로:
- Claude Code가 뭘 하려는지 확인
- 승인/거부 버튼 클릭
- 로그 확인 및 저장
2. 팀 단위 권한 관리
데이터베이스 ←→ 웹 서버 ←→ Claude Code
- 중앙 DB로 권한 관리: 누가 어떤 작업을 승인했는지 추적
- 팀원과 공유: 같은 웹앱으로 여러 Claude Code 인스턴스 제어
- 감사 기록: 모든 이벤트를 DB에 저장
3. 복잡한 로직도 쉽게
쉘 스크립트로는 어려웠던 것들:
- ❌ REST API 호출
- ❌ 데이터베이스 쿼리
- ❌ 복잡한 조건문
- ❌ 실시간 알림
웹 서버에서는:
- ✅ 모든 npm 패키지 사용 가능
- ✅ Prisma, TypeORM 등으로 DB 연동
- ✅ TypeScript로 타입 안전하게
- ✅ Slack/Discord 웹훅 바로 연동
실전 활용 예시
예시 1: 민감한 파일 보호
// hooks/file-protection.ts
const PROTECTED_PATHS = [
'.env',
'secrets/',
'config/production.yml'
];
app.post('/hook', async (req, res) => {
if (req.body.event.type === 'file_write') {
const path = req.body.event.path;
if (PROTECTED_PATHS.some(p => path.includes(p))) {
// Slack으로 알림 전송
await slackNotify({
text: `⚠️ Claude Code가 민감한 파일 수정 시도: ${path}`,
channel: '#security'
});
return res.json({
approved: false,
message: '민감한 파일은 수동 승인이 필요합니다.'
});
}
}
res.json({ approved: true });
});예시 2: 비용 관리
// hooks/cost-tracking.ts
app.post('/hook', async (req, res) => {
const { event, context } = req.body;
// API 호출 비용 추적
if (event.type === 'api_call') {
const cost = estimateCost(event.model, event.tokens);
await db.usage.create({
data: {
userId: context.user,
model: event.model,
tokens: event.tokens,
cost: cost
}
});
// 일일 한도 체크
const todayTotal = await db.usage.sum({ where: {
userId: context.user,
date: new Date()
}});
if (todayTotal > DAILY_LIMIT) {
return res.json({
approved: false,
message: '오늘 일일 한도를 초과했습니다.'
});
}
}
res.json({ approved: true });
});예시 3: 작업 승인 대시보드
// 실시간 승인 대시보드
app.get('/dashboard', (req, res) => {
res.render('dashboard', {
pendingActions: await getPendingActions()
});
});
// 웹소켓으로 실시간 이벤트 전송
io.on('connection', (socket) => {
socket.on('approve', async (eventId) => {
await approveEvent(eventId);
io.emit('event_approved', eventId);
});
});로컬호스트도 가능!
가장 좋은 점:
# 1. 로컬에서 웹 서버 실행
npm run dev # http://localhost:3000
# 2. Claude Code 설정
claude-code --http-hook=http://localhost:3000/hook외부 서버 필요 없음. 개발 머신에서 바로 테스트 가능합니다.
기존 커맨드 훅과 비교
| 기능 | 커맨드 훅 | HTTP 훅 |
|---|---|---|
| 설정 난이도 | 높음 (스크립트) | 낮음 (웹 API) |
| 복잡한 로직 | 어려움 | 쉬움 |
| 팀 공유 | 어려움 | 쉬움 |
| 실시간 대시보드 | 불가능 | 가능 |
| 보안 관리 | 복잡함 | 명확함 (HTTP) |
| 디버깅 | 어려움 | 쉬움 (로그/UI) |
시작하기
-
공식 문서 확인
Claude Code Hooks Reference -
간단한 서버로 시작
import express from 'express'; const app = express(); app.use(express.json()); app.post('/hook', (req, res) => { console.log('Event:', req.body); res.json({ approved: true }); }); app.listen(3000); -
Claude Code 연결
claude-code --http-hook=http://localhost:3000/hook
마무리하며
HTTP Hook는 Claude Code를 **"혼자 쓰는 도구"에서 "팀이 관리하는 인프라"**로 바꿔줍니다.
특히:
- 민감한 작업이 많은 프로덕션 환경
- 여러 사람이 Claude Code를 쓰는 팀
- 승인 프로세스가 필요한 조직
에서 정말 유용할 것 같습니다.
여러분은 어떤 Hook을 만들어보고 싶으신가요?
이 글은 Geeknews에서 발견한 내용을 정리한 것입니다. 원본은 여기에서 확인할 수 있습니다.