문제: 시크릿이 여기저기 흩어져 있다
개발 프로젝트가 6개를 넘어가면서, 각 프로젝트의 .env 파일 위치를 기억하는 게 고역이 됐다.
"contents-hub DB 비밀번호가 뭐였지?"
→ 폴더 들어가서 .env 열어보고...
"AWS 키는 어디 저장했더라?"
→ ssh-keys 폴더 뒤지고...
"프로덕션 Redis 주소는?"
→ docker-compose.prod.yml 찾아보고...
매번 이 삽질을 반복하다가, Claude Code 플러그인으로 해결했다.
해결: /secrets 커맨드 하나로 끝
/secrets → 전체 프로젝트 시크릿 목록
/secrets contents-hub → contents-hub .env 실제 값 전체
/secrets anthropic → Anthropic API Key 위치 + 값
/secrets aws → AWS 자격증명 위치 + 내용
Claude Code에서 슬래시 커맨드 한 번이면 어떤 프로젝트의 어떤 시크릿이든 즉시 조회된다.
구현: 파일 3개면 충분하다
Claude Code 플러그인의 최소 구조는 놀랍도록 단순하다.
1password/
├── secrets-index.md # 시크릿 인덱스 (수동 관리)
├── .claude-plugin/
│ └── plugin.json # 플러그인 메타데이터
└── commands/
└── secrets.md # /secrets 커맨드 정의
1단계: plugin.json — 플러그인 등록
{
"name": "1password",
"version": "1.0.0",
"description": "시크릿 인덱스 조회",
"author": { "name": "elon" }
}
이게 전부다. .claude-plugin/plugin.json만 있으면 Claude Code가 자동으로 플러그인을 인식한다.
2단계: secrets-index.md — 시크릿 지도
모든 프로젝트의 시크릿 위치를 하나의 마크다운 파일에 정리한다.
## 프로젝트별 .env 위치
### contents-hub
- **파일**: ~/elon/ai/projects/contents_hub/backend/.env
- DB: `DATABASE_URL` (PostgreSQL)
- Redis: `REDIS_URL`
- SMTP: `SMTP_USER`, `SMTP_PASSWORD`
- Anthropic: `ANTHROPIC_API_KEY`
핵심 원칙: 변수명만 기록하고, 실제 값은 절대 넣지 않는다. 값은 런타임에 .env 파일을 직접 읽어서 보여준다.
3단계: secrets.md — 커맨드 프롬프트
커맨드 정의는 마크다운 파일 하나다. YAML 프론트매터로 메타데이터를 설정하고, 본문에 AI가 따를 지침을 적는다.
---
name: secrets
description: 시크릿 인덱스에서 비밀 정보 위치와 값을 조회합니다
argument-hint: "[프로젝트명 또는 키워드]"
allowed-tools:
- Read
- Glob
- Grep
---
allowed-tools에 Read/Glob/Grep만 허용해서 읽기 전용으로 동작한다. 실수로 파일을 수정할 위험이 없다.
본문 프롬프트에서 3가지 동작 모드를 정의한다:
| 인자 | 동작 | 예시 |
|---|---|---|
| 없음 | 전체 프로젝트 목록 표시 | /secrets |
| 프로젝트명 | 해당 .env 파일 읽어서 전체 값 출력 | /secrets contents-hub |
| 키워드 | 인덱스 전체 검색 후 매칭 값 출력 | /secrets smtp |
하나의 커맨드에 인자 기반 분기 — 여러 커맨드를 나누는 것보다 사용자 경험이 훨씬 단순하다.
배운 것들
1. 플러그인 설치 3단계 전략
| 단계 | 방식 | 용도 |
|---|---|---|
| 개발 중 | 로컬 자동 인식 | .claude-plugin/ 디렉토리만 있으면 자동 감지 |
| 안정화 | 로컬 마켓플레이스 | known_marketplaces.json에 등록 → 전역 사용 |
| 공유 | GitHub 마켓플레이스 | GitHub 레포로 배포 |
개발할 때는 해당 폴더에서 바로 쓰고, 검증되면 마켓플레이스로 승격한다.
2. 마켓플레이스 통합의 힘
처음에는 플러그인마다 별도 마켓플레이스를 만들었다. 1password, snapkin, disk-cleaner... 금방 복잡해졌다.
하나의 my-plugins 마켓플레이스로 통합하니 관리가 깔끔해졌다:
{
"name": "my-plugins",
"plugins": [
{ "name": "1password", "source": "./1password" },
{ "name": "snapkin", "source": "./snapkin" },
{ "name": "disk-cleaner", "source": "./disk-cleaner" }
]
}
source 필드로 하위 디렉토리를 가리키면 끝. 새 플러그인은 배열에 한 줄만 추가하면 된다.
3. Command vs Skill — 언제 무엇을 쓸까
| 구분 | Command | Skill |
|---|---|---|
| 실행 | 사용자가 / 명령으로 직접 호출 |
Claude가 대화 맥락에 따라 자동 적용 |
| 역할 | "무엇을 할지" (액션) | "어떻게 할지" (지식) |
/secrets는 사용자가 명시적으로 호출하는 액션이니까 Command가 맞다. "시크릿 관리 가이드라인"처럼 배경 지식이라면 Skill이 적절하다.
4. 리소스 배치의 원칙: 소속 범위
리소스(scripts/, config/, references/) 위치를 정하는 기준은 누가 쓰느냐다:
- 하나의 skill에서만 사용 →
skills/해당-skill/내부 - 여러 구성 요소가 공유 → 플러그인 루트
- 외부 서비스 연결 →
.mcp.json
단순하지만, 이 원칙 하나로 "이 파일 어디에 둘까?" 고민이 사라진다.
실제 사용 모습
> /secrets contents-hub
📁 ~/elon/ai/projects/contents_hub/backend/.env
DATABASE_URL=postgresql://contents_hub:xxx@localhost:5432/contents_hub
REDIS_URL=redis://localhost:6379/0
ANTHROPIC_API_KEY=sk-ant-api03-xxx...
SMTP_USER=joomanba@gmail.com
...
🖥️ 운영 환경 (VM: elon.tpm.querypie.io)
- DB: pgvector-postgres-1:5432
- Redis: querypie-redis-1 (172.18.0.1:6379)
.env 파일 위치를 기억할 필요도, 터미널에서 cat으로 열 필요도 없다. Claude Code가 인덱스에서 경로를 찾고, 파일을 읽어서 보여준다.
마무리
Claude Code 플러그인 개발의 진입 장벽은 예상보다 훨씬 낮다.
- 파일 3개로 완전한 플러그인이 만들어진다
- 코드 빌드 없이 마크다운만으로 동작한다
- allowed-tools로 안전한 읽기 전용 플러그인을 만들 수 있다
- 마켓플레이스 통합으로 여러 플러그인을 깔끔하게 관리할 수 있다
반복적으로 .env 파일을 찾아 헤매고 있다면, 30분 투자해서 플러그인 하나 만들어보자. 그 30분이 앞으로 수백 번의 삽질을 없애준다.