{"slug": "skill-md-how-to-write-a-claude-code-skill-that-actually-triggers-format-template", "title": "SKILL.md: how to write a Claude Code skill that actually triggers (format + template)", "summary": "Claude Code skills allow developers to package multi-step procedures into reusable commands triggered by a slash prefix or natural language. The SKILL.md format uses frontmatter fields like description and allowed-tools to control invocation, with arguments supporting substitution syntax. A skill directory can include supporting files for detailed reference material, keeping the main file under 500 lines.", "body_md": "Claude Code skills answer a specific pain: you keep pasting the same checklist into chat, or a section of your CLAUDE.md has quietly grown from *facts about the project* into *a multi-step procedure*. The official guidance is exactly that — when instructions become a procedure you re-explain, move them into a skill. Unlike CLAUDE.md content, a skill's body loads only when it's used, so a long runbook costs you almost nothing until the moment you need it.\n\nThis post covers the SKILL.md format end to end: the frontmatter fields, how triggering actually works, arguments, supporting files, and a template you can copy.\n\nEverything about writing a good skill follows from one design fact:\n\n`/skill-name`\n\n).So the description is not documentation — it's the **trigger**. The body is not a summary — it's the **procedure**. Most broken skills I've seen get these backwards: a vague description (\"Helps with releases\") that never matches anything, and a body that's a one-liner.\n\nA skill is a directory with a `SKILL.md`\n\nfile. In a project:\n\n```\n.claude/skills/release-notes/SKILL.md\n```\n\n(Personal skills live under `~/.claude/skills/`\n\nand follow you across projects.)\n\n```\n---\nname: release-notes\ndescription: \"Draft release notes from merged PRs. Use when the user\"\n  asks for release notes, a changelog entry, or \"what shipped\".\n---\n\nCollect merged PRs since the last git tag, then write release notes.\n\n1. Run `git describe --tags --abbrev=0` to find the last tag.\n2. List merges since then: `git log <tag>..HEAD --merges --oneline`.\n3. Group changes into Added / Fixed / Changed.\n4. Write entries as user-facing outcomes, not commit messages.\n5. Show the draft before writing to CHANGELOG.md.\n```\n\nThat's a complete, working skill. Type `/release-notes`\n\nto run it directly, or just ask \"can you draft release notes?\" and let the description do its job.\n\nIf you've used custom commands before: **commands and skills are now the same thing.** A file at `.claude/commands/deploy.md`\n\nand a skill at `.claude/skills/deploy/SKILL.md`\n\nboth create `/deploy`\n\nand behave the same way. Skills just add optional extras — a directory for supporting files and frontmatter to control invocation.\n\nAll fields are optional. Only `description`\n\nis recommended — without it, Claude has nothing to match against, and the skill is effectively manual-only.\n\n```\n---\nname: my-skill\ndescription: What this skill does\ndisable-model-invocation: true\nallowed-tools: Read Grep\n---\n```\n\n`name`\n\n`/my-skill`\n\n). Defaults to the directory name, so most skills omit it.`description`\n\n`disable-model-invocation: true`\n\n`/name`\n\n. Use it for anything with side effects you want a human to initiate: deploys, commits, publishing, sending messages. This is the difference between a `allowed-tools`\n\n`Read Grep`\n\n), so a read-only helper doesn't stop to ask permission mid-run.That last pairing is worth internalizing: **knowledge skills → model-invoked; action skills → slash-only.** The frontmatter is where you encode that decision, and it's the single biggest safety lever in the format.\n\nSkills take arguments when invoked as commands, with real substitution syntax:\n\n`$ARGUMENTS`\n\n— everything you passed. (If it doesn't appear in the body, arguments are appended as `ARGUMENTS: <value>`\n\ninstead.)`$0`\n\n, `$1`\n\n— positional access, shorthand for `$ARGUMENTS[0]`\n\n, `$ARGUMENTS[1]`\n\n.`arguments: [issue, branch]`\n\nin frontmatter and `$issue`\n\n/ `$branch`\n\nexpand by position. Self-documenting, so I'd default to this for anything with two or more parameters.So `/fix-issue 1423 hotfix/login`\n\nwith `arguments: [issue, branch]`\n\ngives you a body that reads like prose: \"Fix issue `$issue`\n\non branch `$branch`\n\n.\"\n\nOfficial guidance: **keep SKILL.md under 500 lines** and move detailed reference material into separate files in the skill directory:\n\n```\nmy-skill/\n├── SKILL.md        (required — overview and navigation)\n├── reference.md    (detailed API docs — loaded when needed)\n├── examples.md     (usage examples — loaded when needed)\n└── scripts/\n    └── helper.py   (executed, not loaded)\n```\n\nThe important part is the *navigation*: link each file from SKILL.md with a note about what it contains and when to read it —\n\n```\n## Additional resources\n- For complete API details, see [reference.md](reference.md)\n- For usage examples, see [examples.md](examples.md)\n```\n\nThis is the same two-stage trick again, one level down. SKILL.md stays a lean table of contents; the 2,000-line API reference costs nothing until Claude actually follows the link. Scripts are even cheaper — they get *executed*, not read into context.\n\nAlmost every triggering problem is a description problem:\n\n`disable-model-invocation: true`\n\nand stop fighting the matcher.`/skill-name`\n\nonce. If it works manually but never automatically, it's the description. It's almost always the description.One more option worth knowing: skills can run in their own subagent context (`context: fork`\n\n), which keeps a noisy multi-step procedure from flooding your main session. Useful for research-style skills that read a lot but should report back a summary.\n\nSKILL.md follows the Agent Skills open standard, and the same format is now read by several coding agents (Claude Code extends it with invocation control, subagent execution, and dynamic context injection). Writing your team runbooks in this format is a reasonably safe bet even if your tool mix changes later.\n\n*I maintain Rulestack, a set of focused rule and skill packs for Claude Code, Cursor, and Codex — including a full Claude Code skill-authoring pack.*\n\n*Daily AI-coding-agent tips on Bluesky: follow @ai-shop.bsky.social.*", "url": "https://wpnews.pro/news/skill-md-how-to-write-a-claude-code-skill-that-actually-triggers-format-template", "canonical_source": "https://dev.to/rulestack/skillmd-how-to-write-a-claude-code-skill-that-actually-triggers-format-template-27cp", "published_at": "2026-07-22 05:41:02+00:00", "updated_at": "2026-07-22 05:58:23.211840+00:00", "lang": "en", "topics": ["developer-tools", "large-language-models", "ai-tools"], "entities": ["Claude Code"], "alternates": {"html": "https://wpnews.pro/news/skill-md-how-to-write-a-claude-code-skill-that-actually-triggers-format-template", "markdown": "https://wpnews.pro/news/skill-md-how-to-write-a-claude-code-skill-that-actually-triggers-format-template.md", "text": "https://wpnews.pro/news/skill-md-how-to-write-a-claude-code-skill-that-actually-triggers-format-template.txt", "jsonld": "https://wpnews.pro/news/skill-md-how-to-write-a-claude-code-skill-that-actually-triggers-format-template.jsonld"}}