Feature Request: Runtime MCP Server Toggle

Status Closed — not planned
Maintainer reply None cached
Activity 12 comments · opened Aug 22, 2025 · closed Jan 10, 2026

## Feature Request: Runtime MCP Server Toggle

### Problem
Currently, enabling/disabling MCP servers requires editing .claude/settings.local.json and restarting the Claude Code session. This is inefficient when working on projects that need different MCP
servers for different tasks.

### Proposed Solution
Add ability to dynamically enable/disable configured MCP servers during a session without restart.

### Suggested Implementation

  • Slash command: /mcp enable supabase playwright
  • Slash command: /mcp disable supabase
  • Slash command: /mcp list (show available/enabled)
  • UI toggle in settings panel

### Use Case
Working on a project that sometimes needs Supabase MCP for database work, sometimes Playwright for testing, but not both simultaneously to save context window.

### Current Workaround
Manual editing of settings file + restart

View original on GitHub ↗

12 Comments

github-actions[bot] · 1 year ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/1774
  2. https://github.com/anthropics/claude-code/issues/4256
  3. https://github.com/anthropics/claude-code/issues/5722

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

coygeek · 1 year ago

Hey, this is a great feature request. I've run into the exact same issue where I want to toggle different "profiles" of tools without having to restart my session or manually edit JSON files every time.

While we wait for an official feature like /mcp enable, I've found a pretty good workaround using the way Claude Code handles configuration scopes. It's a bit of a setup, but once it's done, you can launch Claude with different MCP sets using a single command.

Here's how I've been handling it:

The "Profiles" Workaround

The main idea is to define all your MCP servers in a shared project scope, and then use a local, git-ignored settings file to control which ones are active. You can then use simple shell aliases or functions to swap out that local settings file before you launch claude.

Step 1: Define All Servers in the Project Scope

First, add all the MCP servers your project might need to the shared .mcp.json file. This is great because it gets checked into git and your whole team can use the same server definitions.

Run these commands from your project root:

# Add supabase server to the shared .mcp.json
claude mcp add --scope project supabase <your_supabase_command>

# Add playwright server to the shared .mcp.json
claude mcp add --scope project playwright <your_playwright_command>

Now you'll have a .mcp.json file in your repo with both server definitions.

Step 2: Use enabledMcpjsonServers for Control

According to the settings docs, you can control which project servers are active using a key called enabledMcpjsonServers in your .claude/settings.local.json file. This file is local to you and isn't checked into git.

So, you can create different "profile" files. For example:

Create ~/.claude/mcp_profiles/db-only.json:

{
  "enabledMcpjsonServers": ["supabase"]
}

Create ~/.claude/mcp_profiles/testing-only.json:

{
  "enabledMcpjsonServers": ["playwright"]
}

Step 3: Create Shell Aliases to Launch Claude with a Specific Profile

Now, tie it all together with some shell functions or aliases in your .bashrc, .zshrc, etc. These functions will copy the right profile into place as .claude/settings.local.json and then launch Claude Code.

# Add these functions to your ~/.zshrc or ~/.bashrc

# Launch Claude with only database tools
function claude-db() {
  cp ~/.claude/mcp_profiles/db-only.json ./.claude/settings.local.json
  claude "$@"
}

# Launch Claude with only testing tools
function claude-test() {
  cp ~/.claude/mcp_profiles/testing-only.json ./.claude/settings.local.json
  claude "$@"
}

# Launch Claude with all tools enabled
function claude-all() {
  # You can either enable them all explicitly...
  # echo '{"enabledMcpjsonServers": ["supabase", "playwright"]}' > ./.claude/settings.local.json
  # ...or just remove the local file to let the default behavior (enable all) kick in.
  rm -f ./.claude/settings.local.json
  claude "$@"
}

After adding those and reloading your shell (source ~/.zshrc), you can just run:

  • claude-db to start a session for database work.
  • claude-test "write a test for the login page" to start a session for testing.
  • claude-all to start a session with everything enabled.

It's not quite a runtime toggle, but it completely avoids manual file editing and makes launching a session with the right toolset a single command.

Hope this helps you out in the meantime! Still, +1 for the built-in /mcp enable/disable feature. That would be even smoother.

JustMaier · 11 months ago

