[FEATURE] Allow skills to be hidden from the main agent (subagent-exclusive skills)

Status Open
Maintainer reply None cached
Activity 9 comments · opened Nov 28, 2025

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Subagents can already specify which skills to auto-load using the skills: field in their frontmatter:

---
name: db-admin
description: Database administration tasks
tools: Bash, Read
skills: database-migration, postgres-ops  # Skills to auto-load for this subagent
---

However, there's no way to hide a skill from the main agent. All skills in ~/.claude/skills/ and .claude/skills/ have their metadata (name and description) loaded into the main agent's system prompt at startup, regardless of whether they're intended only for subagents.

The problem:

  • Main agent's context gets polluted with skills it shouldn't use
  • Main agent may attempt tasks that should be delegated to specialized subagents
  • Can't create truly exclusive subagent capabilities
  • Extra token overhead from irrelevant skill metadata in main agent's prompt

Current workaround:
Embed the knowledge directly in the subagent's .md file instead of creating a skill. This works but loses the benefits of skills (progressive disclosure, reusability across multiple subagents, composability, separate maintenance).

Proposed Solution

Add an optional field to SKILL.md frontmatter that hides the skill from the main agent:

---
name: database-migration
description: Database migration procedures for PostgreSQL
main-agent: false  # Hide from main agent, only subagents can discover this skill
---

Or alternatively, an allowlist approach:

---
name: database-migration
description: Database migration procedures for PostgreSQL
agents: db-admin, data-engineer  # Only these agents can see this skill (main agent excluded)
---

Behavior:

  • If field is omitted → skill visible to all agents including main (backward compatible)
  • If main-agent: false → skill metadata not loaded into main agent's context, only available to subagents that reference it via their skills: field
  • If agents: allowlist specified → only those agents see the skill

Alternative Solutions

Workaround 1: Embed knowledge directly in the subagent's .md file

Instead of creating a skill, put all the instructions directly in the subagent's system prompt:

---
name: db-admin
description: Database administration tasks
tools: Bash, Read
---

# Database Admin Agent

## Database Migration Procedures
[All the specialized knowledge here - only this subagent sees it]

This works but loses the benefits of the skills system:

  • No progressive disclosure (everything loads into context immediately)
  • Can't reuse the same knowledge across multiple subagents
  • Can't use skill scripts or reference files
  • Harder to maintain separately from agent logic

Workaround 2: Use a very specific description to discourage main agent usage

---
name: database-migration
description: "ONLY for db-admin subagent. Do NOT use directly - always delegate to db-admin subagent."
---

This is unreliable - the main agent may still attempt to use the skill despite the description.

Workaround 3: Add delegation instructions to CLAUDE.md

## Task Delegation Rules
- Database migrations → always delegate to db-admin subagent
- Never use the database-migration skill directly

This adds overhead to CLAUDE.md and relies on the main agent following instructions rather than enforcing isolation at the system level.

Priority

Critical - Blocking my work

Feature Category

Configuration and settings

Use Case Example

_No response_

Additional Context

The subagent skills: field already allows subagents to opt-in to specific skills. This feature request is for the inverse - allowing skills to opt-out of the main agent. Together, these would enable full control over skill visibility across the agent hierarchy.

View original on GitHub ↗

9 Comments

github-actions[bot] · 9 months ago

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/6915
  2. https://github.com/anthropics/claude-code/issues/4380

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

Roeia1 · 9 months ago
Found 2 possible duplicate issues: 1. Allow MCP tools to be available only to subagent #6915 2. Feature: Per-agent MCP tool filtering to improve agent focus and accuracy #4380 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

This is not a duplicate of the linked issues.

  • #6915 and #4380 are about MCP tools filtering
  • This issue is about Skills scoping

These are different systems in Claude Code:

  • MCP tools = external tools exposed via Model Context Protocol servers
  • Skills = SKILL.md files with instructions, scripts, and resources that Claude loads dynamically

The feature request here is to add a frontmatter field to SKILL.md (like main-agent: false or agents: [list]) to control which agents can discover the skill. This is unrelated to MCP tool filtering.

That said, this issue is conceptually similar to #6587 (Selective MCP Access Control for SubAgents) - both address the same underlying need for agent-scoped capabilities, just for different systems (Skills vs MCP). Implementing a consistent solution across both would be ideal.

