Every six months there is a new way to give large language models abilities. Tool use, function calling, plugins, agents, MCP, agent-as-a-service. If you blinked in 2025 you probably missed one. I want to do a friendly head-to-head of the three options that actually matter right now, so you can pick one without rolling your eyes at yet another acronym. 🙂
The three contenders
1) Native function calling. This is the original move. You define a JSON schema for a function, the model decides when to call it, and your app runs the code. Anthropic calls it tool use, OpenAI calls it function calling, Google has its own flavor. It is provider specific, tightly coupled to one model API, and incredibly easy to get started with. The downside shows up the moment you want to reuse the same tool inside another app or with another provider. You end up rewriting the glue for every client.
2) MCP (Model Context Protocol). Anthropic introduced it, but it is model agnostic by design. You build a server once. That server exposes tools, resources, and prompts over a small standard protocol. Then any MCP-aware client (Claude Desktop, an IDE, your own agent, a CLI) can connect to it. The big idea is decoupling. The capability lives in one place, and many clients can talk to it. By mid 2026 the ecosystem is genuinely useful, with servers for databases, browsers, design tools, and everything in between.
3) Plugins, or agents-as-a-service. This is the higher-level shape. Instead of shipping a tool definition or an MCP server, you expose an entire agent over an API. The caller talks to your agent the way they would talk to any other service. Think of a hosted research agent that you call with a question and a budget. The plugin handles its own tool calls internally, you just get a result. The classic ChatGPT plugins from 2023 were an early version of this, and the modern shape lives on as hosted agents with proper auth, billing, and SLAs.
Side by side
| Dimension | Function calling | MCP | Agent-as-a-service |
|---|---|---|---|
| Portability | Locked to one provider API | Model agnostic, any MCP client | Any HTTP client, but locked to your agent |
| Ecosystem in 2026 | Huge inside each provider, fragmented across them | Growing fast, real servers for real work | Niche but lucrative for hosted SaaS |
| Security model | Your app controls everything, you own the keys | Per-server auth, capabilities, user consent in client | You hold credentials, caller trusts your service |
| Learning curve | Lowest. A JSON schema and a function | Medium. Spec, transport, server lifecycle | Highest. You are running a product |
| Best for | In-app tools, prototypes, single product | Sharing capabilities across many AI clients | Selling an agent as a paid service |
My honest take
For tools that only ever run inside your own app, native function calling is fine. Do not over-engineer this. If your chatbot needs to look up an order, define a tool, parse the JSON, return the result. You will save days of yak shaving and your code will be easier to debug.
For anything you want to share across many AI clients and tools, MCP is the right shape. The protocol is small enough to learn in an afternoon, and the payoff is real. One server, many consumers. I run an MCP server for my CMS and it gets used by Claude, by my own agents, and by a couple of internal scripts, all without changes. That is the dream.
For "I want to expose my SaaS to other people's agents", a hosted MCP server or an agent-as-a-service is the move. The choice between those two is mostly about how much you want to package up. If you sell raw capability, ship an MCP server. If you sell judgment and workflow, ship an agent.
Picking without overthinking
A small decision tree that has served me well:
- One app, one model, one team? Use function calling and move on.
- Capability that should live once and be reused everywhere? Build an MCP server.
- You want to charge money for the result, not the tool? Wrap it as an agent service.
This debate will look quaint in two years. Standards will consolidate, the lines between these three categories will blur, and somebody will invent a fourth option that we all argue about. In the meantime, do not let architectural taste paralyse you. Pick the simplest thing that works for the shape of your problem right now, and ship.
If you are still on the fence after reading this, default to MCP for new infrastructure and function calling for new product features. You will be wrong sometimes, and that is fine. Code is cheap to move when the abstractions are clean. ✨