| name | plugin-settings |
| description | Configure per-project plugin settings via .claude/plugin-name.local.md files. Use when building plugins with user-configurable behavior, storing agent state, or controlling hooks. |
| user-invocable | false |
| allowed-tools | Bash, Read, Write, Edit, Grep, Glob, TodoWrite |
| created | "2026-03-06T00:00:00.000Z" |
| modified | "2026-07-28T00:00:00.000Z" |
| compatibility | claude-code |
| reviewed | "2026-03-06T00:00:00.000Z" |
Plugin Settings Pattern
Per-project plugin configuration using .claude/plugin-name.local.md files with YAML frontmatter for structured settings and markdown body for additional context.
Reach for a different mechanism when the settings are global (~/.claude/settings.json) or purely structured with no prose/prompt content (a plain .json file). The .local.md form earns its keep when config must carry prompts or instructions alongside structured fields.
File Structure
Location
project-root/
└── .claude/
└── plugin-name.local.md # Per-project, user-local settings
Format
---
enabled: true
mode: standard
max_retries: 3
allowed_extensions: [".js", ".ts", ".tsx"]
---
# Additional Context
Markdown body for prompts, instructions, or documentation
that hooks and agents can read and use.
Naming Convention
- Use
.claude/plugin-name.local.md format
- Match the plugin name exactly from
plugin.json
- The
.local.md suffix signals user-local (not committed to git)
Gitignore
Add to project .gitignore:
.claude/*.local.md
Reading Settings
From Shell Scripts (Hooks)
Use the standard frontmatter extraction pattern from .claude/rules/shell-scripting.md:
#!/bin/bash
set -euo pipefail
STATE_FILE=".claude/my-plugin.local.md"
[[ -f "$STATE_FILE" ]] || exit 0
extract_field() {
local file="$1" field="$2"
head -50 "$file" | grep -m1 "^${field}:" | sed 's/^[^:]*:[[:space:]]*//' | tr -d '\r'
}
plugin_enabled=$(extract_field "$STATE_FILE" "enabled")
[[ "$plugin_enabled" == "true" ]] || exit 0
plugin_mode=$(extract_field "$STATE_FILE" "mode")
Extract Markdown Body
BODY=$(awk '/^---$/{i++; next} i>=2' "$STATE_FILE")
From Skills and Agents
Skills and agents read settings with the Read tool:
1. Check if `.claude/my-plugin.local.md` exists
2. Read the file and parse YAML frontmatter
3. Apply settings to current behavior
4. Use markdown body as additional context/prompt
Common Patterns
Pattern 1: Toggle-Based Hook Activation
Control hook activation without editing hooks.json:
#!/bin/bash
set -euo pipefail
STATE_FILE=".claude/security-scan.local.md"
[[ -f "$STATE_FILE" ]] || exit 0
extract_field() {
local file="$1" field="$2"
head -50 "$file" | grep -m1 "^${field}:" | sed 's/^[^:]*:[[:space:]]*//' | tr -d '\r'
}
scan_enabled=$(extract_field "$STATE_FILE" "enabled")
[[ "$scan_enabled" == "true" ]] || exit 0
Pattern 2: Agent State Between Sessions
Store agent task state for multi-session work:
---
agent_name: auth-implementation
task_number: 3.5
pr_number: 1234
enabled: true
---
# Current Task
Implement JWT authentication for the REST API.
Coordinate with auth-agent on shared types.
Pattern 3: Configuration-Driven Validation
---
validation_level: strict
max_file_size: 1000000
allowed_extensions: [".js", ".ts", ".tsx"]
---
validation_level=$(extract_field "$STATE_FILE" "validation_level")
case "$validation_level" in
strict) run_strict_checks ;;
standard) run_standard_checks ;;
*) run_standard_checks ;;
esac
Implementation Checklist
When adding settings to a plugin:
- Design settings schema (fields, types, defaults)
- Create template in plugin README
- Add
.claude/*.local.md to .gitignore
- Implement parsing using
extract_field pattern
- Use quick-exit pattern (
[[ -f "$STATE_FILE" ]] || exit 0)
- Provide sensible defaults when file is missing
- Document that changes require Claude Code restart (hooks only)
Best Practices
| Practice | Details |
|---|
| Quick exit | Check file existence first, exit 0 if absent |
| Sensible defaults | Provide fallback values when settings file is missing |
Use extract_field | Standard frontmatter extraction from shell-scripting.md |
| Validate values | Check numeric ranges, enum membership |
| File permissions | Settings files should be user-readable only (chmod 600) |
| Restart notice | Document that hook-related changes need a Claude Code restart |