Feature request: Lazy MCP server initialization (connect on demand)
Problem
All configured MCP servers connect at chat startup, registering their full tool lists into context immediately. For users with multiple MCP servers (Gmail, Google Calendar, Notion, Figma, Kling, etc.), this consumes significant context window space before any work begins — even if most servers won't be used in that session.
The current "deferred tools" mechanism helps (only names loaded, full schemas on demand), but the server processes still spin up and the name list still grows with every added server.
Desired behavior
MCP servers should support lazy initialization — credentials stored locally (e.g., .env), but servers only connect and register tools when the user actually needs them mid-conversation.
Ideal flow:
- User configures MCP servers + auth as usual
- On chat start: no MCP servers connect, zero context used
- User says "check my email" → Claude detects Gmail MCP is needed → server connects on demand → tools become available
- Only that server's tools consume context
Possible implementation approaches
- A "lazy" flag per MCP server in settings (e.g.,
"lazy": true) - A lightweight router/proxy MCP server that starts others on demand
- Extending the existing deferred tools mechanism to defer the connection itself, not just the schema
Context
Users who integrate many MCP servers for different workflows (productivity, design, content generation) hit context limits quickly. The workaround today is manually enabling/disabling servers between sessions, which defeats the purpose of having an integrated toolchain.
This would make Claude Code significantly more scalable for power users with broad MCP setups.
6 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
https://github.com/anthropics/claude-code/issues/17668 has some overlaps but is a bit different.
Adding a security dimension to this request
Problem
MCP servers are initialized at session start, which creates two issues:
1. Security: Secrets must be globally exported
MCP servers read env vars from the shell that launched Claude. If a server needs an API key (e.g.,
Authorization: Bearer ${MY_API_KEY}), that key must be present in the parent shell environment before Claude starts.In practice, this means users must add
export MY_API_KEY=...to their.zshenvor.bashrc— making secrets available to every process in every terminal session, not just Claude. There's no way to scope secrets to only the MCP connection that needs them.This is especially problematic for:
2. Performance: Unused MCP servers waste context and resources
All configured MCP servers connect at session start, even if the user never invokes their tools. Each server's tool definitions are loaded into the deferred tool index, and the server process runs for the entire session. In conversations (and
/btw) that never touch the MCP Tool that requires API Keys like PostHog, Jira, etc., this is pure overhead.Proposed Solution
Lazy MCP server initialization — servers are registered at session start (tool names are known) but the actual connection/process is deferred until a tool from that server is first invoked.
This would enable:
source some-cool-decryption-booper.sh), scope them to that server's process, and never export them to the parent shell.Possible Configuration
lazy: true— don't connect until a tool from this server is invokedenvCommand— run this command to populate env vars just before connecting (output or exports are captured and scoped to the server process)Current Workaround
Export all required secrets in your shell init file (.zshenv, .bashrc, etc.); so they're available in every shell session:
This works but defeats the purpose of on-demand secret management.
Additional Context
ToolSearch). Extending this pattern to the server connection itself is a natural next step.SessionStarthook runs in a child process, so exported env vars don't propagate back to the Claude parent process that spawns MCP servers.CLAUDE_ENV_FILEis sourced per Bash tool call but not by MCP server processes.envfield insettings.jsononly supports static string values, not command output.+1 for this. Adding a concrete data point from a different angle: wall-clock startup time amplification under concurrent sessions, not just context-window cost.
Symptom observed 2026-05-01: starting a new
claudesession in any window took ~1 minute when 3 other Claude Code sessions were active on the same machine (one of them dispatching 3 parallel sub-agents inisolation: "worktree"). Tool calls in already-running sessions also lagged. Couldn't even type into the UI.Investigation showed the bottleneck was not hot disk, or memory pressure (24GB free, normal load). It was concurrent MCP server bootstrap. Setup:
nodestartup + JS module load + MCP handshakenpm installs in the agent worktrees → disk I/O saturationLazy MCP startup would have flattened this completely. None of the agents in those parallel sessions actually invoked any of the 6 plugin-installed MCPs - they were paying ~minute of cumulative startup cost for tools they never called.
So in addition to the context-window argument in the OP, the lazy-init request also addresses:
Agentcalls withisolation: "worktree", each worktree spawns a fresh Claude Code instance inside it with the full MCP set. Lazy init would let those agents run cheap and only pay for the one or two MCPs their narrow task actually needs.For maintainers' info on the scoping side:
disabledMcpServersis per-project today, but there's no symmetric "enable only these MCPs in this project" mechanism, which is the cleanest current workaround for narrowing the boot set per repo. A "lazy" flag per MCP would be a much better answer - not having to think per-repo about what's needed.Happy to provide additional repro data if useful (process traces, before/after of
disabledMcpServersboot-time deltas).Thanks for the request. This is the same ask as #17668 (per-server lazy MCP load /
startDisabled). Consolidating tracking there.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.