
When clients ask me how to connect an AI model to their existing data stack, the conversation almost always comes down to three patterns: Model Context Protocol (MCP), function calling, and plugins. They solve related problems but they are not interchangeable. Using the wrong one adds unnecessary complexity; using the right one keeps the architecture clean enough to maintain two years from now.
Here is the mental model I reach for, built from projects across finance, healthcare, and e-commerce.
What Each Pattern Actually Is
Before the decision tree, the definitions -- because "MCP" and "plugin" are terms that get used loosely and that looseness causes real architectural mistakes.
Model Context Protocol is Anthropic's open standard for exposing tools to an AI model in real time. You write an MCP server -- a small process that declares a set of tools in a JSON manifest -- and a compatible client (Claude, for example) connects to it via STDIO or SSE. During a conversation the model can invoke those tools directly and receive results within the same turn. The key characteristic is that the connection is live and bidirectional: the model is an active participant in the session, not just a function that returns JSON.
Function calling is a lower-level pattern available through the raw chat completions API. You pass a tools array when you call the model; the model may return a tool_use content block naming a function and its arguments; your code executes the function and passes the result back in the next turn. The critical difference from MCP is that your code is fully in control of execution. The model proposes; you decide whether to act. This matters when you are running the model inside a batch job or a data pipeline where you need deterministic control over timing, retries, and parallel execution.
Plugins are packaged, distributed tools built on top of MCP (in the Claude ecosystem) or function calling (historically, in the OpenAI ecosystem). When you publish a plugin to the Anthropic marketplace, you are shipping an MCP server with a manifest that end users can install without writing any code. The plugin pattern is the distribution and packaging layer, not a separate protocol. If you need to share a tool broadly -- internal teams, paying customers, or the general public -- a plugin is how you do it without giving everyone access to your backend.
The Decision Tree
The fastest way to pick a pattern is to answer three questions in order.
Who controls when the tool runs? If the model decides when to call the tool based on the conversation, you are in MCP territory. If your code decides when to invoke the model and what to do with the result, you are in function-calling territory. This is the sharpest dividing line. An AI assistant that a data analyst talks to in real time belongs in the model-driven bucket. A nightly batch job that uses an LLM to classify support tickets belongs in the code-driven bucket.
Who consumes the tool? If the answer is "my application or my team," you build an MCP server and connect your client to it directly. If the answer is "other teams in the company without engineering support" or "paying customers," you package it as a plugin and let the marketplace handle distribution and versioning.
Third: Does the tool need to maintain state across turns? MCP servers can be stateful -- they run as a persistent process and can hold context between calls within a session. Function calling is stateless by design; each call is a fresh invocation. If your tool needs to track a multi-step workflow (a data quality remediation process that spans several model turns, for example) MCP handles that natively. With function calling, you manage state externally in your application layer.
Where Each Pattern Wins in Practice
Function calling is the right default for data pipelines. When you need to enrich a million records by running each one through a classification model, you want your orchestration code in charge. You can parallelize the calls, validate the outputs against a schema before writing, and retry failures without the model knowing anything went wrong. LangGraph workflows, dbt post-hooks that trigger model calls, and Spark jobs that use LLMs as UDFs all fit this shape. The LangGraph vs simpler tool-calling post goes deeper on where orchestration frameworks add value versus when a direct function call is enough.
MCP is the right default for interactive, session-based tools. If you are building an internal analytics assistant that your team uses in Claude's desktop client, MCP lets you expose your data warehouse, your internal APIs, and your file system as tools without writing a custom chat loop. The model handles the multi-turn reasoning; your MCP server handles the data access. The MCP Servers Explained post covers the mechanics in more depth if you are starting from zero.
Plugins are the right default when distribution is the problem. I have built MCP servers for several clients where the engineering team is happy maintaining the server but the business wants to roll it out to fifty analysts who just want to install a tool and start asking questions. Packaging as a marketplace plugin means the analysts get a one-click install, the engineering team ships a standard MCP server, and nobody has to teach non-engineers how to edit an .mcp.json file.
The Hybrid Case
Most mature setups use more than one pattern. A common architecture I see: function calling handles the batch enrichment and anomaly detection jobs that run on schedule; an MCP server exposes the results and supporting data to an interactive assistant the operations team uses to investigate anomalies; and a plugin wraps that MCP server so new teams can be onboarded without a configuration session with engineering.
These three layers do not compete. They solve different parts of the same problem.
A Note on Switching Costs
The patterns are not equally easy to swap out once you are in production. Function calling lives entirely in your application code, so you can change models, change schemas, or change orchestration frameworks without touching the AI layer. MCP creates a coupling between the server protocol and the client -- not a painful one, but something to design for. Plugins add a marketplace dependency; updating a published plugin requires a review cycle and you have to manage backward compatibility for existing installations.
If you are early in a project and are not sure which pattern you will need long term, start with function calling. The control it gives you is easiest to trade away when you later decide to move to an MCP architecture. Going the other direction -- from MCP to function calling -- tends to require rethinking the state management approach.
Ready to Map This to Your Stack?
Choosing the right AI integration pattern early saves months of rework later. If you are trying to decide where MCP, function calling, or plugins fit in your specific architecture, I can help you map it out. Reach out through the contact page and we can run through the decision tree for your use case.
Get posts like this delivered weekly: subscribe to Dispatches from the Labyrinth.