CLAUDE.md, skills and MCP servers
TL;DR
Keep CLAUDE.md as close to empty as you can. Add a line only when Claude keeps missing something. Instructions for one kind of task go in a skill. Use an MCP server only when a script or CLI can’t do the job.
How it works
Three ways to give Claude Code more than your code. They differ in what they cost in every conversation. Whatever is loaded up front is sent again with every request, so it costs Claude’s attention and your usage limits on every message, whether the task needs it or not.
CLAUDE.mdis a Markdown file in the root of your repository (and optionally~/.claude/CLAUDE.mdfor yourself). The whole file is loaded at the start of every conversation.- A skill is a folder with a
SKILL.mdin it: a name, a one-line description, and instructions. Put it in.claude/skills/<name>/in the repository, or in~/.claude/skills/<name>/for yourself. Only the description is loaded in every conversation. Claude reads the instructions when the description matches what it’s doing, or when you type/<name>. - An MCP server is a program that gives Claude extra tools: read a Jira issue, query a database, drive a browser. By default, only the tool names are loaded up front, and Claude looks up a tool’s definition when it needs it. Everything a tool returns goes into the conversation.
My take
- Keep
CLAUDE.mdas close to empty as you can. Every line is in every conversation, whether it’s relevant or not, and it competes with the task for Claude’s attention. Modern models figure out most things from the code: how to build from thepom.xml, the conventions from the code around the change. - Only add a line when Claude keeps missing something. Not after one miss: after the same miss in several conversations. A typical one is a reference file it should read and doesn’t find, like your API guidelines. With modern models, this doesn’t happen often. When it copies something wrong, first ask where it got it from and fix that in the code.
- Don’t describe the code base in it. Claude reads the code. A description goes out of date, and Claude keeps following it.
- Don’t write rules a tool already checks. If the formatter, a linter or a test catches it, Claude runs it and fixes what it finds.
- Put instructions for one kind of task in a skill. A checklist for a database migration, or how to grill you on a story, is only useful for that task. As a skill, it costs one line until it’s needed.
- Use an MCP server only when a script or CLI can’t do the job. Claude already runs commands:
gh,curl,psql, your own scripts. With a script, you see exactly what goes in. See the Confluence script for an example. - Don’t install skill packs or MCP servers “just in case”. Every skill description and every MCP tool name is sent with every request, in every conversation, used or not. Add one at a time, when you feel a concrete pain. Now and then, check
/usageto see what your usage goes to, and remove what you don’t use.
Gotchas
/initwrites a longCLAUDE.md. It describes your code base and your build, which is exactly what Claude can read for itself. Delete most of it, or don’t run it.- An outdated
CLAUDE.mdis worse than none. Claude follows it even after the code has moved on. - More skills means more wrong picks. A vague description makes Claude use a skill when it shouldn’t, and with twenty of them, some overlap.
- MCP responses can be large. A Jira issue comes back with every field, and all of it lands in the conversation. From then on, it’s sent again with every request.
Example
A CLAUDE.md after a few months, with the one thing Claude kept missing:
- Before changing a REST endpoint, read `docs/api-guidelines.md`.
A skill, in .claude/skills/db-migration/SKILL.md:
---
name: db-migration
description: Use when adding or changing a Flyway migration.
---
- Never edit a migration that's already on main. Add a new one.
- Name it `V<yyyyMMddHHmm>__<what_it_does>.sql`.
- Make it safe to run while the previous version of the application is still running.