claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

Feature: Per-agent MCP tool filtering to improve agent focus and accuracy

Open stanislavlysenko0912 opened this issue 6 months ago โ€ข 18 comments

Main problem

Claude Code shows ALL MCP tools to main agent and sub agents, causing:

  • Decision paralysis: Agent evaluates many tools for simple "read this file" tasks
  • Wrong tool selection: More tools = higher chance of picking wrong one
  • No specialization: Can't create focused agents (search-only, DB-only, code-only)
  • Higher token usage

Example workflow

I want to build a system with sub agents, where:

  • Main agent: Pure orchestrator, doesn't need to know HOW research happens, just delegates to specialists if needed
  • Research sub-agent: Has access to specialized MCP tools like:
    • perplexity-search
    • web-search
  • Thinking sub-agent: Only needs introspection tools like:
    • zen-mcp (structured reasoning, with only 1 enabled tool)
    • some memory mcp
    • etc

Currently, the main agent sees all these research tools and tries to do research itself instead of delegating. Ideal: Each agent only sees tools relevant to its role.

*What's the reason to use sub agents? If they are all the same differ only in the input prompt and won't be able to run certain tools, but still see them sort of thing. Their potential is not fully realized

Solution

Let us configure which tools each agent sees:

  • Don't send tool schemas for disabled tools (not just block usage)
  • Sub-agents get their own tool visibility, inheriting from parent by default like now, but can be overridden
  • Main + sub-agents each can get their own tool visibility/hide list

Focused agents should perform better than generalists.

Related Issues

  • #3406

stanislavlysenko0912 avatar Jul 25 '25 09:07 stanislavlysenko0912

I am too waiting for this feature so I can leverage MCPs and sub agents in a cost effective manner.

Each sub agent should have the ability to have its own MCPs configured that aren't going to pollute the main agent context.
This is especially important to reduce claude confusion and cost while maintaining conntectivity with other services.

PhilipGarnero avatar Jul 25 '25 21:07 PhilipGarnero

+1

FrancisBourre avatar Aug 11 '25 13:08 FrancisBourre

this is critical, why isnt this being addresses immediately? this defeats the entire purpose of sub agents having access to MCP tools if the MCP tools are clogging the primary context?

jmor1234 avatar Aug 15 '25 16:08 jmor1234

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/3206
  2. https://github.com/anthropics/claude-code/issues/4906

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

github-actions[bot] avatar Aug 15 '25 21:08 github-actions[bot]

I agree this is much needed and critical to improve agent focus. Way too much context is being eaten up by MCP prompts

gabrielbryk avatar Aug 25 '25 15:08 gabrielbryk

+1. We shouldn't have to globally enable an mcp to enable a subagent to have that tool. Likewise, I want granular control over which functions on an mcp server are loaded in contextโ€”26k tokens for a few mcps is brutal, and totally avoidable by just allowing more configuration.

CaptainCrouton89 avatar Aug 29 '25 19:08 CaptainCrouton89

