
1편에서는 메모리 시스템, Hooks, Skills, Subagents, MCP Servers를 다뤘습니다. 각각이 해결하는 문제를 한 줄로 요약하면, 세션 간 지식 유지(메모리), 결정론적 실행 보장(Hooks), 온디맨드 전문 지식(Skills), 컨텍스트 격리(Subagents), 외부 도구 연결(MCP)입니다.
2편에서는 보안 제어(Permissions/Sandbox), Plugins, 세션 관리(Worktrees, Remote Control, /loop, /batch), Agent Teams, 연동 패턴과 외부 배포 방법을 다루도록 하겠습니다.
1편에서 Hooks로 위험 명령을 차단하는 방법을 다뤘는데, Hook은 스크립트를 작성해야 하고 모든 케이스를 커버하기 어렵습니다. Permissions는 더 근본적인 계층에서 도구 자체의 접근 권한을 규칙으로 제어합니다. Sandbox는 한 단계 더 나아가 OS 수준에서 파일시스템과 네트워크를 격리하는 기능입니다.
settings.json에서 도구별 허용/거부/확인 규칙을 정의할 수 있습니다.
{
"permissions": {
"allow": [
"Read",
"Grep",
"Glob",
"Bash(npm test)",
"Bash(uv run *)"
],
"deny": [
"Edit(~/.env)",
"Bash(rm -rf *)"
]
}
}
규칙 형식은 Tool 또는 Tool(specifier)입니다. 평가 순서는 deny -> ask -> allow이며, 첫 매칭이 적용됩니다. 즉 deny에 잡히면 allow에 있어도 거부됩니다.
settings.local.json에서 단일 값으로 설정하는 경우(
model,enable등)는 settings.json보다 우선 적용되지만, 배열로 설정하는 경우 (permissions등)는 merge되는 구조입니다.
(settings.json에 deny, settings.local.json에 allow하는 경우? -> 'Appendix-permission 충돌이 나는 경우' 참고)
Sandbox는 bash 명령을 OS 수준에서 격리합니다. Permission이 "Claude가 이 도구를 쓸 수 있는가"를 제어한다면, Sandbox는 "이 도구가 접근 가능한 시스템에서의 권한을 default로 오픈한다"에 가까운 것 같습니다.
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"excludedCommands": ["docker"],
"filesystem": {
"allowWrite": ["/tmp/build", "~/.kube"],
"denyRead": ["~/.aws/credentials"]
},
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"],
"allowUnixSockets": ["/var/run/docker.sock"],
"allowLocalBinding": true
}
}
}
| 키 | 타입 | 설명 |
|---|---|---|
enabled | boolean | 샌드박스 활성화 여부 |
autoAllowBashIfSandboxed | boolean | 샌드박스 활성 시 bash 명령 권한 프롬프트 건너뜀 |
excludedCommands | string[] | 샌드박스 밖에서 실행할 명령 (docker, watchman 등 비호환 도구용) |
allowUnsandboxedCommands | boolean | excludedCommands로 빠진 명령의 실행 허용 여부 |
| filesystem | ||
allowWrite | string[] | 추가 쓰기 허용 경로 (기본: cwd와 하위만 허용) |
denyWrite | string[] | 쓰기 거부 경로 |
allowRead | string[] | 읽기 허용 경로 (denyRead보다 우선) |
denyRead | string[] | 읽기 거부 경로 |
allowManagedReadPathsOnly | boolean | managed settings의 allowRead만 적용 (user/project/local 무시) |
| network | ||
allowedDomains | string[] | 접근 허용 도메인 (와일드카드 지원) |
allowUnixSockets | string[] | 허용할 Unix 소켓 경로 |
allowLocalBinding | boolean | 로컬 포트 바인딩 허용 (Go, MITM 프록시 등에 필요) |
쉽게 말해, bash 권한은 오픈되고 file system은 claude code를 실행한 프로젝트로 sandboxing, network는 모두 차단되는 상태가 default가 됩니다.
여기서 docker나 외부 경로, 네트워크 등 필요한 부분만 추가 허용해서 사용하는 방식이라고 보면 되겠습니다.
(사실 저도 sandboxing은 --dangerously-skip-permissions를 써도 뜨는 HITL이 귀찮아서 사용하는 경우가 대부분이어서, 자세한 사용팁은 서버에서 프로젝트 단위로 사용해보고 추가로 작성해보도록 하겠습니다..!)
Plugins는 이 문제를 해결한다. Skills, Subagents, Hooks, MCP Servers, LSP Servers를 하나의 설치 가능한 번들로 패키징하는 메커니즘입니다.
현재 가장 유명한 플러그인은
이렇게 네 가지인 것 같습니다.
하지만 실제 사용해보면, 본인의 프로젝트 규모나 의도와 다르게 매우 오버엔지니어링 되거나 토큰을 미친듯이 잡아먹는 경우가 많습니다.
1인 개발을 수행하시거나, 팀 단위로 claude code를 사용하시는 경우에는 직접 본인의 상황에 맞는 plugin을 구현해보시는 것도 좋은 것 같습니다.
(외부 플러그인이나 assets를 조합 및 튜닝하며 custom하는 방식..)
my-plugin/
.claude-plugin/
plugin.json # 메타데이터 (선택, 없으면 자동 탐지)
commands/ # 슬래시 커맨드
agents/ # Subagent
skills/ # 스킬
hooks/ # 이벤트 핸들러
.mcp.json # MCP 서버
README.md
plugin.json은 optional입니다. 생략하면 Claude Code가 디렉토리명에서 플러그인 이름을 유추하고, 기본 위치의 컴포넌트를 자동 탐지하는 방식으로 사용됩니다.
{
"name": "my-plugin",
"version": "1.0.0",
"description": "프로젝트 자동화 도구",
"author": { "name": "Your Name", "email": "you@example.com" },
"license": "MIT"
}
플러그인 사용자에게 설정 값을 입력받을 수도 있습니다. sensitive: true인 값은 시스템 키체인에 저장됩니다.
{
"userConfig": {
"api_endpoint": { "description": "API 엔드포인트", "sensitive": false },
"api_token": { "description": "API 토큰", "sensitive": true }
}
}
설정된 값은 ${user_config.KEY}로 MCP/LSP 설정, Hook 커맨드 등에서 참조할 수 있고, CLAUDE_PLUGIN_OPTION_<KEY> 환경변수로도 내보내집니다.
| 변수 | 설명 |
|---|---|
${CLAUDE_PLUGIN_ROOT} | 플러그인 캐시 디렉토리 (원본이 아닌 복사본) |
${CLAUDE_PLUGIN_DATA} | 플러그인 영구 데이터 디렉토리 |
플러그인은 보안을 위해 캐시 디렉토리에 복사되어 실행됩니다. 원본 디렉토리에서 직접 실행되지 않기 때문에, ../ 같은 외부 경로 참조는 동작하지 않습니다.
/plugin marketplace add owner/repo-name # 마켓플레이스 등록
/plugin install plugin-name@marketplace-name # 설치 (사용자 범위)
/plugin install plugin-name@marketplace --scope project # 프로젝트 범위
/plugin marketplace update # 업데이트
설치 범위는 위와 같이 설정할 수도 있는데, 요즘은 대부분 플러그인이 그냥 install하면 어느 위치에 받을지 선택할 수 있게 나와서 그때 설정하시면 됩니다.
슬래시 커맨드는 plugin-name:command-name 형태로 네임스페이스화됩니다. 플러그인 제공 스킬은 보안상 hooks, MCP servers, permission modes를 정의할 수 없습니다.
하나의 레포에서 여러 세션을 병렬로 돌리면 에이전트끼리 수정 중인 파일을 덮어쓰는 등 개판이 납니다.
날린 파일 확인한다고 작업했던 컨텍스트 다시 읽느라 토큰을 사용하는 모습을 보면 화가 나기도 합니다.
--worktree 플래그를 사용해 각 세션이 독립된 git worktree에서 실행되도록 격리할 수 있습니다.
claude --worktree feature-auth # 네임드 worktree
claude --worktree # 자동 네이밍
claude --worktree name --tmux # tmux 패널에서 실행
.worktreeinclude 파일을 프로젝트 루트에 두면, .gitignore된 파일(.env 등)을 새 worktree에 자동 복사할 수 있습니다.
터미널에서 시작한 세션을 웹(claude.ai/code)이나 iOS/Android 앱에서 원격 제어할 수 있습니다. 코드는 로컬에만 존재하고, 암호화된 채널로 채팅 메시지만 전송하는 방식입니다.
claude rc # 원격 제어 활성화된 새 세션
/rc # 기존 세션에서 활성화
/rename "my-task" # RC 전에 세션 이름 지정
/config # 모든 세션에 자동 활성화
앱에서는 아래와 같이 사용할 수 있습니다.
Remote Control이 "로컬 세션을 원격에서 조작"이라면, Teleportation은 세션 자체를 클라우드와 로컬 간에 이동시키는 기능입니다.
claude --remote "task" # 클라우드로 작업 전송
/tp # 클라우드 세션을 로컬로 가져오기
/tasks # 모든 세션 보기
Cron 스타일의 반복 실행입니다. PR 리뷰 모니터링, 배포 상태 확인 같은 주기적 작업에 적합합니다. OpenClaw의 cron job을 보고 후다닥 만든 기능이 아닐까 싶습니다. 아무튼 편합니다.
/loop "5분마다 새 PR을 확인하고 코드 리뷰 요약을 작성하라"
여러 파일에 걸친 변경을 병렬로 수행합니다. 내부적으로 여러 에이전트가 각각의 파일을 동시에 처리합니다.
/batch "모든 API 엔드포인트에 rate limiting을 추가하라"
| 커맨드 | 설명 |
|---|---|
/plan | Plan 모드 (수정 없이 전략만 수립) |
/fork | 대화 분기 |
/resume | 이전 세션 재개 (최대 50개) |
/compact | 컨텍스트 압축 |
/fast | Fast 모드 토글 (Opus 4.6, 2.5배 빠름) |
/memory | 메모리 확인/편집 |
Ctrl+B | 에이전트를 백그라운드로 전송 |
Alt+T | Extended Thinking 토글 |
Agent Teams(Swarms)는 여러 Claude Code 세션이 병렬로 협업하는 실험적 기능입니다. Subagent가 "메인 세션 안에서 하위 작업을 위임"하는 구조라면, Agent Teams는 "여러 독립 세션이 대등하게 협업"하는 구조라고 합니다.
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
리드 에이전트가 계획을 세우고 전문 백그라운드 에이전트에게 위임하면, 에이전트 간 태스크 보드와 메시징으로 협조한다고 합니다. 팀원은 리드의 권한과 MCP 연결을 상속받습니다.
(기존의 subagents는 supervisor 구조라면, teams는 network 구조의 multi agent 방식이라고 이해했습니다.
host를 통해 소통하는 것이 아니라 각 에이전트끼리 소통하거나 작업을 hand-off 할 수 있는 방식.)
다만 토큰 소비가 Subagent(4-7배)보다도 훨씬 많아서 약 15배 수준입니다. 그리고 아직 실험적 기능이므로 신뢰성 이슈가 보고되고 있습니다. 프로덕션 작업에는 공식 Subagent를 사용하고, Agent Teams는 추후 안정화 되면 시도하는 것이 어떨까 생각하며 저도 사용 후기를 팔로우업 하고 있습니다.
1편과 2편에서 다룬 기능들은 독립적으로도 유용하지만, 조합했을 때 더 강력해집니다.
CLAUDE.md에는 200줄 이하의 공통 규칙만 두고, 파일 유형별 규칙은 .claude/rules/에 paths와 함께 배치합니다. 실제 적용 시 가장 먼저 해야 할 구조화입니다.
여러 Subagent를 순차적으로 연결하여 소프트웨어 개발 파이프라인을 구성할 수 있습니다.
PM Spec Agent -> Architect Review Agent -> Implementer Agent -> QA Agent
각 단계 사이에 Hook으로 전환을 게이팅하고, 사람이 승인 후 다음 단계로 진행합니다. 각 에이전트는 skills 필드로 해당 단계에 필요한 전문 지식을 주입받습니다. claude에 요청하면 알아서 frontmatter와 hook을 세팅해줍니다.
이미 잘 동작하는 Skill이 있는데 메인 컨텍스트를 오염시키고 싶지 않을 때, Subagent 파일을 별도로 만들 필요 없이 frontmatter에 context: fork만 추가할 수 있습니다. 같은 지침이 격리된 컨텍스트에서 실행되고 결과만 돌아옵니다.
(/btw로 작업 중 context를 오염시키지 않고 대화를 할 수는 있지만 skill 사용 등이 제한되기 때문에, 스킬 컨텍스트를 격리하기 위해서는 위 구조가 필수입니다.)
직접 만든 Skills, Subagents, Hooks 등을 팀이나 커뮤니티에 공유하는 방법입니다.
claude code docs에도 적혀있는 공식 권장 방법입니다. 마켓플레이스는 여러 플러그인을 담는 Git 레포지토리입니다.
레포 루트에 .claude-plugin/marketplace.json을 두고, plugins/ 디렉토리 아래에 각 플러그인을 배치합니다.
{
"name": "my-team-marketplace",
"owner": { "name": "Team", "email": "team@example.com" },
"metadata": { "description": "팀 플러그인 모음", "version": "1.0.0" },
"plugins": [
{
"name": "code-review-plugin",
"source": "./plugins/code-review-plugin",
"description": "코드 리뷰 도구"
}
]
}
GitHub에 push하면, 사용자가 /plugin marketplace add owner/repo-name으로 등록하고 /plugin install로 설치합니다. 업데이트는 레포에 push한 뒤 사용자가 /plugin marketplace update로 갱신합니다.
외부 GitHub 레포를 직접 소스로 참조할 수도 있습니다.
{
"name": "external-plugin",
"source": {
"source": "github",
"repo": "owner/plugin-repo",
"ref": "v2.0.0"
}
}
비공개 레포도 지원됩니다. 터미널에서 git clone이 되면 Claude Code에서도 동작합니다. 자동 업데이트를 위해서는 GITHUB_TOKEN 환경변수를 설정해야 합니다.
Plugin Marketplace가 아닌, npm 패키지로 만들어 npx로 설치하는 방법도 많이 사용됩니다.
패키지 구조:
my-claude-toolkit/
package.json
bin/install.js # 설치 스크립트
templates/
skills/my-skill/SKILL.md
agents/my-agent.md
hooks/my-hook.sh
package.json에서 "bin" 필드로 설치 스크립트를 지정하고, 스크립트 내에서 templates/를 대상 프로젝트의 .claude/로 복사하는 로직을 작성합니다. npm publish 후 사용자는 npx my-claude-toolkit으로 설치할 수 있습니다.
templates 단위 말고도 매우 자유롭게 배포할 수 있다는 점이 장점입니다.
저도 실제로 팀에서 marketplace+web을 개발하고 있는데, npx 방식을 채택했습니다.
1. 공식 기능을 활용할 경우, 권장하는 assets만 공유 가능하기 때문입니다.
실제로 CLAUDE.md나 rules 등은 공유할 수 없습니다. (어차피 프로젝트마다 고유의 지시사항이 필요하기 때문) 하지만 팀에서는 업무 중 비슷한 작업을 수행하기 위한 baseline으로 공유가 필요했고, karpathy의 LLM Wiki처럼 IdeaFile도 포함해 운영할 계획이기 때문입니다.2. 다른 agent의 harness로의 확장 가능성입니다.
사실 포스팅의 목적은 claude code harness이지만, 직원들은 codex, cursor, openclaw 등 다양한 에이전트를 활용하고 있습니다. 따라서 Claude Code에 종속된 marketplace를 개발할 수 없었습니다.
조직 전체에 마켓플레이스와 플러그인을 강제 적용하려면 관리자 설정 파일을 사용합니다.
macOS: /Library/Application Support/ClaudeCode/managed-settings.json
Linux: /etc/claude-code/managed-settings.json
{
"extraKnownMarketplaces": {
"company-tools": {
"source": { "source": "github", "repo": "org/claude-plugins" }
}
},
"enabledPlugins": {
"security-hooks@company-tools": true
}
}
CI/CD 환경에서는 CLAUDE_CODE_PLUGIN_SEED_DIR 환경변수로 플러그인을 사전 탑재할 수 있습니다. ~/.claude/plugins와 동일한 디렉토리 구조를 미러링하면 됩니다.

