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"}}
:::info 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 calls
Execute them concurrently and return both results. This reduces round trips and latency.
Model Context Protocol (MCP)β
:::tip 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.