feat(profile): mcpPrune field — auto-prune MCPs without an env var#91
Merged
Conversation
Adds a `mcpPrune: off|profile|all` profile field setting the default non-interactive prune mode, so a heavy profile drops its unused MCPs on every launch with no CUE_PRUNE_MCPS needed. The env var still overrides per launch (explicit launch-time intent > profile default). - profiles/_types.ts: McpPruneMode type + Profile.mcpPrune (flows to ResolvedProfile). - profiles/schema.json: mcpPrune enum [off,profile,all]. - profile-loader.ts: leaf-wins through inheritance; most-aggressive wins across composite parts (off<profile<all) — safe, since prune only drops unused, non-pinned MCPs. Fixed the composite fold loop dropping the resolved value. - launch.ts: effective mode = env (if set) else profile.mcpPrune else off; the auto-prune branch and its log line report the source. - mcp-overrides.ts: McpPruneMode now re-exported from _types (single source). Tests: profile-loader mcpPrune resolution (unset/single/inherit/composite). Verified e2e: a profile with mcpPrune:all drops an unused MCP on a clean-cwd launch with no env var; pinned MCPs kept. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…w M1) Review flagged that the new env-overrides-profile logic enlarged a foot-gun: a non-empty but unrecognized CUE_PRUNE_MCPS (a typo like `profil`) parses to "off" and would silently SUPPRESS a profile's mcpPrune default. Add isRecognizedPruneEnv so a set-but-unrecognized value is a no-op: warn to stderr and fall through to the profile default, instead of disabling it without a diagnostic. An explicit `off`/`0`/`false` still wins over the profile (recognized). Co-Authored-By: Claude Opus 4.8 (1M context) <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.
What
Makes MCP pruning automatic per-profile instead of only opt-in via env. Follow-up to #90 (which added the opt-in
CUE_PRUNE_MCPS). A profile can now declare a default prune mode so a heavy profile drops its unused MCP tool schemas on every launch with no env var..claude.json.CUE_PRUNE_MCPSstill overrides at launch (explicit launch-time intent > profile default). Pruning only ever drops MCPs no active skill needs and that aren'tpinned, so a higher mode is always safe.Changes
profiles/_types.ts:McpPruneModetype +Profile.mcpPrune(flows toResolvedProfile).profiles/schema.json:mcpPruneenum.src/lib/profile-loader.ts: leaf-wins through single inheritance; most-aggressive wins across composite parts (off<profile<all). Fixed the composite fold loop that dropped the resolved scalar.src/commands/launch.ts: effective mode = env (if set) elseprofile.mcpPruneelse off; log line reports the source.src/lib/mcp-overrides.ts:McpPruneModere-exported from_types(single source of truth).Test plan
bun test src/lib/profile-loader.test.ts— newmcpPrune resolutionblock (unset / single / inherit / composite most-aggressive): 32 pass.bunx tsc --noEmit— clean.mcpPrune: alldrops an unused MCP (dataforseo) on a clean-cwd launch with no env var, keeps pinnedcodegraph; env override still works.🤖 Generated with Claude Code