[DOCS] [Subagents] Document MCP server-level specs in subagent `disallowedTools` frontmatter

Open 💬 1 comment Opened Jun 16, 2026 by coygeek

Documentation Type

Missing documentation (feature not documented)

Documentation Location

https://code.claude.com/docs/en/sub-agents

Section/Topic

The "Supported frontmatter fields" table (row for disallowedTools) and the "Control subagent capabilities" -> "Available tools" subsection, including the disallowedTools: Write, Edit example block and the paragraph immediately above it.

Current Documentation

The frontmatter-fields table describes disallowedTools as:

| disallowedTools | No | Tools to deny, removed from inherited or specified list |

The only example in the page that uses this field is the "no-writes" subagent, which only demonstrates bare tool names:

This example uses disallowedTools to inherit every tool from the main conversation except Write and Edit. The subagent keeps Bash, MCP tools, and everything else: ``yaml --- name: no-writes description: Inherits every tool except file writes disallowedTools: Write, Edit --- ``

The "If both are set" paragraph that follows also uses bare names only:

If both are set, disallowedTools is applied first, then tools is resolved against the remaining pool. A tool listed in both is removed.

The permissions.md page documents MCP server-level specs in the global permissions.deny / permissions.ask / --disallowedTools CLI flag / SDK disallowed_tools contexts, but never cross-references the subagent frontmatter field. From permissions.md "Tool name wildcards":

Deny and ask rules also accept glob patterns in the tool-name position. The pattern must match the full tool name: "*" matches every tool, and "mcp__*" matches every MCP tool across all servers.

And from the same page's "MCP" subsection:

mcp__puppeteer matches any tool provided by the puppeteer server (name configured in Claude Code) mcp__puppeteer__* wildcard syntax that also matches all tools from the puppeteer server * mcp__puppeteer__puppeteer_navigate matches the puppeteer_navigate tool provided by the puppeteer server

The v2.1.178 changelog notes the fix:

Fixed MCP server-level specs (mcp__server, mcp__server__*, mcp__*) in subagent disallowedTools being silently ignored

What's Wrong or Missing?

A. The subagent disallowedTools frontmatter field is not documented as accepting MCP server-level specs

The v2.1.178 release fixes a bug where mcp__server, mcp__server__*, and mcp__* entries in a subagent's disallowedTools frontmatter were silently ignored. After the fix, users can drop specific MCP servers (or every MCP tool) from a subagent's pool by listing those specifiers alongside bare tool names.

The "Supported frontmatter fields" row for disallowedTools only says "Tools to deny, removed from inherited or specified list" with no mention of glob patterns, MCP server prefixes, or the now-supported mcp__* family. The lone code example uses bare tool names, and the "If both are set" paragraph below it never lists what kinds of specifiers are valid. Users have no way to learn from the subagent docs alone that they can write disallowedTools: mcp__puppeteer to drop a single MCP server from the inherited pool, or disallowedTools: mcp__* to drop every MCP tool.

B. The "no-writes" example actively misleads readers about MCP coverage

The "no-writes" example states "The subagent keeps Bash, MCP tools, and everything else", which is no longer accurate guidance: the same subagent could now also drop MCP coverage by adding mcp__* to its disallowedTools. The example as written gives the impression that MCP tools can only be allowed or restricted via the subagent's own mcpServers field, which is wrong for the disallowedTools path.

C. The cross-reference from permissions.md to the subagent page is missing

permissions.md clearly states that mcp__* and mcp__<server>__* are valid in deny / ask rules and in the --disallowedTools CLI flag, but it does not link forward to the subagent disallowedTools field on sub-agents.md. Without that cross-reference, users who land on the wildcard rules will not realize the same specifiers also work in the subagent frontmatter (after the v2.1.178 fix), and users who land on the subagent page will not find the wildcard rules at all.

Suggested Improvement

Option A: Comprehensive fix (preferred)

  1. In sub-agents.md, expand the disallowedTools row in the "Supported frontmatter fields" table to mention MCP server-level specs, e.g.:
| disallowedTools | No | Tools to deny, removed from inherited or specified list. Accepts the same specifiers as permission rules, including bare names, Bash(rm *) scoped rules, and MCP server-level specs such as mcp__puppeteer, mcp__puppeteer__*, and mcp__* |
  1. Add a paragraph under the existing disallowedTools: Write, Edit example that introduces the MCP pattern and links to the wildcard reference, e.g.:
The field also accepts the same wildcard specifiers as global permissions.deny rules. To drop a specific MCP server, use its bare prefix (mcp__puppeteer); to drop every tool from a server, add the __* suffix (mcp__puppeteer__*); to drop every MCP tool regardless of server, use mcp__*. See Tool name wildcards for the full set of supported patterns.
  1. Add a worked example to the "Available tools" subsection:
---
name: no-mcp
description: Inherits every tool except MCP tools
disallowedTools: mcp__*
---
  1. Update the "no-writes" example's caption to note that MCP coverage is now controllable through the same field, e.g.:
This example uses disallowedTools to inherit every tool from the main conversation except Write and Edit. The subagent keeps Bash and every MCP tool. To drop MCP coverage, add mcp__* to the same list.
  1. In permissions.md, add a one-line cross-reference in the "Tool name wildcards" section pointing to the subagent disallowedTools field as another location where the same specifiers apply.

Option B: Minimum fix

Add a single paragraph and one example after the existing "no-writes" YAML block:

The disallowedTools field also accepts MCP server-level specifiers: mcp__puppeteer drops a single server, mcp__puppeteer__* drops every tool from that server, and mcp__* drops every MCP tool. These now work in v2.1.178 and later. See Tool name wildcards for the full set of supported patterns. ``yaml --- name: no-mcp description: Inherits every tool except MCP tools disallowedTools: mcp__* --- ``

Then add a one-line cross-reference from the "Tool name wildcards" section in permissions.md to the subagent disallowedTools field.

Impact

Medium - Makes feature difficult to understand

Additional Context

Affected Pages:

| Page | Context |
|------|---------|
| https://code.claude.com/docs/en/sub-agents | Primary documentation location. "Supported frontmatter fields" table row for disallowedTools, and the "Control subagent capabilities" -> "Available tools" subsection (the no-writes example and the "If both are set" paragraph). |
| https://code.claude.com/docs/en/permissions | "Tool name wildcards" and "MCP" subsections document the specifiers in the global permissions.deny / permissions.ask / --disallowedTools CLI flag / SDK disallowed_tools contexts, but do not cross-reference the subagent frontmatter field where the same specifiers also apply. |
| https://code.claude.com/docs/en/cli-reference | --disallowedTools / --disallowed-tools description (line ~70) lists mcp__* but does not link to the subagent page. |
| https://code.claude.com/docs/en/agent-sdk/permissions | SDK disallowed_tools table row documents mcp__* but does not cross-link to the subagent frontmatter field. |

Total scope: 4 pages affected.

Version: The fix ships in Claude Code v2.1.178 (June 15, 2026). The changelog entry at https://code.claude.com/docs/en/changelog is the only public source documenting this capability today.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