How Claude Works: A 5-Layer Mental Model for Developers

June 23, 2026 · updated June 25, 2026 · How Claude Actually Works (part 1)

▶ Watch on YouTube & subscribe to The Stack Underflow

Every tutorial, every blog post, every conference talk about Claude hands you a new piece of the puzzle: prompts here, tools there, MCP somewhere else, agents on a third slide. What nobody draws is the box that holds all those pieces. Without that box, every new Anthropic feature lands in a fog — you file it under “AI stuff” and move on. That mental overhead compounds until debugging feels like guesswork.

The Claude Stack is that box. It is a five-layer model — deliberately analogous to the TCP/IP stack — where each layer hides complexity below it and exposes a clean contract to the layer above. Once you have internalized it, you can place any Claude feature on it in seconds: where does MCP live? L2. Where do hooks live? L3. Where does prompt caching live? The cost plane. The fog lifts.

The one-sentence version: Claude is just tokens in and tokens out — but five layers of infrastructure (model, API call, tool protocol, agent loop, and surface packaging) transform that primitive into every AI application you actually build and use.


The Five Layers at a Glance

Here is the full stack, top to bottom, with the TCP/IP analogy for orientation. The analogy is a teaching device — the layering principle carries over, not the network semantics.

LayerNameTCP/IP AnalogyWhat It Does
L4SurfacesApplicationClaude Code, Agent SDK, Managed Agents
L3OrchestrationTransportThe agent loop — runs until the task is done
L2ReachInternetTools and MCP — the model touching the world
L1ProtocolLinkThe Messages API — one call, one stop reason
L0The ModelPhysicalTokens in, tokens out

Two cross-cutting planes slice vertically through every layer:

  • Prompts and structured output — shape how the model interprets and formats everything above L0
  • Context, reliability, and cost — show up as token counts at L0, caching at L1, tool latency at L2, loop length at L3, and deployment choices at L4
  ┌──────────────────────────────────────┐
  │  L4  SURFACES                        │
  │  Claude Code · Agent SDK · Managed   │
  ├──────────────────────────────────────┤
  │  L3  ORCHESTRATION                   │
  │  agent loop · hooks · subagents      │
  ├──────────────────────────────────────┤
  │  L2  REACH                           │
  │  tools / MCP                         │
  ├──────────────────────────────────────┤
  │  L1  PROTOCOL                        │
  │  Messages API · stop_reason          │
  ├──────────────────────────────────────┤
  │  L0  MODEL                           │
  │  Haiku 4.5 · Sonnet 4.6 · Opus 4.8  │
  └──────────────────────────────────────┘
     |                            |
  PROMPTS &              CONTEXT · COST ·
  STRUCTURED OUTPUT      RELIABILITY
  (vertical planes through all five layers)

L0 — The Model: Tokens In, Tokens Out

At the bottom sits the model itself. As of mid-2026, Anthropic’s production lineup spans three tiers (docs.anthropic.com, 2026):

ModelTierContext WindowBest For
Claude Haiku 4.5Fast / cheap200k tokensHigh-volume, low-complexity tasks
Claude Sonnet 4.6Balanced default1M tokensMost production workloads
Claude Opus 4.8Heavyweight1M tokensComplex reasoning, long-horizon agentic coding

The critical thing to internalize about L0: the model turns tokens into tokens — that is all it does. It cannot read your database, call an API, or remember last Tuesday’s conversation on its own. Every capability beyond text-in/text-out lives in a layer above. If you expect database reads or API calls without extra infrastructure, you will be confused at the wrong moment.

The tier choice is also a cost and latency decision, not just a quality one. Running Opus 4.8 on every call is like deploying a senior engineer to format a CSV. Start with Sonnet 4.6 as your default and escalate only when benchmarks show the gap is worth the price differential.


L1 — The Protocol: One Call, One Stop Reason

You never talk to the model directly. You make a single HTTP POST to the Messages API (client.messages.create), and the API returns a response. Every response carries a stop_reason field. That field is the entire control signal for everything above.

{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "tool_use",
      "name": "read_file",
      "input": { "path": "/tmp/data.csv" }
    }
  ]
}

As of the 2025 API, stop_reason has seven possible values (docs.anthropic.com, 2025):

ValueMeaningWhat to Do
end_turnModel reached a natural stopUse the response
tool_useModel wants a tool callExecute it and loop
max_tokensHit max_tokens param limitHandle context or raise limit
stop_sequenceA custom stop string matchedBranch on your sequence
model_context_window_exceededHit the model’s absolute context ceilingSummarize / prune / cache
refusalContent classifier blocked the responseLog and surface to user
pause_turnLong-running turn was paused by the platformResubmit response as-is

