Skip to content

MCP budget: lower get_index_usage's default row limit under budget (#4198) - #4260

Merged
erikdarlingdata merged 3 commits into
devfrom
fix/4198-index-usage-default
Sep 25, 2026
Merged

erikdarlingdata merged 3 commits into
devfrom
fix/4198-index-usage-default

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Part of #4198.

Why

get_index_usage already had a caller-optional limit parameter (#2636), but its default value was still the pre-#2636 hardcoded cap of 200 rows. #4198 measured a default call, with no arguments, at 69,290 bytes on a busy production store (848 ms). That is more than double McpResponseBudget.DefaultBytes, 32 KB. A default call's reply was large enough for an MCP client to refuse it outright, the same failure #4198 found across the read-tool set.

What changes

  • Darling (DarlingMcpObjectStatsTools.GetIndexUsage) and Lite (McpObjectStatsTools.GetIndexUsage): IndexUsageTop, the limit parameter's default, drops from 200 to 75 rows. That size comes from the measured rate, about 346 bytes per row (69,290 bytes over 200 rows). The parameter itself, its validation (McpHelpers.ValidateTop), and the truncation envelope (returned_index_count, matching_index_count, truncated, note) stay the same. [BUG] - get_index_usage MCP tool hardcodes a 200-row cap ordered unused-first, silently hiding all "Active"/"Write-only" indexes and any database whose indexes don't rank in the global top 200 #2636 already built that shape. This lane only resizes the fallback. An explicit limit still gets exactly what it asks for, up to McpHelpers.MaxTop.
  • Parameter description text changes from "Default 200." to "Default 75." on both products. The tools/list byte-budget pins (DarlingMcpObjectStatsTools.txt, McpObjectStatsTools.txt) drop from 36 to 35 bytes to match, one fewer digit.
  • New live test Darling.Tests/IndexUsageBudgetLiveTests.cs. It seeds 200 index rows across 10 databases on a real PostgreSQL store and checks three things. The default call stays under budget and comes back truncated. An explicit limit covering the seeded set returns every row untruncated.
  • New Lite test Lite.Tests/IndexUsageBudgetTests.cs, the same three checks against Lite's shared DuckDB fixture. No rig needed.
  • get_index_usage is not on A budget pin over every MCP read tool (part of #4198) #4224's McpReadToolBudgetLiveTests ExemptOffenders roster. That fixture does not seed index_object_stats, so McpReadToolBudgetLiveTests.cs itself is untouched here. This lane's own fixture covers the gap A budget pin over every MCP read tool (part of #4198) #4224 already documents for this tool.

Test plan

  • Darling.Tests build: 0 Warning(s), 0 Error(s).
  • Lite.Tests build: 0 Warning(s), 0 Error(s).
  • New live test IndexUsageBudgetLiveTests: default call measured 25,913 bytes, down from the 69,290 bytes the field measurement found, under the 32,768-byte budget. truncated is true. An explicit limit=200 returns all 200 seeded rows, not truncated.
  • New Lite test IndexUsageBudgetTests: default call measured 25,902 bytes. Same three checks, passing.
  • Targeted classes green on the rig. Darling: IndexUsageBudgetLiveTests, IndexUsageTruncationTests, IndexUsageTruncationLivePostgresTests, DarlingMcpObjectStatsToolsSurfaceAndSqlTests, DarlingMcpObjectStatsToolsLivePostgresTests, DarlingIndexLockingRenamedDatabaseLivePostgresTests, McpToolsListBudgetTests, McpPayloadContractCensusTests. Lite: IndexUsageBudgetTests, IndexUsageTruncationTests, McpToolsListBudgetTests, CrossAppMcpToolInventoryPinTests.
  • Full Lite.Tests suite after merging origin/dev: 5,340 total, 0 failed.
  • Full Darling.Tests suite after merging origin/dev: 13,849 total, 3 failed, 47 skipped, 1 not run. All 3 failures passed cleanly when re-run alone right after, on a freshly recreated database: CaptureDownChunkOrderTests...AgainstDevPostgres, ServerListAndSummaryPlanShapeTests...AgainstDevPostgres, TrendPayloadBudgetLiveTests.EveryDefaultAnswer.... These are suite-order, chunk-count flakes from a 13,800-test run sharing one database, not from this change. TrendPayloadBudgetLiveTests is the exact flake the MCP read tools have no default response-size budget: at default arguments 12 tools return >50 KB and 3 return >100 KB for one server, more than an agent client's per-result cap #4198 common brief already names as failing locally on unrelated branches tonight. None of the three touch index_object_stats, DarlingObjectStatsReader, or either object-stats tools file.

CHANGELOG entry

SECTION: Fixed
ENTRY:

Generated with Claude Code

https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3

erikdarlingdata and others added 3 commits September 25, 2026 03:15
…4198)

200 rows (get_index_usage's caller-optional limit default since #2636) measured
69,290 bytes on a busy production store, more than double McpResponseBudget's
32 KB target. Lowers the default to 75 on both Darling and Lite, matching the
per-row math #4198 measured elsewhere; an explicit limit still gets every row
it asks for.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
Matches the Darling live test's diagnostic line so both products' PR
numbers come from the same test run.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
@erikdarlingdata erikdarlingdata changed the title DO NOT MERGE (MCP budget): lower get_index_usage's default row limit under budget (#4198) MCP budget: lower get_index_usage's default row limit under budget (#4198) Sep 25, 2026
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 25, 2026 07:44
@erikdarlingdata
erikdarlingdata merged commit c935602 into dev Sep 25, 2026
20 of 22 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/4198-index-usage-default branch September 25, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant