IntermediateReferenceLearning Paths

Claude and Anthropic tooling

A staged path through the Messages API, tool use, Claude-specific evaluation, MCP, Claude Code permissions, and production cost, latency and failure.

Updated Reviewed
intermediateAssumes working familiarity; skips the fundamentals.

Before you start

What you will be able to do

  • Construct a Messages API request by hand and predict, before sending it, which content blocks are cacheable and where the prefix breaks.
  • Implement a full client-tool round trip, including returning a tool_result for every tool_use block, and explain what happens when one is missing.
  • Distinguish a client tool from a server tool for a given task and say which side of the boundary executes the code and bears the failure.
  • Write an agent evaluation that grades the environment outcome rather than the final assistant message, and say why the two disagree.
  • Configure an MCP server connection and state what the client can read, what it can invoke, and which of those crosses a trust boundary.
  • Read a Claude Code permission configuration and predict whether a specific command is allowed, denied or prompted, given deny-ask-allow precedence.

Skills

  • Message and content block construction
  • Tool schema design
  • Cache prefix design
  • Agent trajectory grading
  • MCP server configuration
  • Permission rule authoring

Prove it to yourself

Break your own cache

Build a prompt with a stable instruction block and a volatile one. Put the volatile block first, measure the cache read and write token counts, then move it last and measure again.

Return a wrong tool_result on purpose

Implement a client tool, then feed back a result that is malformed, empty, and then contradicted by a later message. Record what the model does in each case rather than assuming it errors.

Write a deny rule that a narrower allow rule cannot escape

Configure Claude Code so a broad deny on a command family holds even when a specific allow rule matches, and confirm the precedence order yourself.

This tooling changes faster than any other subject on this site. Model names, tool type identifiers, permission modes and pricing tiers have all moved within the space of a few releases. Any page that enumerates them is wrong shortly after it is written. So this path deliberately teaches mechanisms rather than feature lists: the shape of a request, where a tool executes, what a cache prefix is, who enforces a permission. Those have been stable across the churn, and they are what lets you read a changelog and know whether it affects you.

Two consequences. Every stage links its primary source, and the source wins where it and this page disagree. And treat anything with a version string or a price as a pointer to go and look, not as a fact you can quote.

Stage 1 - The API and the message shape

What you learn. That there is no conversation on the server. The Messages API is stateless: you send the whole prior exchange as an array of alternating user and assistant turns, and the model returns the next turn. Anything you think of as memory is something your application resent. The details that decide how everything later behaves:

Element What it actually is Consequence
messages Array of turns; consecutive same-role turns are merged into one Your careful two-message split may not survive as two messages
content Either a string or an array of typed content blocks The string form is shorthand for a single text block, nothing more
system A top-level parameter, not a role in messages There is no system message to append to
Prefilled assistant turn A final assistant-role message the model continues from The cheapest way to constrain output shape without a tool
max_tokens A ceiling, not a target The model may stop well before it, and often should

The prefill removes a whole class of prompt engineering. If the last message in the array has the assistant role, the response continues directly from that text, so you can force a JSON object or a chosen option by starting it yourself.

What to build. Call the endpoint with an HTTP client, not an SDK, at least once. Send a multi-turn exchange as an explicit array so that the statelessness stops being an abstract claim. Read the token accounting in usage on every response. Do not estimate it from character counts.

Primary source. The Messages API reference, which gives the request body field by field, including the content block types and the per-request limits.

Stage 2 - Tool use, and where the code runs

What you learn. Tool use, also called function calling, does not let the model run anything. The model returns a structured request and something else executes it. The division that matters is where that something else lives.

A client tool is one you define with an input_schema. The response comes back with stop_reason: "tool_use" and one or more tool_use blocks; your code performs the operation and sends a tool_result block back in a following user turn carrying the matching tool_use_id. A server tool such as web search or code execution runs on Anthropic’s infrastructure and you receive the result in the same response. Same conceptual feature, different failure domain: a client tool fails in your code with your credentials, a server tool fails in someone else’s.

Three things reliably bite teams here:

  • Every tool_use block needs a corresponding tool_result. Parallel tool calls mean you can get several in one response, and skipping one produces a malformed conversation, not a partial answer.
  • The tool description is prompt, not documentation. It is the only thing the model has to decide when to call the tool. Vague descriptions produce tools that are called at the wrong moments or never.
  • Tool results are untrusted input. Whatever your tool returns enters the context window and can attempt to steer the model, which is prompt injection arriving through a path you built. The AI Engineering path covers that threat model in its security stage; do not skip it because the tool is yours.

