Domain 2, task statements 2.2, 2.4 and 2.5. An agent stuck retrying a permission error against a tool that only ever says operation failed. The four MCP error classes, project versus user scoped server configuration, MCP resources as content catalogs, and picking the right built-in tool for the job instead of the familiar one. Independent and unofficial. This series is not affiliated with, sponsored by, or endorsed by Anthropic. Nothing in it is exam content. Every practice question was written for this show against the published exam guide, which is a free public document linked below. Chapters * 0:00 Cold open and disclaimer * 0:23 An agent retrying a locked door * 0:52 The isError flag, and its limit * 1:37 Four error classes * 2:17 Structured metadata: category, retryable, description * 3:18 Local recovery versus propagating upward * 4:11 Access failure versus a valid empty result * 5:07 Project versus user scoped MCP config * 6:02 Credentials via environment variable expansion * 6:33 Writing MCP descriptions the agent will prefer * 7:13 Community servers over custom ones * 7:37 MCP resources as content catalogs * 8:07 Grep, Glob, Read, Write, Edit * 8:43 The Read plus Write fallback * 9:16 Exploring an unfamiliar codebase * 9:57 Worked question * 11:00 Why the other three options are there * 11:51 What the exam will ask, and next time Sources * Claude Certified Architect, Foundations Exam Guide, Version 1.0 (section 6, task statements 2.2, 2.4 and 2.5) * MCP in Claude Code Transcript This is Passing C C A R F, an independent study companion for the Claude Certified Architect, Foundations exam. Sixty items, a hundred and twenty minutes, and a published blueprint that tells you almost exactly what it is going to ask. Independent and unofficial. Not affiliated with or endorsed by Anthropic. No exam content. The agent hit a permission error on a backend call, and it tried again. Then it tried again. Four more times, each with a slightly different approach, each one failing for the exact same reason, because the tool’s response, every time, was two words: operation failed. Nothing about why. Nothing about whether trying again could possibly help. The agent had no way to know it was banging on a locked door, so it kept knocking. Domain two continues. Task statements two point two, two point four and two point five. Error responses, server scoping, and the built in tools everyone already has and half the time reaches for wrong. Start with the error, because it is the cleanest version of a pattern you have already seen in this series: a uniform response hides information the agent needs to act well. The Model Context Protocol has a mechanism for this, an is error flag that marks a tool result as a failure rather than a success. That flag alone tells the model something went wrong. It does not tell the model what kind of wrong, and that distinction is the entire episode. There are four classes of error worth telling apart, and the exam wants you fluent in all four. Transient errors, a timeout, a service that is briefly unavailable, where trying again in a moment might genuinely work. Validation errors, the input itself was malformed, where retrying the identical call will fail identically forever. Business errors, the operation was understood perfectly and refused on purpose, a policy violation, not a glitch. And permission errors, which is exactly what opened this episode, where the caller is not allowed to do this at all, and no number of retries changes that. Notice what those four categories buy you that a flat operation failed cannot. They tell the agent whether retrying is even worth attempting. A generic failure response leaves that question unanswered. So the agent either gives up too early on something recoverable, or burns time retrying something that was never going to succeed no matter how many times it asked. The fix is structured metadata, and the shape of it is worth knowing by name. An error category field, transient, validation, business or permission. An is retryable boolean, so the agent does not have to guess from the category alone. And a human readable description that can be surfaced to an actual customer when the failure is the kind of thing a customer needs to hear about. For business errors specifically, that readable explanation matters even more. A policy violation is not a bug to route around. It is information the person on the other end deserves to receive in plain language. Here is where the four category, is retryable pattern actually saves you real cost, and it is the same logic as the enforcement episode a few back. Local recovery belongs inside the subagent that hit the failure. If a call times out and the category is transient, retry it there, quietly, without ever bothering the coordinator. What should travel upward to the coordinator is only the failure that could not be resolved locally. It should travel with two things attached: what was actually attempted, and whatever partial results already exist. A coordinator that receives a bare failure notice with no partial results has to start that piece of the investigation from nothing. A coordinator that receives a structured failure with partial results attached can often keep going with what it already has. One more distinction inside this same territory, and it is subtle enough that people genuinely mix it up under time pressure. An access failure and a valid empty result are not the same thing, even though both can look, from a distance, like nothing came back. An access failure means the query could not run, permission denied, service unreachable, something is actually broken. A valid empty result means the query ran perfectly and there is nothing in your data matching that particular ask. Treating an empty result as a failure means retrying a search that was never going to return anything different. Treating a real failure as an empty result means quietly reporting success on a query that never actually executed. Both are wrong in opposite directions, and the fix for both is the same: know which one you are looking at before you decide what to do next. Now scoping, task statement two point four, and this is mostly about where configuration lives rather than what it says. Two levels. Project scoped configuration, in dot m c p dot Jason, is for shared team tooling, the servers everyone on the project needs and that travel with the repository in version control. User scoped configuration, in your home directory’s claude dot Jason, is for personal or experimental servers. Things you are trying out, that have no business being forced on every other person who checks out the repo. Both levels are active at once. Tools from every configured server, project and user, are discovered when the connection is made and are all available to the agent simultaneously. This is not an either or choice, it is two pools that both feed the same agent. Credentials belong in the project file without ever actually being in the project file, and the mechanism is environment variable expansion. Write a token as a reference to an environment variable rather than the literal secret, and the actual value is pulled from the environment at run time. This is how a team shares MCP server configuration in git without also sharing every team member’s API keys in git, which would otherwise be the obvious and disastrous alternative. There is a quieter skill buried in task statement two point four that is easy to skip past: writing MCP tool descriptions well enough that the agent actually prefers them over a built in. Say you connect a capable MCP tool for ticket lookups, and its description is thin. The agent may keep reaching for a generic built in search instead. The built in tool is the path of least resistance, and the MCP tool never explained why it is the better choice. The fix is the same one from two episodes back: write the description like it is the interface, because it is. And a related judgment call: reach for an existing community MCP server before building your own, for anything standard. Most teams do not need a custom Jira integration when a maintained community one already does the job. Save custom servers for the workflows that are genuinely specific to your team, where nothing off the shelf fits. Last idea in this task statement, and it is a nice one: resources. A resource is not a tool you call to take an action. It is a catalog you can browse, exposed by the server itself: a list of issue summaries, a documentation hierarchy, a database schema. Giving an agent access to that catalog directly means it does not need a round of exploratory tool calls first. It can see what exists before it decides what to actually ask for. Finally, task statement two point five, the built in tools you already have without connecting anything. Grep searches file contents, the tool for finding a function name, an error message, or every place a particular string appears across a codebase. Glob matches file paths by pattern, the tool for finding files by name or extension rather than by what is written inside them. Read and Write handle whole files. Edit makes a targeted change by matching unique surrounding text, and it is precise exactly because it insists on uniqueness. That insistence is also where Edit sometimes fails, and the fallback matters because it comes up constantly in real work. If the text you are trying to anchor an edit to appears more than once in a file, Edit cannot tell which occurrence you mean, and it will refuse rather than guess wrong. The reliable fallback in that situation is Read the whole file, make the change yourself in memory, then Write the full file back. Not a workaround, a documented fallback for exactly this case. There is also a way of working through an unfamiliar codebase that the exam rewards over the more obvious approach. Do not start by reading every file. Start with Grep to find entry points, the handful of