Is there a way to make it so that certain sub agents can boot with specific MCP Servers? It's a pain to clutter the context of the main agent with tools that only a subagent is intended to use. It seems like this "dynamic loading" of MCP servers would enable that critical capacity.

coygeek · 11 months ago

That's a fantastic question, and you've hit on a really powerful and important use case for subagents! The short answer is yes, you absolutely can do this, and it's one of the key design benefits of the subagent system. You don't even need to wait for the dynamic loading feature; you can set this up right now.

The core idea is that you configure all your MCP servers once for the project, but then you use the subagent's tools list to grant it exclusive access to certain MCP tools. This keeps your main agent's toolset clean and focused.

Here’s a step-by-step guide on how to achieve this:

The "Specialized Tool Belts" Pattern for Subagents

This pattern ensures that only the right agent has access to the right tools, preventing the main agent from getting confused by a huge list of tools it doesn't need for its current task.

Step 1: Configure All MCP Servers at the Project Level

First, make sure all the MCP servers you might need are defined in your shared .mcp.json file. This makes them available to the project, but not necessarily enabled for every agent.

# Add your database MCP server (e.g., Supabase, Postgres)
claude mcp add --scope project supabase <your_db_server_command>

# Add your testing MCP server (e.g., Playwright)
claude mcp add --scope project playwright <your_playwright_server_command>

# Add your ticketing MCP server (e.g., Jira via Atlassian)
claude mcp add --scope project --transport sse atlassian https://mcp.atlassian.com/v1/sse

Now, your project is aware of these servers, but we can control who gets to use them.

Step 2: Create Subagents with Specific Tool Permissions

This is the key step. In each subagent's markdown file, you'll use the tools frontmatter key to assign it a specific "tool belt."

Let's create a data-analyst subagent that only has access to the database tools.

File: .claude/agents/data-analyst.md

---
name: data-analyst
description: An expert in SQL and database queries. Use this agent to fetch, analyze, and report on data from our production database.
# This agent ONLY gets access to the supabase MCP server tools and standard read/write tools.
tools: mcp__supabase, Read, Write
---

You are a senior data analyst. Your primary goal is to answer questions by querying the project's database.

- Formulate efficient SQL queries.
- Clearly present the data you retrieve.
- Do not perform any actions outside of data analysis and reporting.

And here's a qa-engineer subagent that only gets the Playwright testing tools.

File: .claude/agents/qa-engineer.md

---
name: qa-engineer
description: A QA automation specialist. Use this agent to write, run, and debug end-to-end tests using Playwright.
# This agent ONLY gets access to the Playwright MCP server tools and file system tools.
tools: mcp__playwright, Read, Edit, Write, Bash
---

You are a QA Engineer specializing in browser automation with Playwright.

- When asked to test a feature, write a clear, concise Playwright script.
- Execute the test and report on the results.
- If the test fails, analyze the failure and suggest a fix for either the test or the application code.

Important Note on MCP Tool Naming:
As you can see, you grant access to all tools from a specific MCP server by using the format mcp__<server-name>. For example, mcp__supabase gives the subagent access to all tools provided by the supabase server.

Step 3: (Optional but Recommended) Restrict the Main Agent

To fully solve your context clutter problem, you can tell the main agent to ignore these specialized tools by default. You do this in your .claude/settings.json file.

File: .claude/settings.json

{
  "permissions": {
    "deny": [
      // Prevent the main agent from seeing these specialized MCP tools.
      // Subagents will still have access because their 'tools' list overrides this.
      "mcp__supabase",
      "mcp__playwright"
    ]
    // ... your other permissions
  }
}

How It All Works Together

  1. When you start claude, it loads the MCP server configurations from .mcp.json.
  2. It then reads your settings.json and applies the deny rule, hiding the supabase and playwright tools from the main agent. Your main conversation context is now clean!
  3. You ask a question like: "Fetch the top 10 users by purchase volume from the database."
  4. Claude sees that this task matches the description of your data-analyst subagent.
  5. It delegates the task to the data-analyst subagent.
  6. The subagent spins up with its own custom toolset, which includes mcp__supabase. It can now successfully query the database.
  7. Once done, it returns the result to the main agent, and its specialized context (and tools) are torn down.

This pattern of "central registration, delegated permissions" is super powerful for building complex, multi-agent workflows without overwhelming any single agent.

Hope that helps you build some incredibly focused and efficient subagents

JustMaier · 11 months ago

Thanks for the detailed walk through @coygeek!

