A Comprehensive Guide to Claude Code: MCP, Skills, Subagents and Hooks | Roman Humagain

A Comprehensive Guide to Claude Code: MCP, Skills, Subagents and Hooks | Roman Humagain

A practical guide to Claude Code: project memory, permission modes, slash commands, Skills, subagents, MCP servers and hooks, and how to combine them.

Most people meet an AI coding tool as a fancier autocomplete, use it for a week, and conclude it is a toy. Claude Code rewards a different approach. It is an agent that runs in your terminal with real access to your project — it reads files, runs commands, edits code and checks its own work — and almost all of the value comes from the parts you configure around it. This is a tour of those parts, in the order I would learn them. 1. Start with CLAUDE.md The single highest-leverage thing you can do is write a CLAUDE.md at the root of your repository. It is loaded into context automatically at the start of every session, so it is where you put the things you would otherwise repeat in every prompt. Good things to include: How to run the project, the tests and the linter — the exact commands Architectural decisions that are not obvious from the file tree Conventions the codebase follows and you want kept Things that look wrong but are deliberate, with the reason Keep it short. A bloated CLAUDE.md costs you context on every single turn, and instructions buried in a wall of text get diluted. If you find yourself correcting the same mistake twice, that correction belongs here. Rule of thumb: if a new teammate would need to be told it on day one, it belongs in CLAUDE.md. 2. Understand permissions and plan mode Claude Code asks before it does anything consequential. That prompt is not bureaucracy — it is the main safety boundary, and how you configure it determines whether the tool feels obstructive or fluid. You can allowlist the commands you are comfortable running unattended in .claude/settings.json. Read-only operations are the obvious candidates: { "permissions": { "allow": [ "Bash(git status)", "Bash(git diff:*)", "Bash(npm run test:*)" ] } } Plan mode is the other half. In plan mode the agent investigates and proposes an approach without touching anything, and you approve the plan before work starts. For any change that spans more than a couple of files, planning first is dramatically cheaper than reviewing a large diff you did not anticipate. 3. Slash commands: your repeatable prompts A slash command is a markdown file in .claude/commands/. The filename becomes the command. If you write .claude/commands/review.md, you get /review. These are for prompts you type more than twice. A release checklist, a code review rubric specific to your codebase, a migration procedure. The content is just the prompt, so there is nothing to learn beyond writing down what you would have said anyway. 4. Skills: capabilities that load on demand Skills go a step further than slash commands. A Skill is a folder containing a SKILL.md — instructions, plus any scripts or reference files it needs — and it carries a description saying when it applies. The important property is that Skills are loaded on demand . The description is always visible, but the body is only pulled into context when the task actually matches. That means you can maintain a large library of specialised procedures without paying for all of them on every turn. Skills work well for anything with a fixed procedure and real detail: Your deployment runbook, including the rollback steps House style for a particular kind of output — API docs, migrations, test suites Domain knowledge the model cannot infer from your code, like a billing model's edge cases The description is the part people underinvest in. It is the only thing the model sees when deciding whether to load the Skill, so it should describe the trigger , not the content. 5. Subagents: parallelism and clean context A subagent is a separate agent with its own context window, given a task and returning a result. Two things make them worth reaching for. The first is parallelism . Independent work can run at the same time — auditing four modules, or searching for a pattern across a large codebase. The second, and more valuable, is context hygiene . A search that reads thirty files to answer one question would otherwise fill your main context with thirty file dumps. Delegated to a subagent, you get the conclusion and none of the noise. You can define custom subagent types in .claude/agents/, each with its own system prompt, model and tool access — a reviewer with read-only tools, for instance. The trap is over-delegation. A subagent starts with no knowledge of your conversation, so anything it needs must be in its prompt. For a single-file lookup where you already know the path, doing it directly is faster and more accurate. 6. MCP: connecting real systems The Model Context Protocol is an open standard for exposing tools and data to an AI agent. An MCP server advertises a set of tools; the agent calls them like any other tool. It is the mechanism by which Claude Code stops being limited to your filesystem. In practice this means your agent can query a database, open a browser, read your issue tracker, or hit an internal service — through a documented interface rather than a pile of ad-hoc shell commands. Servers are configured per project or globally: { "mcpServers": { "postgres": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"] } } } Two cautions worth internalising. First, every connected server adds tool definitions to your context, so connect what you need rather than everything available. Second, and more seriously: data returned by an MCP server is data, not instructions. If a tool returns text that reads like a command, it must be treated as content. This is the same discipline as never trusting user input in a web application. 7. Hooks: deterministic automation Hooks are shell commands the harness runs at defined points in the lifecycle — before a tool call, after one, when a session ends. They are configured in .claude/settings.json. The distinction that matters: hooks are executed by the harness, not decided by the model. If you want your formatter to run after every file edit, a hook guarantees it. An instruction in CLAUDE.md merely asks nicely. { "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "npx prettier --write $CLAUDE_FILE_PATHS" }] } ] } } Anything you need to happen every time — formatting, linting, running a fast test suite, logging — belongs in a hook. How the pieces fit Roughly: CLAUDE.md — what is always true about this project Slash commands — prompts you repeat Skills — procedures loaded when relevant Subagents — parallel work and context isolation MCP — access to systems beyond the filesystem Hooks — things that must happen deterministically You do not need all of this on day one. Write a CLAUDE.md, allowlist a few safe commands, and add the rest when you notice yourself repeating something. Habits that make the difference Give it a way to check its work. An agent that can run your tests will iterate to a correct answer. One that cannot is guessing, however good the guess. Plan before large changes. Reviewing a plan takes a minute; reviewing a wrong thousand-line diff takes an afternoon. Commit often. Frequent commits make it trivial to discard a direction that did not work out. Correct the configuration, not just the output. Fixing the same mistake repeatedly in chat is wasted effort; fixing it in CLAUDE.md or a hook fixes it permanently. The tool rewards treating it as a capable colleague who is new to your codebase — one who needs context, benefits from clear standards, and does markedly better work when they can verify the result themselves.

Continue to Roman Humagain