CertSafari
    Anthropic Claude Certified Architect – Professional (CCAR-P)· Lessons

    Domain 3 · Lesson 18/38

    Choosing Between MCP, Direct Tool Use and Subagents

    Evaluate connection protocols and select the appropriate integration mechanism

    17 min read
    2.38% of exam
    9 sources
    Published 4 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Explain why where the code runs is the main thing that separates client tools, server tools, MCP servers and subagents
    • Pick the right MCP transport (stdio or Streamable HTTP) and the right place to attach a server (Claude Code CLI, Agent SDK, Messages API MCP connector)
    • Spot the limits of the MCP connector that force a different mechanism
    • Decide when a task belongs in a subagent instead of a tool or MCP server

    Key concept

    Execution locus — Every integration mechanism comes down to one question: who runs the code behind a capability, and what gets passed back to Claude. Your application, Anthropic's infrastructure, a separate MCP server process or service, or another agent's isolated loop each lead to a different mechanism.

    1.Direct tool use: the API and CLI path

    The exam guide names three integration mechanisms: MCP, API/CLI, and agent-to-agent. They are easiest to compare from the bottom up, and the bottom layer is plain tool use, also called function calling. With tool use, Claude picks a capability you have described and returns a structured request for it. Claude decides when to call a tool from the user's request and the tool's description. Then something has to execute the call. Who does that is the main distinction.

    Client tools run in your application. You pass a tool with an input_schema. Claude responds with stop_reason: "tool_use" and one or more tool_use blocks. Your code does the work and sends back a tool_result. This is the direct API route. When the capability is a function in your own codebase, or an internal API your service already calls, a client tool wraps it with nothing else in the way.

    Server tools such as web_search, web_fetch, code_execution and tool_search run on Anthropic's infrastructure. You see the results directly and write no handler code.

    In between are tools with Anthropic-defined schemas, such as bash and text_editor. Anthropic publishes the schema and trains Claude on it, but your application still executes each call. The bash tool is the CLI side of "API/CLI": it runs shell commands in a persistent session that keeps its state, so any command-line program on the host becomes reachable without a dedicated integration.

    A client tool definition: name, description and input_schema are everything Claude seespython
    tools = [
        {
            "name": "get_weather",
            "description": "Get the current weather for a given location.",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "City and state, e.g. San Francisco, CA",
                    }
                },
                "required": ["location"],
            },
        }
    ]

    For a client tool, the cost of the direct route is the round trip. You own the loop: you read the tool_use block, run the operation, append a tool_result that carries the matching tool_use_id, and call the API again. The SDK's Tool Runner can do this for you. It executes your tools and sends the results back automatically.

    Checkpoint 1 of 8· Put it in order

    Put the client-tool round trip in order

    1. 1.Your application executes the operation
    2. 2.Claude uses the result to answer the original question
    3. 3.Claude responds with stop_reason "tool_use" and a tool_use block naming the tool and its arguments
    4. 4.A second request sends the output back in a tool_result block
    5. 5.Send a request that defines the tool with a name, description and input_schema

    Checkpoint 2 of 8· Exam question

    A platform team is building an automated CI pipeline step where Claude must read repository files, run test commands, and edit code across multiple iterations until tests pass, without the team writing custom logic to parse tool_use blocks and resubmit tool results. Which integration approach best fits this need?

    Sources1

    2.What MCP adds: a shared protocol and two transports

    A client tool is private to your application. To reuse it in another client, you rebuild it there. The Model Context Protocol fixes that by standardising the boundary. It has three roles. The host creates and manages client instances, enforces security policies and consent, and handles user authorization decisions. Each client establishes one stateful session per server. Servers expose resources, tools and prompts, and can be local processes or remote services.

    The design principles explain why you would choose MCP over a set of client tools. Servers should be extremely easy to build and highly composable. Each provides focused functionality in isolation, and a shared protocol lets many be combined. Isolation is also a security property: servers receive only the context they need, and the full conversation history stays with the host. Under the hood, every message is JSON-RPC 2.0.

    The transport you choose decides where a server can live:

    - stdio: the client launches the MCP server as a subprocess. The server reads JSON-RPC from stdin and writes to stdout, and anything on stdout that is not a valid MCP message is forbidden. This is the local choice. - Streamable HTTP: the client uses HTTP POST to send JSON-RPC to a single MCP endpoint. The server answers with either one JSON object or an SSE stream. This is the remote choice.

    HTTP brings obligations that stdio does not. Servers MUST validate the Origin header to block DNS rebinding. When running locally they SHOULD bind to 127.0.0.1, not 0.0.0.0, and SHOULD authenticate every connection. The spec's authorization framework applies only to HTTP-based transports. An older HTTP+SSE transport still exists. A client can detect it by POSTing an InitializeRequest: a 400, 404 or 405 response means it should fall back to a GET that opens an SSE stream.

    Checkpoint 3 of 8· Match them up

    Match each MCP element to its role

    Tap a term, then the definition that fits it.

    Sources234

    3.Where you attach an MCP server: CLI, Agent SDK, or Messages API

    The same server can be wired in at three places, and each has its own rules.

    Claude Code uses claude mcp add. How the server is described tells you which form to use. A URL such as https://mcp.example.com/mcp means the server is remote. A launch command such as npx -y @example/mcp-server means it runs on your machine. Remote servers take --transport http (or sse), and credentials go in --header. Local servers take --transport stdio with the command after --, and secrets passed through --env. There is a common failure when you paste JSON config: Claude Code reads an entry that has no type as a stdio server, so a url entry without a type fails.

    Adding a remote HTTP server to Claude Code, with and without a bearer tokenbash
    # Basic syntax
    claude mcp add --transport http <name> <url>
    
    # Real example: Connect to Notion
    claude mcp add --transport http notion https://mcp.notion.com/mcp
    
    # Example with Bearer token
    claude mcp add --transport http secure-api https://api.example.com/mcp \
      --header "Authorization: Bearer your-token"

    The Agent SDK takes an mcpServers map, in the same command/args form for a local server. It also supports an in-process SDK server. stdio servers, and HTTP/SSE servers without a cached tool list, delay the first turn until they connect, subject to MCP_TIMEOUT (30 seconds by default).

    The Messages API MCP connector connects to remote MCP servers straight from the Messages API, with no separate MCP client. You list servers in mcp_servers and add one mcp_toolset per server to tools. In the toolset you can enable all tools, allowlist some, or denylist others. One request can reach several servers, and authenticated servers take OAuth Bearer tokens. For OAuth-protected servers, you obtain the access token yourself and pass it in.

    Two limits decide whether the connector fits. The server must be publicly exposed through HTTP, so a local stdio server is out. And only tool calls are supported. If you need resources, prompts, or a server that is not reachable on the internet, build your own MCP client, or keep the capability as a client tool.

    MCP connector request: servers with tokens in mcp_servers, one mcp_toolset per server in toolsjson
      "mcp_servers": [
        {
          "type": "url",
          "url": "https://mcp.example1.com/sse",
          "name": "mcp-server-1",
          "authorization_token": "TOKEN1"
        },
        {
          "type": "url",
          "url": "https://mcp.example2.com/sse",
          "name": "mcp-server-2",
          "authorization_token": "TOKEN2"
        }
      ],
      "tools": [
        {
          "type": "mcp_toolset",
          "mcp_server_name": "mcp-server-1"
        },

    Connecting many servers has a cost in selection quality. Claude picks tools by name and description. For dozens of tools spread across several servers, the connector documentation suggests defer_loading with the Tool search tool, so only the relevant tools are surfaced for each query.

    Checkpoint 4 of 8· Fill the gap

    The Airtable MCP server is started locally with npx. Which transport completes this command?

    claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport  ?  airtable \
      -- npx -y airtable-mcp-server

    Checkpoint 5 of 8· Exam question

    A fintech company wants Claude to call tools hosted on an internal Postgres query service. The service currently only exposes a local stdio-based MCP server used by developers on their laptops, but the production app needs Claude to invoke it directly from server-side Messages API calls without operating a separate MCP client process. What should the team do?

    Sources567

    4.Agent-to-agent: when the integration is another loop

    Tools and MCP servers return data or perform actions. Sometimes the capability you need is a whole piece of reasoning work: explore a codebase, review a module, run a test suite and diagnose what failed. That is where agent-to-agent integration fits. In the Claude Agent SDK you do it with subagents. You can define them in code through the agents parameter of query(), as markdown files in .claude/agents/, or rely on the built-in general-purpose subagent, which Claude calls through the Agent tool.

    A subagent offers four things a tool cannot:

    - Context isolation. The subagent's intermediate tool calls and results stay inside it. Only its final message goes back to the parent. A research subagent can read dozens of files and return a short summary. - Parallelism. Independent subtasks take as long as the slowest one, not the sum of all of them. - Specialised instructions. Each subagent has its own system prompt, so knowledge that would be noise in the main agent stays out. - Tool restrictions. A subagent can be limited to specific tools, which reduces the risk of unintended actions.

    A subagent definition: description tells Claude when to delegate, tools limits what it can dopython
                    "test-runner": AgentDefinition(
                        description="Runs and analyzes test suites. Use for test execution and coverage analysis.",
                        prompt="""You are a test execution specialist. Run tests and provide clear analysis of results.
    
    Focus on:
    - Running test commands
    - Analyzing test output
    - Identifying failing tests
    - Suggesting fixes for failures""",
                        # Bash access lets this subagent run test commands
                        tools=["Bash", "Read", "Grep"],
                    ),

    Claude Code adds two more ways for agents to talk to each other. Dynamic workflows run many subagents from a script Claude writes. Cross-session messaging lets Claude pass a message from one of your sessions to another. These sources describe agent-to-agent integration only through those Claude features. They do not specify a separate wire protocol between independent agents, so this lesson does not describe one.

    Checkpoint 6 of 8· Check yourself

    A doc-reviewer subagent must be able to analyze documentation but never modify it. Which part of its definition enforces that?

    Checkpoint 7 of 8· Exam question

    An engineer wants to interactively debug a failing build by chatting with Claude in a terminal, watching each file it opens and approving risky commands ad hoc, without writing any integration code. Which option best matches this workflow?

    Sources89

    5.Selecting the mechanism

    Put together, the choice is a short series of questions. Is the capability code you already own? Use a client tool. Is it a generic capability Anthropic hosts? Use a server tool. Is it an external service that ships an MCP server, or one you want several clients to share? Use MCP, over stdio if it runs locally and HTTP if it is remote. Is the work a whole task whose intermediate steps would flood the parent's context? Delegate it to a subagent. Claude Code's own guidance says the same: connect a system Claude cannot see as an MCP server, and route a side task that floods your conversation through a subagent.

    Matching the situation to the integration mechanism
    SituationMechanismDeciding fact
    A function or internal API your application already callsClient tool (tool_use / tool_result)Your application executes each call
    Shell commands on your own hostbash tool (Anthropic-defined schema)Still executed by your application, in a stateful session
    Web search or sandboxed code with no handler codeServer tool (web_search, code_execution)Runs on Anthropic's infrastructure
    A service with an MCP server, used from Claude Code or the Agent SDKMCP server over stdio or HTTPLocal subprocess or remote endpoint, shared protocol
    A public, HTTP-exposed MCP server called from the Messages APIMCP connector (mcp_servers + mcp_toolset)No MCP client to build; tool calls only
    Context-heavy or parallel subtasksSubagentOnly the final message returns to the parent

    Checkpoint 8 of 8· Check yourself

    A Messages API application must let Claude query an inventory service that is reachable only inside the company's private network. Which mechanism fits?

    Sources91

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.The Messages API MCP connector can reach any MCP server, including a local stdio server.Why is that wrong?

      The connector only reaches remote servers exposed over HTTP. A local stdio server needs Claude Code, the Agent SDK, or your own MCP client.

      Covered in Where you attach an MCP server: CLI, Agent SDK, or Messages API

    2. 2.A JSON server entry with a url but no type defaults to HTTP in Claude Code.Why is that wrong?

      An entry with no type is read as stdio, so a url-only entry fails. Add "type": "http", "sse" or "ws".

      Covered in Where you attach an MCP server: CLI, Agent SDK, or Messages API

    3. 3.When a parent agent delegates to a subagent, it sees every tool call and file the subagent touched.Why is that wrong?

      Intermediate work stays inside the subagent. The parent receives only the subagent's final message, which is the whole point of the context isolation.

      Covered in Agent-to-agent: when the integration is another loop

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Tools differ primarily by where the code executes.”
      ↩︎ Direct tool use: the API and CLI path
      “Anthropic publishes the schema and trains Claude on it. Your application still executes each call and returns the tool_result.”
      ↩︎ Direct tool use: the API and CLI path
      “Run shell commands in a persistent session that maintains state.”
      ↩︎ Direct tool use: the API and CLI path
      “To skip writing this round trip yourself, use Tool Runner: the SDK executes your tools and sends the results back automatically.”
      ↩︎ Direct tool use: the API and CLI path
      “Your code executes the operation and sends back a tool_result.”
      ↩︎ Selecting the mechanism
      “Tools differ primarily by where the code executes.”
      ↩︎ Key concept
      “your code runs the lookup, and a second request sends the result back in a tool_result block so Claude can reply with the answer.”
      ↩︎ Checkpoint
    2. 3.
      “The client MUST use HTTP POST to send JSON-RPC messages to the MCP endpoint.”
      ↩︎ What MCP adds: a shared protocol and two transports
      “When running locally, servers SHOULD bind only to localhost (127.0.0.1) rather than all network interfaces (0.0.0.0)”
      ↩︎ What MCP adds: a shared protocol and two transports
      “The client launches the MCP server as a subprocess.”
      ↩︎ Checkpoint
    3. 4.
      “Authorization: Authentication and authorization framework for HTTP-based transports”
      ↩︎ What MCP adds: a shared protocol and two transports
    4. 5.
      “A launch command such as npx -y @example/mcp-server: the server runs on your machine.”
      ↩︎ Where you attach an MCP server: CLI, Agent SDK, or Messages API
      “Claude Code reads an entry with no type as a stdio server, so a url entry without a type fails.”
      ↩︎ Exam trap 2
    5. 6.
      “Connect to remote MCP servers directly from the Messages API without an MCP client, and allowlist, denylist, or configure individual tools.”
      ↩︎ Where you attach an MCP server: CLI, Agent SDK, or Messages API
      “For MCP servers that require OAuth authentication, you'll need to obtain an access token.”
      ↩︎ Where you attach an MCP server: CLI, Agent SDK, or Messages API
      “consider enabling defer_loading with the Tool search tool so only relevant tools are surfaced per query.”
      ↩︎ Where you attach an MCP server: CLI, Agent SDK, or Messages API
      “The server must be publicly exposed through HTTP”
      ↩︎ Exam trap 1
      “Of the feature set of the MCP specification, only tool calls are currently supported.”
      ↩︎ Prediction
      “The server must be publicly exposed through HTTP”
      ↩︎ Checkpoint
    6. 8.
      “multiple subagents can run concurrently, so independent subtasks finish in the time of the slowest one rather than the sum of all of them.”
      ↩︎ Agent-to-agent: when the integration is another loop
      “intermediate tool calls and results stay inside the subagent; only its final message returns to the parent.”
      ↩︎ Exam trap 3
      “subagents can be limited to specific tools, reducing the risk of unintended actions.”
      ↩︎ Checkpoint
    7. 9.
      “Cross-session messaging lets Claude pass a message from one of your sessions to another”
      ↩︎ Agent-to-agent: when the integration is another loop
      “Connect that system as an MCP server”
      ↩︎ Selecting the mechanism
      “Route it through a subagent”
      ↩︎ Selecting the mechanism

    Spotted a mistake, or was something unclear? Tell us.