When I started using Claude Code, I treated it like a chat.
I would ask for something, it would respond, and that was it.
It worked, but over time I started to notice that I wasn't getting the full potential out of it.
I repeated the same prompts. I executed the same commands. I wasn't clear on how to take full advantage of it.
So I stopped and asked myself a question:
How does Claude Code actually work inside?
I started reading the documentation, experimenting, and testing.
And what I discovered is this:
It doesn't do magic. It is built on concrete pieces, each with a clear role. And when you understand them, everything else starts to make sense.
→ If you always repeat the same instructions, you turn them into a Skill.
→ If it loses the thread in a long task, you delegate to a SubAgent.
→ If there are manual steps you repeat, you automate them with Hooks.
Understanding the fundamentals is what allows you to know what to use, when, and why.
Today I have more than 100 Skills, automated processes that used to take me hours, and agents to perform code reviews and study topics that interest me.
I wrote this article to share everything I learned with you.
Let's get started.
Agent Loop: The Heart of Claude Code
Claude Code is an agent.
A system to which you give a goal and it works until it fulfills it.
It's different from a chat. In a chat, you ask "How do I add authentication to my app?" and it explains the steps.
But you have to go to the project, modify the code, and test if it works.
You do the work.
With Claude Code, you tell it "Add authentication to my app" and it takes care of it.
It reads the code, chooses the library, writes the changes, and notifies you when it's finished.
It has a goal: add authentication.
And it works until it fulfills it.
But how does it know what to do after each step? How does it know if something worked? It needs something to coordinate those decisions.
That is the loop.

A cycle that repeats itself.
Claude Code executes an action, observes the result, decides what to do next, and starts over. It doesn't stop until the goal is met.
If something fails, it goes back, corrects, and continues.
The loop has 3 phases:
Gather context → Understands what it has to do. Reads files, analyzes code, explores the project structure.
Take action → Executes changes. Edits files, runs commands, installs dependencies.
Verify results → Checks that what it did works. Runs tests, reviews errors, corrects if something fails.
The loop adapts to what you ask.
A simple question might only require gathering context. Fixing a bug might go through all three phases several times.
Claude Code decides what each step requires based on what it learned from the previous one. And you are also part of that loop.
You can interrupt at any time to redirect it, add context, or ask it to try another approach.
This is the heart of Claude Code.
Everything that follows exists to make this loop more powerful.
Tools: How Claude Code Acts in the World
An LLM, by design, only processes text.
It receives text and generates text. It doesn't have access to your file system, it can't execute commands, it doesn't know what's in your project.
It is isolated.
So, how does Claude Code open a file or modify it?
It uses tools.
Tools are functions that Claude Code can invoke to interact with the real world.
Think of it like mobile apps. The phone alone does nothing: it's the apps that give it specific capabilities: taking photos, sending messages, navigating.
Tools are the same for Claude Code.
Every time it uses a tool, it sends a request to the system with what it needs. The system executes it and returns the result.
Claude Code uses that result to decide what to do next.
1Your request2 ↓3Claude Code decides which tool to use4 ↓5┌─────────────────────────────────┐6│ Read · Edit · Write · Bash │7│ Grep · Glob · WebFetch · WebSearch │8└─────────────────────────────────┘9 ↓10System executes the tool11 ↓12Result returns to Claude Code13 ↓14Finished? → No → use another tool15 Yes → respond
Claude Code comes with native tools for the most common operations:
Read / Edit / Write → Read, modify, and create files. The most used. Every time Claude Code "understands your code" or "makes a change," it is using these three.
Bash → Full access to the terminal. If you can do it from the command line, Claude Code can too: install dependencies, run tests, make commits.
Grep and Glob → Search within the project. Glob finds files by name or pattern. Grep searches for specific content within files.
WebFetch and WebSearch → Internet access. Consult documentation, read an API, investigate an error it has never seen before.
Going back to the example of the bug in the login button.
When Claude Code works on that, it uses several tools together:
→ It uses Glob to find the component file
→ It uses Read to read the code and understand what is happening
→ It uses Edit to fix the error
→ It uses Bash to run the tests and verify that it worked
All of that without you intervening. That is the difference between a chat and an agent.
Context and Memory: What Claude Code Remembers
Claude Code works, executes actions, gets results, and decides what to do next.
But how does it know what it did as it progresses?
It's all thanks to context.
The context is the information that Claude Code has available at that moment. Every time it executes an action, the result accumulates in there.
Not just your initial prompt, but everything it finds: files it opened, what it discovered in the code, the actions it executed, and their results.
That's why it can chain steps, correct itself, and finish the task alone.
That context has 2 problems.
1. It has limited capacity. If the session is very long, the context fills up and Claude Code starts to forget what happened before. Later you will see how SubAgents solve this.
2. It is emptied every time you open a new conversation. Claude Code doesn't know what project you're in, how your team works, or what decisions they've already made. If you don't tell it, it infers it or asks you.
Memory resolves the second problem.
It is a markdown file system where you save everything Claude Code needs to know: your stack, team conventions, how projects are structured.
Claude Code reads them at the start of each session and injects that information into the context before you write the first line.
Without Memory: You tell it "add an endpoint to create users" and Claude Code asks you: "What framework do you use? Do you have a database configured? How are the routes structured?"
With Memory: You tell it the same thing and it already knows you use Express with Prisma, that routes go in /src/routes, and that errors are handled with a centralized middleware. It starts working without asking.
Claude Code has 2 memory systems:
→ CLAUDE.md - Markdown files that you write with everything Claude Code needs to know. They can live at different levels:
→ ~/.claude/CLAUDE.md - Applies to all your projects. Your personal preferences go there: how you want it to write code, conventions you always use. Instructions must be specific: "use 2 spaces of indentation" is clearer than "format the code well."
→ /your-project/CLAUDE.md - Specific to the repository. Architecture, team conventions, and important commands go there. When you start a new project, run /init and Claude Code generates it automatically. Keep it under 200 lines: if it grows too much, Claude Code starts ignoring instructions. And if you commit it to the repo, the whole team shares the same context.
→ .claude/rules/ - Modular rules that activate according to the file type. Useful when the project grows and you don't want to put everything in a single file.
Auto Memory - The memory that Claude Code builds on its own. As you work, it takes notes on its own: patterns it detects, corrections you make, decisions you made together. It is saved in
~/.claude/projects/<project>/memory/ and is loaded at the start of each session.

