Claude Code 2.1.287부터 Mod라는 것이 생겼습니다. 이름만 보면 게임 모드 같은데, 실제로 해 보니 Claude Code 화면과 동작에 직접 손을 대는 기능이었습니다.
설명을 읽는 것보다 한 번 띄워 보는 쪽이 빨랐습니다. 공식 문서에 나오는 가장 작은 예제를 그대로 올려 보고, 화면이 어떻게 바뀌는지부터 보겠습니다.
실습 환경: Windows 11, Claude Code 2.1.296, 2026-10-11 확인. 화면은 개인 설정(user settings)을 싣지 않은 깨끗한 상태로 찍었습니다.
Mod를 한 줄로 말하면
공식 문서는 Mod를 "Claude Code가 어떻게 보이고 어떻게 동작하는지 바꾸는 플러그인"이라고 설명합니다.
조금 풀면 이렇습니다. Claude Code 안에서는 쉬지 않고 일이 생깁니다. Claude가 파일을 읽으려 하고, 내가 프롬프트를 보내고, 화면 아래 스피너가 다시 그려집니다. Mod는 이런 일(이벤트)이 생길 때마다 Claude Code가 불러 주는 JavaScript 또는 TypeScript 함수입니다. 그리고 그 함수는 Claude Code 프로세스 안에서 돕니다.
"안에서 돈다"는 점이 다른 기능들과 갈리는 지점입니다. 이 얘기는 뒤에서 다시 하겠습니다.
직접 띄워 본 결과: 스피너 옆에 숫자가 생겼다
연습용으로 아주 작은 할 일 목록 프로젝트(todo-cli)를 만들고, Claude에게 같은 부탁을 두 번 했습니다. "파일 목록을 보고 README와 package.json을 읽어 줘. 아무것도 바꾸지 말고."
먼저 Mod 없이 실행한 화면입니다. Claude가 일하는 동안 아래쪽에 익숙한 스피너가 돕니다.
다음은 공식 예제 Mod(first-mod)를 올리고 똑같이 부탁한 화면입니다.
스피너 문구 뒤에 tool calls: 3이 붙었습니다. Claude가 이번 작업에서 도구를 세 번 썼다는 뜻입니다. 파일 목록을 한 번 보고, 파일 두 개를 읽었으니 맞는 숫자입니다.
별것 아닌 숫자처럼 보여도, 예전에는 이 자리에 내가 무언가를 끼워 넣을 방법이 없었습니다. 상태줄(status line)은 화면 맨 아래 한 줄을 스크립트 출력으로 채우는 기능이라 스피너를 건드리지 못합니다.
이 Mod는 파일 세 개, 코드 20줄이다
Mod는 플러그인 폴더 하나입니다. 가장 작은 형태는 이렇습니다.
first-mod/
├── .claude-plugin/
│ └── plugin.json ← 이름·버전·설명
└── hooks/
├── hooks.json ← 코드 파일 위치
└── register.js ← 실제 코드
hooks.json에는 { "modules": ["./register.js"] } 한 줄만 있으면 됩니다. 실제 동작은 register.js에 들어 있습니다. 공식 문서 예제 그대로입니다.
let calls = 0
export function register(on) {
// Claude가 도구를 쓰려 할 때마다
on('tool.call', async ($, e, next) => {
calls += 1
$.ui.invalidate('ui.render') // 화면을 다시 그려 달라고 요청
return next(e) // 도구는 원래대로 실행
})
// 스피너를 그릴 때마다
on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
return next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } })
})
}
훅이 두 개입니다. tool.call 훅은 숫자를 하나 올리고 도구를 그대로 보냅니다. ui.render 훅은 스피너를 그리기 직전에 끼어들어 글자 뒤에 숫자를 붙입니다. 두 훅은 맨 위의 calls 변수를 같이 씁니다. 한 훅이 센 것을 다른 훅이 보여 주는 구조입니다.
저는 이 폴더를 만든 뒤 claude --plugin-dir D:\lab\mods\first-mod로 실행했습니다. --plugin-dir는 설치하지 않고 그 세션에만 플러그인을 올리는 옵션이라, 시험해 보기에 부담이 없습니다.
Mod가 이벤트를 받으면 할 수 있는 일은 세 가지
훅의 모양은 모두 ($, e, next)입니다. e는 지금 일어난 일이고, next(e)를 부르면 원래 하려던 동작이 이어집니다. 그래서 훅이 고를 수 있는 길은 셋입니다.
- 지켜보기: 기록만 하고
next(e)로 그대로 보냅니다. 위 예제의tool.call훅이 이렇습니다. - 바꾸기:
e를 고쳐서next에 넘깁니다. 스피너에 글자를 붙인ui.render훅이 이쪽입니다. - 대신 답하기:
next를 부르지 않고 직접 결과를 돌려줍니다. 위험한 명령을 막는 Mod가 이런 식으로 만들어집니다.
기존 Claude Code와 무엇이 달라졌나
Claude Code에는 원래도 손댈 수 있는 곳이 많았습니다. 설정 파일의 훅(hooks), 스킬(Skill), 상태줄, MCP 서버. 공식 문서는 이것들이 모두 Claude Code 바깥에서 일한다고 정리합니다. 스크립트를 돌리거나, Claude에게 글이나 도구를 건네는 방식입니다.
Mod는 안에서 돌기 때문에 바깥 도구로는 못 하던 일을 할 수 있습니다. 문서에 나온 것을 추리면 이렇습니다.
| 할 수 있는 일 | 예 |
|---|---|
| 직접 쓰는 화면 만들기 | 대화 옆 패널, 프롬프트 위 띠, 버튼·입력칸 |
| Claude Code가 그리는 화면 고치기 | 도구 호출 줄, 스피너, 질문 창 |
| 도구 호출·요청에 끼어들기 | 실행 전에 나에게 묻기, 실행 없이 답하기 |
| Claude 턴 없이 도는 명령 | Claude가 일하는 중에도 바로 실행되는 /명령 |
| 훅끼리 데이터 나누기 | 위 예제처럼 세고, 보여 주기 |
참고로 Claude Code의 /diff 화면도 Mod로 만들어져 있습니다. 내장 Mod는 다음 편에서 /plugin 화면으로 직접 확인합니다.
먼저 알고 시작할 위험
안에서 돈다는 것은 그만큼 많이 만질 수 있다는 뜻이기도 합니다. 공식 문서가 경고하는 내용을 옮기면, Mod는 내 권한으로 실행됩니다. 파일을 읽고 쓰고, 프로그램을 띄우고, 네트워크 요청을 보낼 수 있습니다. 환경변수에 넣어 둔 API 키도 읽을 수 있고, 내가 보내는 프롬프트와 Claude의 도구 호출도 모두 봅니다.
샌드박스 안에 있지도 않습니다. 샌드박스를 켜도 그건 Claude가 실행하는 Bash 명령에만 걸립니다.
그래서 남이 만든 Mod는 믿을 수 있는 곳에서만 받고, 설치 전에 claude plugin validate <폴더>로 그 Mod가 어떤 이벤트를 잡고 무엇을 호출하는지 먼저 보는 습관을 들이는 게 좋습니다. 이 명령의 출력은 3편에서 자세히 봅니다.
다음 편
오늘은 Mod가 무엇이고 기존 기능과 어디가 다른지를 화면 하나로 확인했습니다. 다음 편에서는 Mod를 쓰기 전에 확인할 것, 즉 버전과 /plugin 화면, 내장 Mod 목록을 순서대로 보겠습니다.
참고한 공식 문서: Mods overview (code.claude.com)
그러면 오늘도 모두 스테이블 하세요.
'Coding, Testing, Challenge' 카테고리의 다른 글
| Claude Code Plugin, Hook, Skill, MCP, Mod 차이 한 장 정리, 헷갈렸던 건 Plugin이 포장이라서였다 (0) | 2026.10.11 |
|---|---|
| Claude Code Mods 쓰기 전 확인할 것, 2.1.287보다 낮으면 아무 일도 일어나지 않는다 (0) | 2026.10.11 |
| AI 에이전트 예약 작업을 서버가 쥐게 한 이유, 도는 척하는 작업과 유령 lease 정리 (0) | 2026.10.11 |
| Git Bash에서 내 명령어가 안 잡히던 이유, Windows PATHEXT와 파이썬 진입점 두 가지 함정 (0) | 2026.10.11 |
| PostgreSQL 시간이 9시간 빨랐다, timestamptz UTC 표시 버그를 저장값은 두고 고친 기록 (0) | 2026.10.11 |