Agentbrisk

Function Calling vs MCP: How They Differ and When to Use Each

March 21, 2026 · Editorial Team · 9 min read · mcpexplainerai-tools

Function calling and MCP are both ways for AI models to use tools. They appear in the same conversations, serve adjacent purposes, and get conflated constantly in developer discussions. The conflation is understandable because both mechanisms end up producing the same user-visible behavior: a model that can query a database, read a file, or call an API instead of just generating text.

But they operate at completely different layers of the stack. Confusing them leads to overengineered setups when one approach would do, or frustratingly brittle integrations when you needed the other. This guide is a direct explanation of how each mechanism works, where the boundaries are, and how to make the call for your own project.

What function calling actually is

Function calling is a capability built into an LLM API. When you send a request to a model that supports it, you can include a list of function definitions alongside your message. Each definition describes a function name, a description of what it does, and a JSON Schema for its parameters.

The model reads your message and your function list together. If it determines that calling one of your functions would help answer the request, it responds not with text but with a structured output specifying which function to call and what arguments to pass. Your application code receives that output, executes the actual function, and sends the result back to the model in the next turn. The model then generates a final response based on what the function returned.

The key thing to understand is that the model never runs the function itself. It produces a structured intent to call a function. Your code does the actual work. The model just decides when a call is warranted and how to format the invocation.

OpenAI popularized this under the name "function calling" with GPT-3.5 and GPT-4. Anthropic ships the same capability under the name "tool use." Google's Gemini calls it "function calling" as well. The implementations differ slightly in how you structure the definitions and how results are passed back, but the core pattern is identical across all major model providers.

What MCP actually is

MCP (Model Context Protocol) is an open standard that defines how AI hosts connect to external servers that expose tools, data, and prompts. It was introduced by Anthropic in late 2024 and has since been adopted by most major AI coding tools and agent platforms.

Where function calling is a feature of an API, MCP is an architecture. It defines three roles: a host (the AI application the user runs, like Claude Desktop or Claude Code), a client (the MCP-speaking component built into the host), and a server (an external process that wraps a tool or data source and exposes it via the protocol).

An MCP server defines tools the model can call, resources the model can read, and optional prompt templates. The host discovers what a server offers, makes that catalog available to the model, and handles the round-trip when the model decides to call something. The communication uses JSON-RPC 2.0 over stdio (for local servers) or HTTP with Server-Sent Events (for remote ones).

The defining property of MCP is portability. Build one MCP server for GitHub and it works with Claude Desktop, Claude Code, Cursor, Windsurf, and every other host that has adopted the standard. You do not rebuild the integration for each platform. For a deeper look at the full architecture, see What Is MCP (Model Context Protocol)?

The actual difference between them

Function calling answers the question: "How does a model decide to call a function, and how does that call get structured?"

MCP answers the question: "How does an AI application discover and connect to the servers that provide those functions in a portable way?"

They are not competing approaches to the same problem. Function calling is the mechanism through which a model expresses tool-use intent at the API level. MCP is the protocol that standardizes how tools are packaged, discovered, and served to any model host. An MCP server exposes its tools via the MCP protocol, and the host that calls them uses the underlying model's function calling (or tool use) capability to do so. In practice, MCP sits on top of function calling.

You can use function calling without MCP. If you are building a single application with a fixed set of tools and you are calling the model API directly, function calling is everything you need. You define your tools inline, handle the model's structured outputs, and run the logic yourself.

You can also use MCP without thinking much about raw function calling. When you configure a Filesystem MCP server in Claude Desktop, you do not write any function definitions. The server advertises what it can do, the host registers those capabilities with the model, and the model uses its built-in function calling mechanism internally. The MCP layer handles the plumbing.

When function calling is the right choice

Function calling is the right default when you are writing application code that calls an LLM API directly and manages the full conversation loop yourself.

If you are building a customer support agent that needs to look up orders from an internal database, you probably have a fixed set of three to five operations the model will ever need. You write those function definitions once, pass them in every API request, and handle the results in your application. You do not need a separate server process, a protocol layer, or any additional infrastructure. Function calling handles this cleanly and keeps the integration contained inside your codebase.

The same logic applies to any agent or workflow where the tools are tightly scoped to one application, where you want direct control over every function the model can call, or where deploying a separate server process adds complexity you do not need.

