When to Use MCP vs Raw Function Calling
Scenario
You're building a simple, single-purpose Slack bot that checks the weather. You decide to spin up a dedicated MCP server in a Docker container just to expose the weather API to your LLM, adding complexity and latency.
A developer building a single-purpose weather chatbot decides to spin up a separate MCP server instance instead of passing the weather schema directly to the LLM. Why is this structurally inefficient?
Mental model
Raw function calling is a direct, hardcoded wire. MCP is a universal switchboard.
You built the raw execution loop in the Function/tool calling lesson. You already know how to pass a JSON schema to `client.chat.completions.create`. MCP doesn't replace that underlying mechanism; it wraps it in a switchboard. MCP is built for runtime discovery and scaling across many models and tools. But if you have a closed, single-purpose app, that switchboard is just overhead. Direct APIs are faster and cheaper.
Deep dive
In standard function calling, you hardcode the schema and send it directly in the LLM's `tools` array. The model replies instantly with a tool call. It's a single network hop. It's extremely fast and requires zero extra infrastructure.
Raw function calling is a direct, single-hop integration with zero protocol overhead.
MCP introduces a negotiation handshake. Before the Host can invoke the LLM, it must send an `initialize` request to the MCP Server, wait for the response, send a `tools/list` request to discover capabilities, and wait for that response. Only then does it pass the schemas to the LLM.
MCP requires a multi-step JSON-RPC negotiation phase before inference begins.
This handshake means MCP inherently introduces latency. It is structurally impossible for MCP to be faster than a raw, direct function call. If a developer benchmarks an MCP server against a raw API call and sees a 50ms increase, the server isn't broken—that is the mathematical reality of protocol negotiation.
MCP adds latency; it does not reduce it. Its benefit is architectural scalability, not execution speed.
So when does MCP earn its complexity? Scale. If you are building an open ecosystem (like an AI IDE) that needs to dynamically discover tools from third-party plugins at runtime, MCP is mandatory. If you are integrating 10 different tools across 4 different LLMs, the M×N integration problem justifies the switchboard.
MCP is for open ecosystems, runtime discovery, and massive multi-tool scale.
Conversely, if you are building a closed system—like a dedicated customer support bot with exactly two internal APIs and one LLM—you should use standard raw function calling. Adding an MCP server to a closed, single-purpose system is pure over-engineering.
For single-purpose, closed systems, raw function calling is definitively faster and cheaper.
Code examples
Raw Function Calling: The single network hop
# 1. You hardcode the schema
weather_tool = {
"type": "function",
"function": {"name": "get_weather", "parameters": {...}}
}
# 2. One direct call to the LLM provider
response = client.chat.completions.create(
model="gpt-4o",
messages=user_messages,
tools=[weather_tool]
)
Zero discovery overhead. You know the tool exists, you format it perfectly, and you send it directly to the model. This is the lowest possible latency.
The MCP overhead: Multi-step negotiation
# To get the same result, the Host must first negotiate:
# 1. Host -> Server: initialize
# 2. Server -> Host: initialize_result
# 3. Host -> Server: tools/list
# 4. Server -> Host: tools_result (containing the schemas)
# 5. NOW the Host translates and calls the LLM provider
response = client.chat.completions.create(
model="gpt-4o",
messages=user_messages,
tools=translated_mcp_tools
)
Steps 1 through 4 add network latency before the LLM even sees the prompt. This overhead is only justified if you don't know what tools are available until runtime.
Common mistakes
- Assuming MCP replaces all function calling: Because of industry hype, developers assume MCP is universally superior and should replace standard OpenAI function calling everywhere. Reality: MCP is built for runtime discovery and standardisation across many tools. For a single, closed-system integration, a direct API call with native function calling is structurally faster, cheaper, and less complex.
- Expecting MCP to reduce LLM latency: Developers assume standardisation equals performance optimization, expecting their LLM to generate faster because the tools use MCP. Reality: MCP actually introduces latency overhead due to the required negotiation handshakes (`initialize`, `tools/list`). If you see a latency increase when switching to MCP, your code isn't broken; that's the cost of the protocol.
Glossary
- Raw Function Calling
- The standard process of directly passing a hardcoded JSON schema to an LLM provider's API (e.g., in the OpenAI `tools` array) without any intermediary protocol.
- JSON-RPC Negotiation
- The multi-step handshake MCP uses to discover tools dynamically before the LLM can even be invoked.
Recall questions
- What operational and latency overhead does the Model Context Protocol introduce compared to raw function calling?
- At what architectural scale does MCP explicitly earn its complexity?
- A developer benchmarks an MCP server against a raw function call, sees a 50ms increase in latency with MCP, and assumes their server code is broken. Are they correct?
- A developer building a single-purpose weather chatbot decides to spin up a separate MCP server instance instead of passing the weather API schema directly to the LLM's tool array. Why is this a poor architectural choice?
Questions & answers
How is MCP different from a regular REST API?
A regular REST API integration (like raw function calling) involves hardcoding the specific tool schema and sending it directly to the LLM in a single hop. MCP is a dynamic protocol that requires the client to negotiate a connection and actively query the server to discover its capabilities at runtime before translating them to the LLM.
Approach: Contrast hardcoded schemas (REST/Function Calling) with dynamic runtime discovery (MCP). Highlight the latency tradeoff.
When would you choose raw function calling over MCP?
I would choose raw function calling when building a single-purpose, closed system where all tools are known in advance (like a dedicated customer support bot). Implementing MCP in this scenario adds unnecessary negotiation latency and infrastructure overhead without providing the runtime discovery benefits that justify the protocol.
Approach: Highlight the overhead of MCP's negotiation handshakes. Position MCP as a solution for open ecosystems, not simple closed scripts.
Continue learning
Previous: Function / Tool Calling
Previous: The M×N integration problem and protocol necessity