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

Resolved 💬 25 comments Opened Jul 25, 2025 by stanislavlysenko0912 Closed Mar 12, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

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

View original on GitHub ↗

25 Comments

PhilipGarnero · 11 months ago

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.

FrancisBourre · 11 months ago

+1

jmor1234 · 11 months ago

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?

github-actions[bot] · 11 months ago

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

gabrielbryk · 10 months ago

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

CaptainCrouton89 · 10 months ago

+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.

eXamadeus · 9 months ago

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)

<details>

<summary>preview of option 2</summary>

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)

</details>

<details>

<summary>preview of option 3</summary>

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)

</details>

---

Thanks for reading this far! Here's a cookie 🍪

b-yond · 9 months ago

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.

eXamadeus · 9 months ago

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.

markgoho · 8 months ago
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)

philikai · 8 months ago

+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.

roddutra · 8 months ago

_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.

NirAyalon1 · 7 months ago

+1

ghost · 7 months ago

@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%.

eXamadeus · 7 months ago

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!

roddutra · 7 months ago

@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!

github-actions[bot] · 6 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.

eXamadeus · 6 months ago

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

Mnigos · 6 months ago

This would be so nice to see

JairoTorregrosa · 5 months ago

Use case: PM subagent with only Linear/Jira MCP access

Skills already support per-subagent scoping via the skills: field. MCP doesn't.

What I want:

.claude/agents/pm.md

  name: pm
  description: Ticket management - Linear, Jira
  tools: Read
  skills: agile-workflow
  mcpServers: linear, jira   # this doesn't exist

A PM subagent that only sees issue tracking tools. Not my Vercel MCP, not my database MCP, not Exa, just Linear/Jira.

Why it matters:

Right now my PM subagent inherits all 20+ MCP tools from the parent. It sees deploy tools, DB tools, everything. So instead of just creating a ticket, sometimes it tries to "help" by deploying or running commands it shouldn't touch.
Also: if I'm building a PM agent, I don't want it to have access to prod infrastructure MCPs. That's just asking for trouble.

What I'd expect:

Same behavior as skills: if you specify mcpServers: in the subagent frontmatter, it only gets those. No inheritance unless explicitly requested.

mcpServers: linear
# or
excludeGlobalMcp: true
roddutra · 5 months ago
### Why it matters: Right now my PM subagent inherits all 20+ MCP tools from the parent. It sees deploy tools, DB tools, everything. So instead of just creating a ticket, sometimes it tries to "help" by deploying or running commands it shouldn't touch. Also: if I'm building a PM agent, I don't want it to have access to prod infrastructure MCPs. That's just asking for trouble.

@JairoTorregrosa until this gets added to Claude Code give the agent-mcp-gateway a try as per my comment earlier in this thread. I made it exactly for this purpose so you can define very granular rules for each agent/subagent either on a certain MCP server as a whole, or down each server's individual tools.

It's certainly not the most elegant solution, but it's the best I could do until this is natively supported and it is working surprisingly well for me so far both in terms of preserving tokens as well as limiting the tools each subagent can use.

hzj629206 · 5 months ago
# Use case: PM subagent with only Linear/Jira MCP access Skills already support per-subagent scoping via the skills: field. MCP doesn't. ### What I want: .claude/agents/pm.md name: pm description: Ticket management - Linear, Jira tools: Read skills: agile-workflow mcpServers: linear, jira # this doesn't exist A PM subagent that only sees issue tracking tools. Not my Vercel MCP, not my database MCP, not Exa, just Linear/Jira. ### Why it matters: Right now my PM subagent inherits all 20+ MCP tools from the parent. It sees deploy tools, DB tools, everything. So instead of just creating a ticket, sometimes it tries to "help" by deploying or running commands it shouldn't touch. Also: if I'm building a PM agent, I don't want it to have access to prod infrastructure MCPs. That's just asking for trouble. ### What I'd expect: Same behavior as skills: if you specify mcpServers: in the subagent frontmatter, it only gets those. No inheritance unless explicitly requested. mcpServers: linear # or excludeGlobalMcp: true

Seems mcpServers was added recently. See https://code.claude.com/docs/en/sub-agents

brianoestberg · 4 months ago

+1

bcherny collaborator · 4 months ago

This is now supported via two complementary frontmatter fields in agent definitions:

tools — restrict built-in tools available to the subagent:
~~~yaml
---
name: research-agent
description: Web research specialist
tools: WebSearch, WebFetch, Read # only these
---
~~~

mcpServers — scope MCP servers to a specific subagent:
~~~yaml
---
name: db-agent
description: Database operations
tools: Bash, Read
mcpServers:

  • postgres:

type: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-postgres", "..."]
---
~~~

With an inline mcpServers definition, the main conversation never sees or loads those MCP tools — they exist only inside the subagent's context. This is the "pure orchestrator + focused specialists" pattern from your example.

Docs:

  • [Subagent tools field](<https://docs.anthropic.com/en/docs/claude-code/sub-agents#available-tools>)
  • [Scope MCP servers to a subagent](<https://docs.anthropic.com/en/docs/claude-code/sub-agents#scope-mcp-servers-to-a-subagent>)

Closing as resolved.

github-actions[bot] · 3 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.