So I have some a proposed solution for this problem. Well, the way I see it there are two problems:

  1. Denied tools are included in context (this is it's own issue, but needs to be addressed)
  2. Subagents do not have their own permissions

Fixing the first issue seems pretty straightforward. If an agent can't use a tool, it shouldn't have that tool pollute it's context. Seems pretty simple to me. The only caveat would be if that agent doesn't know it's been denied the tool. The solution would be to allow the agent to look that up in it's permissions. Seems a fairly straightforward issue and fix.

For the second issue, a more nuanced discussion is warranted. I have a decent suggestion, if you will. It's important to note, however, that my suggestion would REQUIRE the first issue to be addressed. Otherwise you end up with context pollution regardless.

Suggested Solution for Subagent Permissions

Add in a subAgents key to the permissions configuration which allows configuring default and specific subagent permissions

{
  // "default" permissions:
  //   - functions as normal permissions settings currently do
  //   - inherited by all agents in scope (user, project, local) including the "main" agent
  "permissions": {
    "allow": [],
    "deny": ["mcp__notion"],
    "ask": [],
    // "subagent default" permissions:
    //   - applied to any subagents in scope (user, project, local)
    //   - overrides the "default" permissions
    "subAgents": {
      "allow": [],
      "deny": [],
      "ask": [],
      // "subagent" permissions:
      //   - applies only to subagents in scope (user, project, local) with a matching name
      //   - overrides the "default" and "subagent default" permissions
      //   - note: this could be nested in an object to avoid name collisions w/ the other keys
      "notion-agent": {
        "allow": ["mcp__notion"],
        "deny": [],
        "ask": []
      }
    }
  }
}

This concept is applicable to user, project, and project-local scoped settings. For context, these are where those settings files can be located:

  • ~/.claude/settings.json (lowest priority)
  • ./.claude/settings.json
  • ./.claude/settings.local.json (highest priority)

The suggested changes are capable of all sorts of complex permission configurations. In the example above, only notion-agent-named subagents would be allowed to utilize the mcp__notion tools while the "main" agent and other subagents would be denied access. Assuming "issue 1" is fixed, this would keep the notion MCP tools out of context for all agents except for subagents specifically named notion-agent.

The flexibility is pretty drastic, due to the ability to apply these rules from different scopes. I won't go into the details of all permutations, but suffice it to say, this should allow for quite an interesting level of configuration complexity, without overdoing it. The scoping rules for settings would still apply, with the project-local settings being the "highest priority" overriding any rules found at the project or user level.

Potential Issues

[1] This adds complexity to the settings.json schema

While this does provide flexibility, it adds a good bit more complexity to the permissions schema. It also might add a lot of "unnecessary" empty arrays for the unused allow, deny, ask keys.

Solution: make the "permission list" keys optional

For example, this could be considered a valid configuration:

{
  "permissions": {
    "deny": ["mcp__notion"],
    "subAgents": {
      "notion-agent": {
        "allow": ["mcp__notion"]
      }
    }
  }
}

[2] Possible subagent context pollution

Example: a subagent is allowed permission for a tool not included in the front-matter

This is not inherently an issue, but could lead to context pollution, depending on how the subagent context is constructed. I do not know how this currently functions, but the desired state would be that subagents limit their MCP context based on the tools listed in their tools: front-matter, not just their allowed permission set.

If my assumption is incorrect and subagents pull into context all tools they have access to regardless of front-matter, this could lead to hidden subagent context pollution. This would not be desirable and would be hard to detect.

Solution: ensure subagents only pull into context tools they specify in their front-matter

Essentially, the same solution as the original "context pollution" for the main agent, but applied at the subagent-level.

[3] Permission denial reasoning

Example: a subagent is denied permission for a tool included in the front-matter

If a subagent lists a tool in it's tools: front-matter that it does not have access to, it will raise a generic permission error. Due to the increase in configuration complexity, it would be nice to inform the user where the "denial" comes from in a more elegant manner.

I'm going to setup a brief example configuration for an agent and it's permissions and show how this error might look as well as a potentially better error. We will use setup a simple product-agent with the mcp__notion__notion-search in it's front-matter:

product-agent.md

---
name: product-agent
description: Use this agent when you need to ...
tools: mcp__notion__notion-search
model: opus
color: green
---

...

./.claude/settings.local.json

{
  "permissions": {
    "deny": ["mcp__notion"],
    "subAgents": {
      "allow": ["mcp__notion"],
      "product-agent": {
        "deny": ["mcp__notion"]
      }
    }
  }
}

Here is what an example interaction would look like, with the current permission error system in place:

claude

> Use the product-agent and tell me what we are we working on in Notion

โบ product-agent(Check Notion workspace status)
  โŽฟ ย notion - Search Notion and connected sources (MCP)(query: "In Progress", query_type: "internal", data_source_url: "collection://<redacted>")
     Error: Permission to use mcp__notion__notion-search has been denied.

That's not super useful. The subagent is denied permission to use the notion MCP but the error does not help the user determine why that's the case.

Solution: better permission errors

If the user were shown the following, that would be a lot more helpful:

claude

> Use the product-agent and tell me what we are we working on in Notion

โบ product-agent(Check Notion workspace status)
  โŽฟ ย notion - Search Notion and connected sources (MCP)(query: "In Progress", query_type: "internal", data_source_url: "collection://<redacted>")
     Error: Permission to use mcp__notion__notion-search has been denied by:
       โŽฟ scope: ./.claude/settings.local.json
         โŽฟ default
           โŽฟ subAgents: "mcp__notion" allowed
             โŽฟ product-agent: "mcp__notion" denied

It's not necessary, but it would be nice.

[4] Allowing Permissions is more complicated

Example: a subagent requests permission for a tool without specific permissions configured

If we were to allow more complex permission configurations, the standard permission request for subagents would be insufficient. Or at the very least, not super helpful.

This is what it would look like now (assuming we implemented subagent configuration) and you forgot to explicitly allow permission for this tool:

claude

> What are we working on in Notion?

โบ I'll check what we're currently working on in Notion by looking at our Kanban board and recent activity.

โบ notion-agent(Check Notion workspace status)
  โŽฟ ย notion - Search Notion and connected sources (MCP)(query: "In Progress status:In Progress", query_type: "internal", data_source_url: "collection://<redacted>")

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Tool use                                                                                                                                                                                                                                                                                                                                                                                                                                โ”‚
โ”‚   notion - Search Notion and connected sources(query: "In Progress status:In Progress", query_type: "internal", data_source_url: "collection://<redacted>") (MCP)                                                       โ”‚                                                                                                                                                                                                                          โ”‚
โ”‚                                                                                                                                                                                                                                                   โ”‚
โ”‚ Do you want to proceed?                                                                                                                                                                                                                           โ”‚
โ”‚ โฏ 1. Yes                                                                                                                                                                                                                                          โ”‚
โ”‚   2. Yes, and don't ask again for notion - Search Notion and connected sources commands in <redacted>                                                                                                                              โ”‚
โ”‚   3. No, and tell Claude what to do differently (esc)
โ”‚                                                                                                                                                                                                                                                   โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Solution: better permission controls

It would be nice to have more granular options for setting permissions for MCP servers. Maybe something like the following flow:

Do you want to proceed?

   1. Yes
โฏ  2. Yes, and don't ask again (permission configuration)
   3. No, and tell Claude what to do differently (esc)

Selecting 1 or 3 would behave as normal. But selecting 2 would open a different menu:

Do you want to allow this specific tool or all tools for the server?

   1. Allow this specific tool (mcp__notion__notion-search)
โฏ  2. Allow all tools from this server (mcp__notion)
   3. Cancel, and tell Claude what to do differently (esc)

Then you scope it:

Where should we scope this permission ("mcp__notion")?

โฏ  1. Locally (./.claude/settings.local.json)
   2. Project (./.claude/settings.json)
   3. User    (~/.claude/settings.json)
   4. Cancel, and tell Claude what to do differently (esc)

Assuming you make any of those selections then you would see:

Do you want to proceed and allow this permission?

  Modify project-local permissions for "notion-agent"
   โŽฟ scope: ./.claude/settings.local.json
     โŽฟ default
       โŽฟ subagents
         โŽฟ notion-agent: allow "mcp__notion"

โฏ  1. Yes, just for this agent (notion-agent)
   2. Yes, for all subagents
   3. Yes, for all agents
   4. Cancel, and tell Claude what to do differently (esc)
preview of option 2
Do you want to proceed and allow this permission?

  Modify project-local permissions for all subagents
   โŽฟ scope: ./.claude/settings.local.json
     โŽฟ default
       โŽฟ subagents: allow "mcp__notion"


   1. Yes, just for this agent (notion-agent)
โฏ  2. Yes, for all subagents
   3. Yes, for all agents
   4. Cancel, and tell Claude what to do differently (esc)
preview of option 3
Do you want to proceed and allow this permission?

  Modify project-local permissions for all agents
   โŽฟ scope: ./.claude/settings.local.json
     โŽฟ default: allow "mcp__notion"



   1. Yes, just for this agent (notion-agent)
   2. Yes, for all subagents
โฏ  3. Yes, for all agents
   4. Cancel, and tell Claude what to do differently (esc)

Thanks for reading this far! Here's a cookie ๐Ÿช

eXamadeus avatar Sep 24 '25 14:09 eXamadeus

The atlassian MCP alone eats up 23k tokens of context. I tried forever to delegate this (and others) to a subagent before finding this thread.

b-yond avatar Oct 10 '25 23:10 b-yond

Yeah the Notion MCP takes up 28,906 tokens the last I checked. It's painful.

I love that MCP, but it's hard to want to keep it connected. If I was using Notion and Atlassian, I'd be wasting a SHIT ton of tokens, for no good reason.

I get the idea of keeping tools in context, but the prospect of siloing these servers is so powerful, and so close. It hurts not to be able to utilize it in a reasonable manner.

eXamadeus avatar Oct 18 '25 17:10 eXamadeus

The atlassian MCP alone eats up 23k tokens of context. I tried forever to delegate this (and others) to a subagent before finding this thread.

I've switched to the Atlassian CLI and feel confident that this is the better approach anyway (CLI > MCP)

markgoho avatar Oct 27 '25 16:10 markgoho

+1 on this issue! Chrome Dev Tools eat up 20k tokens and they are only needed for UI subagents. Other tools already allow scoping of MCP tools to specific modes / agents. This reduces load on Anthropic endpoints and keep subscriptions on Claude Max longer.

philikai avatar Nov 03 '25 12:11 philikai

Reposting the below that I shared in another similar issue in case this helps others:

+1 this is a must-have to be able to use subagents properly.

I had basically stopped using MCPs because of this but had enough and decided to build something to fix it, so I'm sharing it here in case it helps anyone else. It's been working well for me with multiple custom agents and across various other tools (eg. Claude Desktop, etc).

What I Built

An Agent MCP Gateway that sits between your agents and downstream MCP servers and filters servers and individual tools based on an access policy per agent or subagent. Instead of loading all tool definitions upfront (that 10k-50k token overhead), it exposes just 3 gateway tools (~1k-2k tokens) no matter how many MCP servers you configure:

  • list_servers - see which servers you (the agent/subagent) can access
  • get_server_tools - load tools from a specific server when needed (but only the ones the agent has been given access to)
  • execute_tool - runs the tool in the downstream server

Then you configure per-agent access rules. My main Claude Code agent sees only those 3 MCP tools but has no access to other servers and tools (just delegates). My research agent only sees search tools (eg. brave-search, context7, crawl4ai). Database agent sees database tools but can't drop tables. Frontend agent has only a small subset of playwright's 23 tools that I specify.

Agents discover tools and their definitions only when they need them instead of having everything loaded upfront. With just some basic hints and instructions in each agent's system prompt, this works perfectly and consumes a tiny amount of tokens in comparison.

I was listening to an Andrej Karpathy interview where he talked about focusing less on memory and more on LLM cognitive capacity. This made me wonder why are we loading everything into system prompts upfront every session?! Let agents discover what they need, when they need it.

The Tradeoffs

This is an opinionated implementation based on what I believe works best for my use-case, and there are also some limitations:

1. Agents self-identify: Claude Code doesn't pass agent/subagent identity to MCP servers. My solution is agents include agent_id in their tool calls. I add a brief instruction to each agent's system prompt (template in the README) and it's worked surprisingly well. Also works in Claude Desktop or any other MCP client with a default agent config via an env var. 2. Principle of least privilege: Zero implicit access. Agents must be explicitly granted access to see servers/tools. 3. On-demand only: Can't dynamically push tool updates because Claude Code doesn't listen to listChanged notifications via the MCP protocol. So the 3 gateway tools are loaded and they control what gets exposed depending on the agent calling it. TBH I prefer this anyway because it makes tools discoverable rather than forcing it in the context window every session.

Links

GitHub: https://github.com/roddutra/agent-mcp-gateway

Notes

I don't think it's perfect for everyone and it still needs some work, but it solved my problem so far. Happy to answer questions if anyone tries it.

I do hope that the per-agent MCP tool configs is added to Claude Code soon, but I also think that making tools discoverable on-demand and just adding brief instructions in the agent's system prompts (hints, not specs) is a much better approach than loading all tools' definitions into context upfront every time.

roddutra avatar Nov 05 '25 11:11 roddutra

+1

NirAyalon1 avatar Nov 19 '25 07:11 NirAyalon1

@roddutra Thanks so much for making the agent-mcp-gateway tool! This works great!

Would be cool if Claude-Code added native support for this, because I think it's very non-intuitive that adding MCP servers would degrade your performance so quickly. Personally, I think MCP servers are one of the best features of AI Agent frameworks, and I was excited to add them liberally, to supercharge my workflow. I added 8 - which I didn't even think was too big of a number - I can see myself easily getting up to a dozen or two as I develop my setup - and lo and behold, MCP tokens were eating up 50% of my total context at the beginning of each session. After using agent-mcp-gateway tool they are down to 1.1%.

MaxPleaner avatar Nov 20 '25 00:11 MaxPleaner

Wow @roddutra I was about frustrated enough to build something like this myself, but it seemed a monumental task. Your gateway is EXACTLY what I envisioned. It's wonderful.

If I find some free time, I'll see if I can help contribute. I hope it gets some traction. It's an awesome solution to this rather annoying problem. Kudos!

eXamadeus avatar Nov 21 '25 03:11 eXamadeus

@MaxPleaner @eXamadeus thank you, glad to hear it was useful to you both as well. I was previously having to remove and then re-add my MCPs before Claude Code added the ability to toggle them, and then toggling them on/off all the time since then so I got fed up and had to do something about it, especially since they added the /context command where it became clear how much context was being wasted.

I really hope that this gets added added to CC ASAP but also that the MCP protocol itself gets revised to move towards this discoverable model too.

I don't want to hijack this issue so if you have any feedback or suggestions regarding the agent-mcp-gateway in the meantime feel free to open an issue there!

roddutra avatar Nov 21 '25 04:11 roddutra

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] avatar Dec 21 '25 10:12 github-actions[bot]

Yeah, it's still an issue...don't close this.

eXamadeus avatar Dec 21 '25 18:12 eXamadeus

This would be so nice to see

Mnigos avatar Jan 13 '26 19:01 Mnigos