I'm struggling to get the main agent to not have the MCP tools in the main context, even with deny set for a specific MCP toolset.

My Setup

.mcp.json

{
  "mcpServers": {
    "context7": {
      "type": "http",
      "url": "https://mcp.context7.com/mcp"
    }
  }
}

.claude/settings.local.json

{
  "permissions": {
    "deny": [
      "mcp__context7"
    ]
  },
  "enableAllProjectMcpServers": false,
  "enabledMcpjsonServers": [
    "context7"
  ],
}
  • I have to have enableMcpjsonServers otherwise the MCP won't show up

.claude/agents/docs-agent.md

---
name: docs-agent
description: Use proactively to research how to properly utilize different SDKs, third-party service APIs, frameworks, and programming languages.
tools: mcp__context7
---

You use context7 to look up the documentation on various things.

- Find the appropriate documentation.
- Clearly present a guide for the docs you retrieve.
- Do not perform any actions outside of doc analysis and reporting.

Run Example

> claude

> /mcp
1. context7

> /context
MCP tools · /mcp
└ mcp__context7__resolve-library-id (context7): 691 tokens
└ mcp__context7__get-library-docs (context7): 652 tokens

> Use the docs agent to research how to debounce in react
I'll use the docs agent to research React debouncing techniques for you.

 docs-agent(Research React debouncing)
⎿  Done (0 tool uses · 5.7k tokens · 1m 9.0s)

The Experiment

I'm not sure if I still have things misconfigured or something, but in my attempt Claude still had the context7 mcp tools in the main agent context and it also appears that even though I've permitted the context7 tool use in the subagent, it actually also is having its permission denied and ultimately doesn't use any tools.

To confirm this, I added a PostToolUse hook for tracking tool use. After running this example here's what I see in my metrics:

Task|2025-09-14 16:30:14|2025-09-14

And if I remove the deny on the tool, then I still don't see MCP tool use:

Task|2025-09-14 16:31:27|2025-09-14

I only see the subagent use the tool if I explicitly allow the tool in my settings.json

{
  "permissions": {
    "allow": [
      "mcp__context7__resolve-library-id",
      "mcp__context7__get-library-docs"
    ]
  }
//...
}

and then give the subagent explicit tool access:

---
name: docs-agent
description: Use proactively to research how to properly utilize different SDKs, third-party service APIs, frameworks, and programming languages.
tools: mcp__context7__resolve-library-id, mcp__context7__get-library-docs
---

metrics:

mcp__context7__resolve-library-id|2025-09-14 16:38:13|2025-09-14
mcp__context7__get-library-docs|2025-09-14 16:38:19|2025-09-14
mcp__context7__resolve-library-id|2025-09-14 16:38:23|2025-09-14
mcp__context7__get-library-docs|2025-09-14 16:38:27|2025-09-14
mcp__context7__resolve-library-id|2025-09-14 16:38:32|2025-09-14
mcp__context7__get-library-docs|2025-09-14 16:38:38|2025-09-14
mcp__context7__get-library-docs|2025-09-14 16:38:43|2025-09-14
Task|2025-09-14 16:39:54|2025-09-14

The Issues

  1. The MCP tool context still appears in the main agent context even if the tool is denied
  2. The subagent is unable to use an MCP tool if it's denied at the main agent level
  3. The subagent must be given explicit tools from an MCP toolset, not just the MCP root

The outcome

It doesn't seem like things work the way you described and the current version of Claude Code requires all MCPs to be enabled and in the main agent context to function for subagents.

Am I doing something incorrect?

coygeek · 11 months ago

Wow, thank you for this incredibly detailed and well-documented follow-up, @JustMaier! This is exactly the kind of feedback that helps everyone understand the tool better. Your debugging is top-notch, and you've absolutely uncovered some critical nuances in how permissions and subagents interact.

