From b2adee102a1a2a1870f731b1c6d77594eb299b90 Mon Sep 17 00:00:00 2001 From: LeeJaeYeon <0814jyinjs@com2us.com> Date: Fri, 27 Feb 2026 14:21:26 +0900 Subject: [PATCH] feat: add MCP server support via .mcp.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 작업 디렉토리의 .mcp.json 파일에서 MCP 서버 설정을 읽어 Agent SDK query()에 전달. 프로젝트별 MCP 도구 자동 사용 가능. Co-Authored-By: Claude Opus 4.6 --- src/sessions/claude.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/sessions/claude.ts b/src/sessions/claude.ts index b4944d3..bc94dae 100644 --- a/src/sessions/claude.ts +++ b/src/sessions/claude.ts @@ -91,6 +91,28 @@ function basename(filePath: string): string { return parts[parts.length - 1] ?? filePath; } +/** + * 작업 디렉토리의 .mcp.json 파일에서 MCP 서버 설정을 읽어 반환. + * 파일이 없거나 파싱 실패 시 undefined 반환. + */ +function loadMcpServers(cwd: string): Record | undefined { + const mcpPath = path.join(cwd, ".mcp.json"); + try { + if (!fs.existsSync(mcpPath)) return undefined; + const raw = fs.readFileSync(mcpPath, "utf-8"); + const parsed = JSON.parse(raw); + const servers = parsed.mcpServers ?? parsed; + if (typeof servers !== "object" || servers === null) return undefined; + const names = Object.keys(servers); + if (names.length === 0) return undefined; + console.log(` [MCP] Loaded ${names.length} server(s) from .mcp.json: ${names.join(", ")}`); + return servers; + } catch { + console.error(" [MCP] Failed to parse .mcp.json"); + return undefined; + } +} + export class ClaudeSessionManager implements ISessionManager { private tool: CliTool; private cwd: string; @@ -173,6 +195,7 @@ export class ClaudeSessionManager implements ISessionManager { ): Promise { const cliPath = resolveClaudeCodePath(); const nodePath = await resolveNodeExecutable(); + const mcpServers = loadMcpServers(this.cwd); console.log(` [Claude] cliPath: ${cliPath ?? "(SDK default)"}`); console.log(` [Claude] nodePath: ${nodePath}`); console.log(` [Claude] cwd: ${this.cwd}`); @@ -184,6 +207,7 @@ export class ClaudeSessionManager implements ISessionManager { abortController: this.abortController, executable: nodePath, ...(cliPath && { pathToClaudeCodeExecutable: cliPath }), + ...(mcpServers && { mcpServers }), stderr: (data: string) => console.error("[Claude stderr]", data), // pkg exe 환경에서 signal 옵션이 제대로 전달되지 않을 수 있으므로 // 직접 spawn해서 abort는 수동으로 처리한다.