MCP budget: size get_active_queries defaults to the response budget (#4198) - #4261
Merged
Merged
Conversation
A busy production store's default call (limit 50) measured 56,586 bytes, over McpResponseBudget.DefaultBytes (32 KB). Twenty-three fields per row mean the fixed columns alone run about 700 bytes/row before query_text is counted, so both the default row limit (50 -> 25) and query_text's preview (now 500 chars, full_query_text opts back in) come down, on both Darling and Lite. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
…s-default # Conflicts: # Darling/Darling.Tests/McpToolsListBudgetTests.cs
The full-suite run surfaced five failures, all from the active-queries budget change: a hardcoded param-order pin missing full_query_text, the served head over its own separate 620-character target (moved the preview note after <<GUIDE>> instead, keeping the head at its original 616 bytes), and a doc comment that crefed a file name instead of a real type. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
DarlingMcpSessionTools.GetActiveQueries now delegates to an internal overload that takes an explicit query-text preview length (the split #3897's trend tools use: one MCP-facing method, one budget-taking overload). The MCP tool passes 500 (or null for full_query_text), and DarlingWebEndpoints' /api/read row passes 2000 - the pre-#4198 budget every caller got - so the web viewer's page doesn't shrink under the new MCP default. query_text_truncated stays honest on both paths. Adds a no-rig source-text pin (ReadEndpoints_ActiveQueries_ KeepsTheTwoThousandCharacterWebPreview) that fails if the web row stops calling the overload with 2000; verified it fails against the pre-fix row shape, then confirmed it passes again after restoring the fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
Matches get_store_query_stats' full_text (the #4198 precedent) and the other #4198 tools, on both Darling and Lite. Description text is unchanged, so each param's pinned byte count stays 84; the shorter property name shrinks the served tools/list JSON by 6 bytes on each product, banked by lowering TotalCeilingBytes to the measured total (171,906 Darling, 90,057 Lite). Lite's UI reads LocalDataService directly, not this MCP tool (grep confirms no Lite UI call site), so no UI-facing change there. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
…CutKeys All deltas: audit+plan_corrections+deadlock_detail (dev) + active_queries TH+W2 (HEAD). query_text_truncated merges session+plan_correction files into one entry. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
Lane W2 added ReadRepoFileLf to DarlingWebEndpointsTests.cs for a single-line dispatch-table pin; no line-break anchor, so it belongs in s_lfSubjects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
erikdarlingdata
marked this pull request as ready for review
September 25, 2026 09:14
erikdarlingdata
enabled auto-merge (squash)
September 25, 2026 09:14
Darling: HEAD=172,407 (active_queries +187) + dev=172,367 -> 172,554 Lite: HEAD=90,447 (active_queries +176) + dev=90,418 -> 90,594 Census: merge active_queries files into query_text_truncated + keep top_query_text_truncated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
erikdarlingdata
added a commit
that referenced
this pull request
Sep 25, 2026
Measured with McpToolsListBudgetTests after merging origin/dev (#4261, #4258, #4265, #4267, #4264, #4266 and #4268) plus this PR's catalog changes. Budget, census and tool-guide classes: 219/219. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
erikdarlingdata
added a commit
that referenced
this pull request
Sep 25, 2026
…nder the response budget (#4198) (#4272) * MCP budget: describe_custom_view_catalog default groups measures by source (#4198) Default default-argument call was 98,173 bytes (#4198's own measurement), three times the tool's 32 KB budget. It is pure static reference data (no server/store read), so the cut groups the 179 measures by source and keeps only key/displayName/kind/unitFamily/validAggregates per measure; source=<name> drills into one source's full detail, full_detail=true returns the original shape unfiltered. /api/catalog (the web Custom Views editor) calls the underlying builder directly, never this MCP method, so it is unaffected - pinned in DarlingComposeTests. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3 * Trigger CI (draft PR skipped the Build workflow) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ * Add comment to DarlingMcpCustomViewCatalogSizeTests.cs to trigger Build CI GitHub did not fire pull_request events for this draft-opened PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ * fix(#4272): reword validAggregates description - compact drops allowedDimensions, source=<name> returns it Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3 * #4272: set TotalCeilingBytes to the measured 174,236 after merging dev Measured with McpToolsListBudgetTests after merging origin/dev (#4261, #4258, #4265, #4267, #4264, #4266 and #4268) plus this PR's catalog changes. Budget, census and tool-guide classes: 219/219. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #4198.
Why
get_active_querieshad no default response-size budget. A busy production store's default call (limit 50, hours_back 1) measured 56,586 bytes on 2026-09-25, well over the shared 32 KBMcpResponseBudget.DefaultBytes.Unlike
get_deadlock_detail(#4254), this tool has no single dominant wide field. Each row carries twenty-three fields. The fixed columns (collection_time, every wait/blocking/memory field,login_name,host_name,program_name) add up across the page even beforequery_textis counted. A synthetic 50-row page of this shape measured 81,489 bytes with the old code. Every optional field was populated, a fifth of rows carrying a long literal list. Isolating the fixed-column cost: even atquery_text = "", 50 rows of this shape run close to the budget on their own.What changes
Both Darling (
DarlingMcpSessionTools.GetActiveQueries) and Lite (McpSessionTools.GetActiveQueries), matching the shape #4254 established:limitcomes down from 50 to 25, sized so a full default page of wide rows fits the budget.query_textpreviews to 500 characters by default (down from a flat, unconditional 2000-character cap) with a new per-rowquery_text_truncatedflag.full_textopt-in argument (defaultfalse) returns every row's whole text. This is the same shapeget_store_query_stats'full_textandget_deadlock_detail'sfull_graphuse.truncated/total_snapshotsalready told a caller who wants more to raiselimitor narrowhours_back. That is unchanged.Lane W2 (this update)
McpHelpers.Truncate(r.QueryText, 2000). A naive drop of the MCP default to 500 also shrinks the web page's text.DarlingMcpSessionTools.GetActiveQueriesnow splits in two: a public MCP-facing method, and an internal overload that takes an explicit query-text preview length. This is the same split Trend tools return every raw point: get_file_io_trend sends 12,451 points / 1.4 MB for one server at defaults, more than an LLM client's context #3897's trend tools use for their budgets. The public method passes 500, or no truncation at all whenfull_textis set.DarlingWebEndpoints'/api/readrow calls the internal overload with 2000, the pre-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 amount.query_text_truncatedstays honest on both paths: false whenever the preview length is null, or the text does not exceed it. Lite is unaffected. Its UI readsLocalDataServicedirectly, not this MCP tool. A grep confirms this: the only other reference toMcpSessionToolsinLite/is its MCP host registration.DarlingWebEndpointsTests.ReadEndpoints_ActiveQueries_KeepsTheTwoThousandCharacterWebPreview, that readsDarlingWebEndpoints.cs's source text and fails if theget_active_queriesrow stops calling the overload with the literal2000. Verified it fails against the pre-fix row shape (temporarily reverted, ran the test, saw[FAIL], then restored the fix and reconfirmed[PASS]).full_query_texttofull_text, on both Darling (DarlingMcpSessionTools.cs) and Lite (Lite/Mcp/McpSessionTools.cs). This matchesget_store_query_stats'full_text, 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 precedent named in the issue, and the other 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 tools. Each parameter's own description text is unchanged, so its pinned byte length inMcpToolsListBudget/*SessionTools.txtstays 84 on both products. The shorter property name shrinks the servedtools/listJSON by 6 bytes on each product. That saving is banked by loweringTotalCeilingBytesto the newly measured total (171,906 Darling, 90,057 Lite), with a new change-log comment line on each.query_text_truncatedtoMcpPayloadContractCensusTests' newFieldPreviewCutKeysroster. This is added here because MCP budget: preview the deadlock graph XML by default on get_deadlock_detail (#4198) #4254 had not merged yet. Expect a merge conflict with it that just combines both tools' entries.ExemptOffendersroster, soMcpReadToolBudgetLiveTests(also not merged yet) was left untouched.The tool's served head description is unchanged at 616 bytes. The new preview/opt-in note went after the
<<GUIDE>>marker instead. A separate pin,McpToolGuideTests.EveryConvertedHead_StaysAtOrUnder620Characters, caps converted heads at 620 characters, tighter than the general 1,000-byte cap this repo's skill notes describe.Test plan
New live test
Darling/Darling.Tests/DarlingMcpActiveQueriesBudgetLiveTests.csplants 50 rows shaped like a busy server. It is its own file, not the shared seeding helpers, because many #4198 lanes ran against this rig tonight.full_query_text: trueopts back into the whole text, andquery_text_truncatedis nevertrueon that call.New Lite test
GetActiveQueries_Default_StaysUnderResponseBudget_WithFiftyRealisticRowsinLite.Tests/McpPageContractTests.csasserts the same shape and the same opt-in behavior (DuckDB, no rig needed).darlingtest): 13,849 total, 5 failed, 47 skipped, 1 not run. Every failure traced back to this change. All fixed in a follow-up commit: a param-order pin, the 620-char head cap noted above, and a<see cref>type/file error.DarlingMcpSessionToolsSurfaceAndSqlTests,McpToolGuideTests,McpToolGuideHeadsSqlCoreActiveQueriesTests,DocCommentHygieneTests,McpToolsListBudgetTests,McpPayloadContractCensusTests,DarlingMcpSessionToolsTests,DarlingMcpActiveQueriesBudgetLiveTests,McpFilterSemanticsLivePostgresTests): 181 total, 0 failed.git merge origin/devdone. One conflict, inMcpToolsListBudgetTests.cs's ceiling constant, resolved by keeping both change-log comments and re-measuring the constant.Lane W2 (this update, no rig: DARLING_TEST_PG unset, live classes skip)
ReadEndpoints_ActiveQueries_KeepsTheTwoThousandCharacterWebPreview) proven to fail on the pre-fix row shape, then confirmed passing again after restoring the fix.DarlingWebEndpoints.cs(50 classes, grep-derived), plusMcpToolsListBudgetTests,McpPayloadContractCensusTests, andDocCommentHygiene. 1,506 total, 0 failed, 33 skipped (all live, no rig).CHANGELOG entry
SECTION: Fixed
ENTRY:
get_active_queriesstays under its response-size budget by default ([MCP budget: size get_active_queries defaults to the response budget (#4198) #4261]) - A default call on a busy server returned well over the 32 KB target. The number of fields per row and an uncapped query text preview were the cause. The default page size is now 25 rows (was 50). Query text now previews to 500 characters with aquery_text_truncatedflag. A newfull_textargument opts back into the whole text. The web viewer's Active Queries tab keeps its pre-existing 2,000-character preview.REF:
[MCP budget: size get_active_queries defaults to the response budget (#4198) #4261]: MCP budget: size get_active_queries defaults to the response budget (#4198) #4261
Generated with Claude Code
https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