aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/claude/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/claude/index.ts')
-rw-r--r--src/main/claude/index.ts59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/main/claude/index.ts b/src/main/claude/index.ts
index ca54164..8cf512c 100644
--- a/src/main/claude/index.ts
+++ b/src/main/claude/index.ts
@@ -53,7 +53,38 @@ export async function sendMessage({
53 53
54 // Load MCP servers config (JSON string → object, or undefined if not set) 54 // Load MCP servers config (JSON string → object, or undefined if not set)
55 const mcpServersJson = getSetting("mcpServers"); 55 const mcpServersJson = getSetting("mcpServers");
56 const mcpServers = mcpServersJson ? JSON.parse(mcpServersJson) : undefined; 56 const mcpServersConfig = mcpServersJson ? JSON.parse(mcpServersJson) : undefined;
57
58 // Build allowedTools list from enabled MCP tools
59 // Format: mcp__servername__toolname
60 const mcpAllowedTools: string[] = [];
61 if (mcpServersConfig) {
62 for (const [serverName, config] of Object.entries(mcpServersConfig)) {
63 const serverConfig = config as {
64 enabledTools?: string[];
65 discoveredTools?: Array<{ name: string }>;
66 };
67 // Use enabledTools if available, otherwise allow all discovered tools
68 const enabledTools = serverConfig.enabledTools ||
69 serverConfig.discoveredTools?.map((t) => t.name) ||
70 [];
71 for (const toolName of enabledTools) {
72 mcpAllowedTools.push(`mcp__${serverName}__${toolName}`);
73 }
74 }
75 }
76
77 // Strip tool management fields from config before passing to SDK
78 // SDK only needs: type, command, args, env, url, headers
79 let mcpServers: Record<string, unknown> | undefined;
80 if (mcpServersConfig && Object.keys(mcpServersConfig).length > 0) {
81 mcpServers = Object.fromEntries(
82 Object.entries(mcpServersConfig).map(([name, config]) => {
83 const { discoveredTools, enabledTools, ...sdkConfig } = config as Record<string, unknown>;
84 return [name, sdkConfig];
85 })
86 );
87 }
57 88
58 const phaseConfig = getPhaseConfig( 89 const phaseConfig = getPhaseConfig(
59 session.phase as Phase, 90 session.phase as Phase,
@@ -62,28 +93,32 @@ export async function sendMessage({
62 customSystemPrompt 93 customSystemPrompt
63 ); 94 );
64 95
96 // Build allowedTools for this phase
97 const allowedTools: string[] = [];
98 if (session.phase === "implement") {
99 // Allow git inspection in implement phase
100 allowedTools.push("Bash(git status*)", "Bash(git log*)", "Bash(git diff*)");
101 }
102 if (mcpAllowedTools.length > 0) {
103 // Add enabled MCP tools
104 allowedTools.push(...mcpAllowedTools);
105 }
106
65 const q = query({ 107 const q = query({
66 prompt: message, 108 prompt: message,
67 options: { 109 options: {
68 cwd: project.path, 110 cwd: project.path,
69 model: configuredModel, 111 model: configuredModel,
70 mcpServers, 112 // eslint-disable-next-line @typescript-eslint/no-explicit-any
113 mcpServers: mcpServers as any,
71 resume: session.claude_session_id ?? undefined, 114 resume: session.claude_session_id ?? undefined,
72 tools: phaseConfig.tools, 115 tools: phaseConfig.tools,
73 permissionMode: phaseConfig.permissionMode, 116 permissionMode: phaseConfig.permissionMode,
74 // Required companion flag when bypassPermissions is active 117 // Required companion flag when bypassPermissions is active
75 allowDangerouslySkipPermissions: phaseConfig.permissionMode === "bypassPermissions", 118 allowDangerouslySkipPermissions: phaseConfig.permissionMode === "bypassPermissions",
76 systemPrompt: phaseConfig.systemPrompt, 119 systemPrompt: phaseConfig.systemPrompt,
77 // Allow Claude to inspect git state during implementation without prompts. 120 // Pre-approve specific tools to avoid permission prompts
78 // git add/commit intentionally omitted — the app handles those. 121 ...(allowedTools.length > 0 && { allowedTools }),
79 ...(session.phase === "implement" && {
80 allowedTools: ["Bash(git status*)", "Bash(git log*)", "Bash(git diff*)"],
81 }),
82 // When MCPs are configured in research phase, bypass permissions to allow MCP tools
83 ...(session.phase === "research" && mcpServers && {
84 permissionMode: "bypassPermissions" as const,
85 allowDangerouslySkipPermissions: true,
86 }),
87 }, 122 },
88 }); 123 });
89 124