Plugin Settings
AnthropicOfficialPublished by Anthropic
- Skill
- Guidelines
- Agent tooling
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill defines a standardized pattern for managing plugin-specific settings and state within a project. By utilizing .claude/plugin-name.local.md files, developers can store structured configuration in YAML frontmatter and descriptive content in the markdown body. This approach allows plugins to be highly configurable on a per-project basis while keeping settings out of version control. The skill provides best practices for parsing these files in bash hooks, managing agent state, and ensuring secure, reliable configuration handling.
What it does
- Defines the .claude/plugin-name.local.md file structure for plugin configuration.
- Provides patterns for parsing YAML frontmatter and markdown content in bash scripts.
- Establishes a quick-exit pattern for hooks to skip inactive plugins.
- Offers guidance on creating, updating, and validating settings files.
- Includes security best practices for handling user-provided configuration.
- Suggests standard gitignore entries to prevent accidental commits of local settings.
When to use it
- When you need to make a plugin's behavior configurable per project.
- When you need to store persistent state for an agent or plugin session.
- When you want to provide users with a simple way to toggle plugin features.
- When you need to pass complex instructions or prompts to an agent via a file.
- When you are developing custom hooks or commands that require external configuration.
Advantages
- Keeps configuration local to the project and excluded from version control.
- Uses human-readable markdown and YAML for easy manual editing.
- Enables dynamic behavior changes without modifying core plugin code.
- Provides a consistent structure across different plugins.
- Supports both structured data (YAML) and unstructured content (markdown).
Usage examples
- “How do I make my plugin configurable for users?”
- The agent explains the .claude/plugin-name.local.md pattern, providing a template and instructions on how to parse the YAML frontmatter within bash hooks.
- “How can I read settings from a .local.md file in my bash hook?”
- The agent provides a code snippet using sed to extract the frontmatter block and grep/sed to parse specific fields like enabled status or numeric thresholds.
- “What is the best way to store agent state between tasks?”
- The agent demonstrates using a .local.md file to store task numbers, agent names, and dependencies, showing how to update these values programmatically.
- “How do I ensure my plugin settings are not committed to git?”
- The agent advises adding .claude/*.local.md to the project's .gitignore file and explains why this is a best practice for local configuration.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/anthropics/plugin-settings/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip plugin-settings.zip -d .agents/skills
Documentation by Anthropic
Plugin Settings Pattern for Claude Code Plugins
Overview
Plugins can store user-configurable settings and state in .claude/plugin-name.local.md files within the project directory. This pattern uses YAML frontmatter for structured configuration and markdown content for prompts or additional context.
Key characteristics:
File location:
.claude/plugin-name.local.mdin project rootStructure: YAML frontmatter + markdown body
Purpose: Per-project plugin configuration and state
Usage: Read from hooks, commands, and agents
Lifecycle: User-managed (not in git, should be in
.gitignore)
File Structure
Basic Template
---
enabled: true
setting1: value1
setting2: value2
numeric_setting: 42
list_setting: ["item1", "item2"]
---
# Additional Context
This markdown body can contain:
- Task descriptions
- Additional instructions
- Prompts to feed back to Claude
- Documentation or notesExample: Plugin State File
.claude/my-plugin.local.md:
---
enabled: true
strict_mode: false
max_retries: 3
notification_level: info
coordinator_session: team-leader
---
# Plugin Configuration
This plugin is configured for standard validation mode.
Contact @team-lead with questions.Reading Settings Files
From Hooks (Bash Scripts)
Pattern: Check existence and parse frontmatter
#!/bin/bash
set -euo pipefail
# Define state file path
STATE_FILE=".claude/my-plugin.local.md"
# Quick exit if file doesn't exist
if [[ ! -f "$STATE_FILE" ]]; then
exit 0 # Plugin not configured, skip
fi
# Parse YAML frontmatter (between --- markers)
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$STATE_FILE")
# Extract individual fields
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//' | sed 's/^"\(.*\)"$/\1/')
STRICT_MODE=$(echo "$FRONTMATTER" | grep '^strict_mode:' | sed 's/strict_mode: *//' | sed 's/^"\(.*\)"$/\1/')
# Check if enabled
if [[ "$ENABLED" != "true" ]]; then
exit 0 # Disabled
fi
# Use configuration in hook logic
if [[ "$STRICT_MODE" == "true" ]]; then
# Apply strict validation
# ...
fiSee examples/read-settings-hook.sh for complete working example.
From Commands
Commands can read settings files to customize behavior:
---
description: Process data with plugin
allowed-tools: ["Read", "Bash"]
---
# Process Command
Steps:
1. Check if settings exist at `.claude/my-plugin.local.md`
2. Read configuration using Read tool
3. Parse YAML frontmatter to extract settings
4. Apply settings to processing logic
5. Execute with configured behaviorFrom Agents
Agents can reference settings in their instructions:
---
name: configured-agent
description: Agent that adapts to project settings
---
Check for plugin settings at `.claude/my-plugin.local.md`.
If present, parse YAML frontmatter and adapt behavior according to:
- enabled: Whether plugin is active
- mode: Processing mode (strict, standard, lenient)
- Additional configuration fieldsParsing Techniques
Extract Frontmatter
# Extract everything between --- markers
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$FILE")Read Individual Fields
String fields:
VALUE=$(echo "$FRONTMATTER" | grep '^field_name:' | sed 's/field_name: *//' | sed 's/^"\(.*\)"$/\1/')Boolean fields:
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')
# Compare: if [[ "$ENABLED" == "true" ]]; thenNumeric fields:
MAX=$(echo "$FRONTMATTER" | grep '^max_value:' | sed 's/max_value: *//')
# Use: if [[ $MAX -gt 100 ]]; thenRead Markdown Body
Extract content after second ---:
# Get everything after closing ---
BODY=$(awk '/^---$/{i++; next} i>=2' "$FILE")Common Patterns
Pattern 1: Temporarily Active Hooks
Use settings file to control hook activation:
#!/bin/bash
STATE_FILE=".claude/security-scan.local.md"
# Quick exit if not configured
if [[ ! -f "$STATE_FILE" ]]; then
exit 0
fi
# Read enabled flag
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$STATE_FILE")
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')
if [[ "$ENABLED" != "true" ]]; then
exit 0 # Disabled
fi
# Run hook logic
# ...Use case: Enable/disable hooks without editing hooks.json (requires restart).
Pattern 2: Agent State Management
Store agent-specific state and configuration:
.claude/multi-agent-swarm.local.md:
---
agent_name: auth-agent
task_number: 3.5
pr_number: 1234
coordinator_session: team-leader
enabled: true
dependencies: ["Task 3.4"]
---
# Task Assignment
Implement JWT authentication for the API.
**Success Criteria:**
- Authentication endpoints created
- Tests passing
- PR created and CI greenRead from hooks to coordinate agents:
AGENT_NAME=$(echo "$FRONTMATTER" | grep '^agent_name:' | sed 's/agent_name: *//')
COORDINATOR=$(echo "$FRONTMATTER" | grep '^coordinator_session:' | sed 's/coordinator_session: *//')
# Send notification to coordinator
tmux send-keys -t "$COORDINATOR" "Agent $AGENT_NAME completed task" EnterPattern 3: Configuration-Driven Behavior
.claude/my-plugin.local.md:
---
validation_level: strict
max_file_size: 1000000
allowed_extensions: [".js", ".ts", ".tsx"]
enable_logging: true
---
# Validation Configuration
Strict mode enabled for this project.
All writes validated against security policies.Use in hooks or commands:
LEVEL=$(echo "$FRONTMATTER" | grep '^validation_level:' | sed 's/validation_level: *//')
case "$LEVEL" in
strict)
# Apply strict validation
;;
standard)
# Apply standard validation
;;
lenient)
# Apply lenient validation
;;
esacCreating Settings Files
From Commands
Commands can create settings files:
# Setup Command
Steps:
1. Ask user for configuration preferences
2. Create `.claude/my-plugin.local.md` with YAML frontmatter
3. Set appropriate values based on user input
4. Inform user that settings are saved
5. Remind user to restart Claude Code for hooks to recognize changesTemplate Generation
Provide template in plugin README:
## Configuration
Create `.claude/my-plugin.local.md` in your project:
\`\`\`markdown
---
enabled: true
mode: standard
max_retries: 3
---
# Plugin Configuration
Your settings are active.
\`\`\`
After creating or editing, restart Claude Code for changes to take effect.Best Practices
File Naming
✅ DO:
Use
.claude/plugin-name.local.mdformatMatch plugin name exactly
Use
.local.mdsuffix for user-local files
❌ DON'T:
Use different directory (not
.claude/)Use inconsistent naming
Use
.mdwithout.local(might be committed)
Gitignore
Always add to .gitignore:
.claude/*.local.md
.claude/*.local.jsonDocument this in plugin README.
Defaults
Provide sensible defaults when settings file doesn't exist:
if [[ ! -f "$STATE_FILE" ]]; then
# Use defaults
ENABLED=true
MODE=standard
else
# Read from file
# ...
fiValidation
Validate settings values:
MAX=$(echo "$FRONTMATTER" | grep '^max_value:' | sed 's/max_value: *//')
# Validate numeric range
if ! [[ "$MAX" =~ ^[0-9]+$ ]] || [[ $MAX -lt 1 ]] || [[ $MAX -gt 100 ]]; then
echo "⚠️ Invalid max_value in settings (must be 1-100)" >&2
MAX=10 # Use default
fiRestart Requirement
Important: Settings changes require Claude Code restart.
Document in your README:
## Changing Settings
After editing `.claude/my-plugin.local.md`:
1. Save the file
2. Exit Claude Code
3. Restart: `claude` or `cc`
4. New settings will be loadedHooks cannot be hot-swapped within a session.
Security Considerations
Sanitize User Input
When writing settings files from user input:
# Escape quotes in user input
SAFE_VALUE=$(echo "$USER_INPUT" | sed 's/"/\\"/g')
# Write to file
cat > "$STATE_FILE" <<EOF
---
user_setting: "$SAFE_VALUE"
---
EOFValidate File Paths
If settings contain file paths:
FILE_PATH=$(echo "$FRONTMATTER" | grep '^data_file:' | sed 's/data_file: *//')
# Check for path traversal
if [[ "$FILE_PATH" == *".."* ]]; then
echo "⚠️ Invalid path in settings (path traversal)" >&2
exit 2
fiPermissions
Settings files should be:
Readable by user only (
chmod 600)Not committed to git
Not shared between users
Real-World Examples
multi-agent-swarm Plugin
.claude/multi-agent-swarm.local.md:
---
agent_name: auth-implementation
task_number: 3.5
pr_number: 1234
coordinator_session: team-leader
enabled: true
dependencies: ["Task 3.4"]
additional_instructions: Use JWT tokens, not sessions
---
# Task: Implement Authentication
Build JWT-based authentication for the REST API.
Coordinate with auth-agent on shared types.Hook usage (agent-stop-notification.sh):
Checks if file exists (line 15-18: quick exit if not)
Parses frontmatter to get coordinator_session, agent_name, enabled
Sends notifications to coordinator if enabled
Allows quick activation/deactivation via
enabled: true/false
ralph-loop Plugin
.claude/ralph-loop.local.md:
---
iteration: 1
max_iterations: 10
completion_promise: "All tests passing and build successful"
---
Fix all the linting errors in the project.
Make sure tests pass after each fix.Hook usage (stop-hook.sh):
Checks if file exists (line 15-18: quick exit if not active)
Reads iteration count and max_iterations
Extracts completion_promise for loop termination
Reads body as the prompt to feed back
Updates iteration count on each loop
Quick Reference
File Location
project-root/
└── .claude/
└── plugin-name.local.mdFrontmatter Parsing
# Extract frontmatter
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$FILE")
# Read field
VALUE=$(echo "$FRONTMATTER" | grep '^field:' | sed 's/field: *//' | sed 's/^"\(.*\)"$/\1/')Body Parsing
# Extract body (after second ---)
BODY=$(awk '/^---$/{i++; next} i>=2' "$FILE")Quick Exit Pattern
if [[ ! -f ".claude/my-plugin.local.md" ]]; then
exit 0 # Not configured
fiAdditional Resources
Reference Files
For detailed implementation patterns:
references/parsing-techniques.md- Complete guide to parsing YAML frontmatter and markdown bodiesreferences/real-world-examples.md- Deep dive into multi-agent-swarm and ralph-loop implementations
Example Files
Working examples in examples/:
read-settings-hook.sh- Hook that reads and uses settingscreate-settings-command.md- Command that creates settings fileexample-settings.md- Template settings file
Utility Scripts
Development tools in scripts/:
validate-settings.sh- Validate settings file structureparse-frontmatter.sh- Extract frontmatter fields
Implementation Workflow
To add settings to a plugin:
Design settings schema (which fields, types, defaults)
Create template file in plugin documentation
Add gitignore entry for
.claude/*.local.mdImplement settings parsing in hooks/commands
Use quick-exit pattern (check file exists, check enabled field)
Document settings in plugin README with template
Remind users that changes require Claude Code restart
Focus on keeping settings simple and providing good defaults when settings file doesn't exist.
Files
- ATTRIBUTION.mdAdded by AutoGineer968 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md11.8 KiB
- examples/create-settings-command.md2.1 KiB
- examples/example-settings.md2.9 KiB
- examples/read-settings-hook.shScript2.2 KiB
- references/parsing-techniques.md11.2 KiB
- references/real-world-examples.md9.3 KiB
- scripts/parse-frontmatter.shScript1.2 KiB
- scripts/validate-settings.shScript2.6 KiB
Requirements and compatibility
Written for: Claude Code, Claude apps
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Anthropic
- Publisher
- Anthropic (Official)
- Source
- anthropics/claude-plugins-official · plugins/plugin-dev/skills/plugin-settings · commit 0412be7
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from plugins/plugin-dev/LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Anthropic.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download plugin-settings.zip