Feature Request: Lazy Loading for MCP Servers and Tools (95% context reduction possible)
Feature Request: Lazy Loading for MCP Servers and Tools
Problem Statement
Currently, Claude Code loads all configured MCP servers, tools, and agents at session startup, consuming significant context before any conversation begins. In my environment:
- MCP tools: 39.8k tokens (19.9%)
- Custom agents: 9.7k tokens (4.9%)
- System tools: 22.6k tokens (11.3%)
- Memory files: 36.0k tokens (18.0%)
- Total: ~108k tokens (54% of 200k limit)
This leaves only 92k tokens for actual conversation and work, severely limiting complex tasks.
Proposed Solution
Implement lazy loading for MCP servers and tools, loading them only when needed based on conversation context.
Core Features
- Lightweight Registry System
- Load only a small index (~5k tokens) at startup
- Registry contains tool names, descriptions, and trigger keywords
- Tools load on-demand when keywords are detected
- Intelligent Loading
- Analyze user input for relevant keywords
- Load only required tools for the task
- Cache loaded tools for session duration
- Preload related tools that commonly work together
- Configuration Options
``json``
{
"optimization": {
"lazyLoading": true,
"maxInitialTokens": 5000,
"autoLoadThreshold": 0.8,
"cacheMinutes": 30
},
"mcpServers": {
"example-server": {
"command": "...",
"lazyLoad": true,
"triggers": ["keyword1", "keyword2"],
"preloadWith": ["related-server"]
}
}
}
Benefits
- 95% Token Reduction: From 108k to ~5k initial tokens
- Longer Conversations: 195k tokens available vs 92k currently
- Better Performance: Faster startup, lower memory usage
- Scalability: Can add more tools without context penalty
Implementation Suggestion
Phase 1: Basic Lazy Loading
- Add
lazyLoadflag to MCP server configs - Load registry instead of full tool definitions
- Implement on-demand loading when tool is called
Phase 2: Intelligent Preloading
- Keyword-based auto-loading
- Pattern recognition for common workflows
- Tool relationship mapping
Phase 3: Advanced Optimization
- Session-based learning of tool usage patterns
- Predictive preloading based on project context
- Dynamic unloading of unused tools
User Experience
Before (Current)
Starting session...
Loading 73 MCP tools... [39.8k tokens]
Loading 56 agents... [9.7k tokens]
Loading system tools... [22.6k tokens]
Ready with 92k tokens remaining.
After (With Lazy Loading)
Starting session...
Loading tool registry... [5k tokens]
Ready with 195k tokens available.
User: "I need to build a React component"
> Auto-loading: context7, magic [+3.5k tokens]
> 191.5k tokens remaining
Test Case
I've already built a proof-of-concept in ~/.claude/optimization/ that demonstrates:
- Registry generation from existing MCP configs
- Keyword extraction and mapping
- Lazy loader with pattern matching
- 95% token reduction achieved
Files available for reference:
tool-registry.json- Example registry structurelazy-loader.py- Proof of concept implementationgenerate-index.py- Registry generation logic
Priority
High - This is a critical limitation for power users with many tools and complex workflows. The current 54% context consumption at startup makes many advanced use cases impossible.
Similar Products
- VSCode: Lazy loads extensions based on file types and activation events
- JetBrains IDEs: Load plugins on-demand based on project type
- Vim/Neovim: Lazy loading plugins (lazy.nvim, vim-plug with lazy loading)
Contact
Happy to provide more details, test beta implementations, or share the proof-of-concept code.
---
Submitted by: dtaylor
Date: July 9, 2025
Claude Code Version: [Current Version]
Impact: Affects all users with multiple MCP servers configured
27 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
I've created a proof-of-concept implementation demonstrating this lazy loading system:
🔗 Repository: https://github.com/machjesusmoto/claude-lazy-loading
The implementation shows:
This could be integrated into Claude Code to dramatically improve the experience for power users with multiple MCP servers configured.
@machjesusmoto How does it work? Does it change what mcps / tools are visible when the
/mcpcommand is invoked?I think this is definitely a must to properly support MCP servers. I was thinking just giving defined Agents the ability to keep their own MCP server references (and being able to select only a sub-set of tools from any given MCP server). Then, for example, if I wanted to implement one of my Linear tasks it would call an Agent ("Implement Linear task KEY-123") with the MCP tools in its context for that specific task and not bloat the main thread with context.
Thank you for the feedback! Let me address the questions:
@lukemmtt - How it works
The proof-of-concept creates a lightweight registry (~500 tokens) that replaces loading all MCP tools upfront:
Currently, it's a simulation showing what's possible. The
/mcpcommand would still show all configured servers, but only the registry would consume tokens until tools are actually needed.@wizardlyluke - Agent-specific MCP servers
That's a brilliant approach! Agent-scoped MCP servers would be even more efficient. My implementation could extend to support:
Regarding Duplicates
While related issues exist (#6638, #7172, #3036), this implementation offers:
The key differentiator is having working code that demonstrates the solution. This could help accelerate implementation by providing a reference.
Test It Yourself
Happy to collaborate with others experiencing this issue to refine the approach!
Regarding Duplicate Status
After reviewing the related issues, I believe this should remain open as it provides unique value:
Issue Comparison
#3036 - Reports the problem ("MCP servers eat context")
#6638 - Requests dynamic loading/unloading
#7172 - Proposes token management improvements
#7336 (This) - Provides working implementation with:
Why Keep Open
I suggest we could:
What do you think @lukemmtt @wizardlyluke? Should we consolidate discussion or keep the implementation separate?
Seems like a neat implementation, I'll give it a shot this week.
I've personally been getting by with less refined approach: a custom-built script that I made that adds/removes mcps from the actual claude config files (using a separate json file to persistently store the mcp configs)—the obvious caveat being that I still need to restart the claude code session after each change for it to take effect; your solution sounds much more elegant.
As for consolidating the discussions or not, that's reasonable, but more importantly would be to just mention your solution in the other discussions to tie everything together, and maybe share it in the anthropic / claude / claude code subreddits for visibility, rather than wait for moderator intervention, which seems sparse in this noisy forum.
@lukemmtt Thanks for trying it out! Your config-swapping approach is clever - it's actually complementary to what I built.
Current Limitations
You're absolutely right that this can't truly lazy-load without Claude Code native support. What it does:
Combining Approaches
Your script + this registry could work together:
Next Steps
Great idea about cross-posting! I'll:
The real win would be getting this integrated natively. Until then, your config-swapping + my analysis tool might be the best workaround.
Would you be interested in combining efforts? We could:
lol... @machjesusmoto , you got me. Freeze all motor functions
It is worth noting that a runtime MCP Toggle feature has been introduced in Claude Code 2.0.10:
Dynamically-loading MCPs is still an interesting concept, but the new ability to enable by "@mentioning" is almost equally valuable for my needs.
Wouldn't this feature be the equivalent (though faster and not requiring Claude Code restart) of just removing/adding them manually? The true power of using many MCPs will be when you can get them added per defined agent, or allow the main agent to enable/disable them itself by knowing which MCPs it could have available.
Yes exactly, I would like my main agent to not have any mcp servers and then have specialized research agents etc.. who have mcp severs and use them for example for more detailed research (github mcp, linear, context7) and then report back a condensed summary to the main agent. So the main session always stays clean
2.0.10 made my work on machjesusmoto / mcp-toggle redundant, but then they delivered plugin extensibility in 2.0.12. A plugin system makes makes the project's overarching goal possible when it was previously only a theoretical PoC (machjesusmoto / claude-lazy-loading
So, with a lot of caffeine and a little luck, I'll have functional "lazy loading & unloading with a registry being all that's held in context at launch" code to test soon.
I'd like to second @EugenEistrach 's idea of being able to enable select MCPs for specific subagents, while leaving it disabled for the main agent. Currently if you disable it in the main agent, then you cannot enable it for any subagent.
I understand that there is a security aspect here so subprocesses can't have great privileges than parent processes. I suppose a true lazy-load would work, but something deterministic would be ideal.
https://www.anthropic.com/engineering/advanced-tool-use Hopefully support for this gets added to Claude Code soon 🤞
Update: Anthropic Released an Official API Solution
On November 24, 2025, Anthropic released the Tool Search Tool beta feature that directly addresses this problem.
How It Works
| Approach | Token Usage |
|----------|-------------|
| Traditional (all tools upfront) | ~77K tokens |
| With Tool Search Tool | ~8.7K tokens |
| Reduction | 85% |
Accuracy Improvements
API Usage
Proposed Claude Code Integration
Since this is now a first-party Anthropic feature, it would be great to see Claude Code CLI support via:
Option 1 - Global config:
Option 2 - Per-server config:
Option 3 - Auto-enable when MCP tool count exceeds a threshold (e.g., 20+ tools)
References
+1 to see how and when claude code will implement this
@ everyone try this: https://github.com/anthropics/claude-code/issues/12836#issuecomment-3629052941
Basically:
```bash
Claude Code - Enable experimental MCP-CLI for reduced token consumption
export ENABLE_EXPERIMENTAL_MCP_CLI=true
Running into the same issue and gald to see this work and active development, I would like to chip in an idea on adding a lightweight router model for tool selection for your consideration.
95% token reduction already is awesome, but strict adherence to predefined keywords might hinder some users. Thus -->
Proposed Enhancement: Phase 4 - Intelligent AI Router
The Problem with Static Keyword Matching
While keyword triggers work well for explicit mentions (e.g., "docker" → load docker-mcp), they have limitations:
Solution: Two-Phase Architecture with Lightweight Model Router
Phase 1: Lightweight Router (Haiku/Fast Model)
Phase 2: Main Model (Sonnet/Opus)
How It Works
1. At Session Start
2. On User Input
3. Fallback Mechanism
Integration with Your Registry System
Your POC already has the foundation! The enhancement would be:
Implementation Phases
Phase 4.1: Basic AI Router
Phase 4.2: Context-Aware Routing
Phase 4.3: Hybrid Intelligence
@servermentionsBenefits Beyond Keyword Matching
| Feature | Keyword Matching | AI Router |
|---------|------------------|-----------|
| Explicit mentions | ✅ Excellent | ✅ Excellent |
| Implicit requests | ❌ Misses | ✅ Handles |
| Multi-domain tasks | ⚠️ Partial | ✅ Optimizes |
| Context awareness | ❌ No | ✅ Yes |
| Ambiguity resolution | ❌ No | ✅ Yes |
| Setup effort | ⚠️ Manual triggers | ✅ Zero config |
| Token overhead | ~5k registry | ~3k catalog |
Real-World Example
Scenario: "Check if the deployment is healthy and notify the team"
Keyword Approach:
Discussion Questions
---
Technical Notes
Edge Cases to Handle:
@servermentions limit to these tools considered by router model which then subsets to the tools used for main model callLooking forward to hear if this might be of interest and add useful functionality to the keyword registry approach!
Thanks @machjesusmoto for this excellent feature request and the detailed technical proposal! The discussion here has been very insightful.
My use case adds another dimension: multi-project MCP management with RAM constraints. While most comments focus on context window savings, I'm hitting hard memory limits running Claude Code on a dedicated "AI machine", having 16 GB RAM with multiple projects requiring different MCP combinations. Using a mini PC for my AI projects maybe wasn't such a good idea after all.
---
Additional Use Case: Multi-Project MCP Management with Resource Constraints
I'm running Claude Code on a resource-limited machine (16 GB RAM) managing multiple projects, each requiring different MCPs:
webapp-frontend: github, postgres-mcp, redis-mcpdevops-automation: docker, kubernetes-mcp, aws-mcp, terraform-mcpdata-pipeline: bigquery-mcp, snowflake-mcp, dbt-mcpCurrent problems:
Workaround I've implemented:
SESSION_NOTES.mdwith(TEMPORARY)markersPROJECT_RULES.md(rules shared by _all_ projects)Desired behavior:
This would enable efficient multi-project work on resource-constrained machines.
Given a tool tool, how about a skill skill, a tool/skill skill, or a skill/tool tool?
nice
Adding a data point: on a real project with GSD workflow agents + custom agents + skills, measured ~20% context consumed at session start before typing anything.
After manually deleting unused agents and trimming CLAUDE.md files, got it down to ~9%. But agents I actually want to keep (just not every session) still cost ~3-5% of context permanently.
The current workaround is moving agent files to a disabled folder and back — functional but defeats the purpose of having an integrated ecosystem. Lazy-loading agent/skill descriptions (name-only in system prompt, full description on spawn) would solve this cleanly.
Real-world data from an enterprise iOS dev environment (1M context, Opus 4.6)
Adding concrete numbers from a production setup with 9 MCP servers configured for iOS development at Microsoft:
| MCP Server | Tools | Tokens | Notes |
|---|---|---|---|
| azure-devops | 77 | ~17.2K | Core workflow, can't remove |
| xclaude-plugin (plugin) | 59 | ~13.2K | 36 are duplicates (see below) |
| azure-mcp | 55 | ~12.3K | Rarely used for iOS dev |
| IcM-MCP | 20 | ~4.5K | On-call engineering |
| cupertino | 10 | ~2.2K | Apple docs search |
| bluebird | 5 | ~1.1K | Code search |
| microsoft-docs-mcp | 3 | ~0.7K | MS docs |
| ESChat | 3 | ~0.7K | Internal knowledge base |
| workiq | 2 | ~0.4K | M365 Copilot |
| Total | 234 | ~53K | 5.3% of 1M context |
Even on a 1M context window, 53K tokens of tool definitions is painful -- it's context that could hold ~100 files of source code instead.
The plugin duplication problem makes this worse. The xclaude-plugin registers 59 tools across 8 categories (xc-setup, xc-build, xc-interact, xc-ai-assist, xc-launch, xc-testing, xc-meta, xc-all), but only 23 are unique. The
xc-allcategory is a superset of all others. The category system was designed so agents pick the smallest needed set, but since everything loads at startup, you pay for all 59 regardless.What I'd want from lazy loading:
xc-allOR the individual categories, never bothThis is the single highest-ROI improvement for power users with enterprise tooling.
Built a userland solution for this — an MCP gateway that replaces N tool schemas with 3-4 dispatch tools.
Instead of registering each MCP server directly, you register a single gateway server that proxies
gw("account", "tool_name", {params})to the right upstream MCP server on demand.My setup went from 644 tool schemas (~57K tokens) to 7 schemas (~6.2K tokens) — 89% reduction.
Two patterns included (~150 LOC each):
--climode (subprocess per call)Both support multi-account routing, tool discovery with caching, and batch execution. Works with any upstream MCP server.
Open source (MIT): https://github.com/block-town/mcp-gateway
This has shipped and is now the default behavior — no configuration needed.
What changed:
ToolSearchtool.What you'll see in
/context:Most of the
Toolssection is gone from the upfront context. Tool schemas are loaded progressively as the model uses them.To opt out (if you prefer the old behavior):
~~~json
// settings.json
{ "env": { "ENABLE_TOOL_SEARCH": "false" } }
~~~
Or add
ToolSearchtodisallowedTools.Closing as resolved — thanks for the detailed breakdown, it was a great framing of the problem.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.