These are not three competing options; they are three different layers. Function calling is a model capability for emitting structured invocations. Plugins were a platform-specific distribution mechanism. MCP is an open protocol for discovery and transport. A production system typically uses function calling and MCP together.
The comparison gets framed as a choice because the three appear in the same conversations. Reading the stack correctly dissolves most of the debate.
Where a genuine decision exists, it is narrower than the framing suggests: whether to build integrations against an open protocol or wire them bespoke.
| # | Dimension | Function calling | MCP |
|---|---|---|---|
| 1 | What it is | A model capability | A transport and discovery protocol |
| 2 | Layer | Model output format | Application-to-system connection |
| 3 | Who implements it | The model provider | You, on both client and server side |
| 4 | Discovery | None; tools are declared per request | Dynamic, servers advertise capabilities |
| 5 | Portability | Tied to a provider’s API shape | Any compliant client works with any server |
| 6 | Reuse across applications | Reimplemented per application | One server serves all clients |
| 7 | Statefulness | Stateless per call | A persistent connection with a lifecycle |
| 8 | Data access | Only via function results | Resources exposed separately from tools |
| 9 | Prompt distribution | Not covered | Servers can offer prompt templates |
| 10 | Permission point | Whatever the application implements | The host, consistently across servers |
| 11 | Ecosystem effect | None; each integration is private | Shared servers usable by any application |
Rows 5 and 6 are the whole argument. Everything else follows from whether integration work is reusable across applications or has to be repeated inside each one.
Where do plugins fit?
Historically, and it is worth understanding why they matter less now.
The plugin model let a platform vendor curate a catalogue of integrations for their own product. The integration was distributed through that platform, worked inside it, and did not transfer elsewhere.
That is a distribution mechanism, not a protocol. It solved discovery for users of one product while leaving every other application to solve integration independently. An open protocol solves the underlying problem the plugin catalogue was working around.
Do you choose between them?
Figure 1 — How the layers actually stack
- LAYER 1Function callingModel emits a structured request to invoke a named tool
- LAYER 2Application logicHost receives the request and applies permission policy
- LAYER 3MCPClient routes the call to the server that declared that tool
- LAYER 4The systemServer executes against the database, API or filesystem
Remove any layer and the stack stops working. Without function calling the model cannot express intent. Without the protocol every integration is hand-wired. They are complements, and the comparison framing obscures that.
What is the real decision?
Whether to invest in a protocol-based integration layer or wire connections directly. That trade depends almost entirely on how many applications and systems you expect to connect.
| If your situation is | Do this |
|---|---|
| One application, two or three integrations | Direct function calling. A protocol adds ceremony you will not recover. |
| One application, many integrations | Protocol, for the consistent permission and logging point alone. |
| Several applications sharing systems | Protocol, decisively. This is the case it exists for. |
| You want third-party integrations | Protocol. Bespoke connectors will not attract contributors. |
| Highly regulated, few systems | Either, but centralise permission enforcement regardless. |
Watch for this
Adopting a protocol does not remove the hard parts of tool design. Descriptions still have to be unambiguous, schemas still have to constrain arguments, and errors still have to be actionable. Teams sometimes expect standardisation to fix agent reliability, then find the same selection and argument failures as before, now behind a cleaner interface.
What changes operationally?
- Permission enforcement moves to one place, which makes it auditable rather than scattered.
- Tool inventory becomes dynamic, so capabilities can change without redeploying the client.
- Servers become independently versionable, with their own release cycle.
- The trust boundary becomes explicit, because a third-party server is visibly a third party.
- Debugging gains a seam, since you can test a server independently of any model.
That last point is quietly valuable. A server is an ordinary program, so it can be tested with ordinary tests, and a whole class of “is it the model or the integration” questions becomes answerable.
Where do teams go wrong?
Treating the comparison as a choice
Asking whether to use function calling or MCP is like asking whether to use HTTP or JSON. They operate at different levels and are used together.
Adopting a protocol for two integrations
The benefit scales with the number of application-system pairs. With one application and a couple of systems, direct implementation is simpler and the abstraction never pays back.
Assuming portability means interchangeability
A server working with any compliant client does not mean every client uses it equally well. Prompt structure, model choice and context assembly still differ, and behaviour varies with them.
What do experienced teams do differently?
They separate the integration layer from the agent layer regardless of which protocol they use.
Even without adopting a standard, defining an internal interface that all tool access goes through gives the same permission, logging and testing benefits. Adopting an open protocol then becomes a swap of one interface for another rather than a rewrite.
They also treat protocol adoption as a distribution decision as much as a technical one. The reason to expose a system over an open protocol is that other applications, including ones you do not control, can then reach it. If nothing else will ever connect, that benefit is theoretical.
A short glossary
- Function calling
- A model capability for emitting a structured request to invoke a named function with arguments.
- Plugin
- A platform-specific distribution mechanism for integrations, usable inside that platform only.
- Protocol
- An agreed interface allowing independently built clients and servers to interoperate.
- Dynamic discovery
- Learning what capabilities exist at connection time rather than declaring them in advance.
- Host
- The application owning client connections, where permission policy is enforced.
Key takeaways
- Function calling, plugins and MCP occupy different layers and are not alternatives.
- Function calling is a model capability; MCP is a discovery and transport protocol; plugins were platform distribution.
- The real decision is whether integration work should be reusable across applications.
- Direct implementation wins for one application with a handful of integrations.
- A protocol wins decisively once several applications share the same systems.
- Standardisation does not fix tool design; descriptions, schemas and errors still decide reliability.
- Separating the integration layer from the agent layer delivers most of the benefit even without adopting a standard.
Frequently asked questions
Should I use MCP or function calling?
Both, because they operate at different layers. Function calling is how the model expresses intent to invoke a tool. MCP is how your application discovers which tools exist and routes the call to whatever implements them. Neither substitutes for the other.
What happened to plugins?
They were a platform-specific distribution mechanism rather than a protocol. An integration built for one platform’s catalogue worked inside that platform and nowhere else, so every other application still had to solve integration independently. Open protocols address the underlying problem.
When is a protocol not worth adopting?
When you have one application and two or three integrations. The benefit scales with the number of application-system pairs, so with a small number the abstraction adds ceremony that never pays back. Direct implementation is simpler and entirely reasonable.
Does adopting MCP improve agent reliability?
Not directly. Standardisation fixes distribution and integration cost, not tool design. Ambiguous descriptions, loose schemas and unhelpful error messages produce the same selection and argument failures behind a cleaner interface. Those remain your work.
Can any client use any server?
Any compliant client can connect to any compliant server, but that is not the same as behaving identically. Prompt structure, model choice and context assembly all differ between applications, so the same server can produce different results in different hosts.
What operational benefits does a protocol bring?
One place to enforce permissions, dynamic tool inventory without client redeployment, independently versionable servers, an explicit trust boundary around third-party code, and a testable seam that separates integration bugs from model behaviour.
Do I need a protocol for internal-only tools?
Only if several internal applications will share the same systems. For a single application, an internal interface that all tool access flows through delivers the same permission, logging and testing benefits without the additional layer.
Is exposing a server over an open protocol a technical decision?
Partly a distribution one. The reason to expose a system over an open protocol is so other applications, including ones you do not control, can reach it. If nothing external will ever connect, that benefit stays theoretical.
References
- Anthropic. Model Context Protocol documentation, covering architecture, primitives and host responsibilities.
- Model Context Protocol. Specification and reference implementations.
- Schick, T., et al. Toolformer: Language Models Can Teach Themselves to Use Tools. arXiv:2302.04761.
