O3: MCP & Tools
An LLM without tools is a brain in a jar β it can reason but canβt act. Tools give AI models the ability to read databases, call APIs, execute code, and interact with the real world. This module covers the evolution from function calling to the Model Context Protocol (MCP) and Agent-to-Agent (A2A) protocol. For how agents orchestrate tools, see O2: AI Agents Deep Dive. For the orchestration layer managing tool calls, see O1: Semantic Kernel.
Why Tools Matter
| Without Tools | With Tools |
|---|---|
| βThe weather in Paris is usually mildβ (hallucinated guess) | get_weather("Paris") β βParis is 18Β°C and sunny right nowβ (real data) |
| βI think the stock price is around $150β | get_stock("MSFT") β β$421.53 as of market close" |
| "Hereβs how to send an emailβ¦β (instructions only) | send_email(to, subject, body) β βEmail sent β
β |
Tools transform LLMs from know-it-alls into do-it-alls.
Function Calling: The Foundation
Function calling is the mechanism where the model generates structured JSON describing which tool to call and with what arguments. Your application then executes the function and returns results.
import openai
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
}]
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Weather in Paris?"}],
tools=tools
)
# Model returns tool_call JSON (NOT the result) β your app executes the function
# {"name": "get_weather", "arguments": {"city": "Paris", "units": "celsius"}}Key insight
The model never executes the function β it only generates the JSON call. Your application is the executor. This is a critical security boundary.
Tool Definition Schema
Every tool needs three things:
{
"name": "search_knowledge_base",
"description": "Search internal docs for relevant information. Use when the user asks about company policies or procedures.",
"parameters": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search query" },
"top_k": { "type": "integer", "description": "Number of results", "default": 5 }
},
"required": ["query"]
}
}The description is the most important field β itβs what the model reads to decide when to use the tool. Write it like youβre explaining to a new team member.
Tool Choice Control
tool_choice | Behavior | Use Case |
|---|---|---|
"auto" | Model decides whether to call a tool | Default β let the model reason |
"none" | Model cannot call any tools | Force text-only response |
"required" | Model must call at least one tool | Ensure action is taken |
{"function": {"name": "X"}} | Model must call specific function X | Force a particular tool |
Parallel Tool Calling
Models can request multiple tool calls in a single turn when tasks are independent:
User: "What's the weather in Paris and Tokyo?"
Model: [get_weather("Paris"), get_weather("Tokyo")] β Two parallel callsExecute them concurrently and return both results. This reduces round trips and latency.
Model Context Protocol (MCP)
The βUSB for AIβ Analogy
Before USB, every device needed a custom cable. MCP does for AI tools what USB did for peripherals β one standard protocol for connecting any tool to any AI application.
MCP vs Function Calling
| Dimension | Function Calling | MCP |
|---|---|---|
| Discovery | Manual β hardcode tools per app | Automatic β client discovers tools from server |
| Scope | Per-application | Shared across applications |
| Updates | Redeploy app to add tools | Server adds tools, clients auto-discover |
| Ecosystem | Vendor-specific (OpenAI, Anthropic) | Open standard, any vendor |
| Data access | Tools only | Tools + Resources + Prompts |
MCP Architecture
ββββββββββββββββ ββββββββββββββββ
β AI App β β MCP Server β
β (Client) ββββββββββΊβ β
β β JSON β β Tools β
β Claude β -RPC β β Resources β
β Copilot β β β Prompts β
β Custom App β β β
ββββββββββββββββ ββββββββββββββββMCP servers expose three capability types:
| Capability | What It Is | Example |
|---|---|---|
| Tools | Functions the model can call | search_docs, create_ticket, run_query |
| Resources | Read-only data the model can access | File contents, database schemas, config values |
| Prompts | Reusable prompt templates | βSummarize this documentβ, βReview this PRβ |
MCP Transport
| Transport | How It Works | Best For |
|---|---|---|
| stdio | Server runs as child process, communicates via stdin/stdout | Local tools (VS Code, CLI) |
| HTTP/SSE | Server runs remotely, uses HTTP + Server-Sent Events | Remote/shared servers, cloud deployment |
MCP Server Example
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({ name: "weather-server", version: "1.0.0" });
// Register a tool
server.tool("get_weather", { city: { type: "string" } }, async ({ city }) => {
const data = await fetch(`https://api.weather.com/${city}`);
return { content: [{ type: "text", text: JSON.stringify(data) }] };
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);A2A: Agent-to-Agent Protocol
While MCP connects models to tools, A2A connects agents to other agents:
| Protocol | Connects | Purpose |
|---|---|---|
| MCP | Model β Tool | Tool discovery and execution |
| A2A | Agent β Agent | Task delegation between autonomous agents |
A2A enables an agent to discover other agentsβ capabilities, delegate subtasks, and receive results β without knowing the other agentβs implementation.
Security Best Practices
Tools are the most dangerous part of an AI system. An LLM with unrestricted tool access can delete databases, send emails, or exfiltrate data.
| Practice | Implementation |
|---|---|
| Least privilege | Each tool gets minimum required permissions |
| Sandboxing | Code execution tools run in containers |
| Rate limiting | Max N tool calls per minute per user |
| Audit logging | Log every tool call with user, args, result |
| Input validation | Validate all tool arguments before execution |
| Confirmation gates | Destructive actions require human approval |
| Timeout | Kill tool calls exceeding 30s |
Key Takeaways
- Function calling is the foundation β model generates JSON, your app executes
- Tool descriptions are critical β they guide the modelβs tool selection decisions
- MCP standardizes tool discovery and sharing across AI applications
- MCP exposes Tools + Resources + Prompts via stdio or HTTP/SSE transport
- A2A extends the pattern from modelβtool to agentβagent delegation
- Security is non-negotiable: sandbox, rate-limit, audit, and gate every tool
For how agents use these tools in autonomous loops, see O2: AI Agents Deep Dive. For Azure-native deployment of tool-using AI, see O4: Azure AI Foundry.