Review it often: Claude Code may have saved bad practices without you realizing it.
Tip: You can see and edit everything Claude Code remembers by running /memory.
Hooks and Skills: Take Control
1. Hooks
Claude Code works autonomously.
It executes actions, makes decisions, moves forward.
But that autonomy has a side that isn't mentioned as much: Claude Code does what it considers correct at each step.
If something goes wrong, or it does something you didn't want, it's already done.
How do you control it? With hooks.
A hook is a command that runs automatically at specific points in the cycle. Before Claude Code uses a tool, after it uses it, when the session ends.
You define what happens at each moment.
The key is that hooks are deterministic.
They don't depend on Claude Code "remembering" to do something. They are always executed, without exception.
The four main hooks are:
PreToolUse - Runs before Claude Code uses a tool. It is the only hook that can block an action. Example: Block any command that tries to modify .env files.
PostToolUse - Runs after Claude Code uses a tool. Example: Run Prettier automatically every time Claude Code edits a file.
Notification - Runs when Claude Code needs your attention. Example: Receive a notification on your Mac when Claude Code has finished a long task.
Stop - Runs when Claude Code finishes responding. Example: Automatically push to staging when the agent finishes.
They are configured in .claude/settings.json:
1{2 "hooks": {3 "PostToolUse": [4 {5 "matcher": "Edit|Write",6 "hooks": [7 {8 "type": "command",9 "command": "npx prettier --write $file_path"10 }11 ]12 }13 ]14 }15}
This hook runs Prettier automatically every time Claude Code edits or creates a file.
Without you asking. Without Claude Code having to remember it.
Without Hook: Claude Code edits a file, the code remains unformatted, and you realize it in the next commit.
With Hook: Claude Code edits a file, PostToolUse triggers automatically, Prettier formats the file, and the code always stays clean.
Hooks allow you to add guaranteed behavior to the agent's cycle. Not suggestions, not instructions that the model can ignore. Rules that are always executed.
2. Skills
There is another problem: consistency.
You ask it for the same task twice and get different results. Every time you open a new conversation, Claude Code starts without knowing how you did it last time.
How do you solve it? With Skills.
A Skill is a markdown file where you explain the exact process for a task to Claude Code: what to review, in what order, what format to use, what to ignore.
Every time that task appears, Claude Code follows those instructions.
Without Skill: You ask it to document an API and it generates something, but each time with a different format. Sometimes with examples, sometimes without them.
With Skill: You ask it to document an API and it follows the exact process you defined. Always with the same steps, the same format, the same criteria. Every time the same.
To create a Skill, you define a folder with this structure:
1my-skill/2├── SKILL.md # Main instructions (required)3├── template.md # Template that Claude completes4├── examples/5│ └── sample.md # Example of expected output6└── scripts/7 └── validate.sh # Script that Claude can execute
The only mandatory file is SKILL.md. The rest is optional and you add it according to what the task needs.
The SKILL.md has 2 parts:
The frontmatter - A YAML block with the name and description. The name is the command to invoke it manually. The description is what Claude Code reads to decide when to activate it automatically.
The body - The instructions in markdown. The workflow, the criteria, the output format.
1---2name: api-docs3description: Documents API endpoints. Use it when the user4 asks to document an API or mentions "swagger" or "endpoints"5---67## Process81. Identify all endpoints92. For each one: method, path, parameters, expected response103. Include a request and response example114. Close with a summary table
Once created, you can invoke it in two ways.
By writing /api-docs directly in the chat, or simply by asking Claude Code in natural language.
If the description fits what you're asking for, it activates on its own.
You can create them for any task you repeat with a clear process behind it: API documentation, changelogs, meeting summaries, code migrations.
SubAgents: Delegate When the Problem Grows
We already saw that context has limited capacity.
The longer the session, the more it fills up. And when it fills up, Claude Code starts losing information about what happened before.
Imagine you ask it to review your entire project for security issues. It reads dozens of files, analyzes the code, generates a detailed report.
All of that fills the context quickly.
And while it does that, your main conversation is blocked.
How do you solve it? With SubAgents.
A SubAgent is a separate instance of Claude Code that runs with its own context.
The main agent delegates a task to it, the SubAgent executes it independently, and when it finishes, it sends a summary with the results.
The main agent's context doesn't fill up with the whole process, only with the conclusion.
1Main Agent2 ↓3"review the project for security issues"4 ↓5┌─────────────────────────────┐6│ SubAgent: security-reviewer │7│ │8│ Reads project files │9│ Analyzes code │10│ Detects vulnerabilities │11│ Generates report │12└─────────────────────────────┘13 ↓14Returns summary to main agent15 ↓16Main agent continues with the loop
And not only that.
SubAgents can run in parallel.
Instead of analyzing three parts of the code sequentially, Claude Code can delegate all three at the same time.
What used to take minutes can take seconds.
1Main Agent2 ↓3Divides work into independent tasks4 ↓5┌──────────────┐ ┌──────────────┐ ┌──────────────┐6│ SubAgent 1 │ │ SubAgent 2 │ │ SubAgent 3 │7│ │ │ │ │ │8│ Reviews auth │ │ Reviews DB │ │ Reviews ext │9│ │ │ │ │ APIs │10└──────────────┘ └──────────────┘ └──────────────┘11 ↓ ↓ ↓12 Main agent receives the three summaries13 ↓14 Continues with the loop
Claude Code has 3 native SubAgents that it uses automatically:
→ Explore - A fast, read-only agent specialized in searching and analyzing the project. Results stay in the SubAgent's context, not yours.
→ Plan - Activates in plan mode. Before presenting a plan to you, Claude Code delegates the project investigation to this agent.
→ General-purpose - For complex tasks that require both exploration and modifications.
You can also create your own.
SubAgents are defined in markdown files with YAML frontmatter and saved in .claude/agents/.
1---2name: security-reviewer3description: Reviews code for security vulnerabilities.4 Use it when the user asks for a security review.5tools: Read, Grep, Glob6---78You are a security expert. Analyze the code for:9- SQL Injections10- Sensitive data exposure11- Authentication vulnerabilities1213Finish with a summary of findings ordered by severity.
Notice that in the frontmatter we limit the tools to Read, Grep, and Glob.
This agent can analyze but never modify anything.
When you need fine control over what each agent can do, that tool restriction is key.
Once created, Claude Code detects it automatically by the description and invokes it when the task fits. Or you can call it explicitly: "use the security-reviewer agent to review this PR."
When to use SubAgents and when not to?
It makes sense when the task is long and will generate a lot of output, when you can divide the work into independent parts that run in parallel, or when you need a specialized agent with limited tools.
It's not worth it for short tasks that don't fill the context. Coordinating SubAgents adds complexity that doesn't make sense if the main agent can solve the task in two minutes.
MCP: Connecting the Agent with the External World
Tools give Claude Code the ability to act on your machine.
But there is a limit: everything that happens, happens in there.
It can't open a PR on GitHub, query a production database, or create a ticket in Jira. To do that, you previously had to leave the agent and do it yourself by hand.
How do you solve it? With MCP.
MCP (Model Context Protocol) is an open protocol that defines how Claude Code connects with external services.
It works with a client-server architecture: Claude Code is the client, and each external service has its own MCP server that exposes what it can do.
When you connect an MCP server, Claude Code receives a list of available tools with their name and description.
From there, it uses them exactly like native tools. The only difference is that the action occurs in the external service, not on your machine.
1Claude Code2 ↓3Decides to use a tool from the GitHub MCP server4 ↓5┌─────────────────────────────┐6│ GitHub MCP Server │7│ │8│ Opens the PR │9│ Assigns reviewers │10│ Returns confirmation │11└─────────────────────────────┘12 ↓13Claude Code receives the result and continues
Without MCP: You tell it "I finished the changes, open the PR" and Claude Code can't. You have to go to GitHub, fill out the form, assign reviewers, and merge it yourself.
With MCP: You tell it the same thing and Claude Code opens the PR, writes the description, assigns the reviewers, and notifies you when it's ready. All without you leaving the agent.
Some MCP servers you can connect today:
→ GitHub - PRs, reviews, issues
→ Postgres / Supabase - Query and modify databases
→ Slack - Messages and channels
→ Jira - Tickets and projects
Native tools for your local environment. MCP for the external world.
How It All Fits Together
Claude Code is an agent: a system that takes a goal and operates in an autonomous loop until it fulfills it.
Every piece you saw in this article exists to make that loop more powerful. But the best way to understand it is to see them interacting together.
Case 1: Review and merge a PR
You ask Claude Code: "Review PR #42 and if everything is fine, merge it."
→ It uses GitHub MCP to read the modified files and understand the changes
→ It delegates the security analysis to a specialized SubAgent, so as not to fill the main context
→ A Hook runs the tests locally and verifies that everything passes
→ If the tests pass, it uses GitHub MCP to perform the merge without you touching the interface
You wrote one line. Claude Code coordinated four systems.
Case 2: Document an API and notify the team
You ask Claude Code: "Document the new endpoints and let the team know."
→ It activates a documentation Skill that defines the exact format: what to include, how to structure it, what examples to add
→ It uses Tools to read the code and extract the endpoints
→ A Hook formats the output before saving it
→ It uses Slack MCP to send the summary to the team channel
Every time you do it, the result will be the same. Without variations, without you having to explain anything.
Everything revolves around the loop.
Memory to start each session informed. Tools to act. Hooks to control. Skills to standardize. SubAgents to scale. MCP to connect with the external world.
When you understand that, you understand Claude Code.
And not just Claude Code: Cursor, Copilot, and any agent you use from now on operate on the same foundations.
The names change, the interface changes, but the loop is the same.
AI is advancing fast.
Every week there is something new. But the foundations don't change that often. Having them clear is what will allow you to adapt faster and get more out of what comes next.
Don't use Claude Code just for prompting. Pay attention to what happens underneath. That's where the opportunities are.
Some starting points to begin today:
→ Review your Auto Memory and improve what Claude Code saved
→ Create a CLAUDE.md for your project if you don't have one
→ Connect the GitHub MCP
→ Build a SubAgent for tasks that fill the context
→ Configure a Hook that runs tests after each change
That's all, see you tomorrow.
Marcus