Memorize end_turn and tool_use. They cover 95% of production traffic. The others are the exception paths you must handle or you will have silent failures in production.


L2 — Reach: Tools and MCP

A model at L0 can only describe what it wants. It cannot act. stop_reason: "tool_use" is the model writing “I want to call read_file with these arguments” — but that is still just text in a JSON envelope.

Tools are the contract that turns description into action. You declare available tools in your API request; the model picks one when it needs external data or side effects; your code executes the tool and returns the result in the next API call. The model never runs code directly — it describes; you execute.

MCP (Model Context Protocol) standardizes this contract so that tools can be defined, versioned, and served independently of your application code. The current spec (2025-11-25, modelcontextprotocol.io) is stable and widely implemented across Anthropic’s own clients, VS Code, and third-party registries. Think of MCP as the npm for agent tools: a server you install exposes capabilities any MCP-compatible client can consume.

  Model outputs tool_use block (L0 text)
            |
            v
  Messages API returns stop_reason: "tool_use" (L1)
            |
            v
  Your code or MCP server executes the tool (L2)
            |
            v
  Tool result injected into next messages.create call (L1 again)
            |
            v
  Loop continues...

The L2 contract is deliberately narrow: tools take a name and a JSON input; they return a result. That narrowness is the point — it is what lets an MCP server built by a third party plug into your agent without touching your application logic.


L3 — Orchestration: The Agent Loop

An agent is not a special product. An agent is a while loop.

messages = [{"role": "user", "content": user_input}]

while True:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        tools=tools,
        messages=messages
    )

    if response.stop_reason == "end_turn":
        break  # task is done

    elif response.stop_reason == "tool_use":
        tool_result = execute_tool(response.content)
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_result})

    elif response.stop_reason == "max_tokens":
        handle_context_overflow()  # your responsibility

That loop is L3. It reads stop_reason from L1, dispatches tools from L2, and keeps iterating until the task is complete or an exception path fires. Three additional concerns live at L3:

ConceptWhat It IsWhere to Learn More
HooksCode that fires at lifecycle points (before/after tool calls, on errors, on session start/end)Claude Code Hooks Explained
Sub-agentsAgents that spawn their own context windows to handle isolated subtasks in parallelClaude Code Skills, Subagents, Hooks
MemoryMechanisms to persist information across calls or sessions (in-context, external KV, or summarization)Context Engineering

The Claude Agent SDK (renamed from the Claude Code SDK in September 2025) exposes hooks as typed callbacks — PreToolUse, PostToolUse, Stop, SessionStart, SessionEnd, UserPromptSubmit — so you can validate, log, or block behavior without touching the loop logic itself (Anthropic engineering blog, 2025).

You cannot reason about L3 without stop_reason from L1 and tools from L2. L3 is their composition.


L4 — Surfaces: The Things You Actually Install

At the top sit the packaged products — all four lower layers assembled and opinionated for a specific use case:

  • Claude Code — a terminal agent; the agentic coding assistant you run from your shell. It implements L0–L3 behind a conversational CLI interface, with built-in tools for file editing, shell execution, web fetch, and MCP client support.
  • Claude Agent SDK — the library version; build your own surfaces using the same harness that powers Claude Code. Ships as a Python package (claude-agent-sdk); useful when you want the loop, hooks, and subagent machinery without the terminal UI.
  • Managed Agents — Anthropic-hosted agents; Anthropic runs the loop infrastructure, you supply the instructions and tools. The right choice when you want agent capabilities without owning the deployment.

Every surface is L0 through L3 with opinions about defaults, packaging, and deployment baked in. When Anthropic ships a new product and you are unsure where it fits, ask: which layer does this live at? That question now has a concrete answer.


How to Apply the Stack

When you hit a confusing “AI thing,” run this checklist:

1. What layer does this feature belong to?
   - New model release?          → L0. Swap the model ID string.
   - New API parameter?          → L1. Read the stop_reason table.
   - New MCP server or tool?     → L2. It's a tool contract.
   - New loop behavior or hook?  → L3. It's orchestration.
   - New Claude product?         → L4. It wraps the lower layers.

2. What does the layer depend on?
   - L1 depends on L0 (model must exist to call).
   - L2 depends on L1 (tool_use stop_reason triggers dispatch).
   - L3 depends on L1 + L2 (loop + dispatch = agent).
   - L4 depends on L0–L3 (surface = layers + packaging).

