Articles

Function Calling vs MCP: How AI Agents Call Tools

Function calling lets a model request a tool call within one API request; MCP is a protocol for exposing whole toolservers that many models can share.

Chisato Chisato · · 5 min read
Abstract illustration representing a large language model

Function calling is a model capability — the ability for an LLM to output a structured request to invoke a specific function, defined per-request by whoever is calling the API. The Model Context Protocol (MCP) is a standardized, transport-level protocol for exposing a whole server’s worth of tools, resources, and prompts to any compliant client, independent of which model is on the other end. They’re not competitors so much as different layers of the same stack: MCP is commonly implemented on top of an underlying function-calling mechanism.

Function calling: a per-request capability

When you use function calling, you send the model a list of tool definitions — names, descriptions, and JSON Schema parameter shapes — as part of your API request. The model, if it decides a tool is relevant to the user’s request, responds not with plain text but with a structured object naming a function and the arguments to call it with. Your application code is responsible for actually executing that function, then feeding the result back to the model in a follow-up request so it can incorporate the output into its next response.

Crucially, function calling defines nothing about where the tool definitions come from or how they’re maintained. Every application that wants to expose a “search the web” or “query this database” function has to define that tool’s schema itself, in its own code, for every model provider it targets — there’s no shared registry, no standard transport, and no portability of tool definitions between applications.

MCP: a protocol for tool servers

MCP standardizes the other half of the problem: how an AI application discovers and connects to a server that exposes tools, resources, and reusable prompt templates, using a consistent protocol regardless of which model client is consuming it. An MCP server for, say, a company’s internal ticketing system can be written once and then used by any MCP-compliant client — a coding assistant, a chat application, an autonomous AI agent — without each of those clients needing custom integration code for that specific system.

Under the hood, when an MCP client connects to a server, it typically translates the server’s exposed tools into the function-calling schema the underlying model expects. The model still does exactly what it always did with function calling — it emits a structured request to invoke a named function with specific arguments. What MCP adds is the layer above that: a standard way to discover what tools are available, fetch their schemas, and route the actual execution to the right server, instead of every application hardcoding its own tool definitions and dispatch logic.

Where they actually differ

Function callingMCP
What it isA model API capabilityA client-server protocol
ScopeOne request’s tool listA whole server’s tools, resources, and prompts
Where it’s implementedInside the model provider’s APIBetween a client and one or more independent servers
Reusability across appsNone — schemas are redefined per appHigh — one server, many compliant clients
Model-agnostic?No — tied to a specific provider’s calling formatYes — the protocol layer is independent of the model
Typical unit of workA single function invocationOngoing session: discovery, resources, multiple tool calls

Function calling answers “how does the model tell my code what it wants to run.” MCP answers “how does my application find, connect to, and standardize access across many different tool providers, without writing bespoke integration code for each one.”

A concrete example

Say you’re building an agent that needs access to a company wiki, a code search index, and a customer database. Without MCP, you’d write three separate integrations, each defining its own function-calling schema, request logic, and response formatting — and if you switched model providers, you might need to adapt each schema to that provider’s specific function-calling format.

With MCP, each of those three systems can instead be exposed as an MCP server — potentially built by the wiki vendor, the code search vendor, and your own internal team, independently. Your agent, built with any MCP-compatible client, connects to all three servers, and the protocol handles discovery (what tools does each server expose?) and invocation in a consistent way. The underlying model still only ever sees function-calling-style tool definitions and returns function-calling-style responses — MCP is what assembled and standardized those definitions before they reached the model.

Why both layers matter

It’s tempting to think MCP “replaces” function calling, but that’s not quite right — MCP is largely built on the premise that function calling works and is reasonably standardized across providers already. What MCP fixes is the fragmentation above that layer: the N×M problem where N applications each need custom integrations with M tool providers. Function calling alone doesn’t address that; it just gives the model a way to ask for a tool call once your application has already decided what tools to offer it.

This mirrors a pattern seen elsewhere in software: a low-level capability (function calling, analogous to a system call) gets a higher-level, portable protocol (MCP, analogous to a shared API standard) built on top of it once enough independent parties need to interoperate through it. Building small MCP servers or clients yourself is a good way to see this in practice — see building your own AI agent for a hands-on starting point.

The takeaway

Function calling is the mechanism by which a model requests a specific tool invocation within a single API exchange — a capability defined by the model provider. MCP is a protocol layered above that mechanism, standardizing how applications discover and connect to tool, resource, and prompt servers so integrations can be written once and reused across clients and models. You don’t choose one over the other in most modern agent stacks — MCP typically depends on function calling working correctly underneath it, and adds the discovery and portability layer that raw function calling never defined.