kitaekatt · 8 months ago

I currently have 87 of 113 skills visible in my system prompt and no agency over which skills are and are not visible. This would solve this problem.

vantasnerdan · 8 months ago

Agree. I create new subagents when I add new features, pages, services, etc... Each subagent needs its own set of skills. I need to keep claude skills minimal, it doesnt need the bloat of every subagent skill.

Workaround: configure your subagents to use a slash command so that they load their markdowns like a skill.

vantasnerdan · 7 months ago

Changelog for 2.1: Added support for agent field in skills to specify agent type for execution

Here is my validation test:

<h2 id="feature-2-agent-skills-field" class="atx"> Agent <code>skills</code> Field</h2>
<h3 id="syntax-tested" class="atx">Syntax Tested</h3>
<pre><code class="fenced-code-block language-yaml">---
name: agent-one
description: Agent with access to skill-alpha only
tools: Read, Glob
model: haiku
skills: skill-alpha
---</code></pre>
<h3 id="test-result" class="atx">Test Result</h3>
<p><strong>WORKING - CONFIRMED</strong></p>
<h4 id="agent-one-skills-skill-alpha" class="atx">agent-one (skills: skill-alpha)</h4>
<ul>
<li>Can execute <code>/skill-alpha</code></li>
<li>Cannot execute <code>/skill-beta</code></li>
</ul>
<h4 id="agent-two-skills-skill-beta" class="atx">agent-two (skills: skill-beta)</h4>
<ul>
<li>Can execute <code>/skill-beta</code></li>
<li>Cannot execute <code>/skill-alpha</code></li>
</ul>
<h3 id="key-findings" class="atx">Key Findings</h3>
<ol>
<li>Skill isolation works as intended</li>
<li>Agents only see skills declared in their <code>skills</code> field</li>
<li>Agents can still READ skill files via filesystem (if they have Read tool), but cannot EXECUTE them as skills</li>
<li>Global skills (without agent restriction) remain accessible</li>
</ol>
<h3 id="recommended-usage" class="atx">Recommended Usage</h3>
<pre><code class="fenced-code-block language-yaml">---
name: specialist-agent
description: Agent for specific task domain
tools: Read, Glob, Bash
skills: domain-skill-1, domain-skill-2
---</code></pre>
<p>Use this to reduce context bloat by limiting which skills each subagent can see.</p>
<hr>
<h2 id="feature-3-skill-agent-field--context-fork" class="atx">Feature 3: Skill <code>agent</code> Field + <code>context: fork</code></h2>
<h3 id="key-discovery" class="atx">Key Discovery</h3>
<p>The <code>agent</code> field <strong>requires</strong> <code>context: fork</code> to execute skills in an agent&#39;s context. Without <code>context: fork</code>, the <code>agent</code> field alone does nothing.</p>
<h3 id="syntax---working" class="atx">Syntax - WORKING</h3>
<pre><code class="fenced-code-block language-yaml">---
name: skill-bound
description: Skill bound to a specific agent
agent: agent-executor
context: fork
---</code></pre>
<h3 id="test-results" class="atx">Test Results</h3>
<h4 id="test-a-agent-field-alone-no-context-fork" class="atx">Test A: <code>agent</code> field alone (NO <code>context: fork</code>)</h4>
<ul>
<li>Skill loaded in main conversation context</li>
<li><strong>Full main conversation tools available</strong></li>
<li>Did NOT spawn agent-executor</li>
<li><strong>Result: Does NOT work as expected</strong></li>
</ul>
<h4 id="test-b-agent--context-fork" class="atx">Test B: <code>agent</code> + <code>context: fork</code></h4>
<ul>
<li>Skill executed in <strong>forked sub-agent context</strong></li>
<li><strong>Only agent-executor&#39;s tools available</strong> (Read, Glob, Bash)</li>
<li>Confirmed running in agent-executor&#39;s context</li>
<li><strong>Result: WORKING</strong></li>
</ul>
<h4 id="test-c-context-fork-alone-no-agent-field" class="atx">Test C: <code>context: fork</code> alone (NO <code>agent</code> field)</h4>
<ul>
<li>Skill executed in <strong>forked context</strong></li>
<li>Broad set of default tools available</li>
<li>Isolated execution, but not bound to specific agent</li>
<li><strong>Result: WORKING</strong> (for isolation without agent binding)</li>
</ul>
<h3 id="behavior-matrix" class="atx">Behavior Matrix</h3>