You are 100% correct, and my initial explanation was flawed. It was based on a mental model of how I expected the permission hierarchy to work (subagent's tools list being a complete override), but your experiment clearly shows the actual implementation is different. I apologize for leading you down the wrong path there.

Let's break down what your experiment has proven, because you've hit on several key points:

  1. The deny permission is absolute. As you discovered, if a tool is in deny at the project/user settings level, it's a hard block. No subagent can override it. This makes sense from a security perspective—an admin should be able to enforce a hard "no" that can't be bypassed. My mistake was thinking the subagent's tool list was an exception to this rule. It is not.
  2. deny doesn't remove tools from the context list. This is a subtle but important finding. It seems that Claude Code loads all available tools into the context first, and then applies the permission layer at runtime when a tool is about to be used. So, /context shows you what's loaded, not necessarily what's runnable.
  3. Subagent tools require specific tool names for MCP servers. You are right again. My previous example of using mcp__supabase as a shorthand in the subagent's tools list was incorrect. As you found, you need to list each individual tool explicitly (e.g., mcp__context7__resolve-library-id). This is a crucial detail.

So, given these rules, how can we achieve your original goal: preventing the main agent from using the tools while granting a subagent access?

We can't use deny. But we have another option: ask.

The Corrected Workaround: Use "ask" instead of "deny"

Let's try a new approach. Instead of a hard deny, we'll set the default permission for the context7 tools to ask. This will prevent the main agent from using them without your explicit permission in the UI. Then, we can rely on the subagent's tools list to act as a pre-approval, bypassing the ask prompt.

Here’s my revised theory and the setup to test it:

Step 1: Change deny to ask in your settings

In your .claude/settings.local.json, let's switch from deny to ask. You still need enabledMcpjsonServers to load the server in the first place.

File: .claude/settings.local.json

{
  "permissions": {
    "ask": [
      "mcp__context7"
    ]
  },
  "enableAllProjectMcpServers": false,
  "enabledMcpjsonServers": [
    "context7"
  ]
}

Note: I'm using mcp__context7 here as a blanket "ask" rule for all tools from that server, which is supported according to the IAM docs.

Step 2: Grant Specific Tools to the Subagent

Your subagent file needs to list the exact tools it's allowed to use. This part of your setup was already perfect.

File: .claude/agents/docs-agent.md

---
name: docs-agent
description: Use proactively to research how to properly utilize different SDKs, third-party service APIs, frameworks, and programming languages.
tools: mcp__context7__resolve-library-id, mcp__context7__get-library-docs
---

You use context7 to look up the documentation on various things.

- Find the appropriate documentation.
- Clearly present a guide for the docs you retrieve.
- Do not perform any actions outside of doc analysis and reporting.

What Should Happen Now

With this configuration:

  1. Main Agent: The mcp__context7 tools will still appear in /context. However, if the main agent tries to use mcp__context7__resolve-library-id, it will trigger a permission prompt in the UI, which you can reject. This effectively solves the problem of the main agent accidentally using the tool.
  2. Subagent: When the docs-agent is invoked, its tools list (mcp__context7__resolve-library-id, etc.) should act as an allow list for that specific run. It should bypass the global ask policy and execute the tools automatically without prompting you.

This should give you the behavior you're looking for: the tools are firewalled from the main agent by a permission prompt, but are freely available to the specialized subagent.

Again, thank you so much for the detailed report. This is a super important workflow, and you've helped clarify exactly how the permission system works in practice. Please let me know if this ask-based approach works for you

JustMaier · 11 months ago

@coygeek thanks for the detailed breakdown of another potential course to limit tool access to a subagent. I think that could be a valid workaround. Unfortunately, it only solves a portion of the problem. I was really hoping to be able to eliminate MCP tool definitions from the main context window. The reality is I use a lot of MCP tools and if I have all of them turned on to support all of the subagents I have then it easily consumes 20% of my context right at boot.

This runtime toggle, or the ability to only have subagents load specific MCPs would be the feature I need to make my main agent more efficient and less cluttered.

lukemmtt · 10 months ago

This issue should be closed, as it has been resolved with the release of Claude Code 2.0.10:

## 2.0.10 - Rewrote terminal renderer for buttery smooth UI - Enable/disable MCP servers by @mentioning, or in /mcp - Added tab completion for shell commands in bash mode - PreToolUse hooks can now modify tool inputs - Press Ctrl-G to edit your prompt in your system's configured text editor - Fixes for bash permission checks with environment variables in the command
JustMaier · 10 months ago

@lukemmtt does that imply we can enable MCPs at the agent level as well? For example, limit the MCP to only specific agents?

github-actions[bot] · 8 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

github-actions[bot] · 7 months ago

This issue has been automatically closed due to 60 days of inactivity. If you're still experiencing this issue, please open a new issue with updated information.

github-actions[bot] · 7 months ago

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.