MCP vs Function Calling: What Developers Actually Need to Know
Function calling tells the model what tools exist. MCP standardizes how those tools are discovered, described, and executed across any AI client. Here is how they work together.

When developers compare MCP vs function calling, they usually get one thing wrong right away: they think one replaces the other. It doesn't. Function calling is a model-level feature. The LLM outputs structured JSON that specifies which tool to invoke and with what arguments, based on schemas you define per request. The Model Context Protocol (MCP) is an open protocol that standardizes how those tools get discovered, described, and executed across any AI client. MCP sits on top of function calling. Knowing where each layer starts and stops is how you build agents that scale past a handful of hardcoded tools.
How Function Calling Works
OpenAI introduced function calling in June 2023 for GPT-4 and GPT-3.5 Turbo. Anthropic, Google, and other providers shipped their own implementations after that. The pattern looks the same everywhere:
- You send tool definitions (JSON Schema) alongside your prompt.
- The model returns a structured JSON object naming the tool and its arguments.
- Your application executes the function locally.
- You send the result back to the model.
- The model produces a final response or requests another tool call.
Here is a minimal OpenAI function calling setup:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"],
"additionalProperties": false
},
"strict": true
}
}Anthropic's tool use follows the same concept but uses input_schema instead of parameters. Google Gemini uses functionCall objects. Each provider's format is incompatible with the others. Switching providers means rewriting every tool definition. That fragmentation is exactly the problem MCP solves.
How MCP Works
Anthropic announced MCP on November 25, 2024, describing it as an open standard for "replacing fragmented integrations with a single protocol." The analogy that stuck: MCP is the USB-C for AI. Instead of building M x N custom integrations (M models times N tools), you build M clients and N servers. Each tool implements one MCP server. Each AI application implements one MCP client.
MCP uses JSON-RPC 2.0 across a three-tier architecture:
- Hosts are LLM applications that initiate connections (Claude Desktop, VS Code, your custom agent).
- Clients are connectors within the host that maintain 1:1 sessions with servers.
- Servers are services that expose tools, resources (contextual data), and prompts (reusable templates).
When an MCP client connects to a server, it calls tools/list to discover available tools at runtime. No hardcoded schemas. No provider-specific formats. The client translates those tool definitions into whatever function calling format the underlying LLM expects. The model then selects and parameterizes tool invocations the same way it always has.
That's why MCP vs tool use isn't an either/or question. Function calling is Phase 1: the model decides what to call. MCP is Phase 2: standardized infrastructure for discovering and executing those calls on external servers.
MCP vs Function Calling: Side-by-Side Comparison
| Dimension | Function Calling | MCP | |---|---|---| | What it does | Model outputs structured tool invocations | Protocol for tool discovery and execution | | Scope | Single API request-response cycle | Persistent client-server sessions | | Tool discovery | Static -- schemas embedded in each request | Dynamic -- tools/list at runtime | | Provider lock-in | Yes -- each provider has its own format | No -- provider-agnostic open standard | | Execution | Application code runs the function locally | MCP server runs the function, returns results | | Credential handling | App process holds all API keys | Credentials scoped per-server (isolation) | | Setup complexity | Low -- 20 lines of code | Medium -- server process + client config | | Best for | Few tools, single provider, latency-sensitive | Many tools, multi-client, shared infrastructure | | Governance | OpenAI / Anthropic proprietary | Linux Foundation (AAIF), MIT license |
When to Use Each: A Decision Framework
Use function calling alone when you've got fewer than five tools, a single LLM provider, and tools that run in-process (database queries, internal calculations, simple API calls). Standing up an MCP server isn't worth it for that.
Add MCP when any of these apply:
- The same tool needs to work across multiple clients (Claude Desktop, Cursor, your production agents).
- You have 10+ integrations and the quadratic complexity of per-provider definitions is slowing you down.
- You need credential isolation. Each MCP server holds only its own API keys rather than your application process holding everything.
- Multiple teams or agents share the same tooling infrastructure.
Use both together. Most production systems do. Function calling handles bespoke, tightly coupled tools (a custom scoring function, a proprietary database query). MCP servers handle shared infrastructure tools (Slack, GitHub, Stripe, databases) that multiple agents or clients need access to.
How to Set Up Your First MCP Server
Python (FastMCP)
Install the SDK (requires Python 3.10+):
uv init weather && cd weather && uv venv && source .venv/bin/activate
uv add "mcp[cli]" httpxCreate a server with a tool:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
@mcp.tool()
async def get_weather(location: str) -> str:
"""Get current weather for a location."""
# Your implementation here
return f"Weather data for {location}"
mcp.run(transport="stdio")Python type hints and docstrings automatically generate the tool's JSON Schema definition. No manual schema authoring needed.
TypeScript
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescriptimport { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "weather", version: "1.0.0" });
server.registerTool("get_weather", {
description: "Get current weather for a location",
inputSchema: { location: z.string() }
}, async ({ location }) => {
return { content: [{ type: "text", text: `Weather for ${location}` }] };
});
const transport = new StdioServerTransport();
await server.connect(transport);Connect to Claude Desktop
Add your server to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"weather": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/weather", "run", "weather.py"]
}
}
}Restart Claude Desktop. Your tool appears automatically. No schema copy-pasting, no provider-specific formatting. The same server works with VS Code, Cursor, ChatGPT desktop, and dozens of other clients.
Important: stdout is reserved
For stdio-based MCP servers, don't write non-protocol output to stdout. Use print("msg", file=sys.stderr) in Python or console.error() in TypeScript. Stdout is the JSON-RPC message channel. Stray output corrupts the protocol.
Security Considerations
Both approaches carry security trade-offs you should understand.
Function calling centralizes credentials in your application runtime. If the agent process gets compromised, every API key is exposed. MCP isolates credentials at the server level. Each server holds only its own keys, following least-privilege principles.
MCP does introduce new attack surface, though. Research has found that 43% of sampled MCP servers contained command injection vulnerabilities, and a single vulnerability in mcp-remote (CVE-2025-6514) affected over 437,000 downloads. The MCP specification mandates that servers validate the Origin header on HTTP connections and bind to localhost when running locally.
Practical advice: prefer official MCP servers from the service provider (Stripe, GitHub, Slack all maintain their own), review tool definitions before granting broad permissions, and keep a human in the loop for sensitive operations. The MCP spec explicitly recommends that last point.
Industry Adoption
The "is MCP real or hype" question got answered by adoption numbers. OpenAI adopted MCP in March 2025, with Sam Altman noting that "people love MCP and we are excited to add support across our products." Google followed in April 2025, announcing MCP support for Gemini. Then in December 2025, Anthropic donated MCP to the Linux Foundation's Agentic AI Foundation, co-founded by Anthropic, Block, and OpenAI. That cemented it as a vendor-neutral standard.
On the enterprise side, Block (parent of Square and Cash App) scaled MCP to 12,000 employees across 15 job functions in two months using their open-source agent Goose. By early 2026, the ecosystem had grown to over 5,500 listed servers and 97 million monthly SDK downloads.
Function calling isn't going anywhere. It's still the mechanism every LLM uses to express tool-call intent. But the infrastructure layer beneath it is consolidating around MCP. If you're building agents that use tools like Stripe, Slack, Gmail, or any of the top MCP servers, you're already in MCP territory.
Building Agents That Use Both Layers
At Gamut, agents use MCP servers as their tools (Stripe for payments, GitHub for code, Slack for notifications) while function calling handles the model-level routing that decides which tool to invoke and with what arguments. The two layers work together, not against each other. If you're building AI agents that need to connect to real-world services without wiring each integration from scratch, that's the problem Gamut was built to solve.
FAQ
Does MCP replace function calling?
No. MCP standardizes tool discovery and execution. Function calling is how the LLM expresses which tool to use and generates the arguments. MCP relies on function calling underneath. It adds the infrastructure layer on top.
What is the difference between OpenAI function calling vs MCP?
OpenAI function calling embeds tool schemas in each API request using a provider-specific JSON format. MCP runs a separate server that exposes tools via JSON-RPC 2.0, discoverable at runtime by any compatible client. OpenAI itself now supports MCP in its Agents SDK and Responses API.
Can you use MCP and function calling together?
Yes. Most production systems do. Function calling handles the model's structured output (tool selection and argument generation). MCP handles tool advertisement and execution on the server side. When an MCP client connects to a server, it translates MCP tool definitions into the function calling format the LLM expects.
Is MCP only for Claude?
No. MCP is an open standard under the Linux Foundation. It works with Claude, GPT-4o, Gemini, Llama, and any model accessible through an MCP-compatible client. OpenAI, Google, and Microsoft all support it across their platforms.
How does MCP handle credentials differently than function calling?
With function calling, your application process typically holds all API keys. That's a single point of compromise. MCP isolates credentials per-server: the Stripe MCP server holds only the Stripe key, the GitHub server holds only the GitHub token. If one server is compromised, the blast radius stays contained to that service.
Build AI Agents with MCP Servers as Tools
Gamut lets you build production AI agents that connect to Stripe, GitHub, Slack, and hundreds of other services through MCP servers -- no custom integrations required.