diff --git a/packages/core/src/core/__snapshots__/prompts.test.ts.snap b/packages/core/src/core/__snapshots__/prompts.test.ts.snap
index 0028a052de..3ebee1c156 100644
--- a/packages/core/src/core/__snapshots__/prompts.test.ts.snap
+++ b/packages/core/src/core/__snapshots__/prompts.test.ts.snap
@@ -42,11 +42,9 @@ For example:
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
## Available Tools
-The following read-only tools are available in Plan Mode:
+The following tools are available in Plan Mode:
\`glob\`
\`grep_search\`
-- \`write_file\` - Save plans to the plans directory (see Plan Storage below)
-- \`replace\` - Update plans in the plans directory
## Plan Storage
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/plans/\`
@@ -174,11 +172,9 @@ For example:
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
## Available Tools
-The following read-only tools are available in Plan Mode:
+The following tools are available in Plan Mode:
\`glob\`
\`grep_search\`
-- \`write_file\` - Save plans to the plans directory (see Plan Storage below)
-- \`replace\` - Update plans in the plans directory
## Plan Storage
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/plans/\`
@@ -424,11 +420,9 @@ For example:
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
## Available Tools
-The following read-only tools are available in Plan Mode:
+The following tools are available in Plan Mode:
\`glob\`
\`grep_search\`
-- \`write_file\` - Save plans to the plans directory (see Plan Storage below)
-- \`replace\` - Update plans in the plans directory
## Plan Storage
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/project-temp/plans/\`
diff --git a/packages/core/src/core/prompts.test.ts b/packages/core/src/core/prompts.test.ts
index 0cee2f8ae4..94354847a0 100644
--- a/packages/core/src/core/prompts.test.ts
+++ b/packages/core/src/core/prompts.test.ts
@@ -25,6 +25,7 @@ import {
} from '../config/models.js';
import { ApprovalMode } from '../policy/types.js';
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
+import type { AnyDeclarativeTool } from '../tools/tool-registry.js';
import type { CallableTool } from '@google/genai';
import type { MessageBus } from '../confirmation-bus/message-bus.js';
@@ -85,6 +86,12 @@ describe('Core System Prompt (prompts.ts)', () => {
getToolRegistry: vi.fn().mockReturnValue({
getAllToolNames: vi.fn().mockReturnValue(['grep_search', 'glob']),
getAllTools: vi.fn().mockReturnValue([]),
+ getActiveTools: vi
+ .fn()
+ .mockReturnValue([
+ { name: 'grep_search' } as unknown as AnyDeclarativeTool,
+ { name: 'glob' } as unknown as AnyDeclarativeTool,
+ ]),
}),
getEnableShellOutputEfficiency: vi.fn().mockReturnValue(true),
storage: {
@@ -452,24 +459,11 @@ describe('Core System Prompt (prompts.ts)', () => {
true, // isReadOnly
);
- const nonReadOnlyMcpTool = new DiscoveredMCPTool(
- {} as CallableTool,
- 'nonreadonly-server',
- 'non_read_static_value',
- 'A non-read-only tool',
- {},
- {} as MessageBus,
- false,
- false,
- );
+ // Note: non-read-only MCP tools are implicitly filtered out by the logic
+ // because they are not potentially allowed in Plan Mode by default.
- vi.mocked(mockConfig.getToolRegistry().getAllTools).mockReturnValue([
+ vi.mocked(mockConfig.getToolRegistry().getActiveTools).mockReturnValue([
readOnlyMcpTool,
- nonReadOnlyMcpTool,
- ]);
- vi.mocked(mockConfig.getToolRegistry().getAllToolNames).mockReturnValue([
- readOnlyMcpTool.name,
- nonReadOnlyMcpTool.name,
]);
const prompt = getCoreSystemPrompt(mockConfig);
@@ -483,10 +477,10 @@ describe('Core System Prompt (prompts.ts)', () => {
it('should only list available tools in PLAN mode', () => {
vi.mocked(mockConfig.getApprovalMode).mockReturnValue(ApprovalMode.PLAN);
// Only enable a subset of tools, including ask_user
- vi.mocked(mockConfig.getToolRegistry().getAllToolNames).mockReturnValue([
- 'glob',
- 'read_file',
- 'ask_user',
+ vi.mocked(mockConfig.getToolRegistry().getActiveTools).mockReturnValue([
+ { name: 'glob' } as unknown as AnyDeclarativeTool,
+ { name: 'read_file' } as unknown as AnyDeclarativeTool,
+ { name: 'ask_user' } as unknown as AnyDeclarativeTool,
]);
const prompt = getCoreSystemPrompt(mockConfig);
diff --git a/packages/core/src/prompts/promptProvider.ts b/packages/core/src/prompts/promptProvider.ts
index 4f1a3afbff..0e2be603ee 100644
--- a/packages/core/src/prompts/promptProvider.ts
+++ b/packages/core/src/prompts/promptProvider.ts
@@ -22,7 +22,6 @@ import {
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
import { isGitRepository } from '../utils/gitUtils.js';
import {
- PLAN_MODE_TOOLS,
WRITE_TODOS_TOOL_NAME,
READ_FILE_TOOL_NAME,
ENTER_PLAN_MODE_TOOL_NAME,
@@ -67,25 +66,17 @@ export class PromptProvider {
const contextFilenames = getAllGeminiMdFilenames();
// --- Context Gathering ---
- let planModeToolsList = PLAN_MODE_TOOLS.filter((t) =>
- enabledToolNames.has(t),
- )
- .map((t) => ` \`${t}\``)
- .join('\n');
-
- // Add read-only MCP tools to the list
+ let planModeToolsList = '';
if (isPlanMode) {
- const allTools = config.getToolRegistry().getAllTools();
- const readOnlyMcpTools = allTools.filter(
- (t): t is DiscoveredMCPTool =>
- t instanceof DiscoveredMCPTool && !!t.isReadOnly,
- );
- if (readOnlyMcpTools.length > 0) {
- const mcpToolsList = readOnlyMcpTools
- .map((t) => ` \`${t.name}\` (${t.serverName})`)
- .join('\n');
- planModeToolsList += `\n${mcpToolsList}`;
- }
+ const activeTools = config.getToolRegistry().getActiveTools();
+ activeTools.sort((a, b) => a.name.localeCompare(b.name));
+ planModeToolsList = activeTools
+ .map((t) => {
+ const serverSuffix =
+ t instanceof DiscoveredMCPTool ? ` (${t.serverName})` : '';
+ return ` \`${t.name}\`${serverSuffix}`;
+ })
+ .join('\n');
}
let basePrompt: string;
diff --git a/packages/core/src/prompts/snippets.legacy.ts b/packages/core/src/prompts/snippets.legacy.ts
index 3671490089..33a4d6ddd2 100644
--- a/packages/core/src/prompts/snippets.legacy.ts
+++ b/packages/core/src/prompts/snippets.legacy.ts
@@ -398,10 +398,8 @@ export function renderPlanningWorkflow(
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
## Available Tools
-The following read-only tools are available in Plan Mode:
+The following tools are available in Plan Mode:
${options.planModeToolsList}
-- \`${WRITE_FILE_TOOL_NAME}\` - Save plans to the plans directory (see Plan Storage below)
-- \`${EDIT_TOOL_NAME}\` - Update plans in the plans directory
## Plan Storage
- Save your plans as Markdown (.md) files ONLY within: \`${options.plansDir}/\`
diff --git a/packages/core/src/prompts/snippets.ts b/packages/core/src/prompts/snippets.ts
index f7ea9b1eee..c6fbc2fb0a 100644
--- a/packages/core/src/prompts/snippets.ts
+++ b/packages/core/src/prompts/snippets.ts
@@ -452,11 +452,9 @@ export function renderPlanningWorkflow(
You are operating in **Plan Mode**. Your goal is to produce a detailed implementation plan in \`${options.plansDir}/\` and get user approval before editing source code.
## Available Tools
-The following read-only tools are available in Plan Mode:
+The following tools are available in Plan Mode:
${options.planModeToolsList}
- ${formatToolName(WRITE_FILE_TOOL_NAME)} - Save plans to the plans directory
- ${formatToolName(EDIT_TOOL_NAME)} - Update plans in the plans directory
## Rules