[FEATURE] Project-level plugin loading: let projects control which plugins (and their MCP tools) are active
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Plugins are globally enabled — there is no reliable way to control which plugins load per project. This matters because plugins are the dominant source of MCP tool context overhead.
Measured data (my setup, 14 plugins enabled globally):
| Source type | MCP tools loaded | Tokens | Project-level controllable? |
|-------------|-----------------|--------|-----------------------------|
| Plugins | ~80 tools | ~25k | No |
| mcpServers | ~17 tools | ~4k | Yes (project replace works) |
For an Obsidian vault project that only needs 3 MCP sources (pageindex, claude-mem, xiaohongshu), 65+ plugin MCP tools load for nothing.
Why existing mechanisms don't work:
enabledPlugins: falseat project level — buggy, frequently ignored (#28554). Disabled plugins still fire hooks (#41919, #39307).mcpServersproject-level replace — only controlsmcpServersentries, not plugin-provided MCP servers. Plugins contribute 80% of MCP tools in my setup.--bare— all-or-nothing, also strips skills, memory, and CLAUDE.md./mcptoggle — per-session, manual, not persistent per project.- TUI scope change (#44470) — requested but not yet implemented; would help but still requires manual toggling per plugin.
Proposed Solution
Step 1: Fix project-level enabledPlugins override (minimal, high impact)
Allow projects to reliably declare which plugins should be active via .claude/settings.json:
{
"enabledPlugins": {
"claude-mem@thedotmack": true,
"obsidian@obsidian-skills": true,
"cli-anything@cli-anything": false,
"pyright-lsp@claude-plugins-official": false
}
}
Requirements:
- Project-level
falsemust actually prevent the plugin's MCP server from starting, tools from registering, and hooks from firing - Plugins not listed in project config inherit from global (merge, not replace — unlike
mcpServers) - This requires no new API surface — just making the existing
enabledPluginsproject override work as documented
Step 2: Lazy plugin MCP loading (stretch goal)
Beyond per-project override, plugin MCP servers could adopt the ToolSearch deferred pattern (#44536): register plugin name + tool names at startup, but defer full schema loading and MCP server connection until a tool is actually invoked. This would reduce the ~25k token overhead to near-zero even without per-project config.
Alternative Solutions
- Convert plugins to mcpServers — find each plugin's underlying MCP server command and declare it in
mcpServersfor project-level replace. Works but loses plugin skills, agents, system instructions, and auto-updates. - MCP proxy (lazy-mcp) — community workaround that wraps servers behind 2 meta-tools. Only works for
mcpServers, not plugin MCP. - Global minimalism — keep global plugins minimal, manually toggle. Defeats the purpose of a plugin ecosystem.
Priority
High - Significant impact on productivity
Feature Category
Performance and speed
Additional Context
Related issues:
- #28554:
enabledPlugins: falseignored (core blocker) - #41919, #39307: Disabled plugins still fire hooks
- #44470: TUI plugin scope change request
- #44371: Plugin skills load full content at startup
- #33689: Sub-agent scoped MCP configs broken in plugins
- #44536: Lazy context loading proposal (broader scope)
- #11596: Per-project plugin toggle (closed by autoclose)
- #14202: Project-scoped plugin detection bugs
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