LIVE
Sparks Fly: NVIDIA Accelerates Local AI at IFA 202603/09/26 · NVIDIA|Introducing WeatherNext 3, our most advanced and accurate global weather AI model03/09/26 · Google|Claude outage – Resolved03/09/26 · Anthropic|NeoMME: an efficient Multimodal-native and Multilingual Encoder03/09/26 · Hugging Face|‘NBA 2K27’ With NVIDIA DLSS 5 Leads 28 New Games Coming to GeForce NOW03/09/26 · NVIDIA|NVIDIA to Acquire Hugging Face03/09/26 · NVIDIA|Training a coding model to paint watercolours with TRL and OpenEnv03/09/26 · Hugging Face|Fine-tuning a 350M Model for Better Structured Outputs in 100 GRPO Steps03/09/26 · Hugging Face|Give Your Coding Agents a Memory You Own03/09/26 · Hugging Face|Muse Spark 1.302/09/26|GRADSOLVE: fast exact gradients for ODE ensembles on GPUs02/09/26 · NVIDIA|Proactive cyber defense for governments and enterprises02/09/26 · Google|Sparks Fly: NVIDIA Accelerates Local AI at IFA 202603/09/26 · NVIDIA|Introducing WeatherNext 3, our most advanced and accurate global weather AI model03/09/26 · Google|Claude outage – Resolved03/09/26 · Anthropic|NeoMME: an efficient Multimodal-native and Multilingual Encoder03/09/26 · Hugging Face|‘NBA 2K27’ With NVIDIA DLSS 5 Leads 28 New Games Coming to GeForce NOW03/09/26 · NVIDIA|NVIDIA to Acquire Hugging Face03/09/26 · NVIDIA|Training a coding model to paint watercolours with TRL and OpenEnv03/09/26 · Hugging Face|Fine-tuning a 350M Model for Better Structured Outputs in 100 GRPO Steps03/09/26 · Hugging Face|Give Your Coding Agents a Memory You Own03/09/26 · Hugging Face|Muse Spark 1.302/09/26|GRADSOLVE: fast exact gradients for ODE ensembles on GPUs02/09/26 · NVIDIA|Proactive cyber defense for governments and enterprises02/09/26 · Google|
AdvancedNew🧰

CCA-F Domain 2 — Tool Design & MCP Integration (18%): the complete lesson

The tools domain: how an agent picks the right tool, why it gets it wrong, how a tool should fail, how many tools to give whom, tool_choice, MCP server configuration and Claude Code's built-in tools. Diagrams, traps, night-before checklist and corrected scenario questions.

32 min readPublished September 4, 2026 · today

Domain 2 is worth 18% — roughly 11 questions out of 60. It's shorter than Domain 1 and much more factual: you're rarely asked to arbitrate an architecture; you're asked whether you know why an agent picks the wrong tool, how a tool should signal failure, how many tools an agent should see, and where an MCP server gets configured. Candidates who lose points here almost always lose them for the same reason: they answer "add examples" or "add a routing layer" where the exam expects "fix the tool description".

This lesson follows the 5 task statements of the official exam guide v1.0 (July 2026). The exam scenarios that lean on this domain are the Customer Support Resolution Agent (scenario 1, tools get_customer, lookup_order, process_refund, escalate_to_human), the Multi-Agent Research System (scenario 3) and Developer Productivity (scenario 4, built-in tools + MCP). Keep these three frames in mind: the questions are anchored there.

Where this lesson sits. Second of the five domain-by-domain lessons of our complete CCA-F guide, after Domain 1 — Agentic Architecture. Verified on 4 September 2026 against the official exam guide v1.0. Prerequisites: the agentic loop and hub-and-spoke from Domain 1.

The domain map

The five task statements read like a tool's lifecycle: how it's described (2.1), how it fails (2.2), who gets it and how you force its use (2.3), where it's configured when it comes from an MCP server (2.4), and the special case of Claude Code's built-in tools (2.5).

The 5 task statements of Domain 2: a tool's lifecycle
2.1 Describe description = selection mechanism formats · examples · boundaries 2.2 Fail structured error isError · category isRetryable · empty ≠ error 2.3 Distribute 4-5 tools per role tool_choice auto · any · forced 2.4 Configure .mcp.json (project) ~/.claude.json (personal) ${VAR} · resources 2.5 Built-in Grep · Glob Read · Write Edit · Bash The reflex that runs through the whole domain When the agent picks the wrong tool → fix the DESCRIPTION, don't add a layer. When the agent mishandles a failure → structure the ERROR, don't retry blindly. When the agent has too many tools → RESTRICT by role, don't lengthen the prompt.
Questions 2.1 and 2.2 test interface quality (description, errors). 2.3 tests distribution and control. 2.4 and 2.5 are the most factual: MCP configuration and built-in tool selection.

2.1 — Describing a tool: the description is the selection mechanism

This is question 2 of the official guide, and the most emblematic of the domain. The agent calls get_customer when the user asks "check my order #12345" instead of lookup_order. Both tools have minimal descriptions ("Retrieves customer information" / "Retrieves order details") and accept similar identifier formats. What do you do first?

Minimal description vs guiding description
✗ Minimal — random selection get_customer "Retrieves customer information" lookup_order "Retrieves order details" "check my order #12345" → get_customer? lookup_order? coin flip No input format · no example No boundary between the two No documented edge case ✓ Guiding — reliable selection lookup_order What: status, items, shipping of ONE order Input: order_id "#12345" or "ORD-12345" E.g.: "where's my order", "parcel 12345" Boundary: does NOT return the customer profile → for the profile, use get_customer get_customer What: profile + identity check (email/phone) Boundary: no order details → lookup_order "check my order #12345" → lookup_order, no hesitation
The model only has the description to choose with. If two descriptions look alike, selection becomes random. A good description says: what the tool does, what it expects as input (format, examples), what it returns, its edge cases, and when NOT to use it in favor of a neighboring tool.

What you need to know

The description is the selection channel. The model has neither your internal docs nor your intent: it has the name, the description and the input schema. When descriptions are minimal, it can't distinguish two similar tools, and the misselection rate becomes structural.

What a good description contains. The accepted input formats (with examples: #12345, ORD-12345), example user queries that should land on this tool, the edge cases (what happens if the identifier is unknown, if several results match), and the boundaries: when to use this tool rather than its neighbor, and vice versa.

Overlap creates misrouting. analyze_content and analyze_document with near-identical descriptions: the agent alternates. Two expected fixes: rename to make scope explicit (analyze_contentextract_web_results with a web-oriented description), and split a generic tool into purpose-specific tools with defined contracts (analyze_documentextract_data_points, summarize_content, verify_claim_against_source), each with defined inputs and outputs.

The system prompt can sabotage the description. A keyword-sensitive instruction ("for any question about customer data, use get_customer") creates an unintended association: "my order data" goes to get_customer. When the description is good and routing is still wrong, re-read the system prompt for these shortcuts.

# Before: two interchangeable descriptions
TOOLS_BAD = [
    {"name": "get_customer", "description": "Retrieves customer information",
     "input_schema": {"type": "object", "properties": {"id": {"type": "string"}}}},
    {"name": "lookup_order", "description": "Retrieves order details",
     "input_schema": {"type": "object", "properties": {"id": {"type": "string"}}}},
]

# After: formats, examples, edge cases, boundaries — and meaningful parameter names
TOOLS_GOOD = [
    {
        "name": "get_customer",
        "description": (
            "Retrieves a customer's PROFILE and verifies their identity. "
            "Input: email (jane@ex.com) or phone (+33612345678) or customer_id (CUS-8841). "
            "Example queries: 'is this my account?', 'update my address'. "
            "Returns: verified customer_id, name, address, account status. "
            "Returns NO order details: for an order, use lookup_order. "
            "If several customers match, returns the list and asks for an extra identifier."
        ),
        "input_schema": {"type": "object",
                         "properties": {"identifier": {"type": "string",
                                        "description": "email, E.164 phone or customer_id CUS-xxxx"}},
                         "required": ["identifier"]},
    },
    {
        "name": "lookup_order",
        "description": (
            "Retrieves the status, items and shipping of ONE order. "
            "Input: order_id in the form '#12345' or 'ORD-12345' (prefix optional). "
            "Examples: 'where's my order', 'has parcel 12345 shipped?', 'order ORD-9910'. "
            "Returns: status, items, carrier, ETA, amount. "
            "Does NOT return the customer profile: to verify identity, use get_customer first. "
            "Unknown order_id → validation error (no retry)."
        ),
        "input_schema": {"type": "object",
                         "properties": {"order_id": {"type": "string",
                                        "description": "'#12345', '12345' or 'ORD-12345'"}},
                         "required": ["order_id"]},
    },
]
The 2.1 trap. Faced with a selection problem, the distractors are, in order: (A) "add 5-8 few-shot examples to the system prompt" — costs tokens and doesn't fix the cause; (C) "a keyword routing layer before each turn" — over-engineering that bypasses the model; (D) "merge into a single lookup_entity" — a valid architectural decision but disproportionate for a first step. The expected answer is always enrich the descriptions. The words "first step" in the prompt are the signal.
🏷️
The 2.1 reflex
Wrong tool selected → description (formats, examples, edge cases, boundaries). Overlap → rename or split. Correct description but still wrong routing → look for the keyword instruction in the system prompt.

2.2 — Failing cleanly: the structured error

A tool that fails by saying "Operation failed" condemns the agent to guessing: should it retry? change approach? escalate? explain to the customer? The MCP protocol provides an isError flag; the exam expects you to go well beyond it.

Four error categories, four expected reactions
transient timeout, service down, rate limit isRetryable: true → retry locally, with backoff validation invalid format, unknown id, missing field isRetryable: false (as is) → fix the input or ask the customer again business business rule violated: deadline passed, cap retriable: false + explanation → explain to customer customer-friendly message permission insufficient rights, restricted action isRetryable: false → escalate to an authorized human Special case: the legitimate EMPTY result "no order found" = success with no match, not an error → don't retry, don't escalate, inform
The category determines the agent's reaction. A transient error gets retried; a validation error gets corrected; a business error gets explained to the customer; a permission error gets escalated. A uniform response makes all four decisions impossible.

What you need to know

The isError flag. It's the MCP mechanism for signaling a tool failure to the agent, distinct from a protocol error. But a flag alone doesn't say what to do.

The four categories. Transient (timeout, unavailability): retryable. Validation (invalid input): not retryable as is, the input must be fixed. Business (rule violation: refund past deadline): not retryable, to be explained to the customer. Permission: not retryable, to be escalated.

Why uniform is an anti-pattern. "Operation failed" allows no recovery decision. The agent retries what can't succeed (waste, latency) or gives up on what would have succeeded on the second try.

The expected metadata. errorCategory (transient / validation / permission / business), isRetryable (boolean), and a readable description. For a business rule, a retriable: false accompanied by a customer-understandable explanation the agent can relay directly.

Local recovery, selective propagation. In a multi-agent system, a subagent handles its own transient errors (retry with backoff) and only escalates to the coordinator what it can't resolve — with partial results and what was attempted. Neither silent suppression (returning empty as success), nor raw propagation that kills the workflow.

Access failure vs empty result. A timeout is an access failure: it calls for a decision (retry, alternative). "No order matches" is a success with zero results: it triggers neither retry nor escalation, it gets reported to the customer. Confusing the two produces either useless retries or masked failures.

# MCP tool response: structured, categorized, actionable
def process_refund(order_id: str, amount_eur: float) -> dict:
    order = db.get_order(order_id)
    if order is None:                                    # invalid input → validation
        return {"isError": True, "errorCategory": "validation", "isRetryable": False,
                "message": f"Order {order_id} not found. Check the identifier."}
    if order.age_days > 30:                              # business rule → business
        return {"isError": True, "errorCategory": "business", "retriable": False,
                "message": "30-day refund window exceeded.",
                "customerMessage": "The 30-day window for a refund has passed; "
                                   "I can offer store credit or transfer you to an advisor."}
    if not ctx.user.can("refund"):                       # rights → permission
        return {"isError": True, "errorCategory": "permission", "isRetryable": False,
                "message": "Restricted action: escalate to an authorized agent."}
    try:
        return {"isError": False, "refund_id": payments.refund(order, amount_eur)}
    except payments.Timeout:                             # infra → transient
        return {"isError": True, "errorCategory": "transient", "isRetryable": True,
                "message": "Payment service unavailable, retry in a few seconds."}

# Legitimate empty result: a success, not an error
def search_orders(customer_id: str, since: str) -> dict:
    rows = db.orders(customer_id, since)
    return {"isError": False, "results": rows, "count": len(rows),
            "note": "0 results = no orders in the period, valid query" if not rows else None}
The 2.2 trap. Two recurring distractors. First: "implement automatic retry with backoff in the tool and return a generic status after exhaustion" — the local retry is good, the generic status is the problem (question 8 of the guide). Second: "catch the error and return an empty result marked success so as not to block the workflow" — that's silent suppression, the worst case. The expected answer always combines category + retryable + context (what was attempted, partial results, alternatives).

2.3 — Distributing tools and controlling choice

Who sees which tools, and can you force a call? This is where Domain 2 meets Domain 1 (specialized subagents) and Domain 4 (structured output via tool_choice).

Too many tools degrade selection; per-role scope restores it
✗ 18 tools for everyone Synthesis agent web_search · fetch_url · process_refund · … → synthesis runs web searches → fetch_url on arbitrary URLs decision complexity × 18, reliability collapses ✓ 4-5 tools per role + one scoped cross-role tool Web search web_search · load_document (validated URL, not fetch_url) Synthesis write_section · cite + verify_fact (scoped) 85% simple checks, no round-trip 15% complex Coord. least privilege · no cross-role except frequent need
At 18 tools, every agent decision is a choice among 18 descriptions, and a synthesis agent ends up running web searches it shouldn't. At 4-5 tools per role, selection is reliable. The frequent cross-role need (verify a fact) is handled with ONE scoped tool, not by opening the whole catalog.

What you need to know

Count degrades reliability. An agent with 18 tools chooses worse than with 4-5. It's not a context question but a decision complexity one.

Out of role = misuse. A synthesis agent with web search access ends up searching instead of synthesizing. An out-of-specialization tool is a tool that will be misused.

Per-role scope. Each subagent receives only the tools of its function. Dangerous generic tools are replaced by constrained versions: fetch_url (any URL) → load_document (validates that the URL belongs to the allowed corpus).

The scoped cross-role tool. This is question 9 of the guide: synthesis needs to verify facts; 85% are simple checks (dates, names, figures), 15% need investigation. Expected answer: give synthesis one verify_fact tool limited to simple checks, and keep routing through the coordinator for complex cases. Not "all search tools" (violates separation), not "batch verifications at the end" (blocking dependencies), not "speculatively pre-cache" (unpredictable).

tool_choice. Three modes. {"type": "auto"}: the model may call a tool or answer in text. {"type": "any"}: the model must call a tool, it picks which. {"type": "tool", "name": "extract_metadata"}: the model must call that tool. Typical use of forcing: guarantee that metadata extraction runs before enrichment steps, then handle the rest in later turns. Use of any: guarantee structured output when several extraction schemas exist and the document type is unknown.

# tool_choice: three regimes
client.messages.create(model=M, tools=TOOLS, tool_choice={"type": "auto"}, ...)   # tool OR text
client.messages.create(model=M, tools=TOOLS, tool_choice={"type": "any"}, ...)    # a tool, model's pick
client.messages.create(model=M, tools=TOOLS,
                       tool_choice={"type": "tool", "name": "extract_metadata"}, ...)  # THIS tool

# Forced sequence: metadata first, enrichment next (separate turns)
meta = call(tool_choice={"type": "tool", "name": "extract_metadata"}, doc=doc)
enriched = call(tool_choice={"type": "any"}, doc=doc, context=meta)   # free enrichment among tools

# Scoped cross-role tool for the synthesis agent (guide question 9)
VERIFY_FACT = {
    "name": "verify_fact",
    "description": ("Verifies ONE simple fact (date, name, figure) against already-collected sources. "
                    "Does NOT perform web search. For deeper investigation, "
                    "return the question to the coordinator."),
    "input_schema": {"type": "object", "properties": {"claim": {"type": "string"}},
                     "required": ["claim"]},
}

tool_choice: which one, when?

 auto / anyforced {type: tool, name}
autoTool or free text — normal conversation
anyA tool is mandatory, the model picks — structured output with several possible schemas
Guarantee ONE specific toolNot guaranteedYes — extraction imposed before enrichment
Text answer possibleauto: yes · any: noNo
Next stepsSame turnLater turns, with the forced result in context
Exam signal"must return structured", "unknown document type""ensure X runs first"
The 2.3 trap. "Give the synthesis agent access to all search tools to remove round-trips": it fixes latency and breaks role separation — never accepted. Another trap: confusing any with forced. any guarantees a tool call, not which. If the prompt says "ensure extract_metadata is called first", it's the forced mode.
🎛️
The 2.3 reflex
4-5 tools per role. Dangerous generic → constrained version. Frequent cross-role need → one scoped tool, complex → via the coordinator. auto = text possible, any = a tool mandatory, forced = this specific tool.

2.4 — Integrating MCP servers into Claude Code and agents

A factual section: where each thing is configured, how secrets are handled, what the agent sees, and when to write a server yourself.

MCP configuration scopes and tool discovery
Project · .mcp.json (repo root) • Version-controlled → shared by the whole team • Common tooling: Jira, GitHub, internal DB • Secrets: "${GITHUB_TOKEN}" — env expansion • Never a plain-text token in the file A newcomer clones → they have the servers User · ~/.claude.json • Personal → not shared, outside the repo • Experimental servers, personal tools • Available across all the user's projects • A team tool put here = invisible to others Classic diagnostic error (cf. Domain 3) Connection → discovery all servers, all tools, simultaneously Agent: Jira tools + GitHub tools + personal tools + built-in — one catalog
The .mcp.json file at the project root is version-controlled and shared by the team; secrets go through environment variable expansion, never in plain text. The ~/.claude.json file is personal: experimental servers, not shared. At connection, tools from ALL configured servers are discovered and available simultaneously.

What you need to know

Two scopes. .mcp.json at the project root: shared via version control, for team tooling. ~/.claude.json: user level, for personal or experimental servers. A team server placed at user level isn't seen by teammates — a classic diagnostic question motif.

Secrets by expansion. In .mcp.json, a token is written "${GITHUB_TOKEN}" and resolved from the environment. The file remains committable without exposing a secret.

Simultaneous discovery. At connection, tools from all configured servers are discovered and available together. There's no "active server" to switch.

Tools vs resources. An MCP tool executes an action (create a ticket, run a query). An MCP resource exposes browsable content: a ticket catalog, a documentation hierarchy, a database schema. Exposing a catalog as a resource spares the agent a series of exploratory tool calls to discover what exists.

The description that loses to Grep. If your MCP server exposes a semantic codebase search tool but its description says "searches code", the agent will prefer the built-in Grep, which it knows. You must describe capabilities and outputs in detail ("semantic search by intent, returns relevant functions with signature and callers, where Grep only does textual patterns").

Community vs custom. For a standard integration (Jira, GitHub, Slack), you take an existing community server. You only write a custom server for a team-specific workflow no server covers.

// .mcp.json — at the project root, version-controlled
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
    },
    "jira": {
      "command": "npx",
      "args": ["-y", "mcp-server-jira"],
      "env": { "JIRA_BASE_URL": "${JIRA_URL}", "JIRA_API_TOKEN": "${JIRA_TOKEN}" }
    }
  }
}
# Custom MCP server (sketch): a TOOL to act, a RESOURCE to expose a catalog
@server.tool(
    name="search_codebase_semantic",
    description=("SEMANTIC search by intent across the codebase (e.g. 'where is the shipping "
                 "address validated'). Returns relevant functions with file, signature, callers "
                 "and score. Prefer over Grep when the exact symbol name is unknown; "
                 "Grep remains the right choice for a precise textual pattern."),
)
def search_codebase_semantic(query: str, top_k: int = 5) -> dict: ...

