Keep every MCP server off in Claude Code, and turn one on with a single command when you actually need it:
mcp on playwright # enable a local server
mcp on supabase # enable ONE claude.ai connector, the others stay off
mcp run gmail # enable for one claude session, restored on exit
mcp # status
One file, zero dependencies, Node 18+. Windows, macOS, Linux.
- Every enabled MCP server costs context tokens on every turn. Its tool schemas are sent with each request, whether you use them or not. Ten servers you use once a week is a permanent tax.
/mcpcan't bring back a server blocked bydeniedMcpServers. Once you deny a server in settings, the only way back is editing JSON by hand.claude mcp removeis destructive. It deletes the server config and its OAuth tokens; adding it back means reconfiguring and re-authenticating.- claude.ai connectors are all-or-nothing.
disableClaudeAiConnectorsturns off all of them (Gmail, Notion, Supabase...). There's no built-in way to have just one.
The script only edits two keys in ~/.claude/settings.json:
| Key | Role |
|---|---|
deniedMcpServers |
Deny list by server name. Works for local servers (playwright) and claude.ai connectors (claude.ai Gmail). |
disableClaudeAiConnectors |
Global switch: true blocks every claude.ai connector. |
- Local server (defined in
~/.claude.json, user or local scope):onremoves it from the deny list,offadds it back. - One claude.ai connector:
onlifts the global flag and adds every other known connector to the deny list by name, so lifting the flag doesn't load them all.offdenies it again; when no connector is left on, the global flag is set back (this also covers connectors you add on claude.ai later). - Known connectors are read from
claudeAiMcpEverConnectedin~/.claude.jsonplus any already in the deny list.
Server configs, API keys and OAuth tokens in ~/.claude.json are never touched.
-
Copy the script:
# macOS / Linux curl -fsSL https://raw.githubusercontent.com/Iliesseu28/claude-code-mcp-toggle/main/mcp-toggle.js -o ~/.claude/mcp-toggle.js
# Windows PowerShell Invoke-WebRequest https://raw.githubusercontent.com/Iliesseu28/claude-code-mcp-toggle/main/mcp-toggle.js -OutFile "$HOME\.claude\mcp-toggle.js"
-
Add the
mcpshortcut:- PowerShell: paste
shell/mcp.ps1into your profile (notepad $PROFILE). - bash / zsh: paste
shell/mcp.shinto~/.bashrcor~/.zshrc(orsourceit).
- PowerShell: paste
-
Optional, to start from "everything off":
mcp off all.
Without the shortcut, use node ~/.claude/mcp-toggle.js <command>.
| Command | Effect |
|---|---|
mcp (or mcp status) |
Status of every known local server and claude.ai connector |
mcp on <name...> |
Enable (persistent, all projects) |
mcp off <name...> |
Disable |
mcp on|off all |
Every local server and every connector |
mcp on|off claudeai |
All claude.ai connectors at once |
mcp run <name...> [claude args] |
Enable, launch claude with the args, restore the previous state when it exits |
Connector names are case- and separator-insensitive: supabase, Supabase, claude.ai Supabase, google-calendar, google_calendar and Google Calendar all work. In mcp run, names stop at the first argument starting with -, e.g. mcp run supabase --dangerously-skip-permissions.
A name that's neither in ~/.claude.json nor a known connector (e.g. a project .mcp.json server) prints a warning and is toggled anyway.
Changes take effect the next time claude starts. Check without starting a session:
claude mcp listOnly the servers you enabled should show up. If an unexpected claude.ai Something appears, block it with mcp off "claude.ai Something".
- Before every write, the current
settings.jsonis copied to~/.claude/backups/settings.json.mcp-toggle.bak. - Only
deniedMcpServersanddisableClaudeAiConnectorsare changed; every other setting is kept. ~/.claude.json(server definitions, tokens) is read, never written.
- Relies on the Claude Code settings keys
deniedMcpServers,disableClaudeAiConnectorsand onclaudeAiMcpEverConnectedin~/.claude.json. If Claude Code renames them, the script needs an update. - Restart
claudefor a change to apply;/mcpinside a running session won't pick it up. - A connector you have never connected isn't known yet; toggle it by its full name (
mcp on "claude.ai Notion") as shown byclaude mcp list. mcp runrestores the state whenclaudeexits normally or with Ctrl+C; if the terminal itself is killed, runmcp off <name>by hand.
npm testTests run the script against a temporary home. MCP_TOGGLE_HOME overrides the home directory the script uses (default: os.homedir()); MCP_TOGGLE_JS makes the bash/zsh mcp function point at another copy of the script.