AI Agent Development and Interview Guide: 05-Tool Calling and MCP Protocols in Practice

Analyzes JSON Schema constraints and side-effect isolation in tool calling, builds standardized MCP (Model Context Protocol) servers, and handles security and idempotency.

Contents26 sections

Chapter 5: Function Calling, Tool Use, and Model Context Protocol (MCP)

Function Calling and Model Context Protocol (MCP) transform LLMs from conversational chatbots into autonomous systems capable of querying information and performing operations. However, invoking external capabilities introduces software engineering challenges: permission control, parameter schema validation, idempotency, side-effect isolation, protocol security, and comprehensive evaluation.

1. Tools as Governed Capability Interfaces

Models should never receive direct raw database connections, operating system shells, or arbitrary outbound HTTP capabilities. Expose business capabilities strictly as narrow interfaces:

TEXT
Discouraged: execute_sql(sql: string)
Recommended: get_order_status(order_id: string)

Discouraged: http_request(url, method, body)
Recommended: create_refund_request(order_id, reason, amount)

Advantages of narrow interfaces:

  • Unambiguous authorization and privilege boundaries;
  • Strict parameter schema validation;
  • Full telemetry observability and regression testability;
  • Streamlined implementation of idempotency keys and approval gates;
  • Minimized blast radius of Prompt Injections executing arbitrary operations.

🔥 P0 High-Frequency Essential: Why avoid giving an Agent a generic SQL tool? Generic SQL confers excessive blast radius, making it nearly impossible to govern query intent, resource exhaustion, and PII exfiltration risks. Always favor narrow read-only business tools; when raw SQL is unavoidable, enforce read-only credentials, table/column whitelists, AST query parsing, row/timeout caps, tenant filters, and immutable audit logs.

2. Six Criteria for High-Quality Tool Schemas

  • Tool name expresses a single, atomic action;
  • Docstrings explicitly define "when to use" and "when NOT to use";
  • Input types, enums, string lengths, and formats are strictly bounded;
  • Output schemas maintain deterministic structural stability;
  • Errors return machine-readable error codes rather than free-form text;
  • Side-effects and human approval requirements are identifiable by the runtime.
PYTHON
from decimal import Decimal
from typing import Literal

from pydantic import BaseModel, Field


class RefundRequest(BaseModel):
    order_id: str = Field(pattern=r"^ORD-[0-9]{8}$")
    reason: Literal["duplicate_charge", "not_received", "quality_issue", "other"]
    amount: Decimal = Field(gt=0, max_digits=10, decimal_places=2)
    idempotency_key: str = Field(min_length=16, max_length=128)


class RefundResult(BaseModel):
    request_id: str
    status: Literal["pending_review", "approved", "rejected"]
    message: str

Never represent financial amounts as binary floats; never validate order IDs merely as "non-empty string"; and ensure idempotency keys are generated or verified by trusted backend runtime code rather than letting the LLM invent random keys to bypass deduplication.

3. Tool Return Payloads Must Facilitate Self-Correction

Errors should never return unstructured natural language alone:

PYTHON
from typing import Literal
from pydantic import BaseModel


class ToolError(BaseModel):
    code: Literal[
        "NOT_FOUND",
        "PERMISSION_DENIED",
        "INVALID_STATE",
        "RATE_LIMITED",
        "TEMPORARY_UNAVAILABLE",
    ]
    retryable: bool
    user_fixable: bool
    message: str
    missing_fields: list[str] = []

The Agent runtime inspects retryable for backoff retries and user_fixable to prompt for user clarification; PERMISSION_DENIED must fail immediately without passing errors back for the model to "attempt bypassing."

4. End-to-End Execution Loop for Tool Calling

While provider SDK syntax varies, application runtime logic remains universal:

PYTHON
async def run_tool_loop(model, tool_registry, messages, max_steps=6):
    for step in range(max_steps):
        response = await model.respond(
            messages=messages,
            tools=tool_registry.schemas(),
        )

        if response.final_text is not None:
            return response.final_text

        for call in response.tool_calls:
            tool = tool_registry.get(call.name)

#            # 1. Tool allowlist validation
            if tool is None:
                result = {"error": {"code": "UNKNOWN_TOOL", "retryable": False}}
            else:
#                # 2. Schema validation
                args = tool.input_model.model_validate(call.arguments)

#                # 3. IAM permissions and risk policy
                decision = await authorize_tool(tool, args)
                if decision.requires_approval:
                    return await pause_for_approval(call, decision)

#                # 4. Timeout, idempotency, and audit logging handled by executor
                result = await tool_executor.execute(tool, args)

#            # 5. Tool results and call_id must be mapped back
            messages.append({
                "role": "tool",
                "tool_call_id": call.id,
                "content": result,
            })

    raise RuntimeError("agent exceeded maximum tool steps")

A proposed model tool call does not obligate the system to execute it. Validation, authentication, authorization, approval gates, and rate budgets occur strictly in trusted backend code.

🔥 P0 High-Frequency Essential: What checks must be performed before executing a tool call? Verify tool whitelist membership; validate argument schemas; verify user identity and resource-level permissions; validate current business workflow state; check risk classification and approval gates; verify idempotency keys; check rate/cost budgets; ensure multi-tenant boundary isolation; and apply data masking to sensitive fields.

5. Tool Risk Classification Matrix

Risk TierExample CapabilitiesRecommended Controls
R0 Public Read-OnlyQuery public weather, public documentationRate limiting, timeouts, standard logging
R1 Private Read-OnlyQuery user orders, internal private knowledgeUser auth, tenant isolation, field-level ACL, audit log
R2 Reversible MutationCreate draft, file support ticketIdempotency keys, approval policy, rollback action
R3 External Side-EffectSend email, alter calendar, submit refundExplicit user confirmation, impact preview, immutable audit
R4 Irreversible / High-RiskDelete database records, execute code, transfer fundsDefault-deny, mandatory human approval, sandbox, 2-man rule

Risk tiers must be codified in static tool metadata rather than delegating self-assessment of danger to LLM reasoning.

6. Idempotency, Transactions, and Compensating Actions

Reliable tool execution requires three foundational software mechanics:

  • Idempotency: Re-invoking an action with identical parameters yields identical side-effects; this is a critical execution standard and core baseline in production engineering architecture and system design.
  • Transactions: A bundle of local operations commits atomically or rolls back entirely; this is a critical execution standard and core baseline in production engineering architecture and system design.
  • Compensating Actions: Explicit rollback actions when distributed operations cannot achieve atomic rollback. This is a critical execution standard and core baseline in production engineering architecture and system design.

For example, "Book flight and create calendar event" spans two distributed third-party systems without distributed two-phase commits. Pattern: lock itinerary, persist pending record, book flight after user authorization, create calendar event on success; if calendar sync fails, retry or flag for compensation without cancelling confirmed flight tickets.

⭐ P1: What is the relationship between the Saga pattern and Agents? While Agents plan operational sequences, they must adhere to transactional boundaries. Distributed workflows utilize Saga compensating actions to manage partial failures; compensating logic is deterministic software design, never generated ad-hoc by LLMs.

7. What is Model Context Protocol (MCP)?

The Model Context Protocol (MCP) is an open standard connecting AI applications with external capabilities over JSON-RPC. This chapter covers the 2025-11-25 specification standardizing schema validation via JSON Schema.

MCP Servers expose three fundamental primitives:

PrimitiveControlled ByPrimary Purpose
ToolsModel RequestedExecute dynamic operations or parameterized queries
ResourcesApplication ControlledRead-only context (e.g., files, DB schemas, docs)
PromptsUser SelectedPredefined slash-command workflow templates

Official documentation can be found at Understanding MCP servers.

🔥 P0 High-Frequency Essential: What is the difference between MCP and Function Calling? Function Calling is a model-level capability to emit structured JSON function calls; MCP is an application-level open protocol for clients to discover and invoke Tools, Resources, and Prompts from decoupled external servers. MCP standardizes integration but does not replace model reasoning, tool selection, or backend authorization.

8. MCP Architecture

