Function calling and MCP get confused often, and the confusion is understandable, since MCP is built on top of the same underlying idea function calling introduced. They're not competing approaches to the same problem, though. One is a capability a model has; the other is a protocol for exposing that capability's targets consistently across systems.
What function calling actually is
Function calling is a model capability: given a description of available functions (their names, parameters, and what they do), a model can decide to invoke one with structured arguments instead of just generating text. This is the mechanism that lets a model actually do something (look up data, take an action) rather than only describe in words what it would do.
Function calling by itself says nothing about how those functions are defined, hosted, or shared. Every application that wants to give a model tool access has traditionally had to define its own functions, in its own format, specific to that one integration.
What MCP actually adds
MCP is a standardized protocol for exposing tools (built on the same function-calling mechanism underneath) in a consistent way that any MCP-compatible client can use, without custom integration code for every combination of model and tool. We've written about what MCP actually is in more depth, but the core idea is this: instead of building a custom function-calling integration for every AI application that needs access to a given system, you build one MCP server, and any compatible client can use it.
The actual practical difference
| Function calling | MCP |
|---|---|
| A model capability: invoking a described function with structured arguments | A protocol built on top of that capability, standardizing how tools are exposed and discovered |
| Integration is typically custom per application | One server can serve any MCP-compatible client without custom integration work per client |
| No standardized discovery or permission model across tools | Growing standardization around discovery, schemas, and permission scoping |
When a simple direct function-calling integration is actually the right call
If you're building a single application with a fixed, known set of tools that only that application will ever need, a direct function-calling integration is simpler and has less overhead than standing up an MCP server. MCP's real value shows up when multiple clients, applications, or teams need access to the same underlying tools. That's exactly the scenario we described in what MCP actually looks like in production.
When MCP is the better call
If you're building internal tooling that multiple teams or AI applications will need to access, or you expect the set of AI clients touching a system to grow over time, build against MCP from the start. It saves you from building and maintaining multiple custom integrations to the same underlying systems, which is exactly the sprawl MCP exists to prevent.
How we approach this
We default to direct function calling for genuinely single-purpose integrations, and to MCP when tool access is infrastructure likely to be shared across teams or applications. The choice follows the actual shape of your situation, not whichever approach is currently more discussed.