Function calling also gives you fine-grained control over tool definitions on a per-request basis. You can dynamically choose which tools to expose to the model based on context, user permissions, or workflow state. With MCP, the server declares its tools at connection time and the host exposes them consistently.

For teams evaluating their options, understanding tool calling at this level is worth the time. The tool calling explainer goes deeper on the mechanics if you want the full picture before building.

When MCP is the right choice

MCP becomes the right choice as soon as portability, reusability, or multi-host support enters the picture.

If you are building a tool or integration that you want to work across multiple AI hosts, MCP is the only practical answer. Writing a bespoke integration for each host's proprietary plugin system is the old way of doing things, and it is expensive to maintain. One MCP server, properly built, works everywhere that supports the standard. That is a concrete time savings the first time you need to add a second host.

MCP also makes sense inside a complex agent setup where you want a clean separation between the agent logic and the tools it calls. Instead of your agent code being one large file that mixes LLM calls, business logic, and tool implementations, MCP lets you move each tool group into its own isolated server. The agent code stays clean and focused. The servers evolve independently.

Developers building shareable tools for a community get clear value from MCP. If you have written a useful database integration, browser automation helper, or documentation fetcher, packaging it as an MCP server means anyone using a compatible host can use your tool immediately. Packaging it as raw function calling code means everyone has to copy and integrate your code manually.

Claude Code is a good example of an environment where MCP shines. It is already a capable autonomous agent for coding tasks. Adding MCP servers extends its reach to databases it can query mid-task, APIs it can call, and documentation it can pull in without any bespoke integration work. The MCP catalog has servers ready to drop in for most common development needs.

How they interact in practice

It is worth being concrete about how function calling and MCP relate when you run both in the same setup.

When a host connects to an MCP server, the server's tools/list response sends back a catalog of tools with their names, descriptions, and parameter schemas. The host takes that catalog and converts it into the format the underlying model's API expects for tool definitions, whether that is OpenAI's tools array format, Anthropic's tools block, or another provider's equivalent. When the model responds with a tool call, the host parses the structured output, routes the call to the correct MCP server, and returns the result to the model.

So the model always uses function calling, in the technical sense, to express tool-use intent. What MCP adds is the layer above: where tool definitions come from, how they are kept consistent across sessions, and how results get routed. From the model's perspective, a tool defined via MCP looks identical to a tool defined inline in your API call. The difference is entirely in the plumbing around the model.

The portability gap

The practical limitation that pushes developers toward MCP is the portability gap that raw function calling creates. If you build a GitHub integration using function calling directly, it works in your application and nowhere else. Your teammate building a different internal tool has to rebuild the same integration. If you switch from one model provider's API to another, the schema formats differ and you rewrite the definitions.

MCP solves the portability gap at both levels. A well-built MCP server runs in any compatible host regardless of model provider. The MCP spec translates provider differences away at the protocol layer. This is not a theoretical benefit. It is the reason teams that initially build function-calling integrations often migrate them to MCP once they scale beyond a single application.

Choosing one: a direct guide

Use raw function calling if all of these are true: you are calling a model API directly in your own application, your tool set is fixed and small, and you have no need to share the integration with other hosts or developers.

Use MCP if any of these are true: you want the integration to work across multiple AI tools without rebuilding it, you are building something you intend to share or distribute, you want clean separation between agent logic and tool implementation, or you are working inside a host that already supports MCP (Claude Desktop, Claude Code, Cursor, Windsurf, and most others do).

If you are not sure, MCP is the safer long-term bet for anything that will see real use. The ecosystem has standardized around it fast enough that building a new integration as raw function calling and then migrating it later is a common source of wasted work.

What this means for your stack

The practical implication is straightforward. If you are building an application that calls LLM APIs directly, function calling is the core mechanism you need to understand. Master the definition format, the structured output parsing, and the multi-turn conversation pattern. That knowledge applies across every model provider.

If you are working in a host environment like Claude Code or Cursor, or if you are building tools intended for those environments, MCP is the standard to build toward. The MCP server catalog shows what already exists so you do not rebuild something that is already available.

The two are not in competition. Function calling is the low-level primitive. MCP is the higher-level standard that makes function calling portable and composable at scale. Understanding both is what lets you pick the right layer for each part of what you are building.

Search