Repository navigation
get_pg_extensions/get_pg_write_stats/get_pg_server_config(_changes) move reading guidance off tools/list (#3898) - #4078
Merged
Conversation
…3898) get_pg_extensions, get_pg_write_stats, get_pg_server_config and get_pg_server_config_changes each served 1,146-2,252 characters of guidance in tools/list. Each now serves a short head (498-612 chars) plus a pointer, with the full original text moved to get_tool_guide's tail. Nothing was deleted and no tool behavior changed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M7r1CXmEcBmsrTV34CCLfF
erikdarlingdata
marked this pull request as ready for review
September 23, 2026 21:15
erikdarlingdata
enabled auto-merge (squash)
September 23, 2026 21:15
erikdarlingdata
added a commit
that referenced
this pull request
Sep 23, 2026
…ntries in their sections (#4080) Adds 42 entries and 42 link refs (#3992, #3995, #3996, #3998, #4001, #4002, #4003, #4007, #4010, #4011, #4013, #4015, #4020, #4022, #4025, #4029, #4030, #4031, #4036, #4038, #4039, #4040, #4044, #4047, #4048, #4049, #4050, #4051, #4055, #4061, #4063, #4064, #4065, #4066, #4067, #4068, #4069, #4070, #4071, #4073, #4074, #4078). Each PR's entry was buffered, and this lands every entry whose PR was merged on origin/dev when it ran. #3989 left 26 entries under bare 'Changed' and 'Fixed' lines above '### Added'. They move into '### Changed' and '### Fixed', below the new entries, and one blank line stays under [Unreleased]. Claude-Session: https://claude.ai/code/session_01Ua31ugERL5DmhFVRtf6keQ Co-authored-by: Claude Opus 5.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.
Refs #3898.
Why
Issue #3898: a client that loads Darling's whole MCP catalog pays about 330 KB of
tools/listbefore its firstquestion. Four tools in
DarlingMcpPgServerStateTools.cscarried 1,146 to 2,252 characters each. This PR movesthat guidance off
tools/listand intoget_tool_guide, which serves it on request. Nothing is deleted.What changes
Converted, in this order:
get_pg_extensions,get_pg_write_stats,get_pg_server_config, thenget_pg_server_config_changes. All four are Darling-only. Lite has no PostgreSQL target, so there is no twin toconvert (D6 does not apply).
Every original sentence moved to the tail unchanged. The tail is the tool's full original description, byte for
byte. The head is new, short text written to carry the guardrail facts. Confirmed with the dropcheck script:
missing=0on all four.D2 parameter caps
Two parameters were over the 200-character cap.
get_pg_server_config.include_defaultswas 249 chars and is now 164 chars. Its dropped clause named one fact: apending_restart row is kept in that view whatever its source. That fact now sits in a new tail sentence:
A setting marked pending_restart is kept in the non-default view whatever its source, because it is the row that says the file and the server disagree.get_pg_extensions.database_namewas 803 chars and is now 196 chars. Its dropped clause named one number: asixteen-database host holds 1,632 rows. That number now sits in a new tail sentence:
A sixteen-database host's product is 1,632 rows against the 1,000-row maximum. database_name completes one database at a time instead, sixteen calls that each finish.Head pins
New file:
Darling/Darling.Tests/McpToolGuideHeads.PgB.cs(McpToolGuideHeadsPgBTests). It follows the PgApattern. It pins each tool's guardrail facts. It checks that the D2 overflow text landed in the tail. It checks
that the two trimmed parameters stayed at or under 200 characters.
Budget
Updated
Darling/Darling.Tests/McpToolsListBudget/DarlingMcpPgServerStateTools.txtfor all four tools and theirtwo changed parameters. This PR does not touch the total ceiling (
McpToolsListBudgetTests.TotalCeilingBytes). Itonly lowers the measured total.
No topic file entry
None of these four tools shares repeated prose with another.
PerformanceMonitor.Common/Mcp/McpToolGuideTopics.PgB.csstays at its pre-created empty
s_pgB = [].Corrections
None. No original sentence was found to misstate tool behavior.
D4 removals
None. None of the four descriptions carried an issue reference, an anecdote, or a WIRE CHANGE notice.
Re-pointed pins
None needed re-pointing to a specific half. Three existing pins read the tool's full
[Description]attributetext, head and tail combined, rather than the served head alone. They kept passing once the full original text
landed in the tail.
McpLatestSnapshotStampTests.DarlingOnlyStampedTools_KeepTheStampedDialectrequiresget_pg_server_configtostate
captured_atandLATEST IS A TIME. Both phrases are also in the new head. The brief named them asguardrail facts a caller must see without a second call.
McpPageContractTests.PgServerConfig_NamesItsDenominators_InItsDescriptionrequirestruncated,THE PAGE IS BOUNDED BY limit,COUNTS ARE OF THE SNAPSHOT, NOT OF THE PAGE,non_default_count,non_default_returned, andsettings_returned, plus matching text in thelimitandinclude_defaultsparameter descriptions. This test caught the one real defect in this PR. My first draft of the trimmed
include_defaultsdescription dropped the wordpending_restart. This test requires it. I fixed it byrewording the trimmed parameter to keep the word.
PgServerConfigScopeRungTests.TheToolAttachesTheOverrideSection_AndLeavesTheServerWideCountsAlonerequiresPER-DATABASE AND PER-ROLE OVERRIDES ARE A SEPARATE SECTIONanddatabase_overrides.D9: known traps for the misreading check
get_pg_extensionsreturns fewer rows than a 16-database host has. Does that mean only those databaseshave extensions?
Correct: No. Rows are capped by
limit.truncatedwithholds the state totals, and installed rows (forexample
plpgsql) are the first ones a cap removes.Prevents it: the head's
Rows are databases x extension names, so a multi-database host overflows limit; truncated withholds state totals, and installed rows like plpgsql are cut first. Read install_census for the complete picture.get_pg_extensionsshowsplpgsqlas absent on a large host. Is it really not installed?Correct: No. It is the extension most likely to be cut by a row cap. It is not the extension most likely
to be missing.
Prevents it: the head's
installed rows like plpgsql are cut first.get_pg_write_statsreturns several rows across a day. Can they be charted as a time series?Correct: No. One row describes the whole window. There is no series.
Prevents it: the head's
as ONE row, not a series.get_pg_write_stats.buffers_backendis null on a PostgreSQL 17 server. Was nothing measured?Correct: No. PostgreSQL 17 removed the column. The fact now lives in
pg_stat_io, read byget_pg_io_stats.Prevents it: the head's
buffers_backend/buffers_backend_fsync are NULL on PostgreSQL 17+ (moved to pg_stat_io; see get_pg_io_stats), not unmeasured.get_pg_write_stats'swal_bytesis null on an Aurora target. Does that mean no WAL was written?Correct: No. Aurora does not implement
pg_stat_walat all, so the column is always null there.Prevents it: the head's
wal_* columns are NULL on Aurora (no pg_stat_wal); get_pg_top_queries has per-statement WAL.get_pg_write_stats.checkpoints_requestedis null right after a restart. Is that a data gap?Correct: No. A restart inside the window deliberately nulls that field. A shutdown checkpoint's own
counters cannot be told apart from the workload's.
Prevents it: the head's
A restart inside the window nulls checkpoints_requested, its percent, both checkpoint time fields and buffers_written_checkpoint.get_pg_server_configis called mid-incident. Does it show the setting's live value right now?Correct: No. It is the newest stored snapshot from an hourly collector, not the live server.
Prevents it: the head's
LATEST IS A TIME: the newest stored snapshot, not a window or the live server; captured_at is when it was taken (collector runs hourly).get_pg_server_config'snon_default_countsays 40 but only 25 rows came back atlimit=25. Does theserver only have 25 non-default settings?
Correct: No.
non_default_countcounts the whole snapshot.settings_returned(25) is only this page.Prevents it: the head's
non_default_count is the snapshot's, not the page's.get_pg_server_config's answer has nodatabase_overrideskey. Does that mean the check did not run?Correct: No. The key is present only when the cluster actually has an override.
Prevents it: the head's
database_overrides (present only if any exist) is what sessions actually run with.get_pg_server_config_changesreturns no rows right after an upgrade added new extension settings. Didnothing change?
Correct: A setting's first appearance is deliberately not reported as a change. So "no rows" is expected
even after a real upgrade.
Prevents it: the head's
A setting appearing for the FIRST time (an upgrade, a new extension) is NOT reported as a change.get_pg_server_config_changesshows a row withold_value: null. Is that a collection error?Correct: No. That is a
setchange: an override appeared where none existed, soold_valueislegitimately null.
Prevents it: the head's
carrying change_kind: changed, set (old_value null) or reset (new_value null).get_pg_server_config_changesshows a change right after a monitoring tool reconnected. Is that a realconfiguration change?
Correct: No. Session-scoped rows are excluded, so a reconnect never reads as one.
Prevents it: the head's
Session-scoped rows are excluded.Test plan
dotnet build Darling/Darling.Tests/Darling.Tests.csproj -c Debug. Build succeeded, 0 Warning(s), 0Error(s).
McpToolsListBudgetTests,McpToolGuideHeadsPgBTests,McpLatestSnapshotStampTests,McpPageContractTests,PgServerConfigScopeRungTests,DarlingMcpToolsTests, and the sharedMcpToolGuide*/McpDescription*/McpZeroIsAMeasurement*/McpPayloadContractCensus*suites. Also every other class naming one of the four tools. One real failureturned up along the way and was fixed. See "Re-pointed pins" above.
python dropcheck.py origin/dev HEAD get_pg_extensions get_pg_write_stats get_pg_server_config get_pg_server_config_changes. Result:missing=0on all four.git merge origin/dev, which picked up three unrelated The MCP surface costs ~100k tokens of context before the first call: 157 tools, 336 KB of tools/list, 86 KB of instructions #3898 lanes' commits. Clean merge, no conflicts.Darling.Tests.exe. Total: 13,236, Errors: 0, Failed: 0, Skipped: 631. Theskips are the live-PostgreSQL classes. This lane has no rig.
attribution emoji.
Coordinator verification
Handoff
get_pg_lock_statsandget_pg_buffer_usage, the other two tools onDarlingMcpPgServerStateTools.cs, are leftfor a later lane, per this lane's brief.
🤖 Generated with Claude Code
https://claude.ai/code/session_01M7r1CXmEcBmsrTV34CCLfF