14 KiB
Claude Code Extensions
Note: For comprehensive Claude Code skill development, load the
outfitter:claude-skillsskill. This reference provides a quick overview.
Claude Code-specific implementation details for Agent Skills. For cross-platform concepts (structure, frontmatter, validation), load the outfitter:skills-dev skill.
Table of Contents
- Frontmatter Extensions
- Tool Restrictions
- User Invocable Skills
- String Substitutions
- Dynamic Context Injection
- Context Modes
- Testing with Debug Mode
- Troubleshooting
- Integration Patterns
- Master-Clone Architecture
- Hook-Based Validation
- Skill + MCP Integration
Frontmatter Extensions
Claude Code extends the base Agent Skills specification with additional frontmatter fields:
| Field | Type | Description |
|---|---|---|
allowed-tools |
string | Space-separated list of tools the skill can use without permission prompts |
user-invocable |
boolean | Default true. Set to false to prevent slash command access |
disable-model-invocation |
boolean | Prevents automatic activation; requires manual invocation via Skill tool |
context |
string | inherit (default) or fork for isolated subagent execution |
agent |
string | Agent to use when skill is invoked (e.g., outfitter:analyst) |
model |
string | Override model: haiku, sonnet, or opus |
hooks |
object | Lifecycle hooks: on-activate, on-complete |
argument-hint |
string | Hint text shown after /skill-name (e.g., [file path]) |
Example
---
name: code-review
version: 1.0.0
description: Reviews code for bugs, security issues, and best practices. Use when reviewing PRs, auditing code, or before merging.
allowed-tools: Read Grep Glob Bash(git diff *)
argument-hint: [file or directory]
model: sonnet
---
Note:
user-invocabledefaults totrue, so skills are callable as/skill-nameby default. Only setuser-invocable: falseif you want to prevent slash command access.
Tool Restrictions
Use allowed-tools to specify which tools Claude can use when a skill is active. Listed tools run without permission prompts.
Syntax
# Space-separated list
allowed-tools: Read Grep Glob
# With Bash patterns
allowed-tools: Read Write Bash(git *) Bash(npm run *)
# MCP tools (double underscore format)
allowed-tools: Read mcp__linear__create_issue mcp__memory__store
Bash Pattern Syntax
| Pattern | Meaning | Example |
|---|---|---|
Bash(git *) |
All git commands | git status, git commit |
Bash(git add:*) |
Specific subcommand | git add ., git add file.ts |
Bash(npm run *:*) |
Nested patterns | npm run test:unit |
Common Patterns
# Read-only analysis
allowed-tools: Read Grep Glob
# File modifications
allowed-tools: Read Edit Write
# Git operations
allowed-tools: Read Write Bash(git *)
# Testing workflows
allowed-tools: Read Write Bash(bun test:*) Bash(npm test:*)
# Full development
allowed-tools: Read Edit Write Bash(git *) Bash(bun *) Bash(npm *)
Tool Names (Case-Sensitive)
| Tool | Purpose |
|---|---|
Read |
Read files |
Write |
Write new files |
Edit |
Edit existing files |
Grep |
Search file contents |
Glob |
Find files by pattern |
Bash |
Execute bash commands |
WebFetch |
Fetch web content |
WebSearch |
Search the web |
Behavior
- With
allowed-tools: Listed tools run without permission prompts - Without
allowed-tools: Inherits conversation permissions; Claude may ask
User Invocable Skills
Skills are callable as slash commands by default (user-invocable: true). Use user-invocable: false to prevent slash command access for skills that should only be auto-activated.
---
name: code-review
description: Reviews code for bugs and best practices...
argument-hint: [file or PR number]
---
Users can invoke with /code-review src/auth.ts or wait for auto-activation based on the description.
Disabling Slash Command Access
For skills that should only activate automatically (not manually invoked):
---
name: internal-validator
description: Validates internal state when specific patterns are detected...
user-invocable: false
---
With Arguments
The argument-hint field provides context in the command picker:
argument-hint: [error message or bug description]
Arguments are available in the skill body via $ARGUMENTS.
String Substitutions
Claude Code supports these substitution patterns in skill content:
| Pattern | Replaced With |
|---|---|
$ARGUMENTS |
User input after /skill-name |
${CLAUDE_SESSION_ID} |
Current session identifier |
${CLAUDE_PLUGIN_ROOT} |
Path to the plugin root directory |
Example
# Debug Skill
Investigating: $ARGUMENTS
Session: ${CLAUDE_SESSION_ID}
Use the debugging script:
${CLAUDE_PLUGIN_ROOT}/scripts/debug-helper.ts
Dynamic Context Injection
Use backtick-command syntax to inject dynamic content:
## Current Git Status
`git status`
## Recent Changes
`git log --oneline -5`
When Claude loads the skill, these commands execute and their output replaces the command syntax.
Use cases:
- Current branch state
- Environment information
- Dynamic configuration
- Recent history
Context Modes
The context field controls how skills execute:
inherit (default)
Skill runs in the main conversation context. Has access to conversation history and prior tool results.
context: inherit
fork
Skill runs in an isolated subagent context. Useful for:
- Preventing context pollution
- Parallel execution
- Specialized processing that shouldn't affect main conversation
context: fork
agent: outfitter:analyst
model: haiku
When context: fork, the skill can specify:
agent: Which agent type handles the forkmodel: Override model for the forked context
Testing with Debug Mode
claude --debug
Debug output shows:
Loaded skill: skill-name from path— Skill discoveredError loading skill: reason— Loading failedConsidering skill: skill-name— Activation being evaluatedSkill allowed-tools: [list]— Tool restrictions applied
Testing Process
- Verify loading: Run
claude --debugand check for load messages - Test discovery: Ask Claude something that should trigger the skill
- Verify tool restrictions: Confirm permitted tools run without prompts
- Test with real data: Run actual workflows
Example Test Session
# Start debug session
claude --debug
# In conversation, trigger the skill naturally:
# "Can you help me process this PDF file?"
# Look for:
# "Considering skill: pdf-processor"
# "Activated skill: pdf-processor"
Force Skill Reload
Skills are cached per session. To reload after changes:
/clear
Troubleshooting
Skill Not Loading
Check file location:
# Personal skills
ls ~/.claude/skills/my-skill/SKILL.md
# Project skills
ls .claude/skills/my-skill/SKILL.md
# Plugin skills
ls <plugin-path>/skills/my-skill/SKILL.md
Validate YAML frontmatter:
# Check for tabs (YAML requires spaces)
grep -P "\t" SKILL.md
# Validate syntax
bun run outfitter/scripts/validate-skill-frontmatter.ts SKILL.md
Check file permissions:
chmod 644 SKILL.md
chmod +x scripts/*.sh
Skill Not Activating
Improve description specificity:
# Before (too vague)
description: Helps with files
# After (specific with triggers)
description: Parse and validate JSON files including schema validation. Use when working with JSON data, .json files, or configuration files.
Add trigger keywords that users naturally say:
- File types:
.pdf,.json,.xlsx - Actions:
parse,validate,test,analyze - Domains:
API,database,spreadsheet
Tool Permission Errors
Tool names are case-sensitive:
# Correct
allowed-tools: Read Grep Glob
# Wrong
allowed-tools: read grep glob
Bash patterns need wildcards:
# Correct
allowed-tools: Bash(git *)
# Wrong (matches nothing)
allowed-tools: Bash(git)
MCP tools use double underscores:
# Correct
allowed-tools: mcp__memory__store
# Wrong
allowed-tools: mcp_memory_store
Script Execution Errors
Ensure executable:
chmod +x scripts/*.sh
Use portable shebang:
#!/usr/bin/env bash # Recommended
#!/bin/bash # Also works
Use ${CLAUDE_PLUGIN_ROOT} for paths:
# Correct
${CLAUDE_PLUGIN_ROOT}/scripts/process.sh input.txt
# Wrong (breaks portability)
/Users/me/.claude/skills/my-skill/scripts/process.sh
Integration Patterns
With Commands
Skills activate automatically when commands need their expertise:
Command (.claude/commands/analyze-pdf.md):
---
description: Analyze PDF file
---
Analyze this PDF file: $ARGUMENTS
Use the PDF processing skill for extraction and analysis.
When user runs /analyze-pdf report.pdf, Claude recognizes the PDF context and activates the skill.
With Hooks
Hooks can suggest skill usage:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write(*.ts)|Edit(*.ts)",
"hooks": [
{
"type": "command",
"command": "echo 'Consider using typescript-linter skill'"
}
]
}
]
}
}
Using Skill Tool
Load skills programmatically with the Skill tool:
Use the Skill tool to invoke the pdf-processor skill
This is useful for:
- Forcing specific skill activation
- Chaining skills together
- Loading skills for agents
Master-Clone Architecture
For orchestrating specialized work with context isolation:
Master Agent: Coordinates, maintains conversation context, delegates specialized tasks Clone Agents: Isolated context, loads specific skill, returns focused output
User request
↓
Master agent decides: needs security analysis
↓
Launch clone agent with security-audit skill
↓
Clone returns findings (only findings in main context)
↓
Master synthesizes and continues
Advantage over inline execution: Master preserves main conversation context; specialist work happens in isolated bubble.
Implementation
---
name: security-audit
context: fork
agent: outfitter:reviewer
model: sonnet
---
Or via Task tool:
{
"description": "Security audit of auth module",
"prompt": "Review src/auth/ for vulnerabilities using security-audit skill",
"subagent_type": "outfitter:reviewer",
"run_in_background": true
}
Hook-Based Validation
Use hooks to enforce constraints at decision points.
PreToolUse Hook Example
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write(**/SKILL.md)|Edit(**/SKILL.md)",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate-skill-frontmatter.ts",
"timeout": 10
}
]
}
]
}
}
Use Cases
- Prevent destructive operations
- Enforce testing requirements
- Validate configuration before deployment
- Check security constraints
- Validate skill frontmatter before saving
Block at Submit Pattern
export async function blockAtSubmit() {
const issues = await runStaticAnalysis();
const testsPassing = await runTestSuite();
const securityClear = await runSecurityAudit();
return {
block: issues.length > 0 || !testsPassing || !securityClear,
reason: formatBlockingIssues(issues)
};
}
Skill + MCP Integration
Pattern: Skills provide workflows, MCP servers provide data/tools.
Example Architecture
- MCP Server: Linear API access (issues, projects, users)
- Skill: Project standup workflow (what data to pull, how to format, communication patterns)
---
name: linear-standup
description: Generates team standup reports from Linear issues
allowed-tools: mcp__linear__get_issues mcp__linear__get_projects
---
# Linear Standup Skill
Use the Linear MCP server to:
1. Fetch issues by status and assignee
2. Group by project and priority
3. Format as standup report
Why Separate
- MCP handles authentication, rate limiting, data access
- Skill handles business logic, formatting, workflows
- Easier to reuse across similar domains
Performance Tips
Keep SKILL.md Small
Token impact of skill size:
- 300 lines ≈ 2,000 tokens
- 1,500 lines ≈ 10,000 tokens
Each activation loads the full SKILL.md. Use progressive disclosure.
Tool Restrictions Speed Up Execution
Without restrictions: Claude asks permission for each tool. With restrictions: Listed tools run immediately.
# Fast (no prompts for these tools)
allowed-tools: Read Grep Glob
Quick Reference
# Find all skills
find ~/.claude/skills .claude/skills -name "SKILL.md" 2>/dev/null
# Validate YAML
bun run outfitter/scripts/validate-skill-frontmatter.ts SKILL.md
# Check for tabs
grep -P "\t" SKILL.md
# Test in debug mode
claude --debug
Related Resources
For comprehensive guidance, load the relevant skill:
- Claude Code skills:
outfitter:claude-skills - Cross-platform skills:
outfitter:skills-dev - Plugin development:
outfitter:claude-plugins - Hook integration:
outfitter:claude-hooks - Command integration:
outfitter:claude-commands
Reference docs in this directory:
- best-practices.md — Community patterns and testing strategies
- patterns.md — Advanced skill patterns and degrees of freedom