내 패턴 · 진입점과 플러그인 로딩 (settings.json -> 마켓플레이스 -> 플러그인)
내 패턴 · 진입점과 플러그인 로딩 (settings.json -> 마켓플레이스 -> 플러그인)
한 줄 요약
에이전트(클로드 코드)는 켜질 때 settings.json 한 장을 먼저 읽고, 거기 적힌 주소를 따라가 플러그인 하나를 통째로 자기 능력으로 장착한다.
왜 배우나: “능력 하나씩 설치”가 아니라 “스위치 하나로 한 묶음”이 어떻게 가능한지 알아야, 직접 플러그인을 만들거나 고장 난 로딩을 고칠 수 있다.
그림
flowchart TD
A[프로세스 부팅] --> B["settings.json 읽기<br/>모델 / 켤 플러그인 / 마켓플레이스 주소"]
B --> C["settings.local.json 병합<br/>권한 오버레이만"]
C --> D["installed_plugins.json 조회<br/>설치 경로 / 버전 / 커밋 해시"]
D --> E[각 플러그인 plugin.json 매니페스트 펼치기]
E --> F1[스킬 등록]
E --> F2[슬래시 명령 등록]
E --> F3[서브에이전트 자동발견 등록]
E --> F4[훅 자동발견 등록]
E --> F5[MCP 외부도구 서버 기동]
F1 & F2 & F3 & F4 & F5 --> G["시스템 리마인더로<br/>능력 카탈로그를 모델 앞에 깔기"]
G --> H[모델 실행 루프 시작]
쉽게 풀기
비유: 컴퓨터 켤 때의 BIOS. 전원을 넣으면 화면이 나오기도 전에 BIOS가 “어떤 장치를 붙일지” 목록부터 읽는다. 클로드 코드도 생각을 시작하기 전, 부팅 단계에서 settings.json이라는 “장착 명세서” 한 장을 먼저 펼친다.
명세서에는 딱 세 가지가 적혀 있다.
- 어떤 두뇌를 쓸지 — 모델 (
model) - 어떤 장비를 켤지 — 플러그인 (
enabledPlugins) - 장비를 어디서 가져오는지 — 마켓플레이스 git 주소 (
extraKnownMarketplaces)
이어서 그 주소를 따라가 플러그인의 명세서(plugin.json) 를 펼친다. 가전 박스를 하나 열면 본체·리모컨·충전기·설명서가 한꺼번에 나오듯, 플러그인 하나를 켜면 그 안의 스킬·슬래시 명령·서브에이전트·훅·MCP 가 같이 딸려 와 한 번에 등록된다.
flowchart LR
SW["플러그인 1개<br/>(단일 스위치 ON)"] --> P[plugin.json 매니페스트]
P --> S[스킬]
P --> C[슬래시 명령]
P --> A[서브에이전트]
P --> H[훅]
P --> M[MCP 도구]
[!note] 가장 중요한 한 가지 능력을 하나하나 따로 설치하지 않는다. “플러그인 1개”라는 단일 스위치만 켜면 그 안의 모든 능력이 함께 주입된다 — 이 챕터의 핵심.
왜 모델이 이걸 알아야 하나? 모델은 자기 앞 컨텍스트에 “부를 수 있는 도구 목록”이 깔려 있어야만 호출할 수 있다. 목록에 없으면 그 능력은 없는 것과 같다. 그래서 진입점 로딩은 “이번 세션에서 쓸 능력의 총목록”을 모델 앞에 미리 펼쳐주는 절차다.
핵심 정리
| 파일 | 역할 | 한 줄 비유 |
|---|---|---|
settings.json | 진입점. 모델·플러그인·마켓플레이스 선언 | 장착 명세서(BIOS) |
settings.local.json | 로컬 권한만 덧대는 오버레이 | 이 자리에서만 통하는 허가증 |
installed_plugins.json | 실제 설치 레코드(락파일) | 영수증·재고 대장 |
plugin.json | 플러그인이 가진 능력 선언 | 박스 안 구성품 목록 |
자동발견 vs 명시선언 — 매니페스트에 적어야 등록되는 것과, 약속된 경로에 두면 알아서 잡히는 것이 나뉜다.
flowchart TD
PJ[plugin.json] -->|명시 선언| E1["skills / commands / mcpServers"]
PJ -.약속된 경로.-> E2["hooks/hooks.json<br/>agents/*.md (자동 발견)"]
E1 & E2 --> R["플러그인 1개 = 훅+스킬+명령+에이전트+MCP 한 번에 주입"]
로딩 순서 체크리스트(부팅 시 실제 일어나는 일)
-
settings.json을 읽어 모델·플러그인·마켓플레이스 주소 확정 -
settings.local.json의 권한을 위에 덧댐(덮어쓰기 아님, 보태기) -
installed_plugins.json에서 캐시 경로·버전·커밋 해시 조회 - 각 플러그인의
plugin.json을 펼쳐 능력 등록 - 시스템 리마인더로 카탈로그를 모델 앞에 주입한 뒤 실행 루프 시작
[!note]- 펼쳐보기: 전체 필드 스키마 (4개 파일)
A.
settings.json(전역 진입점) — 최상위 키
이름 타입·필수 설명 modelstring·선택 세션 기본 모델 별칭. 여기선 "opus[1m]"(Opus + 1M 컨텍스트)enabledPluginsobject·선택 켤 플러그인. 키= 플러그인이름@마켓플레이스이름, 값true면 활성extraKnownMarketplacesobject·선택 추가 신뢰 마켓플레이스 등록부. 키=별칭, 값= {source}extraKnownMarketplaces.<name>.sourceobject·필수 {source:"git", url:"...git"}— 플러그인 원격 git 출처skipDangerousModePermissionPromptbool·선택 위험 모드 진입 시 확인 프롬프트 생략 B.
settings.local.json(로컬 오버레이) — 병합 규칙
이름 타입·필수 설명 permissions.allowstring[]·선택 로컬에서만 추가 허용할 도구 패턴. 예: "Bash(sudo npm:*)"전역은 모델/플러그인/마켓플레이스 같은 “구조”를, 로컬은 권한만 덧댄다(덮어쓰기 아닌 보태기 오버레이). 실제 파일엔
permissions.allow단 한 키만 존재.C.
installed_plugins.json— 설치 레코드(락파일)
이름 타입·필수 설명 versionnumber·필수 레코드 파일 스키마 버전( 2)pluginsobject·필수 키= 이름@마켓플레이스, 값=설치 인스턴스 배열plugins.<id>[].scopestring·필수 설치 범위. 여기선 전부 "user"plugins.<id>[].installPathstring·필수 캐시 절대경로( .../cache/<mkt>/<plugin>/<ver>)plugins.<id>[].versionstring·필수 설치된 플러그인 버전( 4.14.6등)plugins.<id>[].installedAt/lastUpdatedISO8601·필수 설치/갱신 시각 plugins.<id>[].gitCommitShastring·필수 출처 git 고정 커밋 해시 — 재현성 보장 D.
plugin.json매니페스트 — 능력 선언(단일 진입 계약)
이름 타입·필수 설명 name/versionstring·필수 플러그인 식별자·버전 skillsstring[]·선택 스킬 디렉터리 경로 배열 commandsstring(dir)·선택 슬래시 명령 디렉터리( ./commands/)mcpServersstring(file)|object·선택 MCP 정의. 여기선 ./.mcp.json파일을 가리킴(자동발견) hooks/hooks.jsonfile·선택 매니페스트에 안 적어도 자동 등록 (자동발견) agents/*.mddir·선택 agents/폴더 서브에이전트 자동 등록(여기 19개)E.
.mcp.json— MCP 서버 정의
이름 타입·필수 설명 mcpServers.<name>.commandstring·필수 실행 바이너리( node)mcpServers.<name>.argsstring[]·필수 인자. ${CLAUDE_PLUGIN_ROOT}로 플러그인 루트 치환
실제 예시
진입점부터 능력 등록까지, 실제 디스크 파일을 따라간다. 아래는 핵심 발췌이며 전문은 접이식으로 둔다.
// ~/.claude/settings.json (핵심)
{
"model": "opus[1m]",
"enabledPlugins": { "oh-my-claudecode@omc": true /* ...외 3개 */ },
"extraKnownMarketplaces": {
"omc": { "source": { "source": "git", "url": "https://github.com/Yeachan-Heo/oh-my-claudecode.git" } }
},
"skipDangerousModePermissionPrompt": true
}
[!note]- 펼쳐보기: 실제 디스크 파일 전문 (5개)
// /home/seunghyeong/.claude/settings.json { "model": "opus[1m]", "enabledPlugins": { "oh-my-claudecode@omc": true, "dd@gptaku-plugins": true, "insane-search@gptaku-plugins": true, "kkirikkiri@gptaku-plugins": true }, "extraKnownMarketplaces": { "omc": { "source": { "source": "git", "url": "https://github.com/Yeachan-Heo/oh-my-claudecode.git" } }, "gptaku-plugins": { "source": { "source": "git", "url": "https://github.com/fivetaku/gptaku_plugins.git" } } }, "skipDangerousModePermissionPrompt": true }// /home/seunghyeong/.claude/settings.local.json { "permissions": { "allow": [ "Bash(sudo npm:*)" ] } }// /home/seunghyeong/.claude/plugins/installed_plugins.json (발췌) { "version": 2, "plugins": { "oh-my-claudecode@omc": [ { "scope": "user", "installPath": "/home/seunghyeong/.claude/plugins/cache/omc/oh-my-claudecode/4.14.6", "version": "4.14.6", "installedAt": "2026-06-10T04:03:46.951Z", "lastUpdated": "2026-06-10T04:03:46.951Z", "gitCommitSha": "deee3a446dadc9bfea31cdc8b19b00b16718082e" } ] } }// .../plugins/marketplaces/omc/.claude-plugin/plugin.json (발췌) { "name": "oh-my-claudecode", "version": "4.14.6", "skills": [ "./skills/ai-slop-cleaner/", "./skills/ask/", "...(총 39개 스킬 폴더)" ], "mcpServers": "./.mcp.json", "commands": "./commands/" }// .../plugins/marketplaces/omc/.mcp.json { "mcpServers": { "t": { "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/bridge/mcp-server.cjs"] } } }
[!note] 단일 진입 계약의 물증 같은 폴더
marketplaces/omc/안에skills/,commands/,agents/(19개),hooks/hooks.json,.mcp.json(서버t)이 동시에 존재한다. 매니페스트엔skills/commands/mcpServers만 적혀 있어도hooks/hooks.json과agents/*.md는 규약 경로에서 자동 발견된다.
직접 만들 때 템플릿
// 1) 진입점 ~/.claude/settings.json
{
"model": "opus[1m]",
"enabledPlugins": { "my-plugin@my-marketplace": true },
"extraKnownMarketplaces": {
"my-marketplace": { "source": { "source": "git", "url": "https://github.com/me/my-marketplace.git" } }
}
}
// 2) 매니페스트 my-plugin/.claude-plugin/plugin.json
{
"name": "my-plugin", "version": "0.1.0", "description": "한 줄 설명",
"skills": ["./skills/hello/"], "commands": "./commands/", "mcpServers": "./.mcp.json"
}
자동발견 배치 — 같은 플러그인 폴더에 두기만 하면 등록된다.
hooks/hooks.json→ SessionStart/UserPromptSubmit 훅agents/*.md→ 서브에이전트 ·commands/*.md→ 슬래시 명령 ·skills/<name>/SKILL.md→ 스킬
[!note]- 펼쳐보기: MCP 정의 템플릿 + 만들 때 점검표
// 3) MCP 정의 my-plugin/.mcp.json { "mcpServers": { "tool": { "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/bridge/server.cjs"] } } }점검표
- 마켓플레이스 별칭이
enabledPlugins키의@뒤=extraKnownMarketplaces키와 정확히 일치하는가- 마켓플레이스 루트에
.claude-plugin/marketplace.json이 있고plugins[].source가 폴더를 가리키는가plugin.json의skills/commands/mcpServers경로가 실제 디스크에 존재하는가- MCP args에
${CLAUDE_PLUGIN_ROOT}를 써서 절대경로 하드코딩을 피했는가- 설치 후
installed_plugins.json에installPath/version/gitCommitSha가 생겼는가- 로컬 권한은 전역이 아닌
settings.local.json의permissions.allow에만 두었는가- 위험 권한 우회를 켤 때만
skipDangerousModePermissionPrompt를 의도적으로 설정했는가
요약 & 셀프체크
3줄 요약
- 클로드 코드는 부팅 시
settings.json을 먼저 읽어 모델·플러그인·마켓플레이스 주소를 정한다. - 그 주소를 따라가
plugin.json을 펼치면 명시 선언(스킬·명령·MCP)과 자동발견(훅·에이전트)이 한꺼번에 능력으로 등록된다. - 등록 결과가 시스템 리마인더로 모델 앞에 깔린 뒤에야 실행 루프가 시작된다 — 목록에 없으면 모델은 그 능력을 못 부른다.
스스로 답해보기
- 플러그인 1개를 켰을 때, 매니페스트에 적지 않았는데도 자동 등록되는 능력 두 가지는?
oh-my-claudecode@omc에서@뒤의omc는 어디서 정의된 이름과 일치해야 하는가?- 로컬에서만
sudo npm실행을 허용하려면 어느 파일의 어느 키에 적는가?
연결
[!tip] Codex 교차검증 (원문 노트에 별도 Codex 교차검증 섹션 없음 — 신규 사실 추가 없이 보존 차원에서 비워 둠. 검증 결과가 생기면 이 콜아웃에 누적한다.)