Blog

Rules, skills, commands, subagents, MCP

Published on 05.06.2026ยท7 min read
#claude-code #ai #tooling

Most people put everything in CLAUDE.md and wonder why the agent skips half of it. The file gets long, the model gets lazy, and the rules you actually cared about disappear into the noise.

The fix is knowing that Claude Code has multiple building blocks, not one. Four are about guidance the agent reads. The fifth is about tools the agent can reach. Each has different rules about when it loads and what it costs.

The five building blocks

Building blockLoadedCostUse for
RuleSession start, full contentEvery requestCoding standards, project layout, "always do X" facts
SkillDescription at start, body when usedDescription every request, body only when triggeredMulti-step procedures and long reference
CommandBody when you type itPer invocationWorkflows you trigger by name
SubagentWhen spawnedIsolated context, returns a summaryResearch and heavy work that floods context
MCP serverTool names at start, schemas on demandLow until a tool is calledIssue trackers, databases, design tools

Rules: the always-on layer

Rules live in .claude/rules/. In my template that's six files: code style, JSDoc essentials, markdown, security, testing, USA English. They load on every turn, so they need to be short.

The test is simple. If forgetting it would produce code you'd reject in review, it's a rule. Everything else belongs elsewhere.

security.md is the cleanest example. Six bullets, no examples, no preamble. Don't commit secrets. Validate input at trust boundaries. Don't shell-interpolate untrusted strings. That's the whole file. It loads every turn because the cost of forgetting any one of them is too high.

Rules are not the place for linting or formatting. Spending context every turn to remind the agent about indentation or import order is wasteful when a tool checks it for free. Let ESLint and Oxlint catch lint violations and Prettier or oxfmt handle formatting.

A rule does not have to load on every turn. Add a paths field to the frontmatter and it only loads when the agent touches a matching file, so a markdown rule stays out of context until there's markdown in play.

---
paths:
  - "**/*.md"
  - "**/*.mdx"
---

Skills: the reference shelf

Skills are markdown files the agent loads only when the task matches. They can be long, because they only cost context when they fire.

The template has a jsdoc skill that loads when I write TypeScript. It carries the full tag taxonomy: which @example format to use, when @default and @deprecated apply, what tags to skip, and the order they go in. That's far too much to keep in context every turn, but exactly what I want on hand the moment I'm documenting a function. It costs nothing until the task triggers it.

The trigger lives at the top of SKILL.md as a short description. The agent reads the description on every turn but only opens the body when the task matches. That's the whole trick.

Commands: workflows you type

Commands are skills you invoke by name with a slash. /code-review, /verify, /changeset. Same file format as a skill, different entry point.

Use them when you want the agent to do something specific on demand, and you don't want to retype the prompt every time. The /code-review command in the template is a good example. It knows the project's conventions, runs the right diff, and posts inline comments.

Subagents: isolated workers

Subagents are different. They run in their own context window. Use one when you want parallel work, or when the task would flood your main context with noise.

Explore is the clearest example. If I ask it to find every place we read from process.env, it reads dozens of files and reports back two lines. My context stays clean.

The anti-pattern is reaching for a subagent when two tool calls would do. Spawning costs latency and tokens. Don't pay it unless the work is genuinely big or parallel.

MCP servers: tools from outside

The first four building blocks are about guidance. MCP servers are different. They run as separate processes and expose tools the agent can call, like GitHub, a database, a browser, or your design system.

You wire one up once in .mcp.json or your user config, and the tools it provides show up alongside the built-in ones. The template ships with the GitHub MCP server enabled because almost every project needs PR comments and issue reads.

For codegen work I add the Kubb MCP server. It exposes Kubb's code-generation tools to the agent, so it can trigger generation, validate a schema, and inspect the config straight from chat instead of me dropping out to the CLI.

The rule of thumb is the same as for subagents: don't add one until you actually need the capability. A server's tool names load at startup and the full schemas stay deferred until a tool is called, so with tool search on by default an idle server costs little. The reason to hold back is focus, not tokens. A long tool list gives the agent more ways to go sideways.

A decision tree

Should every session enforce this? Rule.

Only when a specific task comes up? Skill.

Does the user trigger it explicitly? Command.

Does it need its own context window? Subagent.

Does it need to reach outside the repo? MCP server.

One feature, five touch points

Take "review this PR for security issues." It splits across all five building blocks.

The security rule is always on, so the agent already knows not to log secrets or trust input from the network. The code-review skill loads when the task is a review, bringing the project's reviewing conventions. The /security-review command from Claude lets me trigger the workflow with a slash. The code-reviewer subagent runs in isolation for a second opinion that won't pollute my main context. And the GitHub MCP server posts the inline comments back on the PR when the review is done.

Five building blocks, one feature, no overlap. Each piece earns its keep.

Two more pieces that don't fit the list

These last two work differently from the five above, but you'll run into them.

Hooks are shell commands that run on set events, like SessionStart or Stop. They always run the same way, so they're not advice the agent can ignore. The template runs a SessionStart hook that installs dependencies, so the agent never burns a turn on pnpm install.

Output styles change how the agent writes, not what it does. The template ships a house style with rules like "no em dashes, sentence-case headings, cut filler". It sets the voice for everything the agent says.

Use the Claude Code plugin

You don't need to adopt the whole template to get the agent setup. The tools/claude/ folder ships as a Claude Code plugin, so you can install the same rules, skills, commands, and code-reviewer subagent in any existing project. Run these in Claude Code:

/plugin marketplace add stijnvanhulle/template
/plugin install plugin@stijnvanhulle/template

The hooks (session-start install, format-on-edit, edit guards) stay in the template's own .claude/ and don't ship with the plugin, so installing it won't run scripts in your repo.

Try it

The template has the building blocks populated with working examples. Clone it, open the folders side by side, and the whole setup stops feeling abstract. There's also a project page with a short rundown of what's inside.

References

Portrait of Stijn Van Hulle

Stijn Van Hulle

Front-end engineer