CCDV-F Study Guide

Domain 5 — Tools and MCPs (10.6%)

10.6% of the exam, roughly 6 questions. Split between implementing tools well and building or consuming MCP servers.

5.1 The tool-use exchange

  1. You send tools with the request.
  2. Claude replies with stop_reason: "tool_use" and one or more tool_use blocks, each carrying id, name and input.
  3. Your code executes the tool. Nothing runs on Anthropic's side for a client tool.
  4. You send back a user message containing a tool_result block whose tool_use_id matches.

Failures travel the same channel: {"type": "tool_result", "tool_use_id": "...", "content": "...", "is_error": true}. Throwing an exception on your side and omitting the block breaks the exchange, because every tool_use requires a matching result. When Claude returns several tool_use blocks in one response, return all the results together in the next message; disable the behaviour with {"type": "auto", "disable_parallel_tool_use": true} if your backend cannot handle concurrency.

tool_choice options: auto (default), any (some tool must be called), {"type": "tool", "name": ...} (that one), none. Tools add roughly 286 tokens of system overhead with auto/none and 406 with any/tool, on top of the schemas themselves.

5.2 Designing a tool the model can use

  • The description says when to call it, not only what it does. This is the routing signal, and it is where most tool-selection failures originate.
  • Put units, formats and examples in parameter descriptions. amount_cents beats amount.
  • Constrain in the schema — enum, required, additionalProperties: false, strict: true — rather than in prose.
  • Prefer few high-level tools to many micro-tools. Each costs context and adds a chance of mis-selection.
  • Return results the model can reason over: structured, trimmed, labelled. A 50 KB raw payload in a tool_result is a context bug.
  • Make errors actionable, with a code, a human-readable message and a retryability flag:
{ "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "No order matches ORD-48213 for this customer.",
    "isRetryable": false,
    "suggestedAction": "Confirm the order ID, or call search_orders."
} }

isRetryable is the field to remember. Blanket retry-with-backoff spends latency and budget re-attempting a validation error that will fail identically every time.

5.3 MCP, and why it exists

Writing a tool integration binds it to one application. The Model Context Protocol standardises the interface so one server can serve any client. It is a JSON-RPC 2.0 protocol in which a host (Claude Code, Claude Desktop, your SDK app) creates one client per server.

Server primitivesTools (executable actions), Resources (context data), Prompts (reusable templates)
Client primitivesSampling (server asks the host's LLM), Elicitation (server asks the user), Logging
Transportsstdio for a local process serving one client; Streamable HTTP for a remote server serving many
Lifecycleinitialize → capability negotiation → notifications/initialized
Discovery and calltools/list, resources/list, prompts/list, then tools/call

Choose a tool when the model should be able to take an action; a resource when the client should be able to pull in context data; a prompt when you are packaging a reusable interaction template for the user to invoke.

5.4 Building a server

With the Python SDK the shape is small: the decorator registers the tool, the type hints become the input schema, and the docstring becomes the description the model reads.

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("orders")

@mcp.tool()
async def get_order(order_id: str) -> str:
    """Look up an order by its ID.

    Args:
        order_id: Order identifier, e.g. ORD-48213
    """
    ...

if __name__ == "__main__":
    mcp.run(transport="stdio")

The stdio trap — in a stdio server, never write to stdout. print() in Python and console.log() in Node write there by default and will corrupt the JSON-RPC stream, breaking the server in a way that looks like a connection fault. Log to stderr instead. This is exactly the kind of specific failure the exam likes.

5.5 Consuming MCP servers in Claude Code

Tools are addressed as mcp__<server>__<tool>, which is what makes permission rules and wildcard patterns work: mcp__server__* covers one server, mcp__* covers all of them. Scopes: local and user live in ~/.claude.json; project lives in a committed .mcp.json at the repo root, which is how a team shares a server. Use ${VAR} and ${VAR:-default} expansion so the committed file holds no secrets.

← Previous: Domain 4 — Prompt and Context Engineering  |  Next: Domain 6 — Security and Safety →

Developer CCDV-F Real Exam Questions

Ready to Pass Your CCDV-F Certification?

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

Starting from $69.00
Take Practice Exam →