The chapter's claim: Claude Code's real value is not how capable it is out of the box — it is how much you can plug into it. The author noticed he kept repeating himself: reminding Claude to "run lint first" before every commit, re-explaining conventions for every new component, manually copying SQL results to paste back in.
| Mechanism | Nature | Certainty | Best for |
|---|---|---|---|
| Skills | Markdown instruction packages | High but not 100% (advisory) | Domain knowledge, reusable workflows |
| Hooks | Shell script triggers | 100% guaranteed execution | Formatting, lint, security checks |
| MCP | External tool connectors | 100% | Databases, APIs, third-party services |
Skills are the easiest extension to begin with. The idea: create a folder inside .claude/skills/,
put a SKILL.md file in it, and Claude automatically loads its instructions based on context.
.claude/skills/
├── react-component/
│ └── SKILL.md # Standards and steps for creating React components
├── fix-issue/
│ └── SKILL.md # Standard workflow for fixing bugs
└── deploy-preview/
└── SKILL.md # Steps for deploying a preview environment
You can invoke a skill manually with /skill-name, or Claude decides on its own. Say "help me
create a new React component" and Claude loads the react-component skill's conventions automatically.
| Type | Tells Claude… | Reads like |
|---|---|---|
| Knowledge-based | "Here's how things work in this project" — API conventions, coding style, agreements | Documentation Claude absorbs and follows |
| Workflow-based | "Here are the exact steps for this kind of task" — e.g. /fix-issue, /review-pr | An SOP with clear steps and checkpoints |
/techdebt commandWrite the whole "spot technical debt → assess impact → create issue → link to sprint" workflow as
a skill. Then whenever you find tech debt, type /techdebt and Claude walks through the process:
evaluating priority, creating a GitHub issue, applying the right labels.
Workflow skills often do side-effectful things — creating issues, sending messages,
triggering deployments. To stop Claude from auto-triggering them at the wrong moment, add this to the
front matter of SKILL.md:
---
disable-model-invocation: true
---
What this line does: the skill can now only be invoked manually via
/skill-name. Claude will not trigger it on its own.
mkdir -p ~/.claude/skills/boris && \
curl -L -o ~/.claude/skills/boris/SKILL.md \
https://howborisusesclaudecode.com/api/install
After installing, you get Boris's daily workflows — commit conventions, PR templates, code review
standards. You can also browse the community marketplace inside Claude Code with /plugin.
Skills are fundamentally advice. Claude tries to follow them, but compliance is not 100% — especially deep into a long conversation, when a rule may simply be forgotten after context compression. The author learned this the hard way with an "run eslint after every file edit" rule in CLAUDE.md that disappeared once context was compressed.
| Hook | When it fires | Typical use |
|---|---|---|
PreToolUse | Before Claude calls a tool | Intercept dangerous operations |
PostToolUse | After Claude calls a tool | Auto-format, auto-test |
PermissionRequest | When user authorization is needed | Auto-approve low-risk operations |
Stop | When Claude finishes a turn | Push Claude to continue executing |
PostCompact | After context compression | Re-inject critical instructions to prevent amnesia |
PermissionDenied | After the auto-mode classifier rejects an operation | Log rejected operations, notify user, trigger fallbacks |
// .claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "npx eslint --fix $CLAUDE_FILE_PATH"
}
]
}
}
"PostToolUse" — run this after Claude uses a tool."matcher": "Edit|Write" — only when the tool was an edit or a file write."command": "npx eslint --fix $CLAUDE_FILE_PATH" — run the linter on the file that was just changed. $CLAUDE_FILE_PATH is filled in by Claude Code.Result: every file Claude edits is formatted automatically — no relying on Claude to remember.
| Goal | Hook | What it does |
|---|---|---|
| Auto-approve low-risk operations | PermissionRequest | A script checks the operation type: low-risk (reading files, running tests) auto-approved; high-risk (deleting files, pushing code) still prompts. |
| Prevent "amnesia" after compression | PostCompact | Automatically re-injects critical rules after context is compressed. |
| Keep Claude going in unattended runs | Stop | Detects "should I continue?" pauses and prompts Claude to keep executing. |
.claude/settings.json for you.Skills give Claude knowledge; Hooks guarantee execution — but both stay inside Claude Code's world. To query a database, call an API, or read a design file, you need MCP (Model Context Protocol), an open standard from Anthropic. The book's analogy: MCP is Claude Code's USB port — plug in different MCP servers, and Claude gains the matching capabilities.
# Add an MCP server
claude mcp add slack -- npx -y @modelcontextprotocol/server-slack
# List installed MCPs
claude mcp list
Once added, the server's capabilities appear to Claude as "tools." After the Slack MCP, for example, Claude can search Slack messages, send messages, and create channels.
| MCP | Capability | Best for |
|---|---|---|
| Slack MCP | Search / send messages | Auto-sync progress, reply to questions |
| Database MCP | Direct database queries | No more manually copying SQL results |
| Figma MCP | Read design files | Turn designs directly into code |
| Sentry MCP | Fetch error logs | Claude auto-locates production bugs |
| GitHub MCP | Manage repos / Issues / PRs | Automate project management |
Boris's classic setup: Claude Code connected to the Slack MCP so that when someone reports a bug in Slack, Claude reads the description, finds the code, attempts a fix, submits a PR, and replies "Fixed — PR link here." No human intervention.
// .mcp.json (at the project root)
{
"mcpServers": {
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_TOKEN": "${SLACK_TOKEN}"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "${DATABASE_URL}"]
}
}
}
.mcp.json lives at the project root and can be committed to Git — teammates who clone the project get the same MCP setup.mcpServers is one server: the command and args that launch it."env" passes secrets via environment variables like ${SLACK_TOKEN} — never hardcoded..mcp.json — reference them via environment variables.Skills, Hooks, and MCP are each useful alone; combining them is where it gets powerful. A Plugin
is a packaged combination of all three. Type /plugin to browse the marketplace; one install sets
everything up. Example — a "Code Intelligence" plugin might include:
Commands live in .claude/commands/. Unlike skills, commands can include inline Bash
scripts that run before Claude reads the prompt, embedding the results into it.
# .claude/commands/commit-push-pr.md
Help me complete the following:
1. Review the current git diff:
```bash
git diff --stat
```
2. Generate a commit message and commit
3. Push to the remote branch
4. Create a Pull Request with a title based on the commit content
Note: The PR description should include a summary of the changes.
Type /commit-push-pr and Claude runs the whole workflow. Because the file lives in
.claude/commands/, it is committed with Git and available to every team member.
| Skill | Command | |
|---|---|---|
| Intent | Knowledge and capability | A macro / execution flow |
| How it is applied | By context or manual invocation | Manual; can pre-compute with inline Bash |
| Rule of thumb | Need Claude to know something → skill | Need Claude to do a sequence of things → command |
Team workflow: receive bug report → locate the issue → fix it → run tests → submit PR → notify stakeholders.
Each piece is valuable alone; combined they form a fully automated bug-fix pipeline.
The author has over 60 Skills installed, accumulated over six months, each squeezed out by a real need.
Before Skills, he dictated the same wall of instructions for every article: "reduce the AI tone, no
em-dashes, avoid filler phrases, check for fabricated data, go through every paragraph." So he wrote
huashu-proofreading:
# SKILL.md core structure (simplified)
Three-pass proofreading workflow:
Pass 1: Factual verification
- Are all data points, dates, and product names accurate?
- Is anything fabricated?
Pass 2: Reduce AI tone
- Check for 6 categories of AI-speak: excessive em-dashes, triple parallel structures, ...
- Banned phrases: "to put it simply," "in other words," "simply put" ...
Pass 3: Style refinement
- quotation mark conventions
- Bold key sentences (~10 per article)
- Paragraph density check
Result: proofreading went from 15 minutes of verbal dictation to a single
/proofreading command — and the rules no longer vanish when context gets compressed.
| Stage | Skill | What it does |
|---|---|---|
| Topic generation | /topic-gen | Generates 3–4 topic directions, each with a title, outline, and effort estimate |
| Research | /research | Multi-round WebSearch + incremental saves to a research file to prevent session-cut data loss |
| Writing | /article-edit | Standardised editing flow: full read → list changes → incremental edits → change summary |
| Images | /image-upload | AI-generated images → upload to image host → insert Markdown links, fully automated |
| Proofreading | /proofreading | Three-pass review to reduce AI tone (~60% down to below 30%) |
| Distribution | /article-to-x | Condenses long articles into 200–500 word social media content |
| Publishing | /feishu | Write to Feishu doc + set permissions + send group notification |
Other examples: huashu-book-pdf handles the full ebook pipeline (research → chapter
planning → multi-agent parallel writing → HTML assembly → EPUB → upload);
huashu-video-director goes from concept to a multi-shot AI-generated video;
huashu-script-polish rewrites scripts into natural spoken language over three review rounds.
┌──────────── Claude Code ────────────┐
SKILLS ───►│ "here is HOW to do X" (advisory) │
HOOKS ────►│ shell scripts at lifecycle points │───► 100% enforced
MCP ────►│ USB port to DB / API / Figma / logs │───► outside world
└─────────────────────────────────────┘
PLUGIN = skill + hook + MCP, packaged, one install
COMMAND = macro in .claude/commands/, can pre-run Bash
| Question | CLAUDE.md / Skill | Hook |
|---|---|---|
| Certainty | High but advisory — can be forgotten after compression | 100% — Claude cannot skip it |
| Written in | Natural language / Markdown | Shell scripts + settings.json config |
| Good for | Conventions, workflows, domain knowledge | Formatting, lint, security, "must always happen" checks |
| Skills / Hooks | MCP | |
|---|---|---|
| Scope | Inside Claude Code's world | Connects to external data and services |
| Examples | Coding conventions, auto-lint | Query Postgres, send Slack, read Figma, fetch Sentry logs |
disable-model-invocation: true..mcp.json instead of using environment variables.disable-model-invocation: true to side-effectful workflow skills..mcp.json so the team shares the setup.disable-model-invocation: true do, and when do you need it?.mcp.json?SKILL.md.PostToolUse hook that runs your formatter after every edit, and inspect the settings.json it writes.disable-model-invocation: true..claude/commands/ command that pre-runs git diff --stat and then asks Claude to commit, push, and open a PR.Extensions: Skills, Hooks & MCP
│
├── Skills (advisory, Markdown) -> teach HOW
│ ├── .claude/skills//SKILL.md
│ ├── knowledge-based | workflow-based
│ ├── /skill-name OR auto-loaded
│ └── disable-model-invocation: true (side effects)
│
├── Hooks (100% enforced, shell) -> guarantee checks
│ ├── PreToolUse / PostToolUse / PermissionRequest
│ ├── Stop / PostCompact / PermissionDenied
│ └── config in .claude/settings.json
│
├── MCP (external connectors) -> the outside world
│ ├── "USB port": Slack, DB, Figma, Sentry, GitHub
│ ├── claude mcp add / claude mcp list
│ └── .mcp.json + env vars (never hardcode tokens)
│
├── Plugins = skill + hook + MCP, packaged (/plugin)
└── Commands = macros in .claude/commands/ (pre-run Bash)
Rule: "know something" -> skill ; "do a sequence" -> command
.claude/skills/, knowledge-based or workflow-based, invoked by /name or automatically.disable-model-invocation: true so side-effectful skills only run when you ask./plugin.PreToolUse, PostToolUse, PostCompact, Stop, etc.); configure them in .claude/settings.json, or ask Claude to write them..mcp.json, secrets via env vars.This teaching edition is based on the supplied April 2026, 2nd edition of Claude Code: The Complete Guide (§07, "Extensions: Skills, Hooks & MCP"). File paths, config keys, hook names and package names reflect that edition and may change over time.