[FEATURE] Project-level plugin loading: let projects control which plugins (and their MCP tools) are active

Resolved 💬 2 comments Opened Apr 11, 2026 by Tsinglung-Tseng Closed May 24, 2026

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:

  1. enabledPlugins: false at project level — buggy, frequently ignored (#28554). Disabled plugins still fire hooks (#41919, #39307).
  2. mcpServers project-level replace — only controls mcpServers entries, not plugin-provided MCP servers. Plugins contribute 80% of MCP tools in my setup.
  3. --bare — all-or-nothing, also strips skills, memory, and CLAUDE.md.
  4. /mcp toggle — per-session, manual, not persistent per project.
  5. 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 false must 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 enabledPlugins project 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 mcpServers for 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: false ignored (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

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