@kood/claude-code 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36,29 +36,51 @@ var getTemplatesDir = () => {
36
36
  var getTemplatePath = (template) => {
37
37
  return path.join(getTemplatesDir(), template);
38
38
  };
39
- var copyTemplate = async (template, targetDir) => {
39
+ var copyRecursive = async (src, dest, counter) => {
40
+ const stat = await fs.stat(src);
41
+ if (stat.isDirectory()) {
42
+ await fs.ensureDir(dest);
43
+ counter.directories++;
44
+ const items = await fs.readdir(src);
45
+ for (const item of items) {
46
+ await copyRecursive(path.join(src, item), path.join(dest, item), counter);
47
+ }
48
+ } else {
49
+ await fs.copy(src, dest);
50
+ counter.files++;
51
+ }
52
+ };
53
+ var copySingleTemplate = async (template, targetDir) => {
40
54
  const templatePath = getTemplatePath(template);
41
55
  if (!await fs.pathExists(templatePath)) {
42
56
  throw new Error(`Template "${template}" not found at ${templatePath}`);
43
57
  }
44
- let files = 0;
45
- let directories = 0;
46
- const copyRecursive = async (src, dest) => {
47
- const stat = await fs.stat(src);
48
- if (stat.isDirectory()) {
49
- await fs.ensureDir(dest);
50
- directories++;
51
- const items = await fs.readdir(src);
52
- for (const item of items) {
53
- await copyRecursive(path.join(src, item), path.join(dest, item));
54
- }
55
- } else {
56
- await fs.copy(src, dest);
57
- files++;
58
+ const counter = { files: 0, directories: 0 };
59
+ const claudeMdSrc = path.join(templatePath, "CLAUDE.md");
60
+ if (await fs.pathExists(claudeMdSrc)) {
61
+ await fs.copy(claudeMdSrc, path.join(targetDir, "CLAUDE.md"));
62
+ counter.files++;
63
+ }
64
+ const docsSrc = path.join(templatePath, "docs");
65
+ if (await fs.pathExists(docsSrc)) {
66
+ await copyRecursive(docsSrc, path.join(targetDir, "docs"), counter);
67
+ }
68
+ return counter;
69
+ };
70
+ var copyMultipleTemplates = async (templates, targetDir) => {
71
+ const counter = { files: 0, directories: 0 };
72
+ for (const template of templates) {
73
+ const templatePath = getTemplatePath(template);
74
+ if (!await fs.pathExists(templatePath)) {
75
+ throw new Error(`Template "${template}" not found at ${templatePath}`);
58
76
  }
59
- };
60
- await copyRecursive(templatePath, targetDir);
61
- return { files, directories };
77
+ await copyRecursive(
78
+ templatePath,
79
+ path.join(targetDir, "docs", template),
80
+ counter
81
+ );
82
+ }
83
+ return counter;
62
84
  };
63
85
  var checkExistingFiles = async (targetDir) => {
64
86
  const existingFiles = [];
@@ -116,14 +138,14 @@ var copySkills = async (template, targetDir) => {
116
138
  let files = 0;
117
139
  let directories = 0;
118
140
  const installedSkills = [];
119
- const copyRecursive = async (src, dest) => {
141
+ const copyRecursive2 = async (src, dest) => {
120
142
  const stat = await fs.stat(src);
121
143
  if (stat.isDirectory()) {
122
144
  await fs.ensureDir(dest);
123
145
  directories++;
124
146
  const items = await fs.readdir(src);
125
147
  for (const item of items) {
126
- await copyRecursive(path.join(src, item), path.join(dest, item));
148
+ await copyRecursive2(path.join(src, item), path.join(dest, item));
127
149
  }
128
150
  } else {
129
151
  await fs.copy(src, dest);
@@ -136,7 +158,7 @@ var copySkills = async (template, targetDir) => {
136
158
  const skillDestPath = path.join(targetSkillsDir, skill);
137
159
  const stat = await fs.stat(skillSrcPath);
138
160
  if (stat.isDirectory()) {
139
- await copyRecursive(skillSrcPath, skillDestPath);
161
+ await copyRecursive2(skillSrcPath, skillDestPath);
140
162
  installedSkills.push(skill);
141
163
  }
142
164
  }
@@ -166,26 +188,31 @@ var init = async (options) => {
166
188
  logger.error("No templates found. Package may be corrupted.");
167
189
  process.exit(1);
168
190
  }
169
- let template = options.template;
170
- if (!template) {
191
+ let templates = options.templates || [];
192
+ if (templates.length === 0) {
171
193
  const response = await prompts({
172
- type: "select",
173
- name: "template",
174
- message: "Select a template:",
194
+ type: "multiselect",
195
+ name: "templates",
196
+ message: "Select templates (space to select, enter to confirm):",
175
197
  choices: availableTemplates.map((t) => ({
176
198
  title: t,
177
199
  description: TEMPLATE_DESCRIPTIONS[t] || "",
178
200
  value: t
179
- }))
201
+ })),
202
+ min: 1,
203
+ hint: "- Space to select. Return to submit"
180
204
  });
181
- if (!response.template) {
205
+ if (!response.templates || response.templates.length === 0) {
182
206
  logger.warn("Operation cancelled.");
183
207
  process.exit(0);
184
208
  }
185
- template = response.template;
209
+ templates = response.templates;
186
210
  }
187
- if (!availableTemplates.includes(template)) {
188
- logger.error(`Template "${template}" not found.`);
211
+ const invalidTemplates = templates.filter(
212
+ (t) => !availableTemplates.includes(t)
213
+ );
214
+ if (invalidTemplates.length > 0) {
215
+ logger.error(`Templates not found: ${invalidTemplates.join(", ")}`);
189
216
  logger.info(`Available templates: ${availableTemplates.join(", ")}`);
190
217
  process.exit(1);
191
218
  }
@@ -205,80 +232,116 @@ var init = async (options) => {
205
232
  process.exit(0);
206
233
  }
207
234
  }
208
- logger.blank();
209
- logger.info(`Installing ${template} template...`);
210
- logger.step(`Target: ${targetDir}`);
235
+ const isSingleTemplate = templates.length === 1;
236
+ let totalFiles = 0;
237
+ let totalDirectories = 0;
238
+ const allSkills = [];
211
239
  logger.blank();
212
240
  try {
213
- const result = await copyTemplate(template, targetDir);
214
- logger.success(`${result.files} files copied`);
215
- logger.success(`${result.directories} directories created`);
216
- logger.blank();
217
- const availableSkills = await listAvailableSkills(template);
218
- if (availableSkills.length > 0) {
219
- let installSkills = options.skills;
220
- if (installSkills === void 0) {
221
- const response = await prompts({
222
- type: "confirm",
223
- name: "installSkills",
224
- message: `Install Claude Code skills? (${availableSkills.join(", ")})`,
225
- initial: true
226
- });
227
- installSkills = response.installSkills;
228
- }
229
- if (installSkills) {
230
- const existingSkills = await checkExistingSkills(
231
- targetDir,
232
- availableSkills
233
- );
234
- if (existingSkills.length > 0 && !options.force) {
235
- logger.warn("The following skills already exist:");
236
- existingSkills.forEach((s) => logger.step(s));
237
- logger.blank();
238
- const response = await prompts({
239
- type: "confirm",
240
- name: "overwrite",
241
- message: "Overwrite existing skills?",
242
- initial: false
243
- });
244
- if (!response.overwrite) {
245
- logger.info("Skipping skills installation.");
246
- } else {
247
- const skillsResult = await copySkills(
248
- template,
249
- targetDir
250
- );
251
- logger.success(
252
- `Skills installed: ${skillsResult.skills.join(", ")}`
253
- );
254
- logger.step(`Location: .claude/skills/`);
241
+ if (isSingleTemplate) {
242
+ const template = templates[0];
243
+ logger.info(`Installing ${template} template...`);
244
+ logger.step(`Target: ${targetDir}`);
245
+ logger.blank();
246
+ const result = await copySingleTemplate(template, targetDir);
247
+ totalFiles = result.files;
248
+ totalDirectories = result.directories;
249
+ logger.success(`${template}: ${result.files} files copied`);
250
+ const availableSkills = await listAvailableSkills(template);
251
+ allSkills.push(...availableSkills);
252
+ } else {
253
+ logger.info(`Installing ${templates.length} templates...`);
254
+ logger.step(`Target: ${targetDir}/docs/`);
255
+ logger.blank();
256
+ const result = await copyMultipleTemplates(templates, targetDir);
257
+ totalFiles = result.files;
258
+ totalDirectories = result.directories;
259
+ for (const template of templates) {
260
+ logger.success(`${template}: installed to docs/${template}/`);
261
+ const availableSkills = await listAvailableSkills(template);
262
+ for (const skill of availableSkills) {
263
+ if (!allSkills.includes(skill)) {
264
+ allSkills.push(skill);
255
265
  }
256
- } else {
257
- const skillsResult = await copySkills(template, targetDir);
258
- logger.success(`Skills installed: ${skillsResult.skills.join(", ")}`);
259
- logger.step(`Location: .claude/skills/`);
260
266
  }
261
- logger.blank();
262
267
  }
263
268
  }
264
- logger.success("Claude Code documentation installed!");
265
- logger.blank();
266
- logger.info("Next steps:");
267
- logger.step("Read CLAUDE.md for project guidelines");
268
- logger.step("Explore docs/ for detailed documentation");
269
- logger.blank();
270
269
  } catch (error) {
271
270
  logger.error(
272
- `Failed to install template: ${error instanceof Error ? error.message : "Unknown error"}`
271
+ `Failed to install templates: ${error instanceof Error ? error.message : "Unknown error"}`
273
272
  );
274
273
  process.exit(1);
275
274
  }
275
+ logger.blank();
276
+ logger.success(`Total: ${totalFiles} files, ${totalDirectories} directories`);
277
+ if (allSkills.length > 0) {
278
+ let installSkills = options.skills;
279
+ if (installSkills === void 0) {
280
+ logger.blank();
281
+ const response = await prompts({
282
+ type: "confirm",
283
+ name: "installSkills",
284
+ message: `Install Claude Code skills? (${allSkills.join(", ")})`,
285
+ initial: true
286
+ });
287
+ installSkills = response.installSkills;
288
+ }
289
+ if (installSkills) {
290
+ const existingSkills = await checkExistingSkills(targetDir, allSkills);
291
+ if (existingSkills.length > 0 && !options.force) {
292
+ logger.warn("The following skills already exist:");
293
+ existingSkills.forEach((s) => logger.step(s));
294
+ logger.blank();
295
+ const response = await prompts({
296
+ type: "confirm",
297
+ name: "overwrite",
298
+ message: "Overwrite existing skills?",
299
+ initial: false
300
+ });
301
+ if (!response.overwrite) {
302
+ logger.info("Skipping skills installation.");
303
+ } else {
304
+ await installAllSkills(templates, targetDir);
305
+ }
306
+ } else {
307
+ await installAllSkills(templates, targetDir);
308
+ }
309
+ logger.blank();
310
+ }
311
+ }
312
+ logger.success("Claude Code documentation installed!");
313
+ logger.blank();
314
+ logger.info("Installed templates:");
315
+ templates.forEach((t) => logger.step(t));
316
+ logger.blank();
317
+ logger.info("Next steps:");
318
+ logger.step("Read CLAUDE.md for project guidelines");
319
+ logger.step("Explore docs/ for detailed documentation");
320
+ logger.blank();
321
+ };
322
+ var installAllSkills = async (templates, targetDir) => {
323
+ const installedSkills = [];
324
+ for (const template of templates) {
325
+ const skillsResult = await copySkills(template, targetDir);
326
+ for (const skill of skillsResult.skills) {
327
+ if (!installedSkills.includes(skill)) {
328
+ installedSkills.push(skill);
329
+ }
330
+ }
331
+ }
332
+ if (installedSkills.length > 0) {
333
+ logger.success(`Skills installed: ${installedSkills.join(", ")}`);
334
+ logger.step(`Location: .claude/skills/`);
335
+ }
276
336
  };
277
337
 
278
338
  // src/index.ts
279
339
  var program = new Command();
280
340
  program.name("claude-code").description("Claude Code documentation installer for projects").version("1.0.0");
281
- program.option("-t, --template <name>", "template name (tanstack-start, hono)").option("-f, --force", "overwrite existing files without prompting").option("-s, --skills", "install Claude Code skills").option("--no-skills", "skip skills installation").option("--cwd <path>", "target directory (default: current directory)").option("--list", "list available templates").action(async (options) => {
341
+ program.option(
342
+ "-t, --template <names>",
343
+ "template names (comma-separated: tanstack-start,hono)"
344
+ ).option("-f, --force", "overwrite existing files without prompting").option("-s, --skills", "install Claude Code skills").option("--no-skills", "skip skills installation").option("--cwd <path>", "target directory (default: current directory)").option("--list", "list available templates").action(async (options) => {
282
345
  banner();
283
346
  if (options.list) {
284
347
  const templates = await listAvailableTemplates();
@@ -288,7 +351,7 @@ program.option("-t, --template <name>", "template name (tanstack-start, hono)").
288
351
  return;
289
352
  }
290
353
  await init({
291
- template: options.template,
354
+ templates: options.template?.split(",").map((t) => t.trim()),
292
355
  force: options.force,
293
356
  cwd: options.cwd,
294
357
  skills: options.skills
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kood/claude-code",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Claude Code documentation installer for projects",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",
@@ -1,94 +1,176 @@
1
- # MCP 도구 가이드
1
+ # MCP (Model Context Protocol)
2
2
 
3
- > Claude Code에서 사용하는 MCP (Model Context Protocol) 도구
3
+ > Claude Code 작업 효율성을 높이는 MCP 서버 활용 가이드
4
4
 
5
5
  ---
6
6
 
7
- ## 📋 MCP 도구 개요
7
+ ## 프로젝트 시작 전 필수 확인
8
8
 
9
- | 도구 | 용도 | 사용 시점 |
10
- |------|------|----------|
11
- | **sgrep** | 코드 검색 | 코드베이스 검색 시 (grep/rg 대신) |
12
- | **Sequential Thinking** | 복잡한 분석 | 디버깅, 아키텍처 분석 |
13
- | **Context7** | 라이브러리 문서 | 공식 문서 참조 필요 시 |
9
+ **작업 시작 반드시 아래 3가지 MCP가 활성화되어 있는지 확인하세요:**
10
+
11
+ ```
12
+ 1. Serena - 프로젝트 활성화 확인
13
+ mcp__serena__get_current_config 호출
14
+ → 프로젝트 미활성화 시: mcp__serena__activate_project
15
+
16
+ 2. Sequential Thinking - 복잡한 문제 분석용
17
+ → 사용 가능 여부 확인
18
+
19
+ 3. sgrep - 코드베이스 검색용
20
+ → grep/rg 대신 반드시 sgrep 사용
21
+ ```
22
+
23
+ ---
24
+
25
+ ## 🚨 필수 사용 규칙
26
+
27
+ ```
28
+ ✅ 프로젝트 시작 전 → Serena 활성화 확인 (필수!)
29
+ ✅ 코드베이스 검색 → sgrep 사용 (grep/rg 금지)
30
+ ✅ 복잡한 분석/디버깅 → Sequential Thinking 사용
31
+ ✅ 라이브러리 문서 조회 → Context7 사용
32
+ ✅ 세션 컨텍스트 유지 → Serena 메모리 활용
33
+ ✅ 도구 조합: sgrep로 위치 파악 → Sequential로 분석 → Context7로 문서 확인
34
+ ```
14
35
 
15
36
  ---
16
37
 
17
- ## sgrep - 코드 검색
38
+ ## 🚀 Quick Reference
39
+
40
+ ### Serena - 프로젝트 컨텍스트 관리 (필수)
41
+
42
+ ```
43
+ 프로젝트 시작 시 (필수):
44
+ 1. get_current_config → 현재 상태 확인
45
+ 2. activate_project → 프로젝트 활성화
46
+ 3. check_onboarding_performed → 온보딩 확인
47
+
48
+ 사용 시점:
49
+ - 프로젝트 시작/재개 시 (필수)
50
+ - 심볼 탐색/수정
51
+ - 세션 간 컨텍스트 유지 (메모리)
52
+ ```
53
+
54
+ ### Sequential Thinking - 복잡한 문제 해결
55
+
56
+ ```
57
+ 사용 시점:
58
+ - 버그 분석 및 디버깅
59
+ - 아키텍처 설계
60
+ - 복잡한 로직 구현
61
+ - 코드 리팩토링 계획
62
+ - 성능 최적화 분석
63
+
64
+ 사용법: 문제를 단계별로 분해하여 체계적으로 해결
65
+ ```
66
+
67
+ ### sgrep - 코드베이스 검색 (필수)
18
68
 
19
- > ⚠️ **필수**: 코드베이스 검색 시 grep/rg 대신 sgrep 사용
69
+ ```
70
+ 사용 시점:
71
+ - 코드 위치 파악
72
+ - 자연어 검색
73
+ - 심볼 참조 찾기
74
+
75
+ 주의: grep/rg 대신 반드시 sgrep 사용!
76
+ ```
20
77
 
21
- ### 사용 시점
22
- - 코드베이스에서 패턴 검색
23
- - 함수/클래스 사용처 찾기
24
- - 특정 패턴의 코드 찾기
78
+ ### Context7 - 라이브러리 문서 조회
25
79
 
26
- ### 장점
27
- - AST 기반 시맨틱 검색
28
- - 언어별 최적화된 패턴 매칭
29
- - 정확한 코드 구조 인식
80
+ ```
81
+ 사용 시점:
82
+ - API 사용법 확인
83
+ - 라이브러리 최신 문법 확인
84
+ - 공식 문서 기반 구현
85
+ - 버전별 변경사항 확인
86
+
87
+ 사용법:
88
+ 1. resolve-library-id로 라이브러리 ID 조회
89
+ 2. get-library-docs로 문서 가져오기
90
+ ```
30
91
 
31
92
  ---
32
93
 
33
- ## Sequential Thinking - 분석 도구
94
+ ## 📁 문서 구조
34
95
 
35
- > 복잡한 문제를 단계별로 분석
96
+ ```
97
+ docs/mcp/
98
+ ├── index.md # 이 문서 (개요)
99
+ ├── serena.md # Serena 프로젝트 관리 (필수)
100
+ ├── sgrep.md # 코드베이스 검색 (필수)
101
+ ├── sequential-thinking.md # Sequential Thinking 상세 (필수)
102
+ └── context7.md # Context7 상세
103
+ ```
36
104
 
37
- ### 사용 시점
38
- - 복잡한 버그 디버깅
39
- - 아키텍처 분석/설계
40
- - 성능 병목 분석
41
- - 리팩토링 계획 수립
105
+ ---
42
106
 
43
- ### 특징
44
- - 단계별 사고 과정 기록
45
- - 가설 설정 검증
46
- - 체계적인 문제 해결
107
+ ## 📋 도구 목록
108
+
109
+ | 도구 | 용도 | 필수 여부 |
110
+ |-----|------|----------|
111
+ | [Serena](./serena.md) | 프로젝트 컨텍스트 관리 | ⭐ 필수 |
112
+ | [sgrep](./sgrep.md) | 코드베이스 검색 | ⭐ 필수 |
113
+ | [Sequential Thinking](./sequential-thinking.md) | 체계적 문제 해결 | ⭐ 필수 |
114
+ | [Context7](./context7.md) | 라이브러리 문서 | 권장 |
47
115
 
48
116
  ---
49
117
 
50
- ## Context7 - 라이브러리 문서
118
+ ## 작업별 MCP 선택 가이드
51
119
 
52
- > 공식 라이브러리 문서 조회
120
+ ### 프로젝트 시작 (필수)
121
+ ```
122
+ 1. Serena: get_current_config로 상태 확인
123
+ 2. Serena: activate_project로 프로젝트 활성화
124
+ 3. Serena: list_memories로 이전 컨텍스트 확인
125
+ ```
53
126
 
54
- ### 사용 시점
55
- - 라이브러리 API 확인
56
- - 공식 문서 패턴 참조
57
- - 최신 버전 사용법 확인
127
+ ### 버그 수정
128
+ ```
129
+ 1. sgrep로 관련 코드 위치 파악
130
+ 2. Sequential Thinking으로 문제 분석
131
+ 3. 원인 파악 후 Context7로 관련 API 확인
132
+ 4. 수정 구현
133
+ ```
58
134
 
59
- ### 지원 라이브러리
60
- - Hono
61
- - Zod
62
- - Prisma
63
- - 기타 주요 라이브러리
135
+ ### 기능 구현
136
+ ```
137
+ 1. sgrep로 기존 패턴 검색
138
+ 2. Sequential Thinking으로 구현 계획 수립
139
+ 3. Context7로 사용할 라이브러리 문서 확인
140
+ 4. 단계별 구현
141
+ 5. Serena: write_memory로 주요 결정 저장
142
+ ```
64
143
 
65
- ### 사용 예시
144
+ ### 라이브러리 사용
66
145
  ```
67
- Context7로 Hono middleware 문서 조회
68
- Context7로 Zod v4 validation 문서 조회
69
- Context7로 Prisma transaction 문서 조회
146
+ 1. Context7로 공식 문서 조회
147
+ 2. 필요시 Sequential Thinking으로 복잡한 통합 분석
70
148
  ```
71
149
 
72
- ---
150
+ ### 성능 최적화
151
+ ```
152
+ 1. sgrep로 병목 의심 코드 검색
153
+ 2. Sequential Thinking으로 병목 분석
154
+ 3. Context7로 최적화 관련 API 확인
155
+ 4. 개선 구현
156
+ ```
73
157
 
74
- ## MCP 도구 선택 가이드
158
+ ### 코드베이스 탐색
159
+ ```
160
+ 1. sgrep로 자연어 쿼리 검색
161
+ 2. 관련 코드 위치 파악
162
+ 3. 필요시 Sequential Thinking으로 흐름 분석
163
+ ```
75
164
 
165
+ ### 세션 종료
76
166
  ```
77
- 코드 검색이 필요한가?
78
- ├─ Yes sgrep 사용
79
- └─ No
80
- ├─ 복잡한 분석이 필요한가?
81
- │ ├─ Yes → Sequential Thinking 사용
82
- │ └─ No
83
- │ └─ 라이브러리 문서가 필요한가?
84
- │ ├─ Yes → Context7 사용
85
- │ └─ No → 일반 도구 사용
167
+ 1. Serena: write_memory로 진행 상황 저장
168
+ 2. 다음 세션에서 read_memory로 복구
86
169
  ```
87
170
 
88
171
  ---
89
172
 
90
- ## 관련 문서
173
+ ## 🔗 관련 문서
91
174
 
92
- - [sgrep 상세](./sgrep.md)
93
- - [Sequential Thinking 상세](./sequential-thinking.md)
94
- - [Context7 상세](./context7.md)
175
+ - [Hono](../library/hono/index.md) - Web Framework
176
+ - [Zod](../library/zod/index.md) - Validation
@@ -0,0 +1,269 @@
1
+ # Serena MCP Server
2
+
3
+ > **Purpose**: 시맨틱 코드 이해, 프로젝트 메모리, 세션 지속성을 위한 MCP 서버
4
+
5
+ ---
6
+
7
+ ## 프로젝트 시작 전 필수 확인
8
+
9
+ 프로젝트 작업을 시작하기 전에 **반드시** Serena가 활성화되어 있는지 확인해야 합니다.
10
+
11
+ ### 1. 현재 설정 확인
12
+
13
+ ```
14
+ mcp__serena__get_current_config
15
+ ```
16
+
17
+ **확인 사항:**
18
+ - `Active project`: 현재 작업할 프로젝트명이 표시되는지 확인
19
+ - 프로젝트가 `Available projects` 목록에 있는지 확인
20
+
21
+ ### 2. 프로젝트 활성화
22
+
23
+ 프로젝트가 활성화되지 않은 경우:
24
+
25
+ ```
26
+ mcp__serena__activate_project({ project: "프로젝트명" })
27
+ ```
28
+
29
+ ### 3. 온보딩 확인
30
+
31
+ 새 프로젝트의 경우 온보딩이 필요할 수 있습니다:
32
+
33
+ ```
34
+ mcp__serena__check_onboarding_performed
35
+ ```
36
+
37
+ 온보딩이 필요한 경우:
38
+
39
+ ```
40
+ mcp__serena__onboarding
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 핵심 기능
46
+
47
+ ### 심볼 탐색 (Symbol Navigation)
48
+
49
+ 파일 내 심볼(클래스, 함수, 변수 등) 개요 확인:
50
+
51
+ ```
52
+ mcp__serena__get_symbols_overview({ relative_path: "src/index.ts" })
53
+ ```
54
+
55
+ 특정 심볼 검색:
56
+
57
+ ```
58
+ mcp__serena__find_symbol({
59
+ name_path_pattern: "MyClass/myMethod",
60
+ include_body: true,
61
+ depth: 1
62
+ })
63
+ ```
64
+
65
+ 심볼 참조 찾기:
66
+
67
+ ```
68
+ mcp__serena__find_referencing_symbols({
69
+ name_path: "MyClass",
70
+ relative_path: "src/my-class.ts"
71
+ })
72
+ ```
73
+
74
+ ### 코드 수정 (Code Modification)
75
+
76
+ 심볼 본문 교체:
77
+
78
+ ```
79
+ mcp__serena__replace_symbol_body({
80
+ name_path: "MyClass/myMethod",
81
+ relative_path: "src/my-class.ts",
82
+ body: "새로운 코드 본문"
83
+ })
84
+ ```
85
+
86
+ 심볼 뒤에 코드 삽입:
87
+
88
+ ```
89
+ mcp__serena__insert_after_symbol({
90
+ name_path: "MyClass",
91
+ relative_path: "src/my-class.ts",
92
+ body: "\n\nexport const newFunction = () => {}"
93
+ })
94
+ ```
95
+
96
+ 심볼 앞에 코드 삽입:
97
+
98
+ ```
99
+ mcp__serena__insert_before_symbol({
100
+ name_path: "MyClass",
101
+ relative_path: "src/my-class.ts",
102
+ body: "import { Something } from './something'\n\n"
103
+ })
104
+ ```
105
+
106
+ 심볼 이름 변경 (전체 코드베이스):
107
+
108
+ ```
109
+ mcp__serena__rename_symbol({
110
+ name_path: "oldFunctionName",
111
+ relative_path: "src/utils.ts",
112
+ new_name: "newFunctionName"
113
+ })
114
+ ```
115
+
116
+ ### 파일 탐색 (File Navigation)
117
+
118
+ 디렉토리 목록:
119
+
120
+ ```
121
+ mcp__serena__list_dir({
122
+ relative_path: "src",
123
+ recursive: false
124
+ })
125
+ ```
126
+
127
+ 파일 검색:
128
+
129
+ ```
130
+ mcp__serena__find_file({
131
+ file_mask: "*.ts",
132
+ relative_path: "src"
133
+ })
134
+ ```
135
+
136
+ 패턴 검색:
137
+
138
+ ```
139
+ mcp__serena__search_for_pattern({
140
+ substring_pattern: "createServerFn",
141
+ relative_path: "src/services",
142
+ context_lines_before: 2,
143
+ context_lines_after: 2
144
+ })
145
+ ```
146
+
147
+ ### 메모리 관리 (Memory Management)
148
+
149
+ 프로젝트 관련 정보를 메모리에 저장하여 세션 간 유지:
150
+
151
+ 메모리 목록 확인:
152
+
153
+ ```
154
+ mcp__serena__list_memories
155
+ ```
156
+
157
+ 메모리 읽기:
158
+
159
+ ```
160
+ mcp__serena__read_memory({ memory_file_name: "architecture.md" })
161
+ ```
162
+
163
+ 메모리 작성:
164
+
165
+ ```
166
+ mcp__serena__write_memory({
167
+ memory_file_name: "decisions.md",
168
+ content: "# 주요 결정 사항\n\n- API 설계: REST 대신 Server Functions 사용"
169
+ })
170
+ ```
171
+
172
+ 메모리 수정:
173
+
174
+ ```
175
+ mcp__serena__edit_memory({
176
+ memory_file_name: "decisions.md",
177
+ needle: "REST 대신",
178
+ repl: "REST API 대신",
179
+ mode: "literal"
180
+ })
181
+ ```
182
+
183
+ 메모리 삭제:
184
+
185
+ ```
186
+ mcp__serena__delete_memory({ memory_file_name: "outdated.md" })
187
+ ```
188
+
189
+ ### 사고 도구 (Thinking Tools)
190
+
191
+ 수집된 정보 검토:
192
+
193
+ ```
194
+ mcp__serena__think_about_collected_information
195
+ ```
196
+
197
+ 작업 목표 준수 확인:
198
+
199
+ ```
200
+ mcp__serena__think_about_task_adherence
201
+ ```
202
+
203
+ 작업 완료 여부 확인:
204
+
205
+ ```
206
+ mcp__serena__think_about_whether_you_are_done
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 사용 시나리오
212
+
213
+ ### 시나리오 1: 새 프로젝트 시작
214
+
215
+ ```
216
+ 1. get_current_config → 현재 상태 확인
217
+ 2. activate_project → 프로젝트 활성화
218
+ 3. check_onboarding_performed → 온보딩 필요 여부 확인
219
+ 4. onboarding → 필요시 온보딩 진행
220
+ 5. list_memories → 기존 메모리 확인
221
+ ```
222
+
223
+ ### 시나리오 2: 기존 프로젝트 재개
224
+
225
+ ```
226
+ 1. get_current_config → 프로젝트 활성화 확인
227
+ 2. list_memories → 이전 세션 컨텍스트 확인
228
+ 3. read_memory → 필요한 메모리 읽기
229
+ 4. 작업 진행
230
+ 5. write_memory → 중요 결정/진행 상황 저장
231
+ ```
232
+
233
+ ### 시나리오 3: 대규모 리팩토링
234
+
235
+ ```
236
+ 1. get_symbols_overview → 파일 구조 파악
237
+ 2. find_symbol → 수정할 심볼 찾기
238
+ 3. find_referencing_symbols → 영향받는 코드 확인
239
+ 4. replace_symbol_body → 심볼 수정
240
+ 5. rename_symbol → 필요시 이름 변경
241
+ 6. think_about_whether_you_are_done → 완료 확인
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Best Practices
247
+
248
+ ### 1. 항상 프로젝트 활성화 확인
249
+
250
+ 작업 시작 전 `get_current_config`로 올바른 프로젝트가 활성화되어 있는지 확인하세요.
251
+
252
+ ### 2. 심볼 도구 우선 사용
253
+
254
+ 전체 파일을 읽지 말고, `get_symbols_overview`와 `find_symbol`을 사용하여 필요한 부분만 확인하세요.
255
+
256
+ ### 3. 메모리 적극 활용
257
+
258
+ 중요한 결정, 아키텍처 정보, 작업 진행 상황을 메모리에 저장하여 세션 간 컨텍스트를 유지하세요.
259
+
260
+ ### 4. 사고 도구 활용
261
+
262
+ 복잡한 작업 중에는 `think_about_*` 도구를 사용하여 진행 상황을 검토하세요.
263
+
264
+ ---
265
+
266
+ ## 참고 자료
267
+
268
+ - [Serena GitHub](https://github.com/oraios/serena)
269
+ - [MCP Protocol](https://modelcontextprotocol.io)
@@ -4,12 +4,32 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## ⛔ 프로젝트 시작 전 필수 확인
8
+
9
+ **작업 시작 전 반드시 아래 3가지 MCP가 활성화되어 있는지 확인하세요:**
10
+
11
+ ```
12
+ 1. Serena - 프로젝트 활성화 확인
13
+ → mcp__serena__get_current_config 호출
14
+ → 프로젝트 미활성화 시: mcp__serena__activate_project
15
+
16
+ 2. Sequential Thinking - 복잡한 문제 분석용
17
+ → 사용 가능 여부 확인
18
+
19
+ 3. sgrep - 코드베이스 검색용
20
+ → grep/rg 대신 반드시 sgrep 사용
21
+ ```
22
+
23
+ ---
24
+
7
25
  ## 🚨 필수 사용 규칙
8
26
 
9
27
  ```
28
+ ✅ 프로젝트 시작 전 → Serena 활성화 확인 (필수!)
10
29
  ✅ 코드베이스 검색 → sgrep 사용 (grep/rg 금지)
11
30
  ✅ 복잡한 분석/디버깅 → Sequential Thinking 사용
12
31
  ✅ 라이브러리 문서 조회 → Context7 사용
32
+ ✅ 세션 컨텍스트 유지 → Serena 메모리 활용
13
33
  ✅ 도구 조합: sgrep로 위치 파악 → Sequential로 분석 → Context7로 문서 확인
14
34
  ```
15
35
 
@@ -17,6 +37,20 @@
17
37
 
18
38
  ## 🚀 Quick Reference
19
39
 
40
+ ### Serena - 프로젝트 컨텍스트 관리 (필수)
41
+
42
+ ```
43
+ 프로젝트 시작 시 (필수):
44
+ 1. get_current_config → 현재 상태 확인
45
+ 2. activate_project → 프로젝트 활성화
46
+ 3. check_onboarding_performed → 온보딩 확인
47
+
48
+ 사용 시점:
49
+ - 프로젝트 시작/재개 시 (필수)
50
+ - 심볼 탐색/수정
51
+ - 세션 간 컨텍스트 유지 (메모리)
52
+ ```
53
+
20
54
  ### Sequential Thinking - 복잡한 문제 해결
21
55
 
22
56
  ```
@@ -30,6 +64,17 @@
30
64
  사용법: 문제를 단계별로 분해하여 체계적으로 해결
31
65
  ```
32
66
 
67
+ ### sgrep - 코드베이스 검색 (필수)
68
+
69
+ ```
70
+ 사용 시점:
71
+ - 코드 위치 파악
72
+ - 자연어 검색
73
+ - 심볼 참조 찾기
74
+
75
+ 주의: grep/rg 대신 반드시 sgrep 사용!
76
+ ```
77
+
33
78
  ### Context7 - 라이브러리 문서 조회
34
79
 
35
80
  ```
@@ -51,8 +96,9 @@
51
96
  ```
52
97
  docs/mcp/
53
98
  ├── index.md # 이 문서 (개요)
54
- ├── sgrep.md # 코드베이스 검색
55
- ├── sequential-thinking.md # Sequential Thinking 상세
99
+ ├── serena.md # Serena 프로젝트 관리 (필수)
100
+ ├── sgrep.md # 코드베이스 검색 (필수)
101
+ ├── sequential-thinking.md # Sequential Thinking 상세 (필수)
56
102
  └── context7.md # Context7 상세
57
103
  ```
58
104
 
@@ -60,16 +106,24 @@ docs/mcp/
60
106
 
61
107
  ## 📋 도구 목록
62
108
 
63
- | 도구 | 용도 | 사용 시점 |
109
+ | 도구 | 용도 | 필수 여부 |
64
110
  |-----|------|----------|
65
- | [sgrep](./sgrep.md) | 코드베이스 검색 | 코드 위치 파악, 자연어 검색 |
66
- | [Sequential Thinking](./sequential-thinking.md) | 체계적 문제 해결 | 복잡한 분석, 디버깅, 설계 |
67
- | [Context7](./context7.md) | 라이브러리 문서 | API 확인, 최신 문법 |
111
+ | [Serena](./serena.md) | 프로젝트 컨텍스트 관리 | 필수 |
112
+ | [sgrep](./sgrep.md) | 코드베이스 검색 | 필수 |
113
+ | [Sequential Thinking](./sequential-thinking.md) | 체계적 문제 해결 | 필수 |
114
+ | [Context7](./context7.md) | 라이브러리 문서 | 권장 |
68
115
 
69
116
  ---
70
117
 
71
118
  ## ⚡ 작업별 MCP 선택 가이드
72
119
 
120
+ ### 프로젝트 시작 (필수)
121
+ ```
122
+ 1. Serena: get_current_config로 상태 확인
123
+ 2. Serena: activate_project로 프로젝트 활성화
124
+ 3. Serena: list_memories로 이전 컨텍스트 확인
125
+ ```
126
+
73
127
  ### 버그 수정
74
128
  ```
75
129
  1. sgrep로 관련 코드 위치 파악
@@ -84,6 +138,7 @@ docs/mcp/
84
138
  2. Sequential Thinking으로 구현 계획 수립
85
139
  3. Context7로 사용할 라이브러리 문서 확인
86
140
  4. 단계별 구현
141
+ 5. Serena: write_memory로 주요 결정 저장
87
142
  ```
88
143
 
89
144
  ### 라이브러리 사용
@@ -107,6 +162,12 @@ docs/mcp/
107
162
  3. 필요시 Sequential Thinking으로 흐름 분석
108
163
  ```
109
164
 
165
+ ### 세션 종료
166
+ ```
167
+ 1. Serena: write_memory로 진행 상황 저장
168
+ 2. 다음 세션에서 read_memory로 복구
169
+ ```
170
+
110
171
  ---
111
172
 
112
173
  ## 🔗 관련 문서
@@ -0,0 +1,269 @@
1
+ # Serena MCP Server
2
+
3
+ > **Purpose**: 시맨틱 코드 이해, 프로젝트 메모리, 세션 지속성을 위한 MCP 서버
4
+
5
+ ---
6
+
7
+ ## 프로젝트 시작 전 필수 확인
8
+
9
+ 프로젝트 작업을 시작하기 전에 **반드시** Serena가 활성화되어 있는지 확인해야 합니다.
10
+
11
+ ### 1. 현재 설정 확인
12
+
13
+ ```
14
+ mcp__serena__get_current_config
15
+ ```
16
+
17
+ **확인 사항:**
18
+ - `Active project`: 현재 작업할 프로젝트명이 표시되는지 확인
19
+ - 프로젝트가 `Available projects` 목록에 있는지 확인
20
+
21
+ ### 2. 프로젝트 활성화
22
+
23
+ 프로젝트가 활성화되지 않은 경우:
24
+
25
+ ```
26
+ mcp__serena__activate_project({ project: "프로젝트명" })
27
+ ```
28
+
29
+ ### 3. 온보딩 확인
30
+
31
+ 새 프로젝트의 경우 온보딩이 필요할 수 있습니다:
32
+
33
+ ```
34
+ mcp__serena__check_onboarding_performed
35
+ ```
36
+
37
+ 온보딩이 필요한 경우:
38
+
39
+ ```
40
+ mcp__serena__onboarding
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 핵심 기능
46
+
47
+ ### 심볼 탐색 (Symbol Navigation)
48
+
49
+ 파일 내 심볼(클래스, 함수, 변수 등) 개요 확인:
50
+
51
+ ```
52
+ mcp__serena__get_symbols_overview({ relative_path: "src/index.ts" })
53
+ ```
54
+
55
+ 특정 심볼 검색:
56
+
57
+ ```
58
+ mcp__serena__find_symbol({
59
+ name_path_pattern: "MyClass/myMethod",
60
+ include_body: true,
61
+ depth: 1
62
+ })
63
+ ```
64
+
65
+ 심볼 참조 찾기:
66
+
67
+ ```
68
+ mcp__serena__find_referencing_symbols({
69
+ name_path: "MyClass",
70
+ relative_path: "src/my-class.ts"
71
+ })
72
+ ```
73
+
74
+ ### 코드 수정 (Code Modification)
75
+
76
+ 심볼 본문 교체:
77
+
78
+ ```
79
+ mcp__serena__replace_symbol_body({
80
+ name_path: "MyClass/myMethod",
81
+ relative_path: "src/my-class.ts",
82
+ body: "새로운 코드 본문"
83
+ })
84
+ ```
85
+
86
+ 심볼 뒤에 코드 삽입:
87
+
88
+ ```
89
+ mcp__serena__insert_after_symbol({
90
+ name_path: "MyClass",
91
+ relative_path: "src/my-class.ts",
92
+ body: "\n\nexport const newFunction = () => {}"
93
+ })
94
+ ```
95
+
96
+ 심볼 앞에 코드 삽입:
97
+
98
+ ```
99
+ mcp__serena__insert_before_symbol({
100
+ name_path: "MyClass",
101
+ relative_path: "src/my-class.ts",
102
+ body: "import { Something } from './something'\n\n"
103
+ })
104
+ ```
105
+
106
+ 심볼 이름 변경 (전체 코드베이스):
107
+
108
+ ```
109
+ mcp__serena__rename_symbol({
110
+ name_path: "oldFunctionName",
111
+ relative_path: "src/utils.ts",
112
+ new_name: "newFunctionName"
113
+ })
114
+ ```
115
+
116
+ ### 파일 탐색 (File Navigation)
117
+
118
+ 디렉토리 목록:
119
+
120
+ ```
121
+ mcp__serena__list_dir({
122
+ relative_path: "src",
123
+ recursive: false
124
+ })
125
+ ```
126
+
127
+ 파일 검색:
128
+
129
+ ```
130
+ mcp__serena__find_file({
131
+ file_mask: "*.ts",
132
+ relative_path: "src"
133
+ })
134
+ ```
135
+
136
+ 패턴 검색:
137
+
138
+ ```
139
+ mcp__serena__search_for_pattern({
140
+ substring_pattern: "createServerFn",
141
+ relative_path: "src/services",
142
+ context_lines_before: 2,
143
+ context_lines_after: 2
144
+ })
145
+ ```
146
+
147
+ ### 메모리 관리 (Memory Management)
148
+
149
+ 프로젝트 관련 정보를 메모리에 저장하여 세션 간 유지:
150
+
151
+ 메모리 목록 확인:
152
+
153
+ ```
154
+ mcp__serena__list_memories
155
+ ```
156
+
157
+ 메모리 읽기:
158
+
159
+ ```
160
+ mcp__serena__read_memory({ memory_file_name: "architecture.md" })
161
+ ```
162
+
163
+ 메모리 작성:
164
+
165
+ ```
166
+ mcp__serena__write_memory({
167
+ memory_file_name: "decisions.md",
168
+ content: "# 주요 결정 사항\n\n- API 설계: REST 대신 Server Functions 사용"
169
+ })
170
+ ```
171
+
172
+ 메모리 수정:
173
+
174
+ ```
175
+ mcp__serena__edit_memory({
176
+ memory_file_name: "decisions.md",
177
+ needle: "REST 대신",
178
+ repl: "REST API 대신",
179
+ mode: "literal"
180
+ })
181
+ ```
182
+
183
+ 메모리 삭제:
184
+
185
+ ```
186
+ mcp__serena__delete_memory({ memory_file_name: "outdated.md" })
187
+ ```
188
+
189
+ ### 사고 도구 (Thinking Tools)
190
+
191
+ 수집된 정보 검토:
192
+
193
+ ```
194
+ mcp__serena__think_about_collected_information
195
+ ```
196
+
197
+ 작업 목표 준수 확인:
198
+
199
+ ```
200
+ mcp__serena__think_about_task_adherence
201
+ ```
202
+
203
+ 작업 완료 여부 확인:
204
+
205
+ ```
206
+ mcp__serena__think_about_whether_you_are_done
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 사용 시나리오
212
+
213
+ ### 시나리오 1: 새 프로젝트 시작
214
+
215
+ ```
216
+ 1. get_current_config → 현재 상태 확인
217
+ 2. activate_project → 프로젝트 활성화
218
+ 3. check_onboarding_performed → 온보딩 필요 여부 확인
219
+ 4. onboarding → 필요시 온보딩 진행
220
+ 5. list_memories → 기존 메모리 확인
221
+ ```
222
+
223
+ ### 시나리오 2: 기존 프로젝트 재개
224
+
225
+ ```
226
+ 1. get_current_config → 프로젝트 활성화 확인
227
+ 2. list_memories → 이전 세션 컨텍스트 확인
228
+ 3. read_memory → 필요한 메모리 읽기
229
+ 4. 작업 진행
230
+ 5. write_memory → 중요 결정/진행 상황 저장
231
+ ```
232
+
233
+ ### 시나리오 3: 대규모 리팩토링
234
+
235
+ ```
236
+ 1. get_symbols_overview → 파일 구조 파악
237
+ 2. find_symbol → 수정할 심볼 찾기
238
+ 3. find_referencing_symbols → 영향받는 코드 확인
239
+ 4. replace_symbol_body → 심볼 수정
240
+ 5. rename_symbol → 필요시 이름 변경
241
+ 6. think_about_whether_you_are_done → 완료 확인
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Best Practices
247
+
248
+ ### 1. 항상 프로젝트 활성화 확인
249
+
250
+ 작업 시작 전 `get_current_config`로 올바른 프로젝트가 활성화되어 있는지 확인하세요.
251
+
252
+ ### 2. 심볼 도구 우선 사용
253
+
254
+ 전체 파일을 읽지 말고, `get_symbols_overview`와 `find_symbol`을 사용하여 필요한 부분만 확인하세요.
255
+
256
+ ### 3. 메모리 적극 활용
257
+
258
+ 중요한 결정, 아키텍처 정보, 작업 진행 상황을 메모리에 저장하여 세션 간 컨텍스트를 유지하세요.
259
+
260
+ ### 4. 사고 도구 활용
261
+
262
+ 복잡한 작업 중에는 `think_about_*` 도구를 사용하여 진행 상황을 검토하세요.
263
+
264
+ ---
265
+
266
+ ## 참고 자료
267
+
268
+ - [Serena GitHub](https://github.com/oraios/serena)
269
+ - [MCP Protocol](https://modelcontextprotocol.io)