Demystifying OpenAI Function Calling vs Anthropic’s Model Context Protocol (MCP)
Image 1: Comparison of OpenAI function call vs. MCP generated by flux.1
Large language models (LLMs) have evolved far beyond simple chatbots. Today, they can interact with tools, execute structured actions, and call APIs — turning them into capable agents. Two of the most prominent methods for enabling this behavior are OpenAI’s Function Calling and Anthropic’s Model Context Protocol (MCP).
In this post, we’ll walk through what each of these approaches does, how they differ, and which might be best for your use case. We’ll include illustrative Python code and focus on clarity, practicality, and style.
Large language models (LLMs) have evolved far beyond simple chatbots. Today, they can interact with tools, execute structured actions, and call APIs — turning them into capable agents. Two of the most prominent methods for enabling this behavior are OpenAI’s Function Calling and Anthropic’s Model Context Protocol (MCP).
In this post, we’ll walk through what each of these approaches does, how they differ, and which might be best for your use case. We’ll include illustrative Python code and focus on clarity, practicality, and style.
What Is OpenAI Function Calling?
OpenAI’s function calling lets you define a schema for a function you want the model to “call”. The model returns structured JSON representing the function name and arguments. This is incredibly useful for tool use, plugins, or agent orchestration.
Example: OpenAI Function Calling
from openai import OpenAI
client = OpenAI()
functions = [
{
"name": "get_weather",
"description": "Get the current weather in a given city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Name of the city"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
]
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "user", "content": "What's the weather like in Berlin?"}
],
functions=functions,
function_call="auto"
)
print(response.choices[0].message.function_call)Output:
{
"name": "get_weather",
"arguments": "{\"city\": \"Berlin\", \"unit\": \"celsius\"}"
}Pros
- JSON schema-based validation
- Well-suited for deterministic agent behavior
- Clean separation of generation and function execution
Cons
- Requires schema to be specified up front
- Limited to OpenAI’s interpretation and formatting
What Is Anthropic’s Model Context Protocol (MCP)?
Anthropic’s MCP is a newer, more flexible approach that lets you define tools inside the conversation using special tool_use and tool_result blocks. This makes the tool use more natural and native to the chat flow, rather than invoking a separate function calling mode.
Example: Anthropic MCP in Python (FastAPI-MCP)
from fastapi import FastAPI, Query
from typing import Optional
from fastapi_mcp import add_mcp_server
app = FastAPI(title="Weather API", description="MCP-enabled weather tool", version="1.0")
# In-memory weather data for demo
weather_db = {
"Berlin": {"temperature": 15, "unit": "celsius"},
"London": {"temperature": 12, "unit": "celsius"},
"New York": {"temperature": 60, "unit": "fahrenheit"},
}
@app.get("/get_weather")
async def get_weather(city: str = Query(..., description="City name"), unit: Optional[str] = Query("celsius", enum=["celsius", "fahrenheit"])):
data = weather_db.get(city)
if not data:
return {"error": f"Weather data for {city} not found."}
if unit != data["unit"]:
# Fake conversion
if unit == "fahrenheit":
temp = round(data["temperature"] * 9/5 + 32)
else:
temp = round((data["temperature"] - 32) * 5/9)
else:
temp = data["temperature"]
return {"city": city, "temperature": temp, "unit": unit}
# Attach the MCP server to FastAPI
mcp_server = add_mcp_server(
app,
mount_path="/mcp",
name="Weather API MCP",
description="MCP server for the Weather API",
base_url="http://localhost:8000"
)
@mcp_server.tool()
async def get_supported_cities() -> list[str]:
"""List all cities for which weather data is available."""
return list(weather_db.keys())Pros
- Tools are embedded in context as part of the chat
- Native support for multi-tool workflows
- Easier to mix in reasoning, retries, and corrections
Cons
- Slightly more verbose
- Still new; ecosystem tooling is catching up
Which One Should You Use?
- Use OpenAI Function Calling if you need strict validation, schema enforcement, and tight control over tool execution.
- Use Anthropic MCP if your agent benefits from more flexible tool interaction, mixed reasoning, and inline tool chaining.
Final Thoughts
Both approaches are powerful. OpenAI’s Function Calling is polished and battle-tested, ideal for API-like integrations. Anthropic’s MCP introduces a more expressive and human-like tool usage, potentially better for autonomous agents and tool chaining.
If you’re building LLM agents or applications that require real-world actions, it’s worth experimenting with both. You’ll likely find that the choice depends on your system’s goals: precision and structure vs. fluidity and adaptability.
Stay tuned for follow-ups where we’ll build a multi-tool agent using both methods.
🔗 Connect with me on LinkedIn | ❤️ If you enjoyed this post, clap it up and share!