Anthropic은 거의 매 주 새로운 기능을 개발하고 있기 때문에 이 포스팅도 금방 legacy가 될 것입니다. 그래서 사실 이 주제는 포스팅 할 생각도 없었는데, SNS에서 권장되지 않는 방식이나 이미 사라진 기능 가져다가 장사를 하는 모습(거기에 많은 사람들이 속는 모습)을 보며 답답함을 느껴서 올리게 되었습니다.
요즘은 plugin이나 기능이 없어서 못 쓴다기 보다는, 너무 많아서 못 쓰는 분들이 많은 것 같습니다. 이럴때일수록, 주도적이고 비판적으로 본인에게 필요한 내용을 선별적으로 수용하려는 노력이 필요하다고 생각됩니다.
끝으로, 1,2편에서 소개한 각 기능을 언제 쓸지에 대한 판단 기준을 정리하며 마무리하도록 하겠습니다.
| 상황 | 적합한 기능 |
|---|---|
| 매 세션 반복하는 설명이 있다 | CLAUDE.md |
| 특정 파일 작업 시에만 적용할 규칙이 있다 | .claude/rules/ + paths |
| 반드시 실행되어야 하는 동작이 있다 | Hooks |
| 필요할 때만 꺼내 쓰는 전문 지식이 있다 | Skills |
| 무거운 탐색/분석을 메인 컨텍스트와 분리하고 싶다 | Subagents (또는 Skills + context: fork) |
| 외부 API/도구를 연결하고 싶다 | MCP Servers |
| 도구 접근 자체를 제한하고 싶다 | Permissions |
| bash 명령의 시스템 접근을 격리하고 싶다 | Sandbox |
| 위 기능들을 팀/커뮤니티에 공유하고 싶다 | Plugins + Marketplace |
| 여러 세션을 병렬로 격리 실행하고 싶다 | Git Worktrees |
| 터미널을 떠나서도 세션을 이어가고 싶다 | Remote Control |
settings에서 단일 값을 사용하는 key의 경우는 local setting을 따르고, 다중 값 배열을 사용하는 key는 local을 일반 settings에 merge하는 방식으로 적용됩니다.
{"model": "opus",
"permissions": {
"deny": [
"Bash(uv run *)",
]
}
}
{"model": "opus",
"permissions": {
"allow": [
"Bash(uv run *)",
]
}
}
이 상황에서