3. Which plane does it touch?
   - Affects how the model interprets?   → Prompts plane.
   - Affects tokens, latency, or price?  → Cost/reliability plane.

Prompt caching, for example, is a cost-plane concern that activates at L1: you add cache_control to your request, and the API stores the computed key-value representation of that context block. Cache hits cost 0.1x the standard input price — a 90% reduction for cached tokens — making it the highest-leverage cost lever available at L1 (docs.anthropic.com, 2026). See Prompt Caching: Cut Your AI Bill for implementation details.


Common Misconceptions

  • stop_reason is a status code like HTTP 200 or 404.” It is not a success/failure indicator — it is a dispatch signal that tells your L3 loop what code path to take next. It is closer to an enum in a state machine. end_turn and tool_use are the two happy-path values; the others are exception paths that require explicit handling.

  • “The model calls tools.” The model describes a tool call in structured text. Your code — or an MCP server — actually executes it. The model never runs anything directly. If a tool call silently fails and you do not return the result, the model simply does not know the tool ran.

  • “Agents are a special Anthropic API.” There is no separate agent endpoint. An agent is your L3 loop plus the Messages API plus tools. Claude Code and the Agent SDK give you an opinionated implementation of that loop, but the primitive is the while loop you saw above.

  • “Haiku, Sonnet, and Opus differ only in price.” They have different capability ceilings, latency profiles, and context window behaviors. Haiku 4.5 caps at 200k tokens; Sonnet 4.6 and Opus 4.8 go to 1M. Picking the wrong tier is a common source of both cost overruns and quality failures — benchmark before committing to a tier in production.


Frequently Asked Questions

What is the difference between MCP and regular tool calling? Regular tool calling means you define tools inline in your API request and handle execution yourself. MCP standardizes the protocol so tools can be defined on separate servers and consumed by any MCP-compatible client. Regular tool calling is the primitive (L2); MCP is the ecosystem layer that makes L2 composable and distributable. The current stable MCP spec is dated 2025-11-25 (modelcontextprotocol.io).

If stop_reason: "max_tokens" fires mid-task, is the conversation broken? Not necessarily, but you must handle it. The model hit the max_tokens parameter you set before finishing its response. Common strategies: raise max_tokens, summarize earlier messages to free context, or use prompt caching so cached tokens do not count against your effective budget. The related model_context_window_exceeded value means you hit the model’s absolute ceiling — at that point you must prune or summarize, no other option.

Does Claude Code use all five layers? Yes — that is the point of L4. Claude Code is L0 through L3 packaged as a terminal agent. It uses Sonnet 4.6 or Opus 4.8 at L0, calls the Messages API at L1, has built-in tools for file system and shell access plus MCP client support at L2, runs an agent loop with hooks and subagents at L3, and exposes itself as an installable surface at L4.

Where do prompts fit in the layer model? Prompts are a cross-cutting plane, not a layer. A system prompt shapes how the model interprets everything from L0 upward — it is not isolated to one layer. The same is true for structured output: you might use response_format at L1, but the intent is to constrain the model at L0. Cost and reliability concerns work the same way — they surface at every layer simultaneously.

When should I use the Agent SDK versus Claude Code directly? Claude Code is the right tool when the use case is interactive coding assistance in a terminal or IDE. The Agent SDK is the right tool when you want to embed agent behavior into your own application, CLI, or service — you control the UI, the deployment, and the loop configuration, and you want programmatic access to hooks, subagents, and session management. Both run the same L0–L3 stack.

How does prompt caching interact with the agent loop? Cache a stable prefix — your system prompt, tool definitions, and any large documents — at L1 using cache_control. In a long agentic session with many loop iterations, each iteration re-sends the full message history, but the cached prefix costs 0.1x per hit instead of 1x. For Sonnet 4.6, that is $0.30/MTok on cache hits versus $3.00/MTok on uncached input — the savings compound quickly across loop turns.


Where This Fits in the Series

This tutorial is the orientation episode for the How Claude Actually Works series. It gives you the vocabulary and the five-layer scaffold so that every subsequent episode has a place to land. The next episodes drill into individual layers: How LLM Tokens Work and Your AI Bill and How the Context Window Works go deep on L0, Understanding stop_reason covers L1 exhaustively, and What Is MCP? unpacks L2. When Anthropic ships a new feature and you are unsure where it fits, come back to the stack diagram above. Browse all tutorials for the full series.

Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.

Subscribe on YouTube →