diff --git a/README.md b/README.md index b98457e..2c9a6d7 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ CodeGraph builds a semantic knowledge graph of codebases for faster, smarter cod > This project has CodeGraph initialized (.codegraph/ exists). Use `codegraph_explore` as your PRIMARY tool — it returns full source code sections from all relevant files in one call. > > **Rules:** -> 1. Make at most 6 `codegraph_explore` calls — one broad query, then up to 5 focused follow-ups. +> 1. Follow the explore call budget in the `codegraph_explore` tool description — it scales automatically based on project size. > 2. Do NOT re-read files that codegraph_explore already returned source code for. The source sections are complete and authoritative. > 3. Only fall back to grep/glob/read for files listed under "Additional relevant files" if you need more detail, or if codegraph returned no results. diff --git a/src/installer/claude-md-template.ts b/src/installer/claude-md-template.ts index 9c863a5..130d447 100644 --- a/src/installer/claude-md-template.ts +++ b/src/installer/claude-md-template.ts @@ -23,7 +23,7 @@ CodeGraph builds a semantic knowledge graph of codebases for faster, smarter cod > This project has CodeGraph initialized (.codegraph/ exists). Use \`codegraph_explore\` as your PRIMARY tool — it returns full source code sections from all relevant files in one call. > > **Rules:** -> 1. Make at most 6 \`codegraph_explore\` calls — one broad query, then up to 5 focused follow-ups. +> 1. Follow the explore call budget in the \`codegraph_explore\` tool description — it scales automatically based on project size. > 2. Do NOT re-read files that codegraph_explore already returned source code for. The source sections are complete and authoritative. > 3. Only fall back to grep/glob/read for files listed under "Additional relevant files" if you need more detail, or if codegraph returned no results. diff --git a/src/mcp/index.ts b/src/mcp/index.ts index ddcf828..b740964 100644 --- a/src/mcp/index.ts +++ b/src/mcp/index.ts @@ -255,8 +255,9 @@ export class MCPServer { * Handle tools/list request */ private async handleToolsList(request: JsonRpcRequest): Promise { + this.retryInitIfNeeded(); this.transport.sendResult(request.id, { - tools: tools, + tools: this.toolHandler.getTools(), }); } diff --git a/src/mcp/tools.ts b/src/mcp/tools.ts index aebfe97..585479f 100644 --- a/src/mcp/tools.ts +++ b/src/mcp/tools.ts @@ -15,6 +15,19 @@ import { join } from 'path'; /** Maximum output length to prevent context bloat (characters) */ const MAX_OUTPUT_LENGTH = 15000; +/** + * Calculate the recommended number of codegraph_explore calls based on project size. + * Larger codebases need more exploration calls to cover their surface area, + * but smaller ones should use fewer to avoid unnecessary overhead. + */ +export function getExploreBudget(fileCount: number): number { + if (fileCount < 1000) return 2; + if (fileCount < 5000) return 3; + if (fileCount < 15000) return 4; + if (fileCount < 25000) return 5; + return 6; +} + /** * Mark a Claude session as having consulted MCP tools. * This enables Grep/Glob/Bash commands that would otherwise be blocked. @@ -298,6 +311,32 @@ export class ToolHandler { return this.cg !== null; } + /** + * Get tool definitions with dynamic descriptions based on project size. + * The codegraph_explore tool description includes a budget recommendation + * scaled to the number of indexed files. + */ + getTools(): ToolDefinition[] { + if (!this.cg) return tools; + + try { + const stats = this.cg.getStats(); + const budget = getExploreBudget(stats.fileCount); + + return tools.map(tool => { + if (tool.name === 'codegraph_explore') { + return { + ...tool, + description: `${tool.description} Budget: make at most ${budget} calls for this project (${stats.fileCount.toLocaleString()} files indexed).`, + }; + } + return tool; + }); + } catch { + return tools; + } + } + /** * Get CodeGraph instance for a project * @@ -854,6 +893,16 @@ export class ToolHandler { lines.push('---'); lines.push(`> **Complete source code is included above for ${filesIncluded} files.** You do NOT need to re-read these files — the relevant sections are already shown in full. Only use Read/Grep for files listed under "Additional relevant files" if you need more detail.`); + // Add explore budget note based on project size + try { + const stats = cg.getStats(); + const budget = getExploreBudget(stats.fileCount); + lines.push(''); + lines.push(`> **Explore budget: ${budget} calls max for this project (${stats.fileCount.toLocaleString()} files indexed).** Stop exploring and synthesize your answer once you've used ${budget} calls — do NOT make additional explore calls beyond this budget.`); + } catch { + // Stats unavailable — skip budget note + } + return this.textResult(lines.join('\n')); }