MCP vs function calling
Both let a model call tools. One lives inside the model's runtime; the other is a protocol that reaches across systems.
Short version
Function calling is a model capability. You declare a set of functions in the request, the model may return a structured call, and your own code executes it. Everything happens inside one process that you control.
MCP is a protocol between a client and a server. The tools do not have to live in your process, they can be written by someone else, and the client discovers them at runtime instead of having them declared up front.
Function calling answers "how does the model express a call?" MCP answers "where do the callable capabilities come from, and how does anything find them?"
Side by side
| Aspect | Function calling | MCP |
|---|---|---|
| What it is | A model API feature | A clientβserver protocol |
| Where tools live | In your process, declared in the request | Behind a server, possibly written by someone else |
| Discovery | You pass the full list every call | The client discovers capabilities from the server |
| Scaling the list | More tools means a bigger request every time | Capabilities stay on the server side |
| Execution | Your code runs the function | The server runs the capability |
| Reuse across apps | Copy the declarations and handlers | Point another client at the same server |
| Credentials | In the calling application | At the server boundary, once |
Where they overlap
Despite the table, they are not competitors. A client that supports MCP typically turns discovered capabilities into the same shape the model already understands. From the model's point of view, the call often looks identical whether it came from a declared function or a discovered MCP tool.
The difference sits outside the model: in who owns the implementation, how it is discovered, and where credentials and permissions live.
When to use which
How they combine
In practice you rarely pick one. A typical client declares a couple of local functions and also connects to one or more MCP servers. The model sees a single list of callable things, and your client routes each call to the right place.
local functions β executed in-process mcp servers β capability discovered, call forwarded over the protocol model sees: one merged tool list client decides: route to the local handler or to the server
The design question is therefore not "function calling or MCP" but "which capabilities deserve to be local, and which deserve to be shared?"