Skip to main content
Glama
cli-options-refactor-plan-2025-11-13.md30 kB
# Memory MCP CLI 구조 리팩토링 계획 **작성일**: 2025-11-13 **대상**: `/packages/mcp-server/src/cli.ts` **목적**: MCP 서버로 사용 시 서브커맨드 없이 직접 옵션을 받을 수 있도록 개선 --- ## Executive Summary ### 핵심 문제 현재 memory-mcp CLI는 Commander.js의 서브커맨드 패턴(`server`, `healthcheck`, `version`)을 사용하고 있으며, `--vault`, `--index` 등의 옵션이 `server` 서브커맨드에만 정의되어 있습니다. Claude Desktop과 같은 MCP 클라이언트는 서브커맨드 없이 직접 `node cli.js --vault ... --index ...` 형태로 실행하기 때문에, 현재 구조에서는 `error: unknown option '--vault'` 에러가 발생합니다. ### 권장 솔루션 **옵션 B: 서브커맨드를 선택적으로 (기본 동작 = server)** Commander.js의 기능을 활용하여: 1. 루트 레벨에서 서버 옵션을 직접 받을 수 있도록 설정 2. 서브커맨드가 없으면 자동으로 서버 시작 (기본 동작) 3. 기존 `server`, `healthcheck`, `version` 서브커맨드는 명시적으로 호출 가능하도록 유지 (하위 호환성) ### 예상 효과 - ✅ Claude Desktop 호환: `node cli.js --vault ~/vault --index ~/.index.db` 직접 실행 가능 - ✅ 하위 호환성 유지: 기존 `memory-mcp server --vault ...` 방식도 계속 작동 - ✅ MCP 표준 준수: 다른 MCP 서버들의 일반적인 패턴과 일치 - ✅ 직관적 사용성: 서브커맨드 없이 바로 서버 시작 가능 --- ## 1. 현재 상태 분석 ### 1.1 CLI 구조 (cli.ts) ```typescript // 현재 구조 program .name("memory-mcp") .version(PACKAGE_VERSION); program .command("server") // 서브커맨드 .option("--vault <path>", "볼트 디렉토리 경로", "./vault") .option("--index <path>", "인덱스 데이터베이스 경로", "./.memory-index.db") // ... 기타 옵션들 .action(async (options) => { await startServer(serverOptions); }); program .action(async () => { // 기본 명령: 옵션 없이 서버 시작 await startServer(); }); ``` ### 1.2 문제점 #### 문제 1: 옵션이 서브커맨드에 종속 - `--vault`, `--index` 등이 `server` 서브커맨드 아래에만 정의됨 - 루트 레벨에서 이 옵션들을 인식하지 못함 #### 문제 2: Claude Desktop의 실행 방식과 불일치 ```json // Claude Desktop 설정 (USAGE_GUIDE.md 참조) { "mcpServers": { "memory-mcp": { "command": "node", "args": [ "/path/to/cli.js", "--vault", // ❌ 루트 레벨에서 인식 불가 "/Users/.../vault", "--index", // ❌ 루트 레벨에서 인식 불가 "/Users/.../.memory-mcp/index.db" ] } } } ``` #### 문제 3: 기본 action의 한계 - 현재 루트 레벨 `.action()`은 인자 없이 `startServer()`만 호출 - 옵션을 파싱하지 못하므로 기본값만 사용 - 사용자가 원하는 vault/index 경로를 지정할 방법이 없음 ### 1.3 타 MCP 서버 CLI 패턴 조사 웹 검색 결과를 바탕으로 일반적인 MCP 서버 CLI 패턴: #### 패턴 A: 플랫한 구조 (추천) ```bash # FastMCP 스타일 npx fastmcp run server.py --option value # 대부분의 MCP 서버 npx some-mcp-server --config /path/to/config ``` #### 패턴 B: 서브커맨드 선택적 사용 ```bash # 기본 동작 (서브커맨드 생략) npx tool --option value # 명시적 서브커맨드 npx tool server --option value npx tool healthcheck ``` **결론**: 대부분의 MCP 서버는 **서브커맨드 없이 직접 실행 가능**하며, 추가 기능(healthcheck, version 등)만 서브커맨드로 분리합니다. --- ## 2. 권장 솔루션 (옵션 B) ### 2.1 설계 개요 **핵심 아이디어**: Commander.js의 기능을 활용하여 루트 레벨에 옵션을 정의하고, 서브커맨드가 없으면 자동으로 서버 시작 ```typescript // 새로운 구조 program .name("memory-mcp") .version(PACKAGE_VERSION) .description("Memory MCP Server - 로컬 퍼시스턴트 메모리를 MCP 서버로 노출") // ✅ 루트 레벨에 옵션 정의 .option("--verbose", "상세 로그 출력", false) .option("--vault <path>", "볼트 디렉토리 경로", "./vault") .option("--index <path>", "인덱스 데이터베이스 경로", "./.memory-index.db") .option("--mode <mode>", "동작 모드 (dev|prod)", "dev") .option("--timeout <ms>", "툴 실행 타임아웃 (ms)", parseInteger(value, 5_000), 5_000) .option("--retries <count>", "툴 실행 재시도 횟수", parseInteger(value, 2), 2) .action(async (options) => { // ✅ 루트 레벨 기본 action: 서버 시작 await startServerWithOptions(options); }); // ✅ 하위 호환성: 명시적 server 서브커맨드 유지 program .command("server") .description("MCP 서버 시작 (JSON-RPC 2.0 stdin/stdout)") .action(async () => { // 부모 옵션 상속 const opts = program.opts(); await startServerWithOptions(opts); }); // ✅ 기타 유틸리티 서브커맨드 유지 program .command("healthcheck") .description("시스템 상태 확인") .action(async () => { const opts = program.opts(); await runHealthcheck(opts); }); program .command("version") .description("버전 정보 출력") .action(() => { printVersionInfo(); }); ``` ### 2.2 주요 변경 사항 #### 변경 1: 옵션을 루트 레벨로 이동 - `--vault`, `--index`, `--verbose` 등 모든 서버 옵션을 `.option()`으로 루트에 정의 - 서브커맨드에서는 옵션 재정의 불필요 (부모로부터 상속) #### 변경 2: 루트 action에서 서버 시작 - 서브커맨드 없이 실행 시 루트 `.action()` 호출 - 옵션을 파싱하여 서버 시작 #### 변경 3: `server` 서브커맨드는 별칭으로 유지 - 명시적으로 `memory-mcp server` 호출 가능 (하위 호환성) - 내부적으로 부모 옵션을 참조하여 동일하게 서버 시작 ### 2.3 실행 예시 ```bash # ✅ 방법 1: 직접 실행 (새로운 방식, Claude Desktop 호환) node cli.js --vault ~/vault --index ~/.index.db # ✅ 방법 2: 명시적 서브커맨드 (기존 방식, 하위 호환) node cli.js server --vault ~/vault --index ~/.index.db # ✅ 방법 3: npx 사용 npx memory-mcp --vault ~/vault # ✅ 방법 4: 서브커맨드 명시 npx memory-mcp server --vault ~/vault # ✅ 헬스체크 (서브커맨드) node cli.js healthcheck --vault ~/vault # ✅ 버전 정보 node cli.js version node cli.js --version ``` ### 2.4 Claude Desktop 설정 ```json { "mcpServers": { "memory-mcp": { "command": "node", "args": [ "/Users/inchan/workspace/pilot/memory-mcp/packages/mcp-server/dist/cli.js", "--vault", "/Users/inchan/Documents/vault", "--index", "/Users/inchan/.memory-mcp/index.db", "--mode", "prod" ] } } } ``` **주의**: 서브커맨드 `server`를 제거하고 옵션만 전달 --- ## 3. 구현 계획 ### Phase 1: 옵션 리팩토링 (30분) #### Task 1.1: 루트 레벨 옵션 정의 **파일**: `packages/mcp-server/src/cli.ts` ```typescript program .name("memory-mcp") .description("Memory MCP Server - 로컬 퍼시스턴트 메모리를 MCP 서버로 노출") .version(PACKAGE_VERSION) // 서버 옵션을 루트 레벨로 이동 .option("--verbose", "상세 로그 출력", false) .option("--vault <path>", "볼트 디렉토리 경로", "./vault") .option("--index <path>", "인덱스 데이터베이스 경로", "./.memory-index.db") .option("--mode <mode>", "동작 모드 (dev|prod)", "dev") .option( "--timeout <ms>", "툴 실행 타임아웃 (ms)", (value) => parseInteger(value, 5_000), 5_000 ) .option( "--retries <count>", "툴 실행 재시도 횟수", (value) => parseInteger(value, 2), 2 ); ``` #### Task 1.2: 루트 action 구현 ```typescript /** * 루트 레벨 기본 action: 옵션으로 서버 시작 */ program.action(async (options) => { if (options.verbose) { logger.setLevel("debug"); } const serverOptions: MemoryMcpServerOptions = { vaultPath: options.vault, indexPath: options.index, mode: options.mode, policy: { timeoutMs: options.timeout, maxRetries: options.retries, }, }; logger.info("Memory MCP Server 시작 중...", serverOptions); try { await startServer(serverOptions); } catch (error) { logger.error("서버 시작 실패:", error); process.exit(1); } }); ``` ### Phase 2: 서브커맨드 단순화 (20분) #### Task 2.1: `server` 서브커맨드 별칭화 ```typescript /** * server 서브커맨드: 하위 호환성을 위한 별칭 */ program .command("server") .description("MCP 서버 시작 (JSON-RPC 2.0 stdin/stdout) - 별칭, 생략 가능") .action(async () => { // 부모 옵션 상속 const opts = program.opts(); if (opts.verbose) { logger.setLevel("debug"); } const serverOptions: MemoryMcpServerOptions = { vaultPath: opts.vault, indexPath: opts.index, mode: opts.mode, policy: { timeoutMs: opts.timeout, maxRetries: opts.retries, }, }; logger.info("Memory MCP Server 시작 중 (server 커맨드)...", serverOptions); try { await startServer(serverOptions); } catch (error) { logger.error("서버 시작 실패:", error); process.exit(1); } }); ``` **중요**: 서브커맨드에서 옵션을 재정의하지 않고, 부모 옵션을 `program.opts()`로 상속 #### Task 2.2: `healthcheck` 서브커맨드 간소화 ```typescript /** * 헬스체크 명령 */ program .command("healthcheck") .description("시스템 상태 확인") .action(async () => { const opts = program.opts(); logger.info("시스템 헬스체크 중..."); // TODO: 실제 헬스체크 로직 구현 console.log("✅ Memory MCP Server 상태: 정상"); console.log(`✅ 볼트 경로: ${opts.vault}`); console.log(`✅ 인덱스 경로: ${opts.index}`); console.log("✅ 의존성: 모두 로드됨"); logger.info("헬스체크 완료"); }); ``` **주의**: healthcheck도 vault/index 경로가 필요하므로 부모 옵션 사용 #### Task 2.3: `version` 서브커맨드는 유지 ```typescript /** * 버전 정보 명령 */ program .command("version") .description("버전 정보 출력") .action(() => { console.log(`Memory MCP Server v${PACKAGE_VERSION}`); console.log("- MCP 프로토콜 호환"); console.log("- JSON-RPC 2.0 stdin/stdout 통신"); console.log("- PARA + Zettelkasten 조직 체계"); console.log("- SQLite FTS5 전문 검색"); }); ``` **참고**: version은 옵션 불필요, 변경 없음 ### Phase 3: 테스트 및 검증 (30분) #### Task 3.1: 수동 테스트 시나리오 ```bash # 빌드 cd /Users/inchan/workspace/pilot/memory-mcp npm run build # 테스트 1: 직접 실행 (새로운 방식) node packages/mcp-server/dist/cli.js --vault /tmp/test-vault --index /tmp/test.db --verbose # 테스트 2: 서브커맨드 명시 (하위 호환) node packages/mcp-server/dist/cli.js server --vault /tmp/test-vault --index /tmp/test.db # 테스트 3: 헬스체크 node packages/mcp-server/dist/cli.js healthcheck --vault /tmp/test-vault # 테스트 4: 버전 정보 node packages/mcp-server/dist/cli.js version node packages/mcp-server/dist/cli.js --version # 테스트 5: npx 사용 npx memory-mcp --vault /tmp/test-vault # 테스트 6: 도움말 node packages/mcp-server/dist/cli.js --help node packages/mcp-server/dist/cli.js server --help ``` #### Task 3.2: 유닛 테스트 작성 **파일**: `packages/mcp-server/src/__tests__/cli.test.ts` (신규) ```typescript import { describe, it, expect, beforeEach } from "@jest/globals"; import { execSync } from "child_process"; import { resolve } from "path"; const CLI_PATH = resolve(__dirname, "../../dist/cli.js"); describe("CLI Options Parsing", () => { it("should accept --vault and --index at root level", () => { const result = execSync( `node ${CLI_PATH} --vault /tmp/vault --index /tmp/index.db --help`, { encoding: "utf-8" } ); expect(result).toContain("--vault"); expect(result).toContain("--index"); }); it("should accept server subcommand with options (backward compat)", () => { const result = execSync( `node ${CLI_PATH} server --vault /tmp/vault --help`, { encoding: "utf-8" } ); expect(result).toContain("MCP 서버 시작"); }); it("should show version", () => { const result = execSync(`node ${CLI_PATH} version`, { encoding: "utf-8", }); expect(result).toContain("Memory MCP Server v"); }); it("should show healthcheck", () => { const result = execSync(`node ${CLI_PATH} healthcheck --vault /tmp`, { encoding: "utf-8", }); expect(result).toContain("헬스체크"); }); }); ``` **참고**: 실제 서버 시작 테스트는 통합 테스트에서 수행 (stdin/stdout 통신 필요) ### Phase 4: 문서 업데이트 (20분) #### Task 4.1: USAGE_GUIDE.md 업데이트 **파일**: `docs/USAGE_GUIDE.md` **변경 전 (라인 59-69)**: ```bash #### 서버 시작 ```bash cd /Users/inchan/workspace/pilot/memory-mcp npm start -- --vault ~/Documents/vault --index ~/.memory-mcp/index.db ``` #### 헬스체크 ```bash node packages/mcp-server/dist/cli.js healthcheck \ --vault ~/Documents/vault \ --index ~/.memory-mcp/index.db ``` **변경 후**: ```bash #### 서버 시작 (직접 실행 - 권장) ```bash cd /Users/inchan/workspace/pilot/memory-mcp node packages/mcp-server/dist/cli.js --vault ~/Documents/vault --index ~/.memory-mcp/index.db # 또는 npx 사용 npx memory-mcp --vault ~/Documents/vault --index ~/.memory-mcp/index.db ``` #### 서버 시작 (server 서브커맨드 - 하위 호환) ```bash node packages/mcp-server/dist/cli.js server --vault ~/Documents/vault --index ~/.memory-mcp/index.db ``` #### 헬스체크 ```bash node packages/mcp-server/dist/cli.js healthcheck --vault ~/Documents/vault --index ~/.memory-mcp/index.db ``` #### Task 4.2: README.md 업데이트 **파일**: `README.md` **변경 전 (라인 305-314)**: ```bash ### Running Locally ```bash # Start server with test vault node packages/mcp-server/dist/cli.js --vault /tmp/test-vault # Or with npm npm start -- --vault /tmp/test-vault # Run healthcheck node packages/mcp-server/dist/cli.js healthcheck --vault /tmp/test-vault ``` **변경 후**: ```bash ### Running Locally ```bash # Start server with test vault (direct execution) node packages/mcp-server/dist/cli.js --vault /tmp/test-vault --index /tmp/test.db # Or with npm npm start -- --vault /tmp/test-vault --index /tmp/test.db # With npx npx memory-mcp --vault /tmp/test-vault # Run healthcheck node packages/mcp-server/dist/cli.js healthcheck --vault /tmp/test-vault # Version info node packages/mcp-server/dist/cli.js version ``` #### Task 4.3: Claude Desktop 설정 문서화 **파일**: `docs/USAGE_GUIDE.md` (라인 26-41) **현재 내용 유지, 주의사항 명확화**: ```json { "mcpServers": { "memory-mcp": { "command": "node", "args": [ "/Users/inchan/workspace/pilot/memory-mcp/packages/mcp-server/dist/cli.js", "--vault", "/Users/inchan/Documents/vault", "--index", "/Users/inchan/.memory-mcp/index.db" ] } } } ``` **주의사항 강조**: - ✅ 서브커맨드 `server` 불필요 (직접 옵션 전달) - ✅ 절대 경로 사용 필수 - ✅ `--mode prod` 옵션 추가 권장 (프로덕션 환경) --- ## 4. 리스크 평가 및 완화 방안 ### 리스크 1: 하위 호환성 파괴 **영향도**: 중 **확률**: 낮음 **시나리오**: - 기존 사용자가 `memory-mcp server --vault ...` 방식 사용 중 - 리팩토링 후 동작하지 않을 가능성 **완화 방안**: - ✅ `server` 서브커맨드를 별칭으로 유지 - ✅ 부모 옵션을 상속하여 동일한 동작 보장 - ✅ CHANGELOG.md에 명확히 기록 **검증 방법**: ```bash # 기존 방식 테스트 node cli.js server --vault /tmp/vault --index /tmp/index.db # 새 방식 테스트 node cli.js --vault /tmp/vault --index /tmp/index.db # 결과: 두 방식 모두 동일하게 작동해야 함 ``` ### 리스크 2: Commander.js 옵션 상속 버그 **영향도**: 중 **확률**: 낮음 **시나리오**: - 서브커맨드에서 `program.opts()` 호출 시 부모 옵션을 제대로 상속받지 못함 - Commander.js 버전에 따라 동작 차이 발생 가능 **완화 방안**: - ✅ 현재 설치된 Commander.js 버전 확인 (11.1.0) - ✅ Commander.js 공식 문서 참조하여 옵션 상속 패턴 확인 - ✅ 유닛 테스트로 옵션 파싱 검증 **검증 방법**: ```typescript // 테스트 코드에서 옵션 파싱 확인 const opts = program.opts(); expect(opts.vault).toBe("/tmp/vault"); expect(opts.index).toBe("/tmp/index.db"); ``` ### 리스크 3: Claude Desktop 통합 실패 **영향도**: 높음 **확률**: 낮음 **시나리오**: - Claude Desktop에서 여전히 `unknown option` 에러 발생 - MCP 클라이언트의 stdin/stdout 통신 방식과 충돌 **완화 방안**: - ✅ 리팩토링 후 즉시 Claude Desktop에서 실제 테스트 - ✅ MCP Inspector로 서버 동작 검증 - ✅ 실패 시 즉시 롤백 가능하도록 Git 커밋 분리 **검증 방법**: ```bash # 1. Claude Desktop 설정 업데이트 code ~/Library/Application\ Support/Claude/claude_desktop_config.json # 2. Claude Desktop 재시작 # 3. Claude에서 MCP 도구 확인 # 좌측 하단 🔌 아이콘 확인 # create_note, read_note 등 6개 도구가 표시되는지 확인 # 4. 노트 생성 테스트 # Claude에게 요청: "테스트 노트를 만들어줘" ``` ### 리스크 4: 옵션 파싱 우선순위 혼란 **영향도**: 낮음 **확률**: 중간 **시나리오**: - 루트 레벨과 서브커맨드 레벨 옵션이 동시에 제공될 경우 충돌 - 예: `node cli.js --vault /tmp/a server --vault /tmp/b` **완화 방안**: - ✅ 서브커맨드에서 옵션 재정의하지 않음 (부모만 사용) - ✅ 문서에서 이러한 사용 방식을 명확히 금지 - ✅ 필요 시 옵션 검증 로직 추가 **검증 방법**: ```bash # 이러한 사용은 권장하지 않음 (문서에 명시) node cli.js --vault /tmp/a server # 권장 사용법: node cli.js --vault /tmp/a node cli.js server --vault /tmp/a # 동일 결과 ``` --- ## 5. 검증 방법 ### 5.1 기능 검증 시나리오 #### 시나리오 1: 직접 실행 (새로운 방식) ```bash # 단계 1: 빌드 npm run build # 단계 2: 테스트 vault 생성 mkdir -p /tmp/test-vault mkdir -p /tmp/.memory-mcp # 단계 3: CLI 실행 node packages/mcp-server/dist/cli.js \ --vault /tmp/test-vault \ --index /tmp/.memory-mcp/index.db \ --verbose # 예상 결과: # - 서버가 정상 시작됨 # - "Memory MCP Server 시작 중..." 로그 출력 # - stdin/stdout 대기 상태 진입 ``` #### 시나리오 2: 서브커맨드 명시 (하위 호환) ```bash node packages/mcp-server/dist/cli.js server \ --vault /tmp/test-vault \ --index /tmp/.memory-mcp/index.db # 예상 결과: # - 시나리오 1과 동일한 동작 ``` #### 시나리오 3: 헬스체크 ```bash node packages/mcp-server/dist/cli.js healthcheck \ --vault /tmp/test-vault \ --index /tmp/.memory-mcp/index.db # 예상 결과: # - "✅ Memory MCP Server 상태: 정상" 출력 # - vault/index 경로 출력 ``` #### 시나리오 4: 버전 정보 ```bash node packages/mcp-server/dist/cli.js version # 예상 결과: # - "Memory MCP Server v0.1.0" 출력 # - 기능 목록 출력 node packages/mcp-server/dist/cli.js --version # 예상 결과: # - "0.1.0" 출력 (Commander.js 기본 동작) ``` #### 시나리오 5: 도움말 ```bash node packages/mcp-server/dist/cli.js --help # 예상 결과: # - Usage 정보 출력 # - 루트 레벨 옵션 목록 표시 # - 서브커맨드 목록 표시 (server, healthcheck, version) ``` ### 5.2 통합 검증: Claude Desktop #### 단계 1: 설정 파일 업데이트 ```bash code ~/Library/Application\ Support/Claude/claude_desktop_config.json ``` ```json { "mcpServers": { "memory-mcp": { "command": "node", "args": [ "/Users/inchan/workspace/pilot/memory-mcp/packages/mcp-server/dist/cli.js", "--vault", "/Users/inchan/Documents/test-vault", "--index", "/Users/inchan/.memory-mcp/test-index.db", "--mode", "prod", "--verbose" ] } } } ``` #### 단계 2: Claude Desktop 재시작 - Claude Desktop 완전 종료 - 재시작 후 로그 확인 #### 단계 3: MCP 연결 확인 - 좌측 하단 🔌 아이콘이 표시되는지 확인 - 도구 목록에서 6개 도구 확인: - `create_note` - `read_note` - `list_notes` - `search_memory` - `update_note` - `delete_note` #### 단계 4: 기능 테스트 ``` Claude에게 요청: 1. "테스트 노트를 만들어줘. 제목은 'CLI 리팩토링 테스트', 카테고리는 Projects로." → create_note 도구 호출 확인 2. "방금 만든 노트를 읽어줘." → read_note 도구 호출 확인 3. "노트 목록을 보여줘." → list_notes 도구 호출 확인 4. "'리팩토링'으로 검색해줘." → search_memory 도구 호출 확인 ``` #### 예상 결과: - ✅ 모든 도구가 정상 호출됨 - ✅ 에러 없이 노트 생성/읽기/검색 가능 - ✅ `/Users/inchan/Documents/test-vault` 디렉토리에 .md 파일 생성 확인 ### 5.3 성능 검증 #### 검증 포인트: - 서버 시작 시간 < 1초 - 옵션 파싱 오버헤드 < 10ms - 메모리 사용량 변화 없음 #### 측정 방법: ```bash # 서버 시작 시간 측정 time node packages/mcp-server/dist/cli.js --vault /tmp/vault --index /tmp/index.db & # 메모리 사용량 측정 (서버 실행 중) ps aux | grep cli.js ``` --- ## 6. 롤백 계획 ### 롤백 트리거 다음 중 하나라도 발생 시 즉시 롤백: 1. Claude Desktop 통합 실패 (MCP 도구 인식 불가) 2. 기존 테스트 케이스 실패 3. 하위 호환성 파괴 확인 4. 성능 저하 > 10% ### 롤백 절차 ```bash # 1. Git 커밋 이력 확인 git log --oneline -5 # 2. 리팩토링 커밋 식별 # 예: "refactor(cli): support root-level options for MCP compatibility" # 3. 롤백 git revert <commit-hash> # 4. 빌드 및 테스트 npm run build npm test # 5. Claude Desktop 재검증 ``` ### 롤백 후 조치 1. 리팩토링 실패 원인 분석 2. 대안 솔루션 검토 (옵션 A 또는 C) 3. 이슈 생성 및 커뮤니티 피드백 수집 --- ## 7. 타임라인 및 마일스톤 ### 총 예상 소요 시간: 2시간 | Phase | Task | 예상 시간 | 누적 시간 | |-------|------|-----------|-----------| | **Phase 1** | 옵션 리팩토링 | 30분 | 30분 | | - | Task 1.1: 루트 레벨 옵션 정의 | 15분 | 15분 | | - | Task 1.2: 루트 action 구현 | 15분 | 30분 | | **Phase 2** | 서브커맨드 단순화 | 20분 | 50분 | | - | Task 2.1: server 서브커맨드 별칭화 | 10분 | 40분 | | - | Task 2.2: healthcheck 서브커맨드 간소화 | 5분 | 45분 | | - | Task 2.3: version 서브커맨드 확인 | 5분 | 50분 | | **Phase 3** | 테스트 및 검증 | 30분 | 80분 | | - | Task 3.1: 수동 테스트 시나리오 | 20분 | 70분 | | - | Task 3.2: 유닛 테스트 작성 | 10분 | 80분 | | **Phase 4** | 문서 업데이트 | 20분 | 100분 | | - | Task 4.1: USAGE_GUIDE.md 업데이트 | 10분 | 90분 | | - | Task 4.2: README.md 업데이트 | 5분 | 95분 | | - | Task 4.3: Claude Desktop 설정 문서화 | 5분 | 100분 | | **Phase 5** | 통합 검증 (Claude Desktop) | 20분 | 120분 | ### 마일스톤 **M1: 코드 리팩토링 완료** (50분) - ✅ cli.ts 수정 완료 - ✅ 빌드 성공 - ✅ 로컬 수동 테스트 통과 **M2: 테스트 및 문서화 완료** (100분) - ✅ 유닛 테스트 작성 및 통과 - ✅ 문서 업데이트 완료 - ✅ CHANGELOG.md 작성 **M3: 통합 검증 완료** (120분) - ✅ Claude Desktop 통합 성공 - ✅ 6개 MCP 도구 모두 작동 - ✅ 성능 검증 통과 --- ## 8. 성공 지표 (KPI) ### 기능 지표 - ✅ Claude Desktop에서 `unknown option` 에러 0건 - ✅ 루트 레벨 옵션 파싱 성공률 100% - ✅ 하위 호환성 테스트 통과율 100% - ✅ 6개 MCP 도구 모두 정상 작동 ### 성능 지표 - ✅ 서버 시작 시간 < 1초 (변화 없음) - ✅ 옵션 파싱 오버헤드 < 10ms - ✅ 메모리 사용량 증가 < 1MB ### 품질 지표 - ✅ ESLint 에러 0건 - ✅ TypeScript 컴파일 에러 0건 - ✅ 유닛 테스트 통과율 100% - ✅ 코드 커버리지 유지 또는 증가 ### 사용성 지표 - ✅ 문서 업데이트 완료 (3개 파일) - ✅ 사용 예시 추가 (5개 이상) - ✅ 하위 호환성 명시적 문서화 --- ## 9. 다음 단계 (후속 작업) ### 단기 (v0.1.1) 1. **환경변수 지원 추가** - `MEMORY_MCP_VAULT`, `MEMORY_MCP_INDEX` 환경변수 인식 - 우선순위: CLI 옵션 > 환경변수 > 기본값 2. **설정 파일 지원** - `~/.memory-mcp/config.json` 또는 `./memory-mcp.config.json` - 우선순위: CLI 옵션 > 환경변수 > 설정 파일 > 기본값 3. **npx 배포 및 검증** - npm 레지스트리에 배포 - `npx @memory-mcp/mcp-server --vault ~/vault` 테스트 ### 중기 (v0.2.0) 1. **Claude Desktop 자동 설정 도구** - `memory-mcp setup` 명령 추가 - claude_desktop_config.json 자동 생성/업데이트 2. **인터랙티브 모드** - `memory-mcp init` 명령으로 대화형 설정 3. **로깅 개선** - `--log-file` 옵션 추가 - MCP 서버 로그를 파일로 저장 (디버깅 용이) ### 장기 (v1.0.0) 1. **CLI 플러그인 아키텍처** - 서드파티 플러그인 지원 - `memory-mcp plugin install <name>` 2. **다중 MCP 서버 관리** - 여러 vault를 동시에 관리하는 멀티 인스턴스 모드 --- ## 10. 부록 ### A. Commander.js 옵션 상속 패턴 참조 ```typescript // Commander.js 11.x에서 부모 옵션 상속 예시 const program = new Command(); program .option("--global <value>", "Global option"); program .command("sub") .action(() => { const opts = program.opts(); // 부모 옵션 접근 console.log(opts.global); }); ``` **참고 문서**: https://github.com/tj/commander.js#commands ### B. 다른 MCP 서버 CLI 구조 비교 | 프로젝트 | 패턴 | 예시 | |---------|------|------| | FastMCP | 플랫한 구조 | `fastmcp run server.py` | | cli-mcp-server | 플랫한 구조 | `npx cli-mcp-server --config ...` | | mcp-tools | 서브커맨드 선택적 | `mcp chat` / `mcp --version` | | Angular MCP | 플랫한 구조 | `npx angular-mcp --project ...` | **결론**: 대부분 플랫한 구조 또는 서브커맨드 선택적 사용 ### C. 옵션 비교표 | 옵션 | 장점 | 단점 | 하위 호환성 | 구현 복잡도 | |------|------|------|-------------|-------------| | **A: 루트 레벨 옵션 추가** | 간단 | 중복 코드 | ✅ 완벽 | 낮음 | | **B: 서브커맨드 선택적** | 직관적 | 옵션 상속 필요 | ✅ 유지 | 중간 | | **C: 완전 플랫** | 명확함 | 하위 호환 파괴 | ❌ 파괴 | 낮음 | **권장**: 옵션 B (서브커맨드 선택적) ### D. 관련 파일 목록 | 파일 경로 | 역할 | 수정 필요 | |-----------|------|-----------| | `packages/mcp-server/src/cli.ts` | CLI 진입점 | ✅ 주요 수정 | | `packages/mcp-server/src/server.ts` | MCP 서버 구현 | 변경 없음 | | `packages/mcp-server/package.json` | 패키지 설정 | 변경 없음 | | `docs/USAGE_GUIDE.md` | 사용자 가이드 | ✅ 업데이트 | | `README.md` | 프로젝트 소개 | ✅ 업데이트 | | `CHANGELOG.md` | 변경 이력 | ✅ 추가 | ### E. 체크리스트 #### 리팩토링 전 - [ ] 현재 cli.ts 백업 - [ ] Git 브랜치 생성 (`git checkout -b refactor/cli-root-options`) - [ ] 기존 테스트 실행 및 통과 확인 #### 리팩토링 중 - [ ] 루트 레벨 옵션 정의 (Task 1.1) - [ ] 루트 action 구현 (Task 1.2) - [ ] server 서브커맨드 별칭화 (Task 2.1) - [ ] healthcheck 서브커맨드 간소화 (Task 2.2) - [ ] version 서브커맨드 확인 (Task 2.3) #### 테스트 - [ ] 빌드 성공 (`npm run build`) - [ ] 직접 실행 테스트 (시나리오 1) - [ ] 서브커맨드 테스트 (시나리오 2) - [ ] 헬스체크 테스트 (시나리오 3) - [ ] 버전 정보 테스트 (시나리오 4) - [ ] 도움말 테스트 (시나리오 5) - [ ] 유닛 테스트 작성 및 통과 #### 문서화 - [ ] USAGE_GUIDE.md 업데이트 - [ ] README.md 업데이트 - [ ] CHANGELOG.md 작성 #### 통합 검증 - [ ] Claude Desktop 설정 업데이트 - [ ] Claude Desktop 재시작 - [ ] MCP 도구 목록 확인 - [ ] create_note 테스트 - [ ] read_note 테스트 - [ ] list_notes 테스트 - [ ] search_memory 테스트 #### 완료 - [ ] Git 커밋 (`git commit -m "refactor(cli): support root-level options for MCP compatibility"`) - [ ] 테스트 통과 확인 - [ ] PR 생성 및 리뷰 요청 --- ## 결론 이 리팩토링 계획은 memory-mcp CLI를 MCP 클라이언트(Claude Desktop 등)와 완벽히 호환되도록 개선하면서, 기존 사용자의 하위 호환성을 보장합니다. **핵심 전략**: 1. 루트 레벨에 옵션을 정의하여 서브커맨드 없이 직접 실행 가능 2. `server` 서브커맨드를 별칭으로 유지하여 하위 호환성 보장 3. Commander.js의 옵션 상속 기능을 활용하여 코드 중복 최소화 4. 철저한 테스트와 문서화로 안정성 확보 **예상 효과**: - ✅ Claude Desktop에서 즉시 사용 가능 - ✅ 사용자 경험 향상 (직관적인 CLI) - ✅ MCP 표준 패턴 준수 - ✅ 유지보수성 개선 **다음 단계**: 이 계획에 따라 구현을 시작하고, Phase별로 검증을 진행합니다.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/inchan/memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server