Configuration | Execution Context | Available Tools
-- | -- | --
Neither | Main conversation | All main tools
agent only | Main conversation | All main tools
context: fork only | Forked (isolated) | Default broad set
agent + context: fork | Forked as agent | Agent's tools only

<h3 id="recommended-usage-1" class="atx">Recommended Usage</h3>
<pre><code class="fenced-code-block language-yaml">---
name: code-review-skill
description: Reviews code with restricted tools
agent: code-reviewer
context: fork
---

This skill will execute with only code-reviewer&#39;s tools</code></pre>

<h3 id="why-this-matters" class="atx">Why This Matters</h3>
<ul>
<li><strong>Security</strong>: Restrict skill execution to specific tools</li>
<li><strong>Isolation</strong>: Fork prevents skill from accessing main conversation state</li>
<li><strong>Specialization</strong>: Skills inherit agent configuration (tools, model, etc.)</li>
</ul>
<hr>
<h2 id="feature-3b-skill-context-field" class="atx">Feature 3b: Skill <code>context</code> Field</h2>
<h3 id="syntax" class="atx">Syntax</h3>
<pre><code class="fenced-code-block language-yaml">---
name: isolated-skill
context: fork
---</code></pre>
<h3 id="purpose" class="atx">Purpose</h3>
<p>The <code>context: fork</code> field runs the skill in an isolated sub-agent context. Combined with <code>agent</code>, it determines which agent configuration to use.</p>
<h3 id="values" class="atx">Values</h3>
<ul>
<li><code>fork</code> - Run in forked sub-agent context (confirmed working)</li>
<li>(Other values not tested)</li>
</ul>
<hr>
^@

kitaekatt · 7 months ago

I have found a workaround for this.

If you don't provide a description skill name is not loaded into context but may still be invoked with the Skill tool.

I use hidden-description (not a real field) for descriptions of these skills.

It actually works really well but it would be nice to have a visibility toggle or to at least document that the description field is what controls skill visibility to Claude

vantasnerdan · 7 months ago
I have found a workaround for this. If you don't provide a description skill name is not loaded into context but may still be invoked with the Skill tool. I use hidden-description (not a real field) for descriptions of these skills. It actually works really well but it would be nice to have a visibility toggle or to at least document that the description field is what controls skill visibility to Claude

Useful hack

kitaekatt · 7 months ago

Claude Code 2.1 added new features:

  1. Agent skills field in frontmatter - Subagents can specify which skills to auto-load:

---
name: agent-one
skills: skill-alpha
---
Result: Agent-one can only execute skill-alpha, not skill-beta.

  1. Skill agent + context: fork - Skills can run exclusively in a specific agent:

---
name: skill-bound
agent: agent-executor
context: fork
---

yurukusa · 5 months ago

A UserPromptSubmit hook can control which skills are visible to the main agent vs subagents:

INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.user_prompt // empty' 2>/dev/null)
SUBAGENT_ONLY="internal-review|code-audit|deep-analyze"
if echo "$PROMPT" | grep -qiE "^/($SUBAGENT_ONLY)"; then
    echo '{"hookSpecificOutput":{"additionalContext":"This skill is subagent-exclusive. Spawn a subagent to run it instead of executing directly."}}'
fi
exit 0
PUBLIC_SKILLS=$(find .claude/skills -maxdepth 1 -name "*.md" 2>/dev/null | while read f; do
    if ! head -5 "$f" | grep -q "subagent-only: true"; then
        basename "$f" .md
    fi
done | tr '\n' ', ' | sed 's/,$//')
if [ -n "$PUBLIC_SKILLS" ]; then
    echo "{\"hookSpecificOutput\":{\"additionalContext\":\"Available skills: $PUBLIC_SKILLS\"}}"
fi
exit 0

Add to the skill's frontmatter:

---
subagent-only: true
---
{
  "hooks": {
    "UserPromptSubmit": [{"hooks": [{"type": "command", "command": "bash ~/.claude/hooks/skill-visibility.sh"}]}],
    "Notification": [{"matcher": "start", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/skill-list-filter.sh"}]}]
  }
}

Skills marked subagent-only: true are filtered from the main agent's skill list. They're only discovered when a subagent is spawned.