What to build. Implement one client tool end to end, by hand, including the second request that carries the tool_result. Then break it deliberately: return an error string, return nothing, and return a result that contradicts an earlier turn. Record the behaviour instead of predicting it. Then disable parallel tool use and decide which response shape your orchestration code can handle.

Primary source. Tool use with Claude, which shows the full round trip and the client and server split, and Anthropic’s Writing tools for agents for schema and description design.

Stage 3 - Evaluation: only the Claude-specific part

The general material is not here. Evaluation methodology belongs to Stage 3 of the AI Engineering path, which covers dataset construction, deterministic checks before model-graded ones, validating a judge against human labels, and putting a regression gate in CI. Read that first. This stage assumes it and adds only what is specific to this toolchain.

What you learn. Three things that are properties of Claude and its harnesses, not of evaluation in general.

Grade the outcome, not the transcript. Anthropic’s own framing separates the transcript (the full messages array at the end of a run, including tool calls and intermediate results) from the outcome (the final state of the environment). An agent can end a run saying the booking is confirmed while no row exists in the database. If your grader reads the last assistant message, it grades the claim.

Multiple trials are not optional. Because output varies between runs, the unit of measurement is not a task run once but a task run several times as separate trials.

You are evaluating the harness as well as the model. When you measure “the agent”, you measure the scaffold that orchestrates tool calls together with the model inside it. Change either and the number moves, which is why a result is only meaningful with the harness version recorded next to it. It is also why upgrading a model is a code change: re-run the suite.

What to build. Take one task your system performs, express its success criterion as a check against the environment, not against text, and run it as several trials. Then record cost, token usage and latency on the same bank of tasks, so a change that improves quality and multiplies cost is visible as both.

Primary source. Demystifying evals for AI agents, which defines task, trial, grader, transcript, outcome and harness precisely enough to build against.

Stage 4 - MCP for connecting tools and data

What you learn. The Model Context Protocol is a JSON-RPC exchange between a host (the AI application), a client (one per server connection, created by the host) and a server (the program that supplies context). Read the MCP reference here for where it sits relative to bespoke tool APIs.

The protocol splits into a data layer and a transport layer, and knowing which one your problem is in saves most of the debugging time. The data layer defines the primitives a server exposes: tools (callable actions), resources (data the client can read) and prompts (reusable templates). Discovery is explicit, through */list methods and a server/discover request, so a server’s offering can change between calls. The transport layer defines how the bytes move: stdio for a local process on the same machine, and Streamable HTTP for remote servers, where authentication is ordinary HTTP authentication and the specification recommends OAuth for obtaining tokens.

The security consequence is the reason this stage exists. An MCP server is a supply chain dependency that gets to put text into your prompt and offer tools to your model. Two properties follow directly:

  • Every server needs its own least-privilege credential. Read access and write access should be separate servers or separate tools, so that excessive agency is bounded by configuration rather than by the model’s restraint.
  • A remote server you did not write is an untrusted instruction source. Tool descriptions, resource contents and error messages all reach the context window.

What to build. Stand up a local stdio server exposing one read-only resource and one tool, then connect it and enumerate what the client can see. Then repeat over Streamable HTTP with a token, and write down the list of things a compromised server could cause your agent to do.

Primary source. The MCP architecture overview and the specification. Check the protocol version your client and server negotiated; primitives have been added and deprecated across revisions.

Stage 5 - Agentic coding with Claude Code

What you learn. Claude Code is an agent harness with a permission system. The single most important sentence in its documentation is that permission rules are enforced by Claude Code, not by the model. Instructions in your prompt or in a CLAUDE.md file shape what Claude tries to do; they do not change what the harness allows. Anything you have written as a polite instruction is not a control.