TEXT
User
  -> Host (AI Application)
      -> MCP Client A -> MCP Server A (Knowledge Base)
      -> MCP Client B -> MCP Server B (Ticket System)
      -> MCP Client C -> MCP Server C (Calendar)
  • Host manages model inference, sessions, security boundaries, and UI;
  • Client communicates with individual servers, negotiating protocol capabilities;
  • Server exposes specific Tools, Resources, and Prompts;
  • Servers must never implicitly trust model outputs or untrusted payloads from other servers.

9. Implementing a Minimal FastMCP Server

Official Python documentation leverages FastMCP, where type annotations and docstrings automatically generate tool schemas. Refer to Build an MCP server.

PYTHON
from typing import Literal

from mcp.server.fastmcp import FastMCP
from pydantic import Field


mcp = FastMCP("support-tools")


@mcp.tool()
async def get_ticket_status(
    ticket_id: str = Field(pattern=r"^T-[0-9]{6}$"),
) -> dict:
    """Query ticket status. Read-only operation; does not mutate ticket state."""
    # Production implementation must extract user_id from auth context, not allow arbitrary user parameters.
    return {
        "ticket_id": ticket_id,
        "status": "open",
        "updated_at": "2026-07-22T10:00:00Z",
    }


@mcp.tool()
async def create_ticket_draft(
    title: str = Field(min_length=5, max_length=120),
    category: Literal["billing", "technical", "other"] = "other",
) -> dict:
    """Create a ticket draft without submitting; submission mandates explicit user confirmation in the UI."""
    return {
        "draft_id": "D-000001",
        "title": title,
        "category": category,
        "status": "draft",
        "requires_user_confirmation": True,
    }


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

Package installation per official SDK guidelines typically uses:

BASH
uv add "mcp[cli]"

The STDIO Logging Trap

Under STDIO transport, stdout carries protocol JSON-RPC frames. Official documentation strictly warns: never use print() to stdout, as it corrupts JSON-RPC framing. Always stream logs to stderr or dedicated log files.

PYTHON
import logging
import sys

logging.basicConfig(stream=sys.stderr, level=logging.INFO)

This is a classic, high-frequency interview gotcha in MCP engineering.

10. Choosing Between Resources and Tools

Use Resources when:

  • Data is strictly read-only;
  • Host controls when and how context is injected;
  • Content resembles static files, schemas, or reference manuals;
  • You want to prevent the model from treating reading as an active "action."

Use Tools when:

  • Dynamic parameterized queries are required;
  • Arguments must be computed at runtime;
  • Operations cause mutations or external side-effects;
  • Model must autonomously decide whether and when to invoke.

Never return massive unstructured files directly inside Tool outputs. Return Resource URIs or search tools yielding summaries and citations for selective retrieval.

11. MCP Authorization Architecture

For HTTP transport, the 2025-11-25 specification codifies an OAuth 2.1 authorization framework with Protected Resource Metadata. Key security pillars:

  • Access tokens must be cryptographically bound to specific target resources;
  • Servers must strictly validate Token Audience (aud);
  • Strict prohibition against passing inbound bearer tokens downstream;
  • Enforce principle of least privilege scopes;
  • Mandatory HTTPS, PKCE, short-lived tokens, and secure vault storage;
  • Never log tokens, authorization codes, or private keys.

Refer to MCP Authorization. STDIO transport inherits security context from local process execution and environment variables rather than executing OAuth flows.

🔥 P0 High-Frequency Essential: Why is Token Passthrough dangerous? Downstream servers may erroneously accept tokens not minted for them, causing privilege escalation and confused deputy vulnerabilities. An MCP Server must verify that inbound tokens are explicitly scoped for itself, and mint separate downstream tokens when calling external services.

12. Tool Description Injection and Supply Chain Security

MCP Server tool descriptions constitute untrusted external input. Hosts must never connect to arbitrary unverified servers and grant elevated permissions. Enforce:

  • Server whitelisting with cryptographic signature and origin verification;
  • Transparent UI permission prompts displaying server and tool scopes;
  • Mandatory human authorization on high-risk capabilities;
  • Static analysis and security audits on tool descriptions and JSON schemas;
  • Dependency locking and automated vulnerability scanning;
  • Process sandboxing, network egress policies, and strict rate limits;
  • Continuous auditing of MCP Server version mutations.

