v4.7.x 부터 도입된 Claude Toolkit MCP Server — Claude Code / Cursor / Cline 등 AI agent 가 IDE 안에서 도구의 12+ 분석 기능을 직접 호출.
Before: 도구 사용 = 우리 웹 페이지로 와야 함
After: 도구 = 사내 모든 시스템에서 호출 가능한 플랫폼
├─ 웹 페이지 (사용자가 직접)
├─ MCP Server (IDE 안에서)
├─ CLI (CI/CD pipeline)
└─ REST API (사내 자동화)
| Client | 지원 |
|---|---|
| Claude Code (Anthropic 공식) | ✅ stdio MCP |
| Cursor | ✅ MCP |
| Cline (VS Code) | ✅ MCP |
| Continue.dev | ✅ MCP |
| 자체 AI Agent | ✅ stdio + MCP SDK |
cd claude-toolkit-ui
mvn spring-boot:run
# → http://localhost:8027- ADMIN 으로 로그인 → 사이드바 [관리] → API Key 관리 (
/admin/api-keys) - + 새 키 발급 클릭
- 입력:
- 이름:
Claude Code MCP(식별용) - Role:
READ_ONLY(권장 — 분석만 가능) - 분당 호출 한도: 60
- TTL: 90일
- 이름:
- 발급 → plaintext 모달이 뜸:
→ [복사] 버튼 클릭. 이 키는 다시 표시되지 않음.
ctk_live_a1b2c3d4e5f6g7h8...
~/.config/claude/mcp_settings.json (macOS/Linux) 또는 %APPDATA%\Claude\mcp_settings.json (Windows):
{
"mcpServers": {
"claude-toolkit": {
"command": "npx",
"args": ["-y", "@claude-toolkit/mcp-server"],
"env": {
"CTK_URL": "http://localhost:8027",
"CTK_API_KEY": "ctk_live_a1b2c3d4e5f6g7h8...",
"CTK_DB_PROFILE_ID": "1"
}
}
}
}
⚠️ CTK_DB_PROFILE_ID 는 옵션 — Live DB 활성 프로필 ID 입력 시 SQL 분석에 자동 컨텍스트 첨부.
Claude Code 안에서:
> 이 SQL 리뷰해줘:
SELECT * FROM T_ORDER WHERE STATUS='Y' AND ORDER_DATE >= SYSDATE - 30
Claude 가 자동으로 claude-toolkit__sql_review tool 호출 → 결과를 IDE 안에 표시.
Settings → Features → Model Context Protocol → Add MCP Server:
{
"name": "claude-toolkit",
"command": "npx",
"args": ["-y", "@claude-toolkit/mcp-server"],
"env": {
"CTK_URL": "http://localhost:8027",
"CTK_API_KEY": "ctk_live_..."
}
}VS Code Command Palette → Cline: Add MCP Server → 위와 동일 형식 입력.
| Tool | Args | 설명 |
|---|---|---|
sql_review |
input, reviewType?, dbProfileId? |
성능/보안/가독성 이슈 |
explain_plan |
input, explainPlan?, dbProfileId? |
실행계획 분석 — Live DB 시 자동 EXPLAIN |
index_advisor |
input, dbProfileId? |
인덱스 추천 DDL |
sql_translate |
input, sourceDb, targetDb |
DB 간 번역 (Oracle/MySQL/PG/MSSQL) |
sql_batch |
input, dbProfileId? |
여러 SQL 일괄 분석 |
erd_analysis |
input, dbProfileId? |
ERD + Mermaid 다이어그램 |
| Tool | Args | 설명 |
|---|---|---|
code_review |
input |
Java 코드 리뷰 |
doc_gen |
input |
기술 문서 생성 |
complexity |
input |
복잡도 점수 |
commit_msg |
input |
git diff → conventional commits |
regex_gen |
input, language? |
자연어 → 정규식 |
test_gen |
input |
Java → JUnit 5 |
MCP server 외에도 같은 backend 를 REST API 로 직접 호출 가능 — 인증은 같은 X-Api-Key 사용.
curl -X POST http://localhost:8027/api/v1/analyze \
-H "X-Api-Key: ctk_live_a1b2c3d4..." \
-H "Content-Type: application/json" \
-d '{
"feature": "sql_review",
"input": "SELECT * FROM T_ORDER WHERE STATUS='Y'",
"sourceType": "review",
"dbProfileId": 1
}'{
"success": true,
"feature": "sql_review",
"result": "## 분석 결과\n\n### 1. 성능 이슈\n- ...",
"cached": false,
"tokens": { "input": 1200, "output": 850 },
"costUsd": 0.0042,
"elapsedMs": 4231,
"model": "claude-sonnet-4-20250514"
}- name: Claude SQL Review
run: |
curl -X POST $CTK_URL/api/v1/analyze \
-H "X-Api-Key: $CTK_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"feature\":\"sql_review\",\"input\":\"$(cat changed.sql)\"}" \
| jq -r '.result'
env:
CTK_URL: https://ctk.company.com
CTK_API_KEY: ${{ secrets.CTK_API_KEY }}언제 쓰나? MCP 서버를 한 PC(또는 사내 서버)에 1대만 띄우고, 같은 사내망의 여러 개발자 PC가 그 서버를 공유. 각 사용자는 자기 키로 접속 — audit log/rate limit 이 사람별로 분리됨.
[개발자 A 의 Claude Desktop] [MCP 호스트 (사내 1대)]
npx mcp-remote ───stdio───┐ ┌─ MCP HTTP :8028 ─┐
├─ HTTP + X-Api-Key ─→│ per-request │
[개발자 B 의 Cursor] │ (각자 다른 키) │ ToolkitClient │
npx mcp-remote ───stdio───┘ │ ↓ │
│ POST /api/v1/ │
│ analyze │
└────┬──────────────┘
↓
[도구 backend :8027]
(PlatformAuthFilter 가
각 사용자 키별 검증)
핵심: MCP 서버는 X-Api-Key 헤더를 그대로 backend 에 전달 (per-request 패스스루). MCP 서버 자체는 키를 저장하지 않음 — backend 의 기존 보안 모델이 그대로 살아남음.
cd claude-toolkit-mcp
npm install
npm run build
# 환경변수
export CTK_URL=http://localhost:8027 # 같은 호스트의 backend
export MCP_TRANSPORT=http
export MCP_HTTP_HOST=0.0.0.0 # 사내망 노출 (default)
export MCP_HTTP_PORT=8028 # default
npm run start:http
# → [MCP] http ready — listening on 0.0.0.0:8028 (12 tools, stateless, per-request X-Api-Key)방화벽이 8028 을 사내망에 열어줘야 함. 외부 인터넷에 직접 노출하지 말 것 — VPN/사내망 안에서만 사용.
/admin/api-keys 에서 사람별로 발급. 이름은 홍길동 — Cursor 처럼 식별 가능하게.
플랫폼별 경로:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Cursor:
Settings → Features → Model Context Protocol - Cline:
VS Code Command Palette → Cline: Add MCP Server
{
"mcpServers": {
"claude-toolkit": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://mcp-host.사내도메인:8028/mcp",
"--header",
"X-Api-Key:ctk_live_본인키..."
]
}
}
}
⚠️ --header와 키 사이는 콜론(:)으로 구분, 공백 없음. mcp-remote 가 stdio↔HTTP 브릿지 역할을 하므로 클라이언트 측 코드 수정 불요.
curl http://mcp-host.사내도메인:8028/healthz
# {"status":"ok","tools":12,"transport":"http"}| 상황 | 권장 |
|---|---|
| 개인 노트북에서 단독 사용 | stdio (§2) — 가장 단순 |
| 팀 5명 이상 공유 (개발 PC 1대 기동) | mvn spring-boot:run + auto-launcher (§5-3) |
| 사내 서버 + Docker 배포 | docker-compose 분리 컨테이너 (§5-4) |
| 외부 인터넷 노출 필요 | 권장 안 함. 부득이하면 reverse proxy (nginx) + TLS + 사내망 ACL |
mvn spring-boot:run 시 Spring Boot 의 McpServerLauncher 가 8028을 자동 spawn합니다. 별도 창에서 npm run start:http 를 띄울 필요 없음.
# application.yml — 기본값 (변경 불필요)
toolkit:
mcp:
auto-start: true # ${TOOLKIT_MCP_AUTOSTART:true}
project-root: ../claude-toolkit-mcp
host: 0.0.0.0
port: 8028
node: node # PATH 의 node 또는 절대경로기동 후 Spring Boot 로그에 다음이 보이면 정상:
[MCP] 자동 기동 성공 — pid=..., listening on 0.0.0.0:8028, backend=http://localhost:8027
[MCP] [MCP] http ready — listening on 0.0.0.0:8028 (12 tools, ...)
비활성화: TOOLKIT_MCP_AUTOSTART=false
node PATH 안 잡힐 때: TOOLKIT_MCP_NODE="C:/Program Files/nodejs/node.exe"
dist 가 없을 때: launcher 가 dist/index.js 미존재 경고 후 스킵. cd claude-toolkit-mcp && npm install && npm run build 한 번 실행 후 재기동.
Docker 환경에서는 MCP 를 별도 컨테이너로 분리합니다 (이미 docker-compose.yml 에 추가됨). claude-toolkit 컨테이너의 launcher 는 자동 OFF (TOOLKIT_MCP_AUTOSTART=false).
# 빌드 + 기동 — claude-toolkit-mcp 가 함께 올라옴
docker-compose build --no-cache claude-toolkit claude-toolkit-mcp
docker-compose up -d claude-toolkit claude-toolkit-mcp
# 모니터링 프로필도 함께
docker-compose --profile monitoring up -d| 컨테이너 | 호스트 포트 | 컨테이너 내부 |
|---|---|---|
claude-toolkit |
8027 | 8027 (Spring Boot) |
claude-toolkit-mcp |
8028 | 8028 (Streamable HTTP) |
컨테이너 간 통신: docker network DNS 로 claude-toolkit-mcp → claude-toolkit:8027.
검증:
# 호스트에서
curl http://localhost:8028/healthz
# {"status":"ok","tools":12,"transport":"http"}
# 컨테이너 로그
docker logs -f claude-toolkit-mcpMCP 만 재시작:
docker-compose restart claude-toolkit-mcpMCP 만 재빌드:
docker-compose build claude-toolkit-mcp
docker-compose up -d claude-toolkit-mcp| 증상 | 점검 |
|---|---|
npx mcp-remote 가 connection refused |
호스트 IP/포트, 방화벽 8028 inbound, MCP 서버가 0.0.0.0 으로 listen 중인지 |
| 401 X-Api-Key 헤더 필요 | mcp_settings.json 의 --header 형식 (X-Api-Key:키, 공백 없음) |
| 401 Invalid API key | backend 에서 키 회수/만료 — /admin/api-keys |
| 호출은 되는데 결과가 비어있음 | MCP 서버 로그([MCP] http 처리 실패: ...) 확인 |
[1] 도구 backend
├─ 세션 인증 (브라우저 사용자) → 그대로 통과
└─ X-Api-Key 헤더 (외부 client) → PlatformAuthFilter 검증
[2] PlatformAuthFilter
├─ DB 의 SHA-256 hash 와 timing-safe 비교
├─ 만료/회수/usable 검증
├─ 분당 호출 한도 (sliding window)
└─ 통과 시 SecurityContext set (key.createdBy 으로 인증)
[3] 통제 권한
├─ ADMIN 만 키 발급/회수 가능
├─ 평문 키는 발급 직후 1회만 노출 — DB 에는 해시만
└─ 회수 시 즉시 401 (모든 client 차단)
| 위험 | 대응 |
|---|---|
| 키 노출 의심 | /admin/api-keys 즉시 회수 → 401 |
| 한 키가 비정상 호출 폭증 | 분당 60회 한도 초과 시 429 자동 차단 |
| 도구 backend 침해 | toolkit.platform.enabled=false (kill switch) |
| 평문 키 DB 노출 | DB 에는 SHA-256 해시만. 평문은 발급 직후 1회만 메모리 |
~/.config/claude/mcp_settings.json파일 존재 + JSON 문법 정상 확인- Claude Code 완전 재시작
- npx 가 패키지 다운로드 못 했을 가능성 — 콘솔에 "@claude-toolkit/mcp-server is not found" 에러? 그러면:
npx -y @claude-toolkit/mcp-server # 직접 실행 테스트
mcp_settings.json의 env 객체 안에 정확히 입력- URL 끝에
/없이 —http://localhost:8027(O),http://localhost:8027/(X)
- 키 만료/회수 —
/admin/api-keys에서 상태 확인 - 환경변수 오타 — Bash 와 mcp_settings.json 둘 다 검토
- 한 IDE 가 분당 60회 초과 — 일반적으로 일어나지 않음, 자동화 스크립트 의심
- ADMIN 페이지에서 해당 키의 rate limit 증가 (예: 120/min)
CTK_DB_PROFILE_ID환경변수 설정 확인/admin/health의 Live DB 카드가 ✓ ENABLED 인지 확인 (관련: Live DB 가이드)- 해당 프로필이 활성화됐는지 (
/db-profiles의 🔌 Live: ON)
- Claude API latency — 5~30초가 일반적
- Live DB 통합 시 EXPLAIN 추가 호출 — 1~3초 추가
- timeout 으로 끊기면 backend 의
claude.api.timeout설정 확인
- 발급된 모든 키 목록
- 키별 마지막 사용 시각 + 호출 카운트
- 의심 키 즉시 회수
모든 X-Api-Key 호출은 audit_log 에 기록 (Spring Security 의 audit 통합):
SELECT * FROM audit_log
WHERE endpoint LIKE '/api/v1/analyze%'
ORDER BY created_at DESC;/usage에서 사용자별 (= 키 발급자별) 토큰 사용량- API 응답의
costUsd가 client 측에서 비용 인지 가능
운영 사고 시:
# 즉시 비활성 (재시작 필요)
export TOOLKIT_PLATFORM_ENABLED=false # (옵션) — 추후 보강 가능또는 ADMIN 페이지에서 모든 키 회수 — 같은 효과.