CCAR-F Study Guide

Domain 2 — Tool Design & MCP Integration (18%)

A tool is an interface you are designing for a reader who has no documentation, no source code, and one shot at getting the arguments right. Everything in this domain follows from that.

2.1 The tool-use protocol

{
  "name": "process_refund",
  "description": "Issue a refund for a verified order. Only call after
                  verify_customer has returned verified: true.",
  "input_schema": {
    "type": "object",
    "properties": {
      "order_id":  { "type": "string", "description": "Order ID, e.g. ORD-48213" },
      "amount_cents": { "type": "integer", "description": "Refund amount in cents" },
      "reason": { "type": "string", "enum": ["damaged","late","duplicate_charge"] }
    },
    "required": ["order_id", "amount_cents", "reason"],
    "additionalProperties": false
  },
  "strict": true
}

The exchange: you send tools → Claude returns stop_reason: "tool_use" with a tool_use block carrying id, name, input → your code executes it → you send back a tool_result block whose tool_use_id matches, inside a user message. Failures go back through the same channel with "is_error": true and the message in content — not as an exception thrown away on your side.

ConceptDetail
Client toolsDefined by you; you execute them and return results
Server toolsRun on Anthropic's infrastructure (e.g. web search); results come back in the same response
tool_choice{"type":"auto"} (default) · {"type":"any"} (must use some tool) · {"type":"tool","name":…} (must use this one) · {"type":"none"}
Parallel tool useMultiple tool_use blocks in one response; return all the matching tool_result blocks together. Disable with disable_parallel_tool_use: true
Token overheadTools add a system-prompt block: roughly +286 tokens with auto/none, +406 with any/tool, on top of the schemas themselves

2.2 Designing tools the model can actually use

  • Describe when to call it, not just what it does. The description is the routing signal. "Look up an order" is weaker than "Look up an order by ID. Use when the customer references a specific order; use search_orders if you only have an email address."
  • Put units, formats and examples in parameter descriptions. amount_cents beats amount; "e.g. San Francisco, CA" beats "the location".
  • Constrain with the schema, not with prose. enum, required, additionalProperties: false and strict: true do work no sentence can.
  • Prefer few high-level tools over many micro-tools. Each tool costs context and adds a chance of mis-selection. Consolidate get_user/get_user_email/get_user_tier into one get_customer_profile.
  • Return results the model can reason over. Structured, trimmed, and labelled. Dumping a 50 KB raw API payload into a tool_result is a context bug.
  • Make errors actionable. A structured error with a code, a human message, and a retryability flag lets the agent choose between retrying, trying another tool, and escalating.

The error shape the exam wants

{
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "No order matches ORD-48213 for this customer.",
    "isRetryable": false,
    "suggestedAction": "Ask the customer to confirm the order ID, or call search_orders."
  }
}

isRetryable is the field to remember. Blanket retry-with-backoff on every failure is an anti-pattern: it burns latency and budget retrying a 404 that will never succeed, while a transient 529 gets the same treatment as a permanent validation error.

2.3 MCP: the architecture

Model Context Protocol is a client–server protocol over JSON-RPC 2.0. An MCP host (Claude Code, Claude Desktop, your SDK app) creates one MCP client per MCP server, and each client holds a dedicated connection.

Server primitivesTools (actions) · Resources (context data) · Prompts (reusable templates)
Client primitivesSampling (server asks the host's LLM) · Elicitation (server asks the user) · Logging
Transportsstdio (local process) · Streamable HTTP (remote, +SSE)
Lifecycleinitialize → capability negotiation → notifications/initialized
Discovery / calltools/list, resources/list, prompts/list; then tools/call
Change notificationsnotifications/tools/list_changed, sent only if the server declared listChanged: true

Choose stdio when the server runs beside the client on the same machine and serves one client — lowest overhead, no network. Choose Streamable HTTP for a remote server serving many clients, with standard HTTP auth (OAuth preferred over static bearer tokens).

2.4 Configuring MCP in Claude Code

ScopeStored inShared with the team?
local (default)~/.claude.json, this project onlyNo
project.mcp.json at the project rootYes — commit it
user~/.claude.json, all your projectsNo
{
  "mcpServers": {
    "orders-db": {
      "type": "http",
      "url": "https://mcp.internal.example.com/mcp",
      "headers": { "Authorization": "Bearer ${ORDERS_TOKEN}" },
      "timeout": 600000
    },
    "local-tools": {
      "type": "stdio",
      "command": "python",
      "args": ["server.py"],
      "env": { "DB_URL": "${DATABASE_URL:-postgres://localhost/dev}" }
    }
  }
}

Environment expansion supports ${VAR} and ${VAR:-default}, which is how a shared .mcp.json stays committable without secrets in it. For rotating credentials — Kerberos tickets, short-lived tokens — use headersHelper, a script that prints a JSON object of headers.

Tool naming and permissions

MCP tools are addressed as mcp__<server>__<tool>. That naming is what makes permission rules and disallowedTools patterns work:

mcp__orders-db__query          one tool
mcp__orders-db__*              every tool on that server
mcp__*                         every MCP tool from any server

Precedence when the same server name is defined in several places: local → project → user → plugin-provided → claude.ai connectors → managed (organisation) servers.

Reliability detail — Startup timeout is governed by MCP_TIMEOUT (30 s default); per-server call timeouts by the timeout key; output size by MAX_MCP_OUTPUT_TOKENS. In a CI run, a server that fails validation is skipped silently — the run still exits 0. To fail the build, check mcp_server_errors in the system/init event from --output-format stream-json.

← Previous: Domain 1 — Agentic Architecture & Orchestration  |  Next: Domain 3 — Claude Code Configuration & Workflows →

Architect CCAR-F Real Exam Questions

Ready to Pass Your CCAR-F Certification?

Practice with authentic exam questions, verified explanations, and timed test simulation to guarantee your success.

Starting from $49.00
Take Practice Exam →