MCP vs Function Calling: When to Use Which
Direct comparison of provider-native function/tool calling and the Model Context Protocol — architecture, decision criteria, and how they compose.
MCP and function calling are not competitors. Function calling is the LLM API mechanism by which a model emits a structured tool invocation. MCP is a protocol for where those tools live and how they are discovered. In a system that uses MCP, the model still triggers actions via function/tool calls — the MCP client layer converts tools/list results into provider-native tool schemas before the prompt is sent, and routes the model's call back to the MCP server via tools/call. Understanding the two layers separately eliminates the most common agentic architecture confusion.
Key facts
- Function calling and MCP are not rival technologies — function calling describes how a model outputs a structured request to run some code, while MCP standardizes where that code actually lives and how a client finds it.
- Function calling is in-process, per-provider (schemas are not interchangeable), and has no runtime discovery — the tool list is defined statically by the developer.
- MCP tools run out-of-process and work with any compatible host regardless of model vendor, and the client learns what is available — tools, resources, and prompt templates alike — right when a session begins.
- Function calling suits a single application with only a few tools where you need something working in minutes; MCP suits capabilities that need to be shared across several different host apps or LLM vendors.
- In production systems both layers typically coexist: the host still uses function calling at the API layer while sourcing tools from MCP servers.
What function/tool calling is
Function calling (OpenAI) and tool use (Anthropic) are identical in concept: you pass a set of JSON Schema tool definitions alongside a prompt; the model decides whether to call one, returning structured arguments; your application executes the function and returns the result. The wiring is in-process and per-application.
Key properties:
- In-process. The function implementations live in your application code.
- Per-provider schema. OpenAI uses
tool_calls/tool_choice; Anthropic usestool_usecontent blocks andtools[]. The schemas are not interchangeable. - Per-application wiring. Each app that wants the same capability must define and execute the tool independently.
- No discovery. The tool list is static — defined at call time by the developer.
See /resources/reliable-tool-calling for provider-specific schema details and constrained-decoding guarantees.
What MCP is
The Model Context Protocol (MCP) is a JSON-RPC 2.0 protocol that standardises how tools, resources, and prompts are exposed by a server process and consumed by a host/client. It sits one layer above function calling: the MCP client fetches tool definitions from the server (tools/list), converts them into the provider's native schema, injects them into the prompt, and when the model fires a tool call the client routes it to the server (tools/call).
Key properties:
- Out-of-process. The MCP server is a separate process (local via stdio, or remote via Streamable HTTP). The host application does not own the implementation.
- Provider-agnostic. One MCP server works with any MCP-compatible host — Claude Desktop, Cursor, a custom pipeline — regardless of which LLM is used.
- Runtime discovery. Clients discover tools, resources, and prompts at session start; new capabilities appear without redeploying the host.
- Three primitives. Tools (model-invoked actions), Resources (app-injected context), and Prompts (user-selected templates). See /resources/mcp-primitives for the full primitive breakdown.
- Standardised auth. Remote servers implement OAuth 2.1 + PKCE with RFC 8707 resource indicators. Local stdio servers have no auth surface by design.
This describes the current stable 2025-11-25 specification. A release candidate for the largest revision since MCP launched is locked and set to finalize 2026-07-28 — it keeps JSON-RPC 2.0 and tools/list / tools/call but removes the session handshake for a stateless core and hardens authorization. See MCP goes stateless for the full RC breakdown.
Decision table
| Criterion | Function calling | MCP |
|---|---|---|
| Where the tool runs | In-process (your app code) | Out-of-process server |
| Tool discovery | Static, defined at call time | Dynamic, tools/list at session start |
| Reuse across apps | Manual — duplicate schema per app | Zero-copy — connect any MCP client |
| Provider portability | Tied to one provider schema | Client adapts to any provider |
| Auth requirement | None (your code, your auth) | OAuth 2.1 + PKCE for remote servers |
| Setup cost | Minutes — just JSON schema + handler | Higher — server process + transport |
| Best fit | 1–3 tools, single app, prototype | Shared toolset, many clients, production |
When to use each
Use function calling when you are building a single application, the tool implementations are already in your codebase, you have fewer than ~5 tools, or you need a prototype in minutes. Inline schemas keep everything in one place and add no process boundary.
Use MCP when the same capability needs to be available to multiple host applications or model providers; you want tools versioned and deployed independently of the host; you need runtime discovery so new tools appear without redeploying the host; or your team wants to publish tools to the ecosystem (registry-discoverable, shared). See /resources/building-mcp-servers for implementation steps.
Use both: in production systems the two layers are present simultaneously. The host uses function calling at the LLM API layer and MCP at the tool-sourcing layer. MCP does not replace function calling; it standardises where the tools come from and how they are wired in.
Practical architecture note
For tool discovery across a fleet of MCP servers, see /resources/mcp-server-discovery. A single host can connect to multiple MCP servers; the client merges all tools/list responses before constructing the prompt. Namespace collisions (same tool name from two servers) must be handled by the client — typically by prefixing with the server name.
Verified sources
- MCP specification (tools primitive, OAuth 2.1 auth,
tools/list/tools/callJSON-RPC methods): https://modelcontextprotocol.io/specification - Anthropic tool use (
tool_usecontent blocks,tool_choice): https://docs.anthropic.com/en/docs/build-with-claude/tool-use - OpenAI function calling (
tool_calls,tool_choice): https://platform.openai.com/docs/guides/function-calling - MCP 2026-07-28 release-candidate announcement (stateless core, auth revisions): https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/