The mechanism, from the permissions documentation:

  • Tool classes differ by whether approval is required. Reads within the working directory do not prompt; shell execution, file modification and web fetch do, apart from built-in read-only command and preapproved domain sets.
  • Rules are allow, ask or deny, and they are evaluated in that order: deny, then ask, then allow. First match wins and specificity does not override order. So a broad deny on a command family cannot carry allowlist exceptions, and a matching ask rule prompts even when a narrower allow rule also matches.
  • A bare tool name in a deny rule removes the tool from the model’s context entirely. A scoped pattern leaves the tool present and blocks matching calls.
  • Approvals persist with different lifetimes. A saved shell or domain approval is written to a settings file in the repository and applies to later sessions; a file-modification approval lasts until the session ends.

Approval fatigue is the real failure mode. That is why sandboxing exists and is not an optional extra. Anthropic reports that internally, sandboxing reduced permission prompts substantially (Anthropic, 2025), which matters because a developer clicking approve without reading is a weaker control than no prompt at all. Sandboxing is built on operating system primitives and needs both halves: filesystem isolation so a prompt-injected agent cannot modify files outside its directory, and network isolation so it cannot exfiltrate what it can read. Either alone is defeated by the other’s absence.

What never runs unattended. Derive this from blast radius, not from a feeling about risk. Do not leave an unsupervised session with credentials that can push to a protected branch, publish a package, apply infrastructure changes, run migrations against real data, send external messages, or read a secret store. Do not point it at a repository holding plaintext production credentials, or enable an autonomous mode on a machine carrying signing or SSH keys you would not hand to an attacker who won a prompt injection.

What to build. Write a permission configuration for a real repository and then try to defeat it. Confirm the precedence order yourself with a deny rule and a narrower allow rule. Turn on sandboxing and observe what changes about the prompts you see. Then run an ordinary task in a throwaway container with no credentials mounted, which is the configuration to reach for first, not last.

Primary source. The Claude Code documentation, Claude Code best practices, and the Claude Code reference here.

Stage 6 - Production: cost, latency, caching and failure

What you learn. Four operational facts. Each has a mechanism worth understanding, not a number worth memorising.

Caching is prefix caching. A cache breakpoint covers the entire prompt prefix in the order tools, system, messages, up to and including the marked block. Cacheable content therefore has to be physically first and stable. A per-request identifier at the top of your system prompt invalidates everything behind it, and the resulting cost looks like the model got more expensive. The cache lifetime is measured from the start of the request that writes or reads it, not from when your response finished streaming, so a long generation eats into the window before your next request begins. Longer-lived entries cost more to write. See context window economics for the interaction with growing chat history.

Latency has two independent components. Prompt length drives time to first token; generated length drives the rest. They are optimised differently, and a team that shortens its prompt to fix a slow response is often fixing the smaller half.

Failure classes are distinguishable, and the distinction dictates the response. From the errors reference:

Status Meaning Correct response
400 Malformed request, or a spend limit reached Fix the request, or alert; do not retry blindly
401 or 403 Credential invalid, or lacks permission Alert; retrying cannot succeed
413 Request exceeds the size limit for that endpoint Reduce payload; batch and file endpoints allow more than the messages endpoint
429 Rate limit or spend cap Back off, honouring retry-after; a spend-cap rejection has no such header and will keep failing
500 or 529 Server-side error or overload Retry with exponential backoff
504 Timed out while processing Stream instead of waiting on a single long response

The official SDKs already retry transient failures with backoff a limited number of times and honour retry-after, so hand-rolled retry logic on top of them usually double-retries. Capture the request-id header on every response, successful or not: it is the only identifier support can act on and the only way to correlate your logs with theirs afterwards.

Streaming changes error handling. An error can arrive mid-stream after a 200 response, so your client needs a path for a request that started succeeding and then did not.

What to build. Instrument one feature so a dashboard answers four questions: cache hit rate, cost per request, latency split into time to first token and total, and error rate by the classes above. Then set a hard budget cap outside the model, because unbounded consumption is an availability problem before it is a finance one.

Primary sources. Prompt caching and Claude API errors.

What will go stale here first

Likely to change What to read instead of trusting this page
Model names, identifiers, pricing tiers, cache lifetimes The pricing and models pages, at the time you cost the work
Tool type strings and available server tools The tool use reference; the identifiers are dated
Claude Code permission modes and settings keys The settings reference; behaviour has differed by release
MCP primitives and protocol revisions The specification for the revision your client negotiated

What has not moved: the statelessness of the API, the tool use round trip, the client and server execution split, deny before ask before allow, prefix caching, and permission enforcement living in the harness. Learn those and the rest is a changelog.