MCP vs Function Calling — I Tried Both, Here's What's Actually Different
After building the same database query tool both ways, here's the honest comparison: function calling gets you to a demo faster, but MCP gives you fewer reasons to hate your life two months later.
Lee Li
Independent Developer · MCP Enthusiast
MCP is better than function calls when a tool needs to live beyond a single app. Not close.
I don't mean "better" in the abstract architecture-diagram sense. I mean "better" in the somewhat dull way that becomes important after week two. When the same tool definition is found in two different repositories, and someone asks whether it also works in Claude Desktop, what seemed like a simple feature suddenly becomes an infrastructure requirement. Earlier this year, I created the same internal database query flow in both directions. It utilized the same PostgreSQL table, the same model-facing interface, and had the same objective. The function calling version got me to a demo faster. The MCP version gave me fewer reasons to hate my life later.
The function calling build was what you'd expect. Define a schema in the app, describe the parameters, handle the callback, parse the model output, patch the places where the model misfires, and ship it. That part was fine. Then I needed the same tool in another environment. Then another. Then I realized the actual problem wasn't "can the model call this thing" but "who owns the definition of this thing." With function calling, the app owns it. Every host ends up carrying a copy, or a variation, or some wrapper around a wrapper. Great for speed. Terrible for reuse.
MCP made me do the annoying part up front. I needed to treat the tool as a primary interface, including the server, transport, and configuration. On the first day, I wasted 45 minutes on a configuration file, mistakenly assuming the host would resolve a path the way my terminal did. It didn't. However, once that issue was resolved, the tool no longer belonged to just one application. That was the entire payoff.
People often compare protocols, but the real difference is in operational ownership. In function calling, the host app team manages the tool and its integration interface changes. In contrast, with MCP, the tool provider owns the contract. You only need to update it once, and clients can then consume it. That's the part that actually compounds over time.
There's a fair counterargument here. For a small project with a single model, app, or feature, function calling is the simpler choice. When creating something specific and unique, using the Model-Component-Presentation (MCP) structure might seem complicated. With the function-calling version, I had to update tool descriptions in three different places. In contrast, the MCP approach allowed me to make all the updates in one location! It's interesting to see how one tool can offer such different experiences in terms of maintenance. Each method has its own advantages, and it's all about finding what works best for us!
One thing the MCP crowd sometimes oversells is that the protocol somehow fixes sloppy tool design. If your description is unclear, your parameter names are poorly chosen, or your authentication model is disorganized, the model will still produce unsatisfactory results. In one instance, I found that renaming a parameter from "query" to "sql_query" significantly improved behaviour, more so than any transport decision I made that week. Proper design is important. Language is important as well.
Also, and this is only loosely related, every AI vendor inventing its own tool interface before converging on a shared one was such a waste of time. We burned a ridiculous amount of energy translating the same concept into slightly different schemas because everyone needed their own flavour of "function calling, but our way."
So, function calling is fine for side projects. This tool is suitable for demonstrations and for features that are tightly integrated with a specific host application. However, it becomes less effective when the tool needs to function outside of the initial app that called it. It also falls short if another team wants to reuse it without extracting your internal schema definitions from the application code. This is the key point I am concerned about now.
This was all based on local workflows and some internal experiments, not a large multi-team platform rollout. A larger organisation with stricter release tools might organise differently.
Lee Li
Independent Developer · MCP Enthusiast
Building and breaking things with AI tools since 2023. MCP Find started as a personal project to track the rapidly evolving MCP ecosystem. Based in Hong Kong.