Skills are SOPs for your AI. You write a workflow once, save it as a skill file, and Claude follows it reliably every time — the same way you'd train a new hire with a process document, except the agent actually reads and follows it.
The difference from prompting: a skill is permanent, reusable, and gets better every time you run it and add to it. Your 10th run is meaningfully better than your first because you've added every edge case.
Skills can run Python or JavaScript scripts, call APIs, scrape and process data, write and edit files, spawn subagents, be invoked by other skills, and trigger via slash command or natural language. They aren't passive prompt templates — Claude reads the skill and then acts.
Anatomy of a skill
A skill is a folder with a SKILL.md file inside, at .claude/skills/your-skill-name/SKILL.md.
Top section (YAML frontmatter):
---
name: linkedin-post-writer
description: Generates LinkedIn posts in Conigma format. Use when asked to write a LinkedIn post, create content for the feed, or draft a post about [topic].
---
Body section — step-by-step instructions in plain markdown:
# linkedin-post-writer
## Goal
Write a LinkedIn post that matches Conigma's format and ICP.
## Process
1. Ask: what's the post about? What format (listicle, insight, data drop, story)?
2. Read the tone rules from @.claude/rules/tone.md
3. Draft the post following the format guide below
4. Check against banned phrases list
5. Output final post + CTA in the correct convention
## Rules
- Never use em dashes
- CTA always: Follow me + comment [KEYWORD]
Why the description is the most critical part
Claude scans skill descriptions (roughly 100 tokens per skill) at session start to decide which skill to load. The full body only loads when relevant.
If your description is vague, the skill won't load when you need it. If it's too narrow, it won't load for variations of the same request.
- Good: "Generates LinkedIn posts in Conigma format. Use when asked to write a LinkedIn post, create content for the feed, or draft a post about any topic."
- Bad: "LinkedIn post"
Reference files
Point to additional files from inside a skill — Claude only loads them if the task requires it:
@.claude/rules/tone.md — your tone guide
@references/linkedin-formats.md — your post format library
@scripts/scrape-leads.py — a Python script the skill should run
@data/icp-definitions.md — ICP breakdown the skill should reference
Storing reference data separately keeps SKILL.md lean (under 500 lines) while giving Claude everything it needs.
How to build a skill: the feedback loop
Don't try to write a perfect skill upfront. Build iteratively.
Step 1: do the task manually with Claude. Walk Claude through it step by step in a normal conversation. When you get a result you're happy with, say: "This is great. This is something I do regularly. Turn this into a skill I can invoke anytime. Ask me any questions you need to get the instructions right."
Step 2: run it on a fresh session and watch. Invoke the skill and observe every step without intervening. Note anything that:
- Took too long — Claude was doing unnecessary work that could be hardcoded
- Was wrong — a rule you forgot to specify
- Was right but fragile — worked this time, might not next time
Step 3: update the skill with your observations. Add every failure to a ## Gotchas section at the bottom:
## Gotchas
- The Notion API returns pagination tokens. Always handle these — don't assume one call gets all records.
- Instantly rate limits at 100 requests/minute. Add a 1-second delay between calls.
- LinkedIn posts must not exceed 3000 characters or they get cut off in feed.
If a step always takes too long, hardcode its output. If Claude spends tokens looking up your Notion database ID every run, put the ID in the skill file.
Step 4: repeat until the error rate drops below 5%. First run maybe 60% correct, fifth run 85%, tenth run 95%+. Most knowledge-work skills hit reliable accuracy within 5–10 iterations.
GTM skills worth building first
LinkedIn post writer. Trigger: "Write a LinkedIn post about [topic]". Process: read tone rules → identify post format → draft → check against banned phrases → add CTA in correct format → output. Hardcode your CTA convention, keyword capitalisation rule, and character limits per format.
Asset brief generator. Trigger: "Write a brief for [asset type] promoting [topic]". Process: identify asset type → match to correct Figma template → fill in goal, audience, key message, visual direction, CTA, copy elements → output. Hardcode your template selection logic, brief structure, and design rules.
Content calendar card writer. Trigger: "Create a content calendar card for [topic] in status [X]". Process: read the card schema from Notion → generate post text → generate boosting comment → write asset brief anchor → push to Notion via MCP. Hardcode your Notion DB ID, card property names, boosting comment format, and the empty-block anchor string.
Lead scraper and classifier. Trigger: "Scrape [N] [job title/company type] in [location/vertical]". Process: test scrape 25 leads → verify quality → full scrape in parallel batches → LLM classify by ICP fit → enrich emails → upload to Google Sheet or Instantly. Hardcode your source, quality thresholds, ICP scoring criteria, and destination. Result: what used to take 60–90 minutes runs in under 2 minutes.
Cold email sequence writer. Trigger: "Write a [N]-step cold email sequence targeting [ICP] about [offer]". Process: read ICP definition → identify pain point angle → write subject lines and body per step → check against deliverability rules → format for Instantly import. Hardcode your sequence structure, character limits, CSV format, and CTA type.
Morning pulse check. Trigger: "Run morning pulse check" or "What do I need to action today?". Process: query ClickUp/Notion for open tasks → check Gmail for anything needing response → pull lead gen metrics from yesterday → summarise what needs attention, prioritised. Hardcode your specific list IDs — this saves significant tokens versus having Claude search for them every time. Delegate heavy data retrieval to a searcher subagent to keep the main session context clean.
Boosting comment generator (bulk). Trigger: "Generate boosting comments for all Review script cards in the content calendar". Process: query Notion for all cards in that status → read each post text → generate a boosting comment in your format → write it back to the card field.
Global vs project-level skills
Project-level (.claude/skills/) — only available in this project, checked into git so the whole team gets them. Keep to 3–5 per repo.
Global (~/.claude/skills/) — available in every project on your machine. For skills you use across all clients: your LinkedIn post format, your tone checker, your email writer.
Distribute team skills as plugins through a shared GitHub repo. Developers don't need the content writer's LinkedIn skills, and content writers don't need the developer's code review skills.