13. Tool Evaluation: Multi-Layer Benchmarking

Benchmark across at least four distinct dimensions:

  • Selection Precision: Whether the model accurately selects the correct tool; this is a critical execution standard and core baseline in production engineering architecture and system design.
  • Argument Validity: Schema conformity, type adherence, and business constraint validity; this is a critical execution standard and core baseline in production engineering architecture and system design.
  • Execution Reliability: Timeout resilience, retry backoff, idempotency, and IAM authorization; this is a critical execution standard and core baseline in production engineering architecture and system design.
  • Trajectory Efficiency: Minimizing redundant invocations and excessive intermediate steps. This is a critical execution standard and core baseline in production engineering architecture and system design.

Example evaluation benchmark case:

JSON
{
  "input": "Check the status of ticket T-123456",
  "expected_tool": "get_ticket_status",
  "expected_arguments": {"ticket_id": "T-123456"},
  "forbidden_tools": ["create_ticket_draft"],
  "max_tool_calls": 1
}

14. Chapter Exercises

Exercise A: Enterprise Tool Registry

Implement a central Tool Registry validating schemas, risk classification tiers, permission scopes, timeouts, and idempotency keys prior to tool execution.

Exercise B: FastMCP Server

Implement three capabilities: a read-only ticket query Tool, a ticket draft creation Tool, and a support policy Resource. Ensure all STDIO logging routes strictly to stderr.

Exercise C: Security Red-Teaming Suite

Write automated tests verifying: unknown tool handling, unauthorized cross-tenant IDs, idempotency key replay, malicious parameter payloads, tool description prompt injections, duplicate write loops, and approval bypass attempts.

15. High-Frequency Interview Q&A

🔥 P0: How do you design a reliable production Tool?

Scope narrow business capability, enforce strict Pydantic schemas, return structured machine-readable error codes, enforce least-privilege IAM, inject server-side authenticated context, configure timeouts and bounded retries, ensure idempotency, classify risk tiers, enforce approval gates, and maintain audit logs. Validate continuously with tool selection and argument test suites.

🔥 P0: What are MCP Tools, Resources, and Prompts?

Tools are model-requested executable actions; Resources are application-controlled read-only context documents; Prompts are user-selected slash-command templates. They differ fundamentally in control plane ownership; avoid flattening all capabilities into Tools.

🔥 P0: How do you handle tool execution failures?

Classify the error: retry transient network faults with exponential backoff; pass schema errors back for bounded model correction; interrupt for user input on missing parameters; reject immediately on permission violations; and query idempotency status on uncertain mutations before attempting retries.

⭐ P1: Why doesn't MCP automatically solve security challenges?

MCP standardizes discovery, invocation, and authorization protocols, but server trustworthiness, tool over-privileging, human approvals, business parameter validation, and execution sandboxing remain the responsibility of the Host and Server implementations. Standardized protocols do not equate to standardized trust.

⭐ P1: How do you mitigate tool selection degradation when registry sizes grow large?

Dynamically expose minimal tool subsets per intent; route requests prior to tool injection; refine docstring semantic boundaries; filter tools by user permission; benchmark confusion matrices; and merge overlapping tools or replace them with deterministic code rules.

16. Chapter Completion Criteria

  • Able to design narrow, typed, and idempotent tool interfaces;
  • Able to implement the complete Request—Validate—Authorize—Approve—Execute—Observe loop;
  • Able to articulate MCP Host/Client/Server architecture and the three core primitives;
  • Able to implement and execute a FastMCP Server with correct STDIO logging;
  • Able to explain HTTP OAuth 2.1 authorization, Token Audience verification, and anti-passthrough rules;
  • Possess automated test suites covering tool selection, argument validation, IAM boundaries, and deduplication.

REFERENCES

References

  1. 012025-11-25 规范
  2. 02Understanding MCP servers
  3. 03Build an MCP server
  4. 04MCP Authorization

Series

AI Agent Development and Interview Guide

Next step

Continue with related topics

Continue along the same topic.

Browse latest news