Last Step/Tool Design and MCP Integration18%
Domain 25 task statements18% of the exam

Tool Design and MCP Integration

How to shape tool contracts so Claude chooses the right tool, recovers cleanly from failures, sees only the tools it needs, and connects to external systems through MCP without leaking secrets or wasting turns.

Tool design and MCP integration is where the exam tests whether Claude can act effectively in the world through the contracts you publish. The model never sees your backend code. It sees the tools array you send with each Messages request, where every tool carries a name, a description, and an input_schema that together determine both selection and execution. When those contracts are vague, overlapping, or too numerous, selection degrades, errors become unbranchable, and the agent burns turns recovering from misrouting that a few precise sentences would have prevented.

The domain is the tooling counterpart to agentic orchestration. Orchestration asks how you sequence capabilities and route information between agents. Tool design asks which capabilities you expose at all, how you shape their schemas so they are distinguishable, how you handle the four classes of failure so the agent knows whether to retry or to pivot, how you distribute tools across agents at four to five per turn, and how MCP servers are integrated so that shared configuration stays credential free and standard systems are not rebuilt as custom first steps. Expect scored scenarios that blend a minimal description with a plausible classifier, a generic error string with a retry loop, or an overloaded single agent with a second server that does not actually reduce the flat list.

This guide follows the five tasks exactly as tested. Task 2.1 makes selection reliable by writing production grade descriptions and fixing system prompt coupling. Task 2.2 gives every failure a structured envelope that separates access failure from valid emptiness and transient from validation, business, and permission. Task 2.3 reduces choice complexity by scoping per role, consolidating homogeneous variants into one parameterised tool, and using tool_choice modes correctly. Task 2.4 places MCP configuration where it belongs, keeps secrets out of the shared file with expansion, prefers community servers for standard systems, and makes MCP tools selectable through richer descriptions and Resources. Task 2.5 enforces the built in hierarchy of Grep for inside, Glob for names, and Edit with a unique anchor before Read plus Write, all through incremental discovery rather than bulk reading.

On this page
  1. 2.1 Tool Schema Design Write production grade tool descriptions and strict schemas so Claude selects the right tool without guessing and executes it without type errors.
  2. 2.2 Structured Error Responses Return isError plus errorCategory and isRetryable so the agent can distinguish access failure from valid emptiness and retry only what is retryable.
  3. 2.3 Tool Distribution and Choice Keep four to five role scoped tools per agent, consolidate homogeneous variants into one enum tool, and apply tool_choice modes to enforce structure where needed.
  4. 2.4 MCP Server Integration Scope MCP servers correctly, keep the shared file credential free with expansion, prefer community servers for standard systems, and make MCP tools selectable via enriched descriptions and Resources.
  5. 2.5 Built-in Tools Use Grep for inside, Glob for names, and Edit with a unique anchor before Read plus Write, all through incremental discovery rather than bulk reading.
The essentials
Everything below explains why each of these is true.
  1. Claude sees only name, description, and input_schema before emitting tool_use, so description quality is the runtime control plane for selection.
  2. Production descriptions contain purpose, expected inputs with formats, concrete example queries, edge cases and limitations, and explicit when not to use this tool versus its neighbor.
  3. A generic umbrella tool such as analyze_document must be split into narrow typed tools such as extract_data_points, summarize_content, and verify_claim_against_source to make selection crisp.
  4. System prompt wording such as always check customer details can override even well written descriptions and must be reviewed as part of the same change.
  5. Tool failures need isError plus errorCategory and isRetryable, where only transient is retryable as is and only the category tells the agent what to do when isRetryable is false.
  6. Access failure is isError true with result unknown and retryable true, valid empty is isError false with resultCount zero and never retried.
  7. Four to five tools per agent per turn is the ideal, with role scoping for heterogeneous sets and enum consolidation for homogeneous overloads such as nineteen transform variants.
  8. MCP clients present one flat list from every connected server, so moving tools between servers without merging does not reduce the model's choice burden.
  9. Project .mcp.json at the repository root is shared and must stay credential free via ENV_VAR expansion, user ~/.claude.json is personal, community servers are evaluated before custom builds for Jira, GitHub, Slack, and similar standard systems.
  10. Resources expose read only catalogues such as schema or issue lists that eliminate exploratory tool chains, Tools are model controlled actions with side effects.
  11. Grep searches inside files for strings such as function names, Glob matches file names by pattern such as star star slash star dot test dot tsx, Edit with a unique anchor or replace_all is preferred over Read plus Write for cost.
  12. Incremental Grep then Read then Grep for wrappers beats bulk reading and preserves the context budget for synthesis and validation.
Task 2.118 min

Tool Schema Design

Write production grade tool descriptions and strict schemas so Claude selects the right tool without guessing and executes it without type errors.

What you need to know

Tool descriptions are the primary mechanism through which Claude selects which tool to call for a given user request, and the interface definition as a whole determines whether that selection can be executed without error. The model never sees your backend implementation. It sees the JSON Schema you publish in the tools array of the Messages request, where each tool carries a name, a description, and an input_schema that describes its typed parameters. Selection and parameter synthesis flow from those three fields, and description quality dominates the selection half while schema hygiene dominates the execution half.

In current deployments, before any tool call is issued the model receives the full list of tool definitions alongside the conversation history and the system prompt. Claude's tool use reference describes the tools parameter as a list of tool definitions with name, description, and input_schema, and notes that while the schema is required for inference the descriptions are where you steer the model toward precise behaviour. When two tools have overlapping capability and their descriptions are minimal, for example get_customer described only as Retrieves customer information and lookup_order described only as Retrieves order details, the model cannot differentiate which to use when the user says check my order number 12345. Both read as retrieval tools over entities identified by an identifier like value, and with no distinguishing input formats, example queries, or boundary statements, selection defaults to plausibility rather than correctness, leading to systematic misrouting where order queries are dispatched to the customer tool.

A production grade description removes the guesswork with five elements, what the tool does stated unambiguously, what inputs it expects including formats and required versus optional fields, concrete example queries the tool handles well that anchor pattern matching, edge cases and limitations including what the tool does not do, and explicit boundaries that say when to use this tool versus any similar one in the set. Our material illustrates the difference directly. The minimal get_customer line gives no identifier type, no return shape, and no boundary, while the production variant states that it looks up a customer account by email, phone, or customer identifier, returns name, contact details, account status and loyalty tier, is for identity verification, and explicitly says do not use it for order queries where lookup_order should be used instead. The production variant for lookup_order mirrors that shape, stating that it requires order number in format number NNNNN or tracking identifier, returns order status, items, shipping details and refund eligibility, and excludes identity verification work.

Beyond individual description quality, the distribution of overlap matters. A generic analysis tool such as analyze_document that claims to analyse a document and return results is a single overloaded entry point for at least three distinct jobs that deserve distinct contracts, extracting structured data fields, summarising key arguments, and verifying whether a claim is supported by the source. Splitting the generic tool into extract_data_points, summarize_content, and verify_claim_against_source, each with a narrow description and typed input output contract, makes the selection decision crisp because the task description now aligns with one tool rather than with a vague umbrella. Renaming is a lighter version of the same fix. When two tools have confusingly similar names, giving one a behaviour anchored name such as extract_web_results and rewriting its description to be web specific resolves overlap at the interface without touching implementation.

System prompt wording can silently override good descriptions, which is why interface design cannot be reviewed in isolation. If the system prompt contains keyword sensitive instructions such as always check customer details before proceeding, the model may route any customer phrasing to get_customer regardless of retrieval context, creating an unintended tool association that no description broadening can correct without also revising the prompt. After improving descriptions, the correct step is to review the prompt for such cues and remove or clarify them, ensuring prompt and interface convey the same routing policy.

The decision framing that extends beyond this task is equally important. Descriptions are the fix when the agent has a workable number of tools and simply cannot tell two apart. When the toolkit is large, rewriting descriptions does not rescue selection because the agent is past the point where decision quality depends on wording and must instead have its tool count reduced, which is the subject of Task 2.3. Recognising which regime you are in prevents description work where distribution work is needed and vice versa.

How tool definitions travel to Claude

Tool definitions are transmitted in the Messages API request under the tools key as an array of objects, each containing name as a unique snake case identifier, description as free form natural language that the model uses to decide whether to call this tool, and input_schema as a JSON Schema object constraining what arguments Claude can pass. The input_schema uses standard JSON Schema keywords including type object, properties with per property type, description, enum, format, pattern, minimum, maximum, additionalProperties, and required as an array of keys that must be present. Optional flags on the tool object include strict as a top level boolean alongside name, description, and input_schema, which when set to true constrains token sampling so the resulting input field in the tool_use block is guaranteed to match the declared schema, with only the shape guaranteed not business validity.

The model response for a tool call is a message whose content array contains one or more tool_use blocks, each with type tool_use, id, name, and input matching the schema, and the stop_reason is tool_use when at least one such block is present. Claude returned tool results are sent back as user role messages containing tool_result blocks with tool_use_id copied from the originating block and content as a string, optionally with is_error when the tool signalled failure. This surrounding contract matters to schema design because the description and property level description fields are the only content the model sees before deciding to emit a tool_use block. Precision in those fields is therefore not documentation polish, it is the runtime control plane.

Schema hygiene that prevents execution failure

Every property should carry its own description with format guidance and examples, for example User identifier in USR dash XXXXX format such as USR dash 48721, and any parameter with a fixed set of valid values should use enum rather than relying on prose, because without an enum the model may invent values outside the allowed set. Required arrays should list only truly required fields, optional parameters with sensible defaults should be omitted from required so Claude can skip them, integer and number should be distinguished precisely, nesting should remain shallow with no more than two levels, and additionalProperties should be closed when stray keys would break backend validation.

A well defined schema that is also vague in description still misroutes, and a well described tool with a loose schema still fails at execution with type mismatches or missing fields. Strict tool mode as grammar constrained sampling guarantees that the input in the tool_use block matches the input schema exactly, including enum and type correctness, but it does not guarantee business validity. Hygiene and description are therefore a pair, and either alone leaves one half of the correctness equation uncovered.

From one vague tool to crisp selection via splitting and renaming

When a single tool must cover extracting data points, summarising, and verifying claims, its description cannot be crisp for any one of those jobs. The tool selection problem is then structural. Splitting replaces one generic tool with several narrow, well named tools, each with its own contract. After splitting, a summary task aligns with summarize_content and an extraction task aligns with extract_data_points, so selection is a match rather than a guess. This is a low infrastructure fix compared with adding a routing classifier that bypasses model judgement entirely.

Renaming is the lightest version of the same interface repair. When two tools have confusingly similar names, giving one a behaviour anchored name such as extract_web_results and rewriting its description to be web specific changes the lexical trigger the model pattern matches on. Keeping the original name and lengthening the description leaves the name ambiguity in place, so the fix must include the name change rather than only prose growth.

Prompt coupling and when wording stops rescuing selection

System prompt wording can reintroduce the ambiguity a description rewrite just removed. Keyword sensitive instructions that mention customer details or always check a particular entity create an unintended association that persists even after the description adds an explicit boundary. The interface fix must therefore be validated against prompt wording before being declared complete, with conflicting prompt phrasing removed or narrowed and stability remeasured on the same benchmark.

The four to five tool ideal and the hard ceiling beyond eighteen tools for a single agent establish a second regime. Where tools are few enough to handle yet two read alike, sharpen the descriptions as described above. Where many tools share a shape such as data in plus operation plus data out, consolidate into one parameterised tool rather than rewriting eighteen descriptions. Moving servers without merging does not change the flat list the model reasons over, so distribution must be evaluated on the merged prompt rather than per server.

Mechanism and API surface

Messages API tools array
Transmit tools as an array of name, description, and input_schema on every request. The model receives this list alongside system and history and emits tool_use blocks with type tool_use, id, name, and input when it chooses to act.
JSON Schema keywords for input_schema
Use type object, properties with per property type and description, enum for fixed sets, pattern and format for identifier shapes, minimum and maximum for ranges, additionalProperties false to close stray keys, and required listing only truly required fields.
Strict mode as sampling constraint
Set strict true alongside name, description, and input_schema to guarantee the emitted input matches the schema shape, including enum and type correctness. Shape is guaranteed, business validity remains host side.
Five part description template
State what the tool does, what inputs it expects with formats and required versus optional, concrete example queries it handles well, edge cases and what it does not do, and explicit when to use this tool versus its neighbor.
Property level guidance and examples
Every property carries its own description with format and example such as USR dash XXXXX with USR dash 48721 as example. Fixed sets use enum so the model does not invent values outside the allowed set.
Splitting and renaming as interface repair
Replace one generic umbrella with narrow typed tools such as extract_data_points, summarize_content, and verify_claim_against_source. Where names confuse, rename to a behaviour anchored form such as extract_web_results and rewrite the description to be scope specific.
Customer support agent that stops misrouting check my order queries
A production walkthrough with the reasoning chain made explicit.

A production customer support agent exposes two retrieval tools with minimal interfaces. get_customer is advertised as Retrieves customer information. lookup_order is advertised as Retrieves order details. No parameter shapes, example queries, or boundary statements are given, and both accept an opaque identifier string that could be a phone number, an email address, or an order code.

During testing, ten representative user queries are executed, of which four mention order language such as check my order number 12345, where is my order with tracking identifier TRK dash 8841, has my order shipped, and can I modify order number 77890, while two mention identity such as verify my account for jane at example dot com and update my phone number. With minimal descriptions, two to three of the order queries are dispatched to get_customer because the model sees customer when the order prompt says my order and cannot distinguish which retrieval tool handles which noun phrase, and the retrieval agent then returns a customer profile rather than an order status, forcing a recovery turn.

The same inputs handled by production grade descriptions show reliable routing. The get_customer description now states it looks up a customer by email, phone, or customer identifier and returns profile attributes, and adds do not use for order specific queries, while lookup_order now states it requires order number in format number NNNNN or tracking identifier and returns order status, items, shipping details, and refund eligibility, adding do not use for identity verification. The fix is low effort yet high leverage, which is the distinction the exam probes. Adding these sentences to each description directly reduces confusion about identifier types and task boundaries without any change in routing logic, retrieval backend, or tool count.

The harder branch exercises the overloaded single tool case. An analyze_document tool that claims to analyse a document and return results is invoked for a summary task and returns an extraction instead, again because the single entry point's description is too generic to align with precise intent. Splitting the tool into extract_data_points for fields such as dates and amounts, summarize_content for key arguments, and verify_claim_against_source for claim support produces three crisp selection targets where previously there was one ambiguous hub, and selection accuracy improves without adding routing infrastructure. Review of the system prompt for always check customer details phrasing completes the repair.

Distinctions that decide answers

ThisNot thisHow to tell them apart
Production grade description with boundaries and examplesMinimal single sentence descriptionThe production form carries purpose, expected inputs with formats, example queries, edge cases, and explicit when not to use guidance, while the minimal form supplies only a headline that two plausible tools share.
Tool splitting for overlapping single toolPrompt level clarification for overlapSplitting replaces one generic tool with several narrow, well named tools each with its own contract. Prompt clarification keeps the generic tool and tries to steer selection in text, which fails when the single entry point must cover distinct jobs.
Description driven fixRouting classifier as first stepThe description fix addresses why the model is confused between two tools in a small set. A classifier bypasses model judgement and adds infrastructure, and is over engineered as the first response when sentence level clarity would suffice.
Renaming with description rewriteKeeping confusing names with longer proseRenaming changes the lexical trigger the model pattern matches on. Keeping the original name and lengthening the description leaves the name ambiguity in place.
Interface scope for selectionEnforcement logic for complianceInterfaces guide the model toward the right retrieval. Compliance such as refunds is enforced programmatically in executor code and not in description wording, so no description variant can replace a gate.

Traps

Patching selection with few shot examples alone

The tempting answer. Add a few shot example block to patch selection when descriptions are the root cause because examples feel tangible.

Why it fails. Examples improve parameter ambiguity such as date formats or prefix conventions, but they impose token overhead and do not address the confusion between two tools on the selection axis, which is driven by what the descriptions say about when each tool applies.

What is correct. Rewrite both descriptions to the five part template with formats, example queries, and explicit boundaries, then remeasure routing before adding examples.

Implementing a routing classifier as the first response to two tool overlap

The tempting answer. Introduce a deterministic classifier that picks the tool before the model sees the prompt, guaranteeing selection between two similarly described tools.

Why it fails. That guarantee is premature when the underlying problem is sentence level vagueness and it adds a system dependency the exam treats as disproportionate early compared with a low effort description rewrite.

What is correct. Revise descriptions and system prompt coupling first, then evaluate whether a classifier is still needed under distribution pressure.

Consolidating two similar tools into one polymorphic lookup first

The tempting answer. Merge get_customer and lookup_order into one lookup with polymorphic identifier to remove the choice being made incorrectly.

Why it fails. Consolidation removes the choice but collapses distinct return shapes and business boundaries, leaving the model with one large schema where two focused ones would have been easier to choose between, with larger implementation cost than revising descriptions.

What is correct. Keep two focused tools with explicit format and boundary guidance and review prompt wording, using consolidation only for homogeneous overloads such as nineteen transform variants.

Leaving the system prompt unchanged after improving descriptions

The tempting answer. Ship the description fix alone even where the prompt contains instruction templates such as always check customer details before proceeding.

Why it fails. Keyword sensitive prompt instructions can create unintended tool associations that override even well crafted descriptions, so prompt and interface must convey the same routing policy and the fix is incomplete without that alignment.

What is correct. Inspect the system prompt for triggers, remove or narrow the conflicting phrasing, and remeasure stability on the same benchmark.

Keeping one generic tool with vague prose instead of splitting

The tempting answer. Keep analyze_document as one tool and lengthen its umbrella description rather than splitting into bounded tools because one tool feels simpler to maintain.

Why it fails. A generic analyser that returns results cannot simultaneously specify extraction, summary, and verification contracts crisply, and selection error persists until each job has its own typed entry point with narrow description and schema.

What is correct. Split the generic tool into extract_data_points, summarize_content, and verify_claim_against_source each with a focused description and typed contract.

Going deeper than the task statement
Adjacent material that shows up in harder scenario questions.
Strict mode and deferred loading for large libraries

Strict grammar constrained sampling guarantees input shape, and deferred loading plus correlated input examples address scale problems that show up once a library grows past one context window.

Tool Definition Schemas
Batch endpoints and parallel variants for latency

A single batch tool that accepts an array of parameter sets replaces N sequential calls with one server side fan out, while parallel tool variants keep selection crisp without boolean switches.

Tool Orchestration
Prompt coupling and caching patterns for description examples

Effective description authoring, caching patterns, and context engineering illustrate how to choose examples that disambiguate choice versus loading irrelevant text that buries the selection signal.

Prompt Engineering for Loop Engineers
Build it
Turn vague routing into measured crisp selection without changing backends
  1. Create two MCP tools with intentionally ambiguous descriptions such as Retrieves customer information and Retrieves order details, registering each with the same generic string identifier, and confirm that selection between them is unstable across paraphrased queries.
  2. Run ten representative user intents through the agent and log which tool is selected for each, keeping the transcript and the selected tool name, to surface the specific confusion between my order and customer verification phrasing.
  3. Rewrite both descriptions to the production grade five part template, adding accepted identifier formats, example queries, edge cases, and a boundary paragraph of the form do not use this when you need the other tool, and check in the new definitions as the only change.
  4. Replay the same ten queries and measure the change in routing accuracy, confirming that previously misrouted order language now hits the lookup_order entry point while identity language now hits get_customer without an intermediate recovery turn.
  5. Inspect the system prompt for keyword sensitive triggers such as always check customer details language that reintroduces the deleted association, removing or narrowing that phrasing and remeasuring routing stability.
  6. Optionally introduce a generic umbrella tool such as analyze_document, record the misrouting for a summary versus extraction task, then split it into extract_data_points, summarize_content, and verify_claim_against_source and remeasure selection crispness on the same tasks.

Verify. Routing stabilises on the same ten queries with only description and prompt wording changes, proving selection is an interface property, while the split umbrella shows where one crisp contract must become three.

Answer real questions on this task
8 exam-style questions written against the rules above. You get the reasoning and a note on every wrong option after each answer.
Task 2.216 min

Structured Error Responses

Return isError plus errorCategory and isRetryable so the agent can distinguish access failure from valid emptiness and retry only what is retryable.

What you need to know

When an MCP tool fails, the error response it returns to the agent carries more weight than the failure itself, because the agent's next decision is driven by that response, not by the exception you caught on the server. A generic message such as Operation failed contains no signal about what went wrong, whether the input was malformed, whether a policy blocked the request, whether credentials are missing, or whether a retry might succeed, and the model given no structured field to route on either retries blindly, escalates prematurely, or treats an error as a successful empty result. The MCP protocol provides an isError flag for exactly this purpose on tool_result like responses, signalling that execution failed so the model can reason about recovery rather than interpreting the error text as data. The flag alone is coarse, though, and production systems extend it with a small taxonomy that lets the model branch to the right recovery action.

Four categories describe the space of tool failures the exam tests, each demanding a distinct recovery strategy that only works when the agent can distinguish the category from structured metadata rather than from free text. Transient errors such as timeouts, overload, and rate limits are the one category where the underlying system is temporarily unreachable yet the request itself is valid, so the correct action is to retry the same call after a delay, ideally with exponential backoff and jitter at the executor layer before the model retries itself. Validation errors such as invalid formats, missing required fields, or out of range enum values reflect a malformed request, and the correct recovery is to reformulate the input, not to resend the same payload, so the error must include the accepted format and an example. Business errors such as refund exceeds policy limit represent requests that are technically correct but violate business constraints, and the correct action is to take an alternative path or escalate rather than retry. Permission errors such as access denied reflect missing credentials or insufficient scope on the caller, and again the correct action is to retry only as a different principal or to escalate, never to resend the same call and expect a different outcome.

A narrow convention clarifies how two fields interact. isRetryable answers one question only, will resending this exact request with no change in input, authentication, or business context succeed. Only transient failures get true on that field, because the request was valid and the system was briefly unavailable. Validation, business, and permission are false on that field, because something must change first, the input for validation, the request strategy or an escalation decision for business, and the caller for permission. The surrounding errorCategory field is where the recovery instruction lives when the retryable answer is false, telling the agent to correct an identifier, restructure a call, or seek an alternative workflow, and the distinction inside the false rows matters most, with validation recoverable by the agent alone and business and permission requiring a different path or a different principal. Reading isRetryable to decide whether to resend as is, and then reading errorCategory to decide what to do when retry is not the answer, is the token budget safe branching the exam expects.

A closely related distinction the exam tests directly is between an access failure and a valid empty result, which share no recovery logic yet are trivially confused when a tool returns an empty array for both cases. An access failure means the tool could not reach the data source because of a timeout, authentication failure, or service outage, so whether the data exists remains unknown and a retry may help. A valid empty result means the tool reached the source, ran the query, and found no matches, so the request succeeded, the absence is meaningful, and a retry will return the same absence. A scenario tested repeatedly illustrates the failure mode. A lookup tool returns an empty array for a customer that does not exist, and because the envelope cannot distinguish could not fetch from found nothing, the agent retries three times and then escalates, while a reviewer shows the account never existed and the data shape misled the model into treating a successful zero match as a retriable failure. The fix is to structure successful empties so the empty payload is materially distinct from an access failure, with isError false and resultCount zero plus descriptive text rather than an undifferentiated empty array on isError true.

In multi agent orchestration, the same taxonomy gains a local recovery dimension. Subagents handle transient failures themselves before involving the coordinator, propagating only unresolved failures upward with partial results and a record of what was tried, so the coordinator can distinguish found nothing from could not search and decide whether synthesis should proceed, retry, or escalate. That layering keeps retries cheap and local while preserving the signal the coordinator needs for global decisions without silently suppressing errors as empty successes.

The envelope and how isRetryable narrows to one meaning

At the protocol level, the standard MCP error representation for an unsuccessful tool call uses isError true in the tool response alongside content as a human readable message, while a successful call with no data returns isError false with a descriptive text payload and a typed field such as resultCount. The structured envelope that extends isError includes at minimum errorCategory as an enum string and isRetryable as a boolean, plus a message and an optional technicalDetail whose content is server side rather than model facing, and a context object that may carry resource, sanitised input, attemptNumber, retryAfterMs, or a suggestion the model can act on.

Category values may vary by codebase, references include transient, validation, business, permission, and in richer implementations rate-limit, auth, not-found, and permanent as distinct codes with matching retry semantics, where transient and rate-limit are retryable after delay and the rest are not. HTTP idioms align loosely but not perfectly with this taxonomy, which is why the envelope matters more than status code alone. A 503 behind a transient error suggests retry after backoff, a 422 on a validation error says correct the input, a 403 on a permission error says elevate or escalate rather than retry, and business errors rarely map to a single status code at all, often returning 200 with a domain reason.

Why valid emptiness must not look like failure

A lookup tool that returns an empty array for a customer that does not exist and also for a store timeout shares a data shape across two recovery branches that must not share. The agent parsing the phrase not found versus unavailable is fragile. The robust fix is to put valid emptiness on the success side of the envelope, with isError false, a text field that says the query executed successfully but found no matches, and a numeric resultCount of zero, so the empty payload is materially distinct from an access failure that carries isError true, errorCategory transient, and isRetryable true.

That split also prevents wasteful retry counts. A successful zero match will return the same zero on every retry, so branching on the envelope suppresses retries that string parsing would have triggered. The pattern extends to graceful degradation where a tool backed by several services returns what it can with per section degraded versus unavailable statuses, exposing degradedSections and availableSections to the agent so a partial dashboard still renders rather than failing the whole workflow.

Retry timing and where it belongs

In tool level retry wrappers, transient detection is encoded explicitly, for example checking status greater than or equal to 500, code equals TIMEOUT, or code equals RATE_LIMITED before choosing to retry, and distinguishing that detection from the outer isRetryable flag that the model reads in the tool result block. The executor layer owns exponential backoff with jitter, caps attempts, enforces maxDelayMs, and only then surfaces a structured failure to the model, rather than letting the model retry immediately and hammer a failing backend many times in rapid succession.

A backoff configuration object with maxAttempts, baseDelayMs, maxDelayMs, and useJitter, with a full jitter algorithm that scales baseDelayMs exponentially and caps at maxDelayMs, matches the executor timing principles in the loop harness rather than leaving cadence to the model. That separation is why transient is the only isRetryable true case. The request was valid, the system was briefly unavailable, and the same request after a delay has a chance to succeed without changing inputs or principals.

Branching table the agent follows after the error

Transient and rate-limit are retryable after delay, with the agent either retrying locally a few times or the executor handling the first retries before the model sees the result. Validation is not retryable as is but agent recoverable via correction, where the response names the expected format such as USR dash XXXXX and provides a suggestion to correct the prefix style. Business and permission are not retryable and not agent recoverable alone, requiring an alternative path or escalation because the policy or credential constraint will block every resend of the same payload.

Interpreting isRetryable false as abandon the task conflates three distinct non retryable branches. The correct reading is cannot retry this exact call as written, then consult errorCategory for what to do next, whether to correct the identifier, to restructure the call, to seek approval, or to escalate. That preserves budget and avoids both infinite retry loops on business policy errors and silent suppression that hides failure from the coordinator.

Mechanism and API surface

MCP error envelope fields
Return isError boolean, errorCategory enum such as transient, validation, business, permission, isRetryable boolean, message for the model, optional technicalDetail hidden from the user, and context with resource, sanitised input, attemptNumber, retryAfterMs, and suggestion.
Transient and rate-limit as retryable
System temporarily unavailable such as timeout, 503, or rate limit. The request is valid. Retry the same call after exponential backoff with jitter. Only this class gets isRetryable true.
Validation as correction not retry
Invalid format, missing required field, or out of range enum such as USR dash XXXXX expected. isRetryable false. The response includes expected format and example so the agent can reformulate the input rather than resending the same payload.
Business and permission as alternative path
Policy violation such as refund over threshold or access denied due to missing scope. isRetryable false. The agent must take an alternative workflow or escalate as a different principal rather than looping on the same amount or caller.
Valid empty versus access failure
Valid empty is isError false with descriptive text and resultCount zero, reached the source and found no match, never retried. Access failure is isError true with category transient and isRetryable true, did not reach the source.
Executor owned backoff and jitter
Tool level detection on status greater than or equal to 500 or TIMEOUT or RATE_LIMITED, retry one to three attempts with baseDelayMs scaled exponentially and capped at maxDelayMs with jitter, then surface structured failure to the model rather than model side immediate retry.
One lookup tool exercised across four recovery branches
A production walkthrough with the reasoning chain made explicit.

A customer lookup tool with three exercised failure modes illustrates the full envelope and the routing trace an agent follows. The first failure is transient. The tool receives a lookup for a known identifier and the underlying store times out after four seconds. The response uses isError true, errorCategory transient, isRetryable true, and a description such as inventory database temporarily unavailable with the resource tag for the inventory store, and in some implementations a retryAfterMs field that the agent can communicate back to the user. The agent reading structured metadata rather than parsing the phrase retries twice with backoff and succeeds on the third attempt, consuming a few seconds instead of escalating immediately.

The second lookup is malformed. The supplied identifier does not match the USR dash XXXXX pattern expected by the tool, which returns isError true, errorCategory validation, isRetryable false, and a message that names the expected format together with an input field and a suggestion to correct the prefix style. The agent does not resend the same string. It reformulates the call with the required prefix and succeeds, having been told explicitly that resending this exact call will never work.

The third call is a valid empty result. The identifier is well formed and the store confirms there is no matching record, so the tool returns isError false with a text payload such as Product prod dash abc123 not found in warehouse east together with resultCount zero, rather than a failure. The agent reports that the product does not exist in the named warehouse. Had the tool instead returned an undifferentiated empty array on isError true, the agent would have treated that absence as an access failure and retried before escalating, reproducing the wasteful lookup loop the exam targets.

The fourth failure is a business constraint. A refund request exceeds the ten thousand threshold and the tool replies isError true, errorCategory business, isRetryable false, noting that a human must review, and the agent escalates with that structured reason rather than retrying the same payload. Across all four, the agent branches on isError and errorCategory rather than parsing strings, which keeps budget intact and prevents both infinite loops on policy errors and suppressed failures that would have omitted a source from synthesis silently.

Distinctions that decide answers

ThisNot thisHow to tell them apart
Access failureValid empty resultAccess failure did not reach the source and is isError true with category transient and retryable true. Valid emptiness reached the source, found no match, and is isError false with resultCount zero.
TransientValidationTransient is retryable as is after backoff. Validation is retryable only after reformulating the input, so isRetryable is false and the response names the expected format.
ValidationBusinessBoth are not retryable, but validation is recoverable by the agent alone by correcting fields, while business requires an alternative path or escalation because the policy will block every resend.
isRetryable trueerrorCategory recoveryThe boolean answers should I resend this exact call. The category answers what to do when I cannot, including correcting input, seeking approval, or trying a different workflow.
Structured envelopeGeneric error stringThe envelope carries isError, errorCategory, isRetryable, and a suggestion or context the model can act on. The generic string carries no branchable metadata and forces the model to guess.

Traps

Retrying a valid empty result as if transient

The tempting answer. Retry when the tool returns an empty array for a customer that does not exist because emptiness looks like failure.

Why it fails. Both cases produce empty data yet only access failures are retryable, and a successful query that finds nothing will return the same emptiness on every retry, burning turns before escalating to a human who has no better information.

What is correct. Treat isError false with resultCount zero as success with absence, report not found without retry, and keep retry for isError true with transient.

Marking a validation error as isRetryable true

The tempting answer. Set isRetryable true for a validation error because the agent can correct the input and succeed, so it feels recoverable.

Why it fails. isRetryable answers whether this exact request would succeed on resend, and a string failing a format check will fail the same check every time until the input changes, so the correct value is false with recovery carried in errorCategory and the suggestion that says how to fix the input.

What is correct. Return isRetryable false for validation, include expected format and example, and let the agent reformulate rather than resend as is.

Retrying a business policy error

The tempting answer. Retry a refund over the threshold because retry is the default reflex for any tool that returns an error.

Why it fails. The policy that blocks the first call blocks every retry of the same amount with the same principal, so looping wastes turns and never changes the outcome, while the correct action is to take an alternative path or escalate to a human reviewer.

What is correct. Branch business to alternative workflow or escalation and do not loop on the same payload, using the structured reason to explain why to the user.

Reading isRetryable false as abandon the task

The tempting answer. Treat isRetryable false as stop entirely because false reads as end of recovery.

Why it fails. False splits into three distinct branches, validation correctable by the agent alone, business and permission requiring a different workflow or principal, and only treating the three separately yields the right branching rather than premature abandonment.

What is correct. Read isRetryable false as cannot retry this call as written, then read errorCategory to decide whether to correct the identifier, restructure the call, or escalate.

Silently suppressing subagent errors as empty success

The tempting answer. Return an empty success from a subagent when its tool failed, to keep the coordinator input clean.

Why it fails. That hides failure information from the coordinator, prevents intelligent recovery such as retry or partial synthesis, and leads to output that silently omits the failed source with no indication of degraded coverage.

What is correct. Propagate the structured failure upward with partial results and a record of what was tried so the coordinator can distinguish found nothing from could not search.

Going deeper than the task statement
Adjacent material that shows up in harder scenario questions.
Typed ToolError with retry context and jitter

Full envelope with resource, sanitised input, attemptNumber, suggestion, plus backoff config with maxAttempts, baseDelayMs, maxDelayMs, and useJitter, matching harness executor timing rather than model cadence.

Tool Error Handling
Graceful degradation and fallback chains

Multi service tools return degradedSections and availableSections so a partial dashboard renders, and fallback chains try primary then secondary then estimated sources with explicit accuracy labelling.

Tool Orchestration
Multi agent local recovery before coordinator involvement

Subagents handle transient locally, propagate only unresolved failures with partials, so synthesis can proceed, retry, or escalate with accurate provenance.

Communication Patterns
Build it
Give every failure a branchable envelope and suppress retry on valid emptiness
  1. Implement a mock MCP tool such as customer_lookup that accepts a customer identifier and an explicit failure mode toggle you can trigger per call, along with a mode that returns a successful empty result for a known absent identifier, to inject the four failure shapes under test.
  2. Return four distinct error shapes for distinct modes, transient with isError true, isRetryable true, and a resource tag, validation with isError true, isRetryable false, naming the expected number NNNNN or USR dash XXXXX format, business with isError true, isRetryable false, describing the policy and the alternative, and permission with isError true, isRetryable false, indicating a principal change rather than a retry.
  3. Make valid empty input return isError false with a text field that says the query executed successfully but found no matches and a numeric resultCount of zero, so the empty payload is materially distinct from an access failure.
  4. Implement a tool level fast retry wrapper for infrastructure transients that retries one to three attempts with exponential backoff and jitter when status greater than or equal to 500 or code equals TIMEOUT, and a separate model observed branch where the tool returns a rate limit shape the agent can branch on.
  5. Write an agent loop that reads errorCategory and branches to retry after delay for transient and rate-limit, reformulate the identifier for validation, escalate to a human for business and permission, and report not found for the empty success case, logging that each path used the structured fields rather than string parsing.
  6. Inject an empty array without isError differentiation from the lookup tool and observe the wasteful retry count, then replay the same scenario through the structured envelope and confirm retries are suppressed, demonstrating that the failure was in the interface not in the model.

Verify. The agent retries only transient as is, corrects validation inputs, escalates business and permission, and never retries valid emptiness, with retries paced by the executor rather than by model immediacy.

Answer real questions on this task
8 exam-style questions written against the rules above. You get the reasoning and a note on every wrong option after each answer.
Task 2.316 min

Tool Distribution and Choice

Keep four to five role scoped tools per agent, consolidate homogeneous variants into one enum tool, and apply tool_choice modes to enforce structure where needed.

What you need to know

How many tools an agent sees on a turn, and how relevant each tool is to that agent's role, determines the reliability of tool selection more directly than any prompt refinement can compensate for. Our curriculum's distribution guidance states the optimal range as four to five tools per agent, scoped to that agent's specific role, with reliability degrading as more options compete for attention. Each additional tool adds description overhead to the context budget, one more option to weigh before invoking anything, and one more chance to pick a plausible sounding tool over the correct one, so quantity and relevance must both be managed together rather than optimised separately.

Role scoping answers relevance. A synthesis agent should not have web search tools, a web search agent should not have document analysis tools, and more generally each agent should see only the tools it needs for its defined responsibilities. Giving an agent tools outside its specialisation invites misuse, such as a synthesis agent running its own searches instead of using results already handed to it, duplicating work and bloating context with unverified claims. The same discipline applies when a synthesis agent needs occasional verification of simple facts. Routing every such fact check back through the coordinator adds two to three round trips per verification and in our material inflates latency by roughly forty percent for workloads where eighty five percent of verifications are simple single site lookups. The tested fix is a scoped cross role tool such as verify_fact given directly to the synthesis agent for the common simple case, while complex verifications that need multiple sources, cross referencing, or judgement continue to route through the coordinator, combining local speed for the frequent path with full pipeline quality where needed.

Consolidation answers overload when the overload itself is homogeneous. A data platform server with twenty two tools where three query tools serve distinct sources but nineteen transformation tools such as pivot, percentile normalisation, and currency conversion all share the shape data in, operation, data out, is not well served by splitting by role, because a transformation agent handed nineteen tools still carries almost the whole problem moved one level down and still cannot choose reliably. For such groups, the correct move is to collapse the nineteen into a single parameterised tool such as transform_data with dataset, transform_type as an enum of the operations, and an options object, reducing twenty two tools to four with no capability lost, because every operation remains reachable as a value the model chooses inside one call rather than a tool it must locate among near identical descriptions. The diagnostic for this distinction is to count the tools before reaching for a remedy. Two similar tools in a set of five is a description problem addressed in Task 2.1, while twenty plus tools where many are variations on one job signals a toolkit shape problem that no description rewrite resolves.

Least privilege is the companion constraint on scope. Replacing a generic fetch_url that can fetch any URL with a constrained load_document that validates document URLs only prevents misuse by capability removal, clarifies the tool's purpose through its narrowed description, and reduces the risk of unintended side effects such as fetching non document resources that should never have been in the agent's repertoire. The interface becomes self documenting because the name itself conveys the allowed scope without extra prose.

A framing that consistently traps candidates is where tool boundaries sit physically. Server boundaries are invisible to the model. A client hands the model every tool from every connected MCP server as one flat list, so a twenty two tool problem split across two servers remains a twenty two tool problem, and consolidation and scoping must be evaluated on the merged prompt not per server. That single fact explains why moving tools between servers is not a distribution fix and why per agent allowlists and consolidation are the levers that actually reduce choice complexity.

Role scoping and the four to five ideal

Scoping by role means each agent's allowlist contains only the tools that implement its responsibilities, with synthesis holding compile_report, format_citation, assess_coverage, and a scoped verify_fact for simple lookups, while web search holds search_web, fetch_page, extract_links, and save_snippet, and document analysis holds extract_metadata, extract_data_points, summarize_content, and verify_claim. Each agent now sees four domain focused tools, and cross role misuse disappears because synthesis no longer carries search tools at all where it might otherwise run its own searches and duplicate coordinator handed results with unverified claims.

The four to five ideal is not a stylistic preference but a measured planning limit. Beyond that per turn choice degrades irrespective of description quality, which is why adding descriptions to an eighteen tool agent is still the incorrect action compared with distributing those tools across role scoped agents. The exam probes this by offering improved wording as a distractor when the toolkit size itself is the cause, and expects distribution rather than narration.

Consolidation for homogeneous overloads

Homogeneous overloads are groups of tools that share an input output shape and differ primarily by operation name, such as nineteen transform tools that all take data in and return data out with operation as the varying part. Splitting by role does not help here because the transformation agent still holds nineteen near identical contracts after the split, leaving selection almost as hard as before. Consolidation replaces the group with one parameterised entry point that exposes transform_type as an enum of the operations and an options envelope for per operation parameters, so the model's decision collapses from which tool among nineteen to which enum value inside one call while preserving every capability.

Counting before acting diagnoses the regime. Two similar tools where the set size is five signals a description problem addressed in Task 2.1. Twenty plus tools where many are variations on one job signals a toolkit shape problem where no description rewrite rescues selection and consolidation is the correct first step. Batch parameter design as a single endpoint that accepts an array of parameter sets for server side fan out is a companion cost reduction that follows the same shape thinking.

tool_choice modes and least privilege

The Messages API tool_choice parameter controls how the model interacts with the available set on this turn. The default auto lets the model decide freely whether to call a tool or return text and is used for general conversation where some turns legitimately need no tool. Any forces the model to call a tool, letting it choose which one, and is used to guarantee structured output against one of several schemas when the document type is unknown, ensuring the model always produces a tool call rather than a conversational response which is valuable for pipelines where unstructured text would otherwise require reparsing. Forced selection with type tool and a name property requires the model to call exactly the named tool and is used to enforce mandatory first steps such as metadata extraction before enrichment, after which subsequent turns typically revert to auto for the remaining steps.

Least privilege sharpens both selection and safety. A constrained load_document that validates document URL shape and host allowlist or extension is preferable to a generic fetch_url that can reach any URL, because the narrowed tool's description is sharply indicative of when to use it and its capability removal prevents misuse by construction. Applying required at the load_document level to URLs while leaving generic fetch capabilities off the allowlist creates a workflow shape that is enforced outside the model's discretion rather than narrated into it.

Why server splits do not reduce the flat list

MCP project level dot mcp dot json carries the shared set and supports ENV_VAR expansion so all tools from every configured server become the single list the model ultimately reasons over. The Agent SDK adds options dot agents and options dot allowedTools with Task or Agent as the delegation meta tool, letting the coordinator assign four to five tools per specialist while keeping the coordinator itself lean without domain specific tools. Moving tools between servers without merging does not change that flat size, so overload persists after the move and only per agent allowlist trimming and enum consolidation actually reduce selection pressure.

That invisibility also interacts with cost heuristics. Where tools are few enough to handle yet two read alike, sharpen descriptions as in Task 2.1. Where tools belong to different jobs such as query, transform, and export, split by role at four to five tools each. Where many tools share a shape such as data in plus operation plus data out, consolidate into one parameterised tool. Producing those three before reaching for a server boundary change is the operational check the exam rewards.

Mechanism and API surface

Per agent allowlists and coordinator leanness
Use options dot agents and options dot allowedTools with Task or Agent as the meta tool, assigning four to five domain tools per specialist such as web search, document analysis, and synthesis, while the coordinator stays without domain tools and owns routing.
Scoping versus packing
Scoping keeps each turn's choice among four or five role specific tools and eliminates cross role misuse. Packing eighteen tools onto one agent raises decision complexity and misrouting irrespective of description quality.
Homogeneous consolidation pattern
Collapse nineteen near duplicate tools sharing data in, operation, data out into one parameterised tool such as transform_data with dataset, transform_type as an enum of operations, and an options object, preserving capability at lower choice complexity.
Scoped cross role verify_fact
Give synthesis a verify_fact limited to simple single source lookups for the eighty five percent frequent path, with description stating complex multi source verification should be escalated through the coordinator for full pipeline quality.
tool_choice auto, any, and forced named
auto lets the model decide freely whether to call a tool, any forces at least one tool call while letting the model choose which, forced named with type tool and a name enforces a mandatory first step such as extract_metadata on this turn.
Flat list invisibility of server boundaries
Every tool from every connected MCP server is merged into one prompt visible list. Splitting across servers without consolidation leaves the model's option count unchanged and is not a distribution fix.
From one eighteen tool synthesis agent to three focused agents plus one parameterised transform
A production walkthrough with the reasoning chain made explicit.

A research multi agent system starts as a single synthesis agent holding eighteen tools including two query tools and sixteen transformation style tools, several of which overlap semantically such as a numeric filter and a range selector, leading to measurable misrouting where the model chooses the generic variant for tasks the specialised one would have handled more precisely. The starting point is both overloaded and mixed, so no single remedy is expected to be sufficient.

The first correction partitions by domain role into three collectives, web search with search_web, fetch_page, extract_links, and save_snippet, document analysis with extract_metadata, extract_data_points, summarize_content, and verify_claim, and synthesis with compile_report, format_citation, assess_coverage, and a scoped verify_fact for simple lookups. Each agent now sees four domain focused tools, and cross role misuse disappears because synthesis no longer carries search tools at all. Selection stability improves for heterogeneous steps while the transformation overload remains.

The second correction is applied where partitioning alone does not resolve the overload, in the data platform case where the transformation agent still held nineteen closely related tools after partitioning. Those nineteen are collapsed into the single transform_data tool with an enum of operations and an options envelope for per operation parameters. The resulting platform has four tools total where previously there were twenty two, with every capability reachable, and selection accuracy improves because the decision to choose a tool shrank from one of nineteen to one of four while the decision to choose a transformation became an enum value choice inside the tool rather than a tool name search.

Latency tracing completes the correction. The synthesis agent's frequent fact verification previously suffered coordinator round trips for every check. A scoped verification tool with a description explicitly limited to simple single source lookups is added to synthesis, with the description stating that complex multi source verification should be escalated, and the workflow measure confirms that the eighty five percent simple lookup share is now handled locally without the two to three hop penalty, while the fifteen percent complex share still routes through the full pipeline with proper coverage assessment. Server split alone was tested as a non fix. Moving tools to a second server left the flat list at twenty two and selection unchanged until allowlist trimming and consolidation were applied.

Distinctions that decide answers

ThisNot thisHow to tell them apart
Scoping by role at four to five tools per agentPacking all tools onto one agentScoping keeps each turn's choice among four or five role specific tools. Packing eighteen tools onto one agent raises decision complexity and misrouting irrespective of description quality.
Consolidating near duplicate tool variants into one parameterised toolSplitting by role across agentsThe consolidated form replaces nineteen tools that share a shape with one enum driven tool. Splitting separates tools that do different jobs, such as query versus transform, into different agents.
Scoped cross role verify_factRouting every verification through the coordinatorThe scoped tool handles the eighty five percent simple cases locally in one hop. Coordinator routing for every verification adds two to three round trips regardless of complexity.
tool_choice autotool_choice anyauto leaves the model free to return text without a tool call, suitable for general turns. any forces at least one tool call, suitable where structured output from one of several schemas must be produced.
tool_choice anyForced tool type tool with nameany forces some tool but lets the model choose which. Forced named selection enforces that a specific mandatory first step such as extract_metadata executes on this turn.

Traps

Routing every simple verification through the coordinator

The tempting answer. Centralise all fact verification at the coordinator because centralisation feels cleaner and more observable.

Why it fails. Centralisation for the simple single site share adds two to three hops per task and inflates latency by roughly forty percent for that share, where measurement shows eighty five percent of checks are simple lookups that a scoped verify_fact handles locally while complex checks remain centralised.

What is correct. Add a scoped verify_fact to synthesis for the simple path with explicit escalation language for multi source verification, keeping complex verification on the coordinator pipeline.

Using tool_choice auto where a pipeline requires guaranteed structure

The tempting answer. Leave the turn on auto because auto feels safe and non coercive.

Why it fails. auto lets the model decide not to call a tool even when a structured extraction step is mandatory, so pipelines that require structured output must enforce it via any where the tool identity can vary or via forced named selection where the step is fixed.

What is correct. Use any to guarantee some structured call or forced type tool with name for a mandatory first step, reserving auto for conversational turns where a tool call is legitimately optional.

Expecting description rewrites to rescue an eighteen tool agent

The tempting answer. Improve wording alone for a single agent with eighteen tools because the descriptions read well individually and tool count is only a number.

Why it fails. Decision complexity scales with tool count in the prompt, and the four to five per agent guidance is the tested anchor, so description work on a bloated agent leaves misrouting in place where distribution is the correct lever.

What is correct. Distribute via role scoping or enum consolidation before investing further in prose, measuring selection on the merged flat list rather than per server.

Giving a subagent a generic fetch_url instead of a constrained load

The tempting answer. Keep the generic fetch_url because flexibility feels valuable and avoids maintaining a narrower variant.

Why it fails. That flexibility enables misuse, muddies the tool's purpose for selection, and creates unintended side effects such as fetching non document resources, while the constrained load_document variant implements least privilege and makes description sharply indicative.

What is correct. Replace generic fetch with load_document that validates document URL shape and allowlist, keeping the narrower contract on the allowlist.

Fixing overload by moving tools onto a second MCP server

The tempting answer. Create a second MCP server and place half the tools there, assuming the model will see two smaller lists.

Why it fails. Server boundaries are not visible to the model, which receives one flat list from every connected server, so the overload persists after the move and only per agent allowlist trimming and consolidation actually reduce selection pressure.

What is correct. Evaluate overload on the merged prompt and apply scoping or enum consolidation rather than a server topology change.

Going deeper than the task statement
Adjacent material that shows up in harder scenario questions.
Three heuristics before reaching for a remedy

Two similar tools in five is a description problem, tools from different jobs is a role split problem at four to five each, many tools sharing one shape is an enum consolidation problem that moving servers cannot fix.

Tool Choice Parameter Deep Dive
Agent topologies that express distribution as architecture

Router, sequential pipeline, fan out, and hierarchical nesting map tool inventories to graph topologies so partitioning decisions read as architecture rather than as single agent tweaks.

Workflow Topologies: The Five Patterns as Graphs
Execution cost companions to selection cost

Batch endpoints that accept arrays of parameter sets run long operations server side in parallel, and lightweight summary variants keep the model from pulling heavyweight fields it does not need.

Harness Engineering: Advanced Patterns
Build it
Prove distribution fixes beat wording on an overloaded toolkit
  1. Create three agent roles for web search, document analysis, and synthesis, and assign four to five tools to each with no tool shared across roles except the scoped cross role tool introduced later, verifying that every tool name clearly indicates purpose and scope.
  2. Measure selection on a small benchmark with and without the scope constraint, confirming that synthesis no longer emits search calls when it has no search tools, and that misrouting between similarly phrased document versus search variants is reduced by role separation alone.
  3. Implement a scoped verify_fact on the synthesis agent limited to simple single source lookups, with a description that explicitly escalates complex verifications to the coordinator, and confirm that eighty five percent simple path workloads no longer incur coordinator hops.
  4. Configure forced tool_choice with type tool and name extract_metadata on the document analysis agent for its first turn, switching to auto for subsequent analysis steps, and verify the mandatory first step is not skipped when the model is encouraged to summarise before extracting.
  5. Replace a generic fetch_url with a constrained load_document that validates document URL shape and host allowlist or extension, and verify that a non document URL is rejected with a clear domain error rather than being fetched.
  6. Replay an overloaded inventory containing twenty two mixed tools over an unscoped single agent, then over the four to five per agent scoped and consolidated shape, measuring that the consolidated platform preserves capability at four tools versus the scattered overload and that server splits alone do not change the flat list size the model reasons over.

Verify. Role scoping removes cross role misuse, enum consolidation collapses homogeneous overload without loss, tool_choice enforces mandatory structure where needed, and latency on the frequent simple verification path drops without sacrificing complex verification quality.

Answer real questions on this task
8 exam-style questions written against the rules above. You get the reasoning and a note on every wrong option after each answer.
Task 2.416 min

MCP Server Integration

Scope MCP servers correctly, keep the shared file credential free with expansion, prefer community servers for standard systems, and make MCP tools selectable via enriched descriptions and Resources.

What you need to know

The Model Context Protocol, or MCP, is the standard open protocol that defines how hosts such as Claude Desktop and Claude Code connect to external systems such as databases, search APIs, version control hosts, and internal services through Servers that expose Resources, Tools, and Prompts over a JSON-RPC 2.0 transport. Because MCP decouples the language provider's request response so that tool discovery, invocation, and management happen over persistent connections with initialization, negotiated capabilities, and ordered shutdown, configuration scoping determines whether a team shares a consistent toolset or drifts into configuration chaos.

The scoping hierarchy is two tiered, and the line between the tiers is where most setup problems start. Project level configuration lives in dot mcp dot json at the repository root, is version controlled, and is shared automatically with every teammate who clones or pulls the repository. It is used for servers the entire team needs, such as Jira for issue tracking, GitHub for source control, or internal connectors that represent the shared workflow. A representative entry declares an mcpServers object mapping names to server specs with command, args, and env, for example command npx, args with dash y and at modelcontextprotocol slash server-github, and an env block that references a token variable rather than containing it. User level configuration lives in tilde slash dot claude dot json in the home directory, is personal, is not version controlled, and is not shared with teammates, and is used for experimental servers or personal integrations that are being evaluated before being proposed to the team. At connection time every tool from every configured server on either tier is discovered and available simultaneously with no manual activation step, and if a server is configured and reachable its tools appear in the agent's toolkit.

Credential handling follows from that bridge. The shareable file must not contain secrets, and MCP's variable expansion for dollar brace VARIABLE_NAME in dot mcp dot json keeps the shared file safe to commit because each developer sets their own values locally in a shell profile, dot env file, or secret manager, and rotation then requires no file change and leaves no secret in the repository history. A common vendor of this failure is a dot mcp dot json committed with the literal GITHUB_TOKEN value, which exposes a secret to every clone and every continuous integration log, whereas the correct file contains the reference syntax and every member authenticates with their own locally scoped token. The protocol itself does not define credential management beyond transport, so host level expansion plus local secret storage is the convention that makes shared configuration safe.

MCP Resources are the catalogue complement to Tools, and choosing to expose them well reduces wasted exploratory calls. Where a Tool lets the model take an action that may mutate the world, a Resource exposes read only, host controlled data such as issue summaries with titles and statuses, documentation hierarchies, or database schemas with table names, column types, and relationships, which the host can fetch and inject as context before the model is asked to choose Tools. Without that catalogue the model must discover what exists by calling a sequence like list_tables then describe_table for every table, burning turns purely to get bearings, while with an exposed schema Resource it knows immediately and can call the substantive Tools correctly. The read only distinction matters for the exam. Resources are not write capable, so examining a catalogue cannot create the side effects a misuse of a Tool call would.

Build versus use is the integration choice the exam tests most directly in this task, and it is consistently framed as a pragmatic first step before bespoke work. For standard integrations such as Jira, GitHub, Slack, Linear, or Notion, mature community MCP Servers already exist, are maintained and tested by the community, receive updates without local build cost, and handle the common use cases correctly. The correct response when a team needs one of those systems is therefore to evaluate existing community Servers first and only build custom when there are team specific workflows, custom business logic at the tool layer, or proprietary internal systems with no community equivalent. Building a custom Jira integration as the first response when a standard server would have sufficed trades maintained code for a one off fork that will diverge over time, which the exam consistently marks as the wrong priority.

Tool selection quality inside MCP also depends on the model being able to read what an MCP Tool is capable of at selection time, not merely that it exists. When two tools share a name stem or an overlapping capability, the agent may prefer a built in tool such as Grep over a semantically richer MCP search, because the built in tool's description is detailed while the MCP entry is sparse, even when the MCP implementation is more capable for the task at hand. The correction is to enhance MCP Tool descriptions to the same five part standard that governs API tools generally, stating the capability, the expected inputs, the returned shape and example outputs, edge cases, and explicit when to use this tool versus built in or sibling MCP tools, for instance calling out that AST aware indexing is more accurate than text search for intent, so the model's choice under tool_choice auto is guided by substance rather than by length of description. This pattern illustrates how MCP design feeds back into tool design, where the same description standard that removed ambiguity for get_customer versus lookup_order also determines whether an MCP catalogue is actually chosen in practice.

Scoping hierarchy and discovery without manual activation

Project dot mcp dot json at the repository root is version controlled and shared, carrying the mcpServers map for team wide dependencies. User tilde slash dot claude dot json is personal and never shared, carrying experimental or personal servers that are evaluated before being proposed to the team. The runtime property that bridges both tiers is that at connection time every tool from every configured server on either tier is discovered simultaneously with no manual activation step. If a server is configured and reachable its tools appear, which is why placing shared servers in the personal file or requiring a local activation command is the incorrect model of how discovery works.

That simultaneity interacts with distribution. Because the client merges all tools from all servers into one flat list, a team that fixes overload by moving tools to a second server has not reduced the model's option count. The correct fix remains per agent allowlist trimming and enum consolidation, while scoping decisions remain about sharing versus personal experimentation rather than about choice complexity.

Credential hygiene via expansion

The shareable dot mcp dot json must not contain literal secrets. MCP's variable expansion for dollar brace VARIABLE_NAME in that file keeps the shared file credential free because each developer sets values locally in a shell profile, dot env file, or secret manager, and rotation then requires no file change and leaves no secret in repository history. A common failure is a dot mcp dot json committed with the literal GITHUB_TOKEN value, which exposes a secret to every clone and every build log. The correct file contains the reference syntax and every member authenticates with their own locally scoped token, with continuous integration injecting the same variable from the secret manager.

This hygiene is convention rather than protocol, because MCP itself does not define credential management beyond transport. Host level expansion plus local storage is the boundary that makes shared configuration safe and reviewable, and it is the detail the exam probes when a file diff shows a literal token versus a reference.

Resources as catalogues that eliminate exploratory chains

Resources expose read only, host controlled data such as issue summaries, documentation hierarchies, or database schemas with table names, column types, and relationships, which the host can fetch and inject as context before the model chooses Tools. Without that catalogue the model must discover what exists by calling a sequence like list_tables then describe_table for every table, burning turns purely to get bearings, while with an exposed schema Resource it knows immediately and can call the substantive Tools correctly.

The read only distinction matters for exam reasoning. Resources are not write capable, so examining a catalogue cannot create the side effects a misuse of a Tool call would. Rendering schema or issue lists as Resources under a db colon slash slash style URI with declared mimeType therefore moves orientation cost from turns to one context injection, preserving budget for the substantive workflow.

Build versus evaluate and description enrichment for selection

For standard external systems such as Jira, GitHub, Slack, Linear, or Notion, mature community MCP Servers already exist, are maintained and tested, receive updates without local build cost, and handle the common use cases correctly. The correct response when a team needs one of those systems is to evaluate existing community Servers first and only build custom when there are team specific workflows, custom business logic at the tool layer, or proprietary internal systems with no community equivalent. Proposing custom Jira work as the opening move trades maintained code for a one off fork that will diverge, which the exam marks as the wrong priority.

Even after a server is chosen, selection quality depends on how selectable its tools appear. When a sparse MCP entry named search_codebase carries the description Searches code, the agent prefers Grep over that server even where semantic search would be better, because the built in tool has richer text. The correction is to enhance MCP Tool descriptions to the same five part standard, stating the capability as AST aware semantic search, the returned shape as functions and methods with file path and line number, and the scope advice such as Use this instead of Grep when searching by intent rather than by exact string, after which selection stabilises.

Mechanism and API surface

Two tier configuration map
Project dot mcp dot json at the repository root with mcpServers holding command, args, and env, version controlled and shared, versus user tilde slash dot claude dot json in the home directory, personal and never shared, with every tool from every server on either tier discovered simultaneously with no manual step.
ENV_VAR expansion for secrets
Write dollar brace VARIABLE_NAME in dot mcp dot json env blocks such as GITHUB_TOKEN, JIRA_URL, and JIRA_TOKEN, with each developer and CI injecting values locally via shell profile or secret manager, keeping the shared file credential free and rotation requires no JSON edit.
JSON-RPC 2.0 lifecycle and pagination
Every connection sequences initialize to exchange supported primitives and version, initialized to confirm readiness, then discovery calls tools slash list and resources slash list, and invocation via tools slash call with pagination via nextCursor as an opaque string the client must not parse.
Transport choice without behaviour change
Stdio wraps a child process with stdin and stdout for local development and fast iteration, Streamable HTTP exposes MCP over HTTP as stateless endpoints scaling across users, with legacy SSE superseded, selection does not change tool semantics but determines sharing scope.
Resources versus Tools versus Prompts
Resources are read only host controlled catalogues with uri, name, description, and mimeType, Tools are model controlled actions with name, description, and inputSchema that may mutate the world, Prompts are user task templates consumed as slash commands or skills, with transport security and sampling governed at the host.
Enriched MCP description for selection
Expand sparse entries such as Searches code into multi sentence statements that name AST aware capability, returned shape with file path and line number, and when to prefer this tool over Grep or sibling servers, so model choice under auto is guided by substance rather than description length.
Jira for sprints without building first, scoping correctly, and making semantic search win over Grep
A production walkthrough with the reasoning chain made explicit.

A product team building a Claude Code workflow requests Jira issue tracking for sprint coordination and proposes to build a custom MCP Server, citing the need for bespoke handling of fields specific to their sprint model. The first correction is on the decision horizon. Because Jira is a standard external system with mature community Servers for issues, sprints, and workflow transitions, the correct first step is not to build but to evaluate community options alongside requirements, comparing supported fields and operations against the sprint scope and confirming whether the community Server already covers the required issue types and transitions before committing to build and maintenance. In this case it does, so the community Server is adopted as the baseline before any custom wrapper is considered.

The second correction is on scoping. The team stores the shared configuration in dot mcp dot json at the repository root with two entries, github and jira, each under mcpServers, each declaring command and args for the npx runnable package, and each referencing credentials via expansion, dollar brace GITHUB_TOKEN, dollar brace JIRA_URL, and dollar brace JIRA_TOKEN in env. No literal secret is written to the JSON. Teammate machines set GITHUB_TOKEN in shell profiles while CI injects the same variable from the secret manager, so no pull request shows a credential and rotation requires no JSON edit. A developer also keeps a local experiment for a different issue tracker in tilde slash dot claude dot json under mcpServers as a personal Server for a feasibility spike, and the exam expects recognition that this is correctly placed because it is not yet a team shared dependency.

The final correction is on tool selection in practice. The team also runs an internal MCP Server that wraps a community codebase search indexer with a sparse entry named search_codebase carrying the description Searches code. The agent repeatedly prefers Grep over this server even where semantic search would be better, because the built in tool has richer context. The fix is to replace the description with a multi sentence statement that names the capability as AST aware semantic search, the returned shape as functions and methods with file path and line number, and the scope advice such as Use this instead of Grep when searching by intent rather than by exact string, after which selection stabilises and redundant Grep paths diminish. A schema catalogue describing tables and relationships is also moved from an exploratory describe_table tool chain into a db colon slash slash style Resource, so the agent sees structure without burning tool calls.

Distinctions that decide answers

ThisNot thisHow to tell them apart
Project dot mcp dot jsonUser tilde slash dot claude dot jsonProject file is at the repository root, version controlled, and shared by the team. User file is in the home directory, personal, and never shared.
Dollar brace ENV_VAR expansion in dot mcp dot jsonLiteral secret in dot mcp dot jsonExpansion keeps the shared file credential free and lets each developer authenticate locally. A literal secret leaks to every clone and build history.
Community MCP Server for Jira or GitHubCustom Server as first stepCommunity options are already maintained, tested, and updated for standard systems and should be evaluated first. Custom is reserved for team specific logic or proprietary systems with no community equivalent.
Resources as content cataloguesTools as actionsResources expose read only data such as schema or issue lists that the host fetches for context before tool choice. Tools mutate or query with side effects and are model controlled.
Enhanced MCP description that states output shapeSparse MCP description such as Searches codeThe enhanced description supplies capability, input format, output shape, and when to prefer this tool over Grep or sibling servers. The sparse one leaves the model to prefer the better described built in tool.

Traps

Building a custom MCP Server for Jira as the first response

The tempting answer. Propose a custom integration for Jira or GitHub immediately because custom sounds more tailored to the team's sprint model.

Why it fails. Evaluated community Servers for Jira, GitHub, Slack, Linear, and Notion already cover standard workflows, receive updates, and remove build and maintenance cost, so the exam consistently prefers evaluation before build and marks custom first as the wrong priority.

What is correct. Evaluate the community Server against the required fields and operations first, adopt it when it covers the scope, and reserve custom for team specific workflow fields or proprietary systems with no community equivalent.

Placing team shared servers in the user home file

The tempting answer. Store team wide servers in tilde slash dot claude dot json so each developer maintains their own connection.

Why it fails. That file is personal and not version controlled, so teammates do not inherit the same toolset on clone and the team drifts, while the repository root file is the correct shared model with automatic inheritance on pull.

What is correct. Place shared servers in dot mcp dot json at the repository root and keep only experimental personal servers in the home file.

Committing literal secrets to the shared file

The tempting answer. Paste the GITHUB_TOKEN value directly into dot mcp dot json because pasting feels simpler than managing environment injection.

Why it fails. That value then lives in every cloned history and every CI log, exposing the credential, whereas expansion keeps the JSON credential free while each environment injects its own secret and rotation requires no JSON edit.

What is correct. Write dollar brace GITHUB_TOKEN in the JSON and inject the actual token via shell profile or secret manager at the developer and CI layer.

Leaving MCP Tool descriptions sparse on capability and output shape

The tempting answer. Leave the MCP entry as Searches code because the name feels self documenting and longer prose feels redundant.

Why it fails. Model selection at tool_choice auto is driven by available text, so a sparse MCP entry loses to a well described built in such as Grep even when the MCP index is semantically richer, and selection only stabilises after an enriched description.

What is correct. Rewrite the description to state AST aware semantic capability, returned shape with file path and line numbers, and when to prefer this tool over Grep or sibling servers.

Scanning schema via repeated describe_table tool calls instead of a Resource

The tempting answer. Discover an unfamiliar backend by iterating list_tables then describe_table for every table because iterative calls feel explicit.

Why it fails. That burns multiple turns purely to get bearings, while a Resource catalogue exposes schema with table names, column types, and relationships in one read only fetch that the host injects before tool choice, preserving budget for substantive calls.

What is correct. Expose the catalogue as a db colon slash slash style Resource with declared mimeType and consume it as context before invoking domain tools.

Going deeper than the task statement
Adjacent material that shows up in harder scenario questions.
Full MCP stack of Host, Client, and Server with JSON-RPC lifecycle

Three layer topology, initialize plus initialized plus capability negotiation, control boundaries where Resources serve the host's context, Tools serve the model's action, and Prompts serve the user's task, plus the sampling anti pattern that risks recursion.

MCP Architecture
Transport choice and shared versus personal scoping in production

Stdio for local tools versus Streamable HTTP as the current remote standard with header routing via Mcp-Method and Mcp-Name, situating dot mcp dot json command servers versus URL servers on one decision axis with secret rotation and scaling.

MCP Transports
Resource URI templating and Prompt lifecycle as consumer layer

Resources with URI templating for dynamic listings, Prompts covering prompt lifecycle including slash commands and skills, plus building servers scaffolding and testing patterns.

MCP Resources
Build it
Scope correctly, stay credential free, and make the catalogue do the orientation
  1. Create dot mcp dot json at the repository root with an mcpServers object containing a community Server entry such as github with command npx, args with dash y and at modelcontextprotocol slash server-github, and an env block referencing dollar brace GITHUB_TOKEN rather than a literal secret, confirming the file diff is credential free.
  2. Store the actual GITHUB_TOKEN injection at the developer or CI layer via shell profile or secret manager, and confirm local resolution and remote pipeline both work without modifying dot mcp dot json, proving that rotation requires no JSON edit.
  3. Add a personal experimental Server under tilde slash dot claude dot json with its own mcpServers entry that is intentionally not checked in, demonstrating the distinction between project shared and personal scoping by cloning fresh and confirming the experiment does not reappear.
  4. Register a Resource on the production Server that exposes a content catalogue such as a database schema with table names, column types, and relationships under a db colon slash slash style URI with declared mimeType, and verify that the agent consumes that catalogue without exploratory describe_table chaining.
  5. Rewrite a sparse MCP Tool entry such as search_codebase with a three to five sentence description that states it is AST aware semantic search, enumerates the returned shape including file path and line numbers, and says Use this instead of Grep when searching by intent not by exact string, and observe selection bias toward the MCP tool where semantically appropriate.
  6. Evaluate the community Server before any custom proposal for the external system under test, capturing the gap that would actually require a custom Server such as team specific workflow fields with no community coverage, and recording that gap rather than building the full server as the first change.

Verify. The team shares one toolset via the repository root file with no secrets in history, personal experiments stay personal, orientation uses one Resource fetch rather than exploratory chains, and enriched MCP descriptions let the richer search win where intent rather than exact string drives selection.

Answer real questions on this task
8 exam-style questions written against the rules above. You get the reasoning and a note on every wrong option after each answer.
Task 2.516 min

Built-in Tools

Use Grep for inside, Glob for names, and Edit with a unique anchor before Read plus Write, all through incremental discovery rather than bulk reading.

What you need to know

Claude Code includes six built in tools for codebase work, Read, Write, Edit, Bash, Grep, and Glob, and using the right one for the task is a source of measured productivity rather than style. The workflow the exam probes is codebase comprehension and modification at scale, where choosing between Grep and Glob, or between Edit and Read plus Write, determines whether context is spent well or burned, and whether results are complete or truncated. The distinctions are small in name but large in consequence, because each tool emits a different shape of evidence and costs a different amount of the context budget.

The sharpest distinction the task tests is between Grep and Glob. Grep searches file contents for patterns such as function names, import strings, error messages, and variable assignments. It answers what is inside files. Glob matches file paths by naming patterns such as extension or directory shape, answering which files exist by name without opening them. The sentence that anchors the difference is simple. Grep finds what is inside files, Glob finds files by their names. The exam deliberately presents scenarios where the wrong choice produces a null result or an expensive misfire. Using Glob to find callers of a deprecated function fails entirely, because Glob can only match star star slash star processLegacyOrder star as a file name pattern, not the string processLegacyOrder inside OrderProcessor dot ts. Using Grep to find test files by naming suffix works technically by searching content for the literal test substring, but is the wrong tool because Glob is purpose built for star star slash star dot test dot tsx style path matching and the exam expects that choice.

The file write family has an analogous preferred order. Edit performs a targeted modification via unique text matching, where you supply the precise old_string and its replacement and the tool touches only that occurrence. When old_string appears multiple times in the file, Edit fails by design rather than guessing which occurrence was meant, which is a safety property rather than a bug. When that happens the documented recovery is to widen the anchor with more surrounding context until the match becomes unique, or to set replace_all true if every occurrence should be changed within the same turn. Both options keep you on Edit, which costs almost no additional context, while falling back to Read plus Write, loading the entire file and rewriting it, is a context heavy fallback that the exam treats as a last resort rather than the immediate next step, because it spends a file's worth of tokens to change a line. The ordering therefore matters. Attempt Edit with the shortest plausible unique anchor, widen until it is unique on a non unique match or set replace_all where a global change was intended, and only escalate to Read plus Write when neither narrowing path can disambiguate the target.

The discovery shape around these tools matters as much as the tools themselves. The correct orientation is incremental discovery rather than eager bulk reading. Grep first for entry points such as the function name, class name, or error string that anchors the investigation to learn which files are relevant, then Read those specific files to follow imports and trace flows, then Grep again for any wrapper or re export names to find indirect consumers, and only Read what each prior discovery step justified. The opposite shape, loading every file into context before knowing what is relevant, is the highest cost discovery failure in this domain, because a two hundred file codebase read upfront can exhaust the window largely on files with nothing to do with the task at hand.

Tracing through wrapper modules is a specific instance of that shape. When a function is defined in one module, re exported through a wrapper or a barrel file such as index dot ts, a naive Grep for the original name misses every consumer who imports the wrapper name, so the correct trace is to Grep for the definition to find the defining file, Read the defining file to identify exported and re exported names, Grep for each of those names across the codebase, and if a barrel file is involved, Grep for the barrel module's import path to include consumers that never mention the function directly. That layered trace is what the exam contrasts with Glob first or Bash for both steps when built ins would suffice, and with bulk Read before any selection.

The deprecation scenario brings these choices together into the canonical examined sequence. To find every file that calls a deprecated function and every test that covers those files, the correct order is Grep for the function name to locate callers, including tests that import it directly because call content search surfaces them, then Glob for the sibling test of each caller file, such as star star slash OrderProcessor dot test dot star for OrderProcessor dot ts, to capture tests that cover the function transitively through the source module without mentioning it by name, then a further Grep for any wrapper or alias name under which the caller exposes the function, catching remaining tests that covered it through that alias. That Grep then Glob then Grep again pattern, content for direct references, path for adjacent tests, content for indirect coverage, is a structured trace that the exam contrasts with Glob first, Bash for both steps when built ins would suffice, and bulk Read before any selection.

Grep versus Glob by evidence shape

Grep accepts a pattern and an optional path scope and emits matches with file path, line number, and line content, which is why search plus Read is sufficient to reconstruct the call sites for the deprecation scenario without an intermediate Bash pipeline. Glob accepts a pattern such as star star slash star dot test dot tsx or star star slash config dot star scoped to the working tree and emits matching paths without reading contents. The evidence shapes are therefore complementary. Grep tells you where a string occurs inside files, Glob tells you which files exist by naming convention, and the question wording itself tells you which you need, inside versus named.

That complementarity explains the two most common misfires. Using Glob to find callers searches path names for a function name that lives inside files and returns nothing, because the name is not in the path. Using Grep to find files by extension searches content for the literal substring test rather than matching the path pattern star star slash star dot test dot tsx, which is technically possible yet imprecise and slower compared with Glob which matches the extension directly without opening contents.

Edit with widened anchor versus Read plus Write

Edit accepts old_string and new_string plus an optional replace_all and returns success or a structured non unique match error naming the count of locations, which the caller handles by supplying a longer surrounding anchor that includes unique neighbouring lines, comments, or function signatures, and Write accepts a full path and content payload and replaces or creates the file, which is why its token cost scales with file size on every path. Read accepts a file path and an optional range and returns the requested window with no evaluation of contents beyond text delivery, requiring the caller to supply surrounding context when Edit needs a wider anchor.

The cost ordering is therefore attempt Edit with the shortest plausible unique anchor, on non unique failure widen until unique or set replace_all true where a global change was intended, and only then escalate to Read plus Write. The widened anchor returned success in the worked trace with only a few extra lines, while the fallback would have consumed the entire file length in tokens for what remained a single line edit. That ordering is what the exam marks as the expected workflow rather than Read plus Write as the default.

Incremental discovery as budget control

The correct discovery shape is Grep first for entry points such as the function name, class name, or error string that anchors the investigation to learn which files are relevant, then Read those specific files to follow imports and trace flows, then Grep again for any wrapper or re export names to find indirect consumers, and only Read what each prior discovery step justified. Each Read is therefore justified by a prior hit, and context spend is proportional to relevance rather than to repository size.

The opposite shape, loading every file into context before knowing what is relevant, is the highest cost discovery failure in this domain. A two hundred file upfront read is primarily a budget burn that the exam explicitly warns against, because most files have nothing to do with the task at hand and their inclusion crowds out the synthesis and validation budget needed later for correct integration.

Wrapper tracing and the canonical deprecation sequence

When a function is defined in one module and re exported through a wrapper or a barrel file such as index dot ts, a naive Grep for the original name misses every consumer who imports the wrapper name. The correct trace is to Grep for the definition to find the defining file, Read the defining file to identify exported and re exported names including the wrapper, Grep for each of those names across the codebase, and if a barrel is involved Grep for the barrel module's import path to include consumers that never mention the function directly. That reconstruction is necessary because no single Grep sees the full consumer set without the intermediate Read that reveals what was wrapped.

The deprecation scenario assembles the whole chain into the canonical order the exam expects. Grep for the deprecated function name to locate callers, including tests that imported it directly. Glob for the sibling test of each caller file such as star star slash OrderProcessor dot test dot star for OrderProcessor dot ts to capture transitive coverage. Grep for any wrapper or alias name to catch remaining tests that covered the function through that alias. That Grep then Glob then Grep again content for direct, path for adjacent, content for indirect, is the structured trace that beats Glob first, Bash for both steps when built ins would suffice, and bulk Read before any selection.

Mechanism and API surface

Grep for content
Searches inside files for patterns such as function names or error strings, emitting file path, line number, and line content without path matching, and is the only choice for finding callers by name.
Glob for path
Matches file names by pattern such as star star slash star dot test dot tsx or star star slash config dot star, emitting matching paths without reading contents, and is the purpose built choice for test suffix or extension discovery.
Edit via unique anchor
Accepts old_string and new_string with exact text matching and optional replace_all. On non unique match the tool fails by design with count rather than guessing, and the correct recovery is to widen the anchor with surrounding signature or comments until unique.
Read plus Write as fallback
Read returns a requested window, Write replaces or creates the file with full content. Cost scales with file size on every use, so this path is the documented last resort after widened anchor and replace_all have been tried.
Incremental discovery ledger
Grep for entry points, Read only the hit files to follow imports, Grep for wrapper and alias names, Read only what that step justifies. No bulk upfront reads, with each Read justified by a prior hit.
Wrapper and barrel tracing
After finding the defining file via Grep and reading it for exported and re exported names, Grep for each name plus the barrel import path, catching consumers that never mention the deprecated function directly.
Deprecation trace that finds direct callers, sibling tests, and one wrapper covered test
A production walkthrough with the reasoning chain made explicit.

A product codebase has five files that call a deprecated helper processLegacyOrder directly, six sibling test files for those callers, and one wrapper module applyLegacyOrder in OrderProcessor dot ts that calls the deprecated helper internally and is itself covered by one extra test file that does not import the helper by name. No single search sees the whole set without a layered trace.

The sequence starts with Grep for the string processLegacyOrder across the repository. The response returns five caller files including two tests that imported the helper directly to assert backward compatibility, with line numbers such as src slash OrderProcessor dot ts colon 42 showing the exact call site and surrounding import context. Glob is then issued with star star slash star dot test dot tsx and a filter by caller base name, retrieving six candidate sibling test paths including OrderProcessor dot test dot tsx and RefundHandler dot test dot tsx for the four callers whose test files are named by convention. A naive Bash script that combined find and grep in one pass would have surfaced a similar set, but the exam expects the Grep then Glob shape, and the Bash path also hides whether the built in constraints around unique Edit anchors and incremental discovery have been observed.

The trace is not yet complete. Reading OrderProcessor dot ts reveals the wrapper export applyLegacyOrder that re exports the deprecated behaviour behind a new name. A second Grep for applyLegacyOrder retrieves the final test file that exercises the deprecated function transitively through the wrapper. At this point incremental discovery is satisfied. Six source callers plus seven tests covering direct, sibling, and indirect paths are known, three incorrect hypotheses have been pruned, Grep did not need to be used for path matching, and Glob did not need to be abused for content search, and only the files justified by prior hits were Read, preserving context budget.

Modification follows the same budget discipline. In OrderProcessor dot ts the replacement of processLegacyOrder with processOrder plus validate true is attempted via Edit with a minimal anchor processLegacyOrder orderId. The anchor occurs three times in the file, so Edit returns a non unique match error naming the count rather than guessing. The tuple is retried with old_string expanded to include the surrounding function signature function shipOrder orderId string return processLegacyOrder orderId and adjacent comment as a unique anchor, at which point Edit succeeds at the intended line with no change at the other two, and the test is rerun. In a separate file where every occurrence truly needed the same change, replace_all true would have applied the substitution at all three in one turn, a cheaper path than reading the full file and rewriting it.

Distinctions that decide answers

ThisNot thisHow to tell them apart
GrepGlobGrep searches what is inside files. Glob matches file names by path pattern. The question wording tells you which you need, inside versus named star star slash star dot test dot tsx.
Edit with unique anchorRead plus Write for a one line fixEdit touches exactly the identified string with minimal context. Read plus Write replaces the whole file and is a last resort because it costs far more tokens.
Widen anchor with surrounding context or replace_all trueJump straight to Read plus Write on non unique matchThe widened anchor or replace_all keeps the fix on Edit at nearly zero extra cost. Jumping to Read plus Write escalates immediately to the heavyweight fallback.
Incremental Grep then Read then GrepRead all files upfrontIncremental traversal spends tokens only on files that prior Grep hits justified. Bulk reading upfront is the most expensive discovery failure in the built ins.
Bash find plus xargs grep as combined stepGrep for callers then Glob for sibling testsBash can surface a similar result set, but the exam's expected trace separates concerns by tool purpose and preserves the Grep then Glob then Grep shape for wrapper tracing.

Traps

Using Glob to find function callers

The tempting answer. Run Glob with a pattern such as star star slash star processLegacyOrder star because Glob accepts patterns that look like names.

Why it fails. Glob can only match star star slash star processLegacyOrder star against path names, not inside OrderProcessor dot ts where the call lives. Content search is always Grep and Glob returns nothing for this task.

What is correct. Use Grep with the literal function name and an appropriate path scope to retrieve call sites with file and line information.

Using Grep to find files by extension or naming convention

The tempting answer. Search file contents for the literal test substring to find star star slash star dot test dot tsx files because Grep will technically surface the substring.

Why it fails. Grep surfaces test as a content hit not a path match, which is slower and less precise, while Glob is purpose built for extension and directory matching and matches the suffix directly without opening contents.

What is correct. Use Glob with star star slash star dot test dot tsx or star star slash config dot star for path based discovery by suffix.

Reading all source files upfront before discovery

The tempting answer. Load every file into context before any search because reading feels like diligence and avoids missing a hidden consumer.

Why it fails. A two hundred file upfront read is primarily a context budget burn that crowds out synthesis and validation, where incremental Grep for entry points then targeted Read for imports is the tested pattern that spends proportionally to relevance.

What is correct. Grep first for entry points, Read only the hit files, then Grep for wrapper names and Read only what that step justifies.

Defaulting to Read plus Write for every modification

The tempting answer. Use Read plus Write for every file change because that path never raises a non unique anchor error.

Why it fails. It spends a file's worth of tokens on every line change. The exam marks the Edit first, widen then Write last ordering as the expected workflow, with Write as a last resort.

What is correct. Attempt Edit with the shortest plausible unique anchor, widen until unique or set replace_all where a global change was intended, and only then escalate to Read plus Write.

Jumping from Edit non unique failure straight to Read plus Write

The tempting answer. Treat the non unique match error as proof that Edit cannot handle the file and escalate immediately to the heavyweight fallback.

Why it fails. The widened anchor path succeeded in the worked trace with only a few extra lines of surrounding signature and comment, while the fallback costs the entire file on every use, so escalation skips the cheaper correct recovery.

What is correct. Supply surrounding context that makes the anchor unique or select replace_all true for the global case, keeping the fix on Edit before considering Read plus Write.

Going deeper than the task statement
Adjacent material that shows up in harder scenario questions.
Four to five tool ideal keeps each tool crisp even where Bash could substitute

Tool definition and orchestration lessons place Grep and Glob inside the four to five ideal where each tool should be a precise entry point rather than a baggy universal.

Tool Definition Schemas
Context budget control for discovery versus synthesis

Context engineering lessons pair Grep to locate entry points, Read to follow imports, and Grep again for wrapper names as the minimal sequence that preserves headroom for synthesis and validation.

Context Engineering for Loop Engineers
Built ins versus MCP transport choices for capability placement

Workflow pattern notes compare host managed Claude Code built ins with MCP delivered tools that require separate process or HTTP transport, so a candidate can state when a built in suffices and when an MCP server must carry the capability.

MCP Transports
Build it
Run the canonical Grep then Glob then Grep trace and keep edits on Edit
  1. In a repository with at least ten TypeScript files and one deprecated export in a barrel, run Grep for processLegacyOrder and capture file, line, and content for every content hit, confirming that Glob against the same query would have produced no hits.
  2. For each Grep hit file, derive the sibling test name and run Glob for star star slash base dot test dot star, comparing expected sibling paths against what a Grep for test substring would have returned, to confirm path matching versus content matching.
  3. Identify any caller that re exports or wraps the deprecated symbol, and for each wrapper name run Grep across the repository to retrieve test files covering the deprecated behaviour transitively through the wrapper, confirming that the initial Grep alone missed those consumers.
  4. For three discovered caller files, read only the justified files sequentially, and document the incremental discovery ledger, Grep hit list, wrapper map, and distinct Read set, confirming no bulk upfront Read was needed.
  5. Prepare the edit by attempting Edit with the shortest unique anchor for a one line migration such as adding validate true to the replacement call, capturing the non unique match error where appropriate, then expanding old_string with surrounding signature context or enabling replace_all true and reattempting, logging whether the unique anchor or global change path kept the fix on Edit.
  6. Compare the token path where Edit with a widened anchor succeeded against a counterfactual Read plus Write for the same change, confirming that Edit preserved context budget and remained the documented default before Read plus Write as fallback.

Verify. The trace finds direct, sibling, and indirect coverage with only justified Reads, and the migration stays on Edit via a widened anchor rather than paying a file's worth of tokens to change a line.

Answer real questions on this task
8 exam-style questions written against the rules above. You get the reasoning and a note on every wrong option after each answer.
Tool Design and MCP Integration exam
11 questions, the same number this domain contributes to the real 60-question paper. Drawn fresh from a larger pool each attempt, so a retake is a different paper. You can reveal the answer to any question while taking the exam, which locks that question. Otherwise answers stay hidden until you submit.
Cross-cutting decision table
DecisionChoose thisOver thisWhy
How to fix misrouting between two similar toolsRewrite both descriptions to the five part template with formats, examples, and explicit boundariesAdding a routing classifier or few shot onlySelection is driven by description text in this regime, and a classifier is over engineered before sentence level clarity is restored.
How to handle an overloaded single toolSplit into narrow typed tools such as extract plus summarize plus verifyLengthening the umbrella descriptionOne entry point cannot be crisp for three distinct jobs, and selection stays vague until each job has its own contract.
How to branch on a tool failureRead isError plus errorCategory plus isRetryable, where only transient is retryable as isParsing the human message for should I retryThe envelope is the branchable signal. Message parsing is fragile and hides the distinction between validation correctable and business requires escalation.
How to treat an empty resultisError false with resultCount zero as success with absence, never retriedEmpty array on isError true as retriable failureValid emptiness reached the source and found nothing. Access failure did not reach the source. Only the envelope keeps them distinct.
How to keep selection reliable as tool count growsFour to five per agent with role scoping, enum consolidation for homogeneous overloadsAdding descriptions to an eighteen tool agent or splitting servers without mergingDecision complexity grows with the flat list size the model sees, so distribution is measured on the merged prompt not per server.
How to share MCP configuration across a teamProject dot mcp dot json at the root with dollar brace ENV_VAR expansion, community servers evaluated firstPersonal file for shared servers or custom build for Jira before evaluationShared file gives automatic inheritance on clone, expansion keeps history credential free, and community servers remove build cost for standard systems.
How to eliminate exploratory tool chainsExpose catalogues as read only Resources with declared mimeType before tool choiceIterative list_tables then describe_table chainsOne Resource fetch preserves turns and budget versus exploratory calls purely to get bearings.
How to find callers and sibling testsGrep for inside, Glob for names, Edit with unique anchor before Read plus Write, incremental discoveryGlob for callers, Grep for suffix, bulk Read upfront, Read plus Write as default editEach tool emits a different evidence shape and costs a different amount of budget, and only the canonical order preserves both completeness and budget.
Why wrong answers keep looking correct
Wording improvements feel disproportionate for a routing bug, so a system change sounds more engineered. A few precise sentences in the description change the model's pattern match directly, which is why the exam probes the low effort high leverage fix before a classifier or a server topology change. The engineered sounding answer adds infrastructure where clarity would have sufficed.
isRetryable true reads as recoverable in general, so any error that is fixable looks retryable. isRetryable has the narrowest possible meaning, will this exact request succeed if resent with no change. Validation feels recoverable yet is false because the same payload fails the same format check every time. Only transient is true because only the system availability changed.
Moving tools to a second server feels like reducing load because servers suggest separation. The client merges every server's tools into one flat list, so the model's option count is unchanged by server count. Only per agent allowlists and enum consolidation reduce the choice set the model actually reasons over.
Last five minutes
Rules
  • If two tools sound alike and the set is small, choose the answer that rewrites descriptions with formats, examples, and explicit do not use boundaries, not the classifier or the merge.
  • If a tool returns an error, read errorCategory first, retry only transient and rate-limit as is after backoff, correct the input for validation, and escalate for business and permission.
  • If a tool returns an empty result, treat isError false with resultCount zero as found nothing and do not retry. Only isError true with transient is retryable.
  • If an agent holds many tools, count then choose, two in five is a description fix, mixed jobs is role scoping at four to five, homogeneous variants is enum consolidation, server splits do not change the flat list.
  • If the task is MCP integration, project dot mcp dot json is shared and credential free via dollar brace expansion, personal file is not shared, community servers are evaluated before custom builds for standard systems.
Trigger phrases

Look for phrasing such as Retrieves customer information versus Retrieves order details, Operation failed with no category, empty array returned for both found nothing and could not fetch, eighteen tools on one agent, dot mcp dot json with a literal token, and Glob for callers or Grep for star star slash star dot test dot tsx. Each maps to exactly one rule above.

If you see X, think Y

If you see strict true think shape guarantee not business validity. If you see tool_choice auto where a pipeline step is mandatory think any or forced named is needed. If you see search_codebase described as Searches code think enriched description is needed before the MCP tool can win over Grep. If you see Read plus Write as the first edit choice think widen the Edit anchor or set replace_all true first.