People use "MCP," "function calling," and "tool use" interchangeably in AI discussions, and almost every time it causes confusion. They're related but they mean different things, operate at different layers, and solving your problem with the wrong one creates unnecessary work.
Here's a precise breakdown of all three, how they relate to each other, and which one you should actually care about for your project.
The one-line definitions
Tool use: the ability of an LLM to call external functions or APIs during a conversation. The umbrella concept.
Function calling: a specific API mechanism — the JSON-schema-based request/response loop where you define functions, the model returns a structured call, and your code executes it. OpenAI coined the term; it's often used interchangeably with "tool use."
MCP (Model Context Protocol): a standardized protocol for connecting AI models to external tools and data sources. Not about LLM reasoning — about the transport layer between model hosts and tools.
The relationship: tool use is the concept, function calling is the implementation mechanism, MCP is the ecosystem/protocol for sharing tools across hosts. MCP uses function calling under the hood.
Tool use: the concept
When you give an LLM a description of available tools and let it decide when to call them, that's tool use. The model reads the tool descriptions, determines which tool (if any) to call based on the user's request, generates the appropriate parameters, and waits for your code to execute the tool and return the result.
This is distinct from the model "knowing" things. Tool use is for getting live information, taking actions in the world, or running computation the model can't do internally. A model knowing the capital of France is retrieval from training. A model calling your weather API to get today's temperature is tool use.
The function calling lesson covers the mechanics in more depth, but the key insight is that tool use is a property of how you've set up the conversation — not some special model capability that's switched on or off.
Function calling: the mechanism
Function calling is how tool use actually works at the API level. You define tools as JSON Schema objects, pass them with your request, and the model responds with either regular text or a structured tool call you need to handle.
OpenAI function calling:
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools
)
# If the model decides to call the tool:
if response.choices[0].finish_reason == "tool_calls":
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_weather(args["city"])
# Append the model's tool call and your result back to messages
messages.append(response.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
})
# Continue the conversation
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools
)
Claude's equivalent:
tools = [{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}]
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages
)
if response.stop_reason == "tool_use":
tool_use_block = next(b for b in response.content if b.type == "tool_use")
result = get_weather(tool_use_block.input["city"])
messages.append({"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use_block.id,
"content": str(result)
}]
})
Same concept, slightly different syntax. The core loop is identical: define tools → model decides to call one → you execute it → you return the result → model continues.
"Function calling" and "tool use" are often used interchangeably because they're two names for the same thing. OpenAI used "function calling" when they introduced the feature in 2023. Anthropic (and the broader industry) tends to say "tool use." When you see either term in API docs, they mean this JSON-schema request/response loop.
MCP: the protocol layer
MCP (Model Context Protocol) is something different. Anthropic released it in late 2024 and it's become a standard for connecting AI models to tools and data sources.
The problem MCP solves: before MCP, every AI application built its own integration for every tool. You wanted Claude Desktop to read your files? You wrote a custom integration. You wanted it to query your database? Another custom integration. You wanted another team's app to use the same database tool? They wrote their own.
MCP defines a standard interface — an MCP server exposes tools (functions), resources (data sources like files or database tables), and prompt templates. Any MCP-compatible client — Claude Desktop, any app built with MCP support — can connect to any MCP server and use its tools without writing custom integration code.
A Claude Desktop config connecting to a filesystem MCP server:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/you/Documents"
]
}
}
}
With this config, Claude Desktop can call read_file, write_file, list_directory, and other filesystem tools — without you writing a single line of integration code. The MCP server ships with those tools already defined.
Under the hood, when Claude calls read_file through an MCP server, it's still using the function calling mechanism. MCP doesn't replace function calling — it standardizes how tools are discovered, connected, and transported between the model host and your tools.
The relationship, visualized
┌─────────────────────────────────────────┐
│ TOOL USE │
│ (concept: LLMs calling tools) │
│ │
│ ┌───────────────────────────────────┐ │
│ │ FUNCTION CALLING │ │
│ │ (API mechanism: JSON schema loop)│ │
│ └───────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────┐ │
│ │ MCP │ │
│ │ (protocol: share tools across │ │
│ │ hosts using function calling) │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
MCP uses function calling. Function calling is how you implement tool use. Tool use is the overall concept.
The same tool, two ways
Here's what a "get weather" tool looks like implemented directly (function calling in your API call) vs. as an MCP server.
Direct function calling — in your app:
# You define the tool in your API call
tools = [{"name": "get_weather", "description": "...", "input_schema": {...}}]
# You handle the tool call in your code
if response.stop_reason == "tool_use":
result = get_weather(tool_use_block.input["city"])
# Return result and continue conversation
As an MCP server:
# weather_server.py — a standalone MCP server
from mcp.server import Server
from mcp.server.stdio import stdio_server
import mcp.types as types
server = Server("weather")
@server.list_tools()
async def list_tools():
return [
types.Tool(
name="get_weather",
description="Get current weather for a city",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
result = fetch_weather_api(arguments["city"])
return [types.TextContent(type="text", text=str(result))]
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream, server.create_initialization_options())
The MCP server version is more code upfront, but it's now a shareable, reusable component. Any MCP-compatible client — Claude Desktop, your web app, your colleague's app — can connect to it. The function calling version is tightly coupled to your application.
Which one should you use?
The decision isn't "MCP vs function calling" — it's about what you're building.
Use direct tool use / function calling when:
- You're building a one-off integration in your own application
- You're writing an agent in code that calls tools programmatically
- The tools are specific to your app and won't be reused elsewhere
- You're using the raw API (Claude API, OpenAI API) — MCP isn't available at the raw API level
Build or install an MCP server when:
- You want to share the same tool across multiple clients (Claude Desktop + your app + a teammate's app)
- You're using Claude Desktop or another MCP-compatible host
- You're building something the broader ecosystem could use — an MCP server for a popular API, a database connector, etc.
- You don't want to write custom integration code from scratch
Install existing MCP servers when:
- You're using Claude Desktop and want to add capabilities (filesystem access, web search, GitHub access)
- Someone has already built the MCP server you need
See the best MCP servers 2026 guide for a curated list of ready-to-install servers, and build MCP server tutorial if you're building your own.
MCP's limitation: host support required
MCP requires the host application to support it. Claude Desktop supports MCP. If you're calling the Claude API directly in your Python script, you don't get MCP — you define tools in your API call like any other function calling implementation.
This matters because a lot of "I'm using MCP" claims are actually "I'm using Claude Desktop with MCP servers installed." For API-based agents and programmatic tools, you're doing function calling with tool use, not MCP. MCP is the ecosystem layer that sits above individual API calls.
The MCP protocol complete guide has full protocol details if you're building MCP servers or integrating MCP support into your own app.
Common confusion points
"Does Claude support MCP?" — Claude Desktop does, through its configuration. The Claude API does not expose an MCP interface; you define tools in your API calls using the standard function calling mechanism.
"Is function calling the same as tool use?" — Yes, for practical purposes. Function calling is the original OpenAI term for the mechanism. Tool use is the generic term. Same thing.
"Do I need MCP to build an AI agent with tools?" — No. Most agents are built with direct function calling. MCP is useful when you want to share tools across clients or use Claude Desktop. For code-based agents, direct tool use is simpler and more flexible. For agent design patterns that work with direct tool use, see the tool design for agents guide.
The terms will continue to blur in casual use. But when you're building something real, the distinction matters: function calling is how your code talks to the model, MCP is how tools are standardized and shared, and tool use is the capability that makes all of it useful.