@server.resource(uri="issues://open", name="Open issues",
                 description="Catalog of open issues: id, title, priority, assignee. "
                             "Read this resource before any get_issue call.")
def open_issues_catalog() -> str: ...
The 2.4 trap. "The agent doesn't use our MCP search tool even though it's more powerful than Grep: we should disable Grep." No — the answer is to improve the MCP tool's description. Another trap: "write a custom MCP server for Jira" when a community server exists. And the classic: a GitHub token in plain text in .mcp.json "to keep it simple". Any option that commits a secret is wrong.

2.5 — Built-in tools: Read, Write, Edit, Bash, Grep, Glob

Scenario 4 (Developer Productivity) relies on these six tools. Questions test picking the right tool for a given intent, and the codebase exploration strategy.

Which built-in for which intent?
Grep — content "who calls processRefund?" "where is the message 'Invalid token'?" "which files import stripe?" pattern inside file text Glob — paths "all tests: **/*.test.tsx" "migrations: db/migrations/*.sql" "configs: **/config.*.json" pattern on name / extension Bash — execution npm test · pytest · git diff build, lint, scripts anything that isn't read/write/search restrict in allowed-tools if needed Modifying a file Edit replaces a UNIQUE text anchor anchor found exactly once? yes Edit applied no (0 or several) Fallback: Read (whole file) + Write reliable modification without relying on uniqueness Exploring a codebase: Grep (entry points) → Read (follow imports) — never read everything at once
Grep searches INSIDE files (a function name, an error message, an import). Glob searches FOR files by path pattern. Edit modifies by unique text match; if the anchor isn't unique, you read the whole file (Read) and rewrite it (Write). Bash for everything else: tests, build, git.

What you need to know

Grep vs Glob. Grep searches a pattern in file contents: all callers of a function, an error message, an import statement. Glob searches paths by name pattern: **/*.test.tsx, db/migrations/*.sql. "Find all test files" = Glob. "Find where processRefund is called" = Grep.

Read / Write / Edit. Read loads a whole file, Write writes it whole, Edit makes a targeted modification by unique text match. When Edit fails because the anchor appears zero or several times, the reliable fallback is Read of the whole file then Write — not attempts at ever-longer anchors.

Incremental exploration. To understand an unfamiliar codebase, you start with Grep to find entry points, then Read to follow imports and trace flows. Reading every file upfront saturates context (a theme picked up in Domain 5).

Tracing through wrapper modules. To follow usage of a function re-exported by several modules: first identify all exported names (the original name and its aliases), then search for each across the codebase. Searching only the original name misses uses via alias.

The 2.5 trap. "Use Glob to find all callers of a function" (Glob doesn't see content) or "use Grep to list test files" (works by accident if the word "test" is in the file, but Glob is the tool). And on Edit: an option proposing to "lengthen the anchor until it's unique" is a hack; the expected answer is Read + Write.

Cross-cutting traps of Domain 2

Reading grid for a Domain 2 question
Symptom in the scenario Expected answer Distractors wrong tool called, "minimal" descriptions Enrich the descriptions formats, examples, boundaries "few-shot", "router", "merge the tools" useless retries or masked failures Structured errors category + isRetryable + context "retry + generic status", "return empty = success" agent using a tool outside its role Restrict by role + scoped tool if frequent need "give all tools to reduce latency" a teammate doesn't have the MCP server Project .mcp.json with ${VAR} for secrets "plain-text token", "custom server for Jira" Golden rule: fix the tool's INTERFACE before adding anything around it
Domain 2 has a signature: the right answer touches the tool's interface (description, error, scope), not a layer added around it. Identify the symptom, trace back to the interface.
  1. Interface before layer. Description, error, scope: three properties of the tool itself. Any option that adds a component (router, classifier, cache) without fixing the interface is a distractor.
  2. "First step" = the cheapest move. When the prompt asks for a first step, the answer is the one that addresses the root cause with the least effort — almost always a description or a configuration.
  3. Least privilege always wins. Between an option that opens access and one that restricts it (with a scoped tool for the real need), it's the second.
  4. Secrets don't get committed. Whatever the convenience, an option that writes a plain-text token is wrong.

Night-before checklist

Re-read the night before the exam — Domain 2
- The description is the selection mechanism: input formats, example queries, edge cases, "X rather than Y" boundaries. - Overlap → rename (extract_web_results) or split (extract_data_points / summarize_content / verify_claim_against_source). - Wrong routing despite a good description → look for the keyword instruction in the system prompt. - Tool error = isError + errorCategory (transient / validation / business / permission) + isRetryable + readable message. - Business rule → retriable: false + relayable customer-friendly message. - Subagent: local recovery of transients, propagation only of the unresolved, with partials + attempts. - Access failure (timeout) ≠ legitimate empty result (success with no match). - 4-5 tools per role, not 18; out of role = misuse. - Dangerous generic → constrained version (fetch_urlload_document). - Frequent cross-role need → one scoped tool (verify_fact); complex → via the coordinator. - tool_choice: auto (text possible), any (a tool mandatory), forced (this tool). - Forced for "X first", then later turns; any to guarantee structured output with unknown schema. - .mcp.json project root = team, version-controlled, ${VAR}; ~/.claude.json = personal. - All servers discovered at connection, available simultaneously. - Tool = action; resource = browsable catalog (reduces exploratory calls). - MCP tool ignored in favor of Grep → enrich its description. - Community for standard (Jira), custom for team-specific. - Grep = content; Glob = paths; Edit = unique anchor, otherwise Read + Write. - Explore: Grep (entries) → Read (imports); trace via wrappers: list exports then search each name.

Five original scenario questions, corrected

Questions written by nAIvigate in the spirit of the exam, reproducing no real items. Hide the corrections, answer, compare.

Question 1 — Research scenario. Your system has two tools, analyze_content ("Analyzes content and returns insights") and analyze_document ("Analyzes a document and returns insights"). Logs show the agent alternates between them at random for web pages and PDFs alike. Best first fix?

A. Add a rule to the system prompt: "web pages → analyze_content, PDFs → analyze_document". B. Rename analyze_content to extract_web_results with a web-page-centered description (input: URL, output: titles, excerpts, dates), and state in analyze_document that it handles provided files. C. Merge both into analyze_anything with automatic type detection. D. Add 6 few-shot selection examples.

📚Answer Q1

B. Description overlap → rename and differentiate. A adds a keyword rule that bypasses the selection mechanism. C is an architectural decision disproportionate for a first step. D costs tokens without addressing the cause.

Question 2 — Support scenario. process_refund returns "Refund failed" in every failure case. The agent retries three times on refunds refused for exceeding the deadline, then tells the customer "a technical error occurred". Which fix?

A. Limit retries to a single attempt. B. Return a structured error: errorCategory: "business", retriable: false, and a message explaining the exceeded deadline that the agent can relay. C. Add to the prompt: "if the refund fails, don't retry". D. Raise the raw exception to the coordinator.

📚Answer Q2

B. The uniform error prevents any recovery decision. A and C treat the symptom (the retry) without giving the agent the information to react correctly. D propagates without structuring.

Question 3 — Research scenario. The synthesis agent has 14 tools, including web_search and fetch_url. It's observed running searches instead of synthesizing, and it has fetched URLs outside the corpus. What do you do?

A. Remove all tools except writing and citation ones; add a scoped verify_fact for simple checks; replace fetch_url on the search side with load_document that validates the URL. B. Add to the synthesis prompt: "don't use web_search unless necessary". C. Increase context so the agent sees the 14 descriptions better. D. Route all verifications through the coordinator, no exceptions.

📚Answer Q3

A. Per-role scope + scoped cross-role tool + constrained version of the generic. B is probabilistic. C confuses context size with decision complexity. D ignores the frequent need and recreates the latency of question 9.

Question 4 — Productivity scenario. A developer configured the team's Jira MCP server in ~/.claude.json with their token in plain text. A new colleague clones the repo and has no Jira tools. Correct configuration?

A. Ask the colleague to copy the block into their ~/.claude.json. B. Move the configuration to .mcp.json at the project root, with "${JIRA_TOKEN}" resolved from each person's environment. C. Put .mcp.json at the root with the token in plain text, since the repo is private. D. Write a custom MCP server for Jira embedding the credentials.

📚Answer Q4

B. Team tooling → project scope, version-controlled, secrets by expansion. A doesn't scale. C commits a secret. D reinvents an existing community server and embeds credentials.

Question 5 — Productivity scenario. You want to change one return null; line in a 900-line file. Edit fails: the anchor appears 11 times. Reliable approach?

A. Lengthen the anchor to include the 3 preceding lines and retry. B. Use Grep to find the right occurrence, then Edit with the line number. C. Read the whole file, apply the change, Write the file. D. Use Bash with sed to replace the 7th occurrence.

📚Answer Q5

C. The documented fallback when Edit finds no unique anchor is Read + Write. A is a fragile hack. B: Edit works by text match, not line number. D is risky and outside the expected pattern.

Validation quiz

🧠 Quiz
Question 1 of 8

The agent confuses two tools with minimal descriptions. Expected first step?

📚Domain 2 glossary (expand)

Tool description — Text the model uses to pick a tool; must contain input formats, example queries, edge cases and boundaries with neighboring tools.

Boundary — Part of the description that says when NOT to use this tool and which one to use instead.

Functional overlap — Two tools with near-identical descriptions, a source of misrouting; fixed by renaming or splitting.

Keyword instruction — System prompt directive that associates a word with a tool and can override a good description.

isError — MCP flag signaling that a tool call failed, distinct from a protocol error.

errorCategory — Error metadata: transient, validation, business or permission; determines the agent's reaction.

isRetryable / retriable — Boolean indicating whether a new attempt has a chance of succeeding.

Transient error — Timeout, unavailability, rate limit: retryable with backoff.

Validation error — Invalid input (format, unknown identifier): fix the input before any new attempt.

Business error — Rule violation (deadline, cap): not retryable, to be explained to the customer.

Permission error — Insufficient rights: not retryable, to be escalated.

Legitimate empty result — Successful query with no match; not an error and triggers neither retry nor escalation.

Local recovery — Handling of transient errors by the subagent itself before any propagation.

Tool scope — Restricting each agent to only the tools of its role (4-5), to make selection reliable.

Scoped cross-role tool — Limited tool (e.g. verify_fact) given to an agent outside its main role for a frequent, simple need.

Constrained tool — Restricted version of a generic tool (load_document validating the URL instead of fetch_url).

tool_choice — Messages API parameter: auto (tool or text), any (a tool mandatory), forced ({"type":"tool","name":…}).

.mcp.json — Project-level MCP configuration, version-controlled, shared by the team, with secrets as ${VAR}.

~/.claude.json — User-level MCP configuration, personal, not shared.

Environment variable expansion${GITHUB_TOKEN} syntax resolved at runtime so a secret is never committed.

MCP resource — Browsable content exposed by a server (issue catalog, doc hierarchy, DB schema), as opposed to a tool that acts.

Community server — Existing MCP server for a standard integration (Jira, GitHub); preferred over a custom server.

Grep — Built-in tool for pattern search inside file contents.

Glob — Built-in tool for file search by path pattern (**/*.test.tsx).

Edit — Targeted modification by unique text match; Read + Write fallback if the anchor isn't unique.

Incremental exploration — Grep for entry points then Read to follow imports, instead of reading everything upfront.

Going further

Next is Domain 3 — Claude Code Configuration & Workflows (20%), which picks up project/user scope for CLAUDE.md, commands, skills and path-scoped rules. Structured errors and propagation return in Domain 5, and tool_choice in Domain 4 for structured output. To see real MCP tools described and scoped, our 40 Claude Code / MCP tools sheet and the agentic systems architecture course give context.

If you want to certify a whole team — or have clean MCP tool interfaces (descriptions, structured errors, scopes) designed for a really deployed system — that's what nAIvigate Studio does in a Sprint.

Tags
certificationclaudeccacca-fmcpagents-iaagentssdkclaude-codeformationpython
⚡ FICHE #005Skills & MCP: the fiche that maps the whole path2 MIN

Read next