Function Calling vs MCP: Different Layers, Different Jobs

Function calling and MCP are not competing standards. This guide explains the layer split, how they work together, and when direct function calling is enough.

Function calling and MCP do not solve the same problem. Function calling is the model's way of asking for a tool invocation. MCP is the protocol a host uses to discover, negotiate, and connect to external capabilities. If you keep those layers separate, most of the confusion disappears.

OpenAI's current function calling guide defines callable functions inside the tools parameter and describes their parameters with JSON Schema. Anthropic's current tool definition docs do the same job with an input_schema field. Meanwhile, OpenAI's tools guide lists remote MCP servers as a separate tool type entirely. That is the tell: these concepts are related, but they live at different layers.

If you need the protocol basics first, read What Is MCP?. If your real question is whether MCP replaces APIs, go to MCP vs API.

The short answer

QuestionFunction callingMCP
What is it?A model capability for structured tool requestsAn open protocol for connecting AI hosts to tools, resources, and prompts
Who defines it?Individual model platforms and APIsThe MCP standard
ScopeA tool call loop inside a model workflowA host-client-server integration layer
DiscoveryYou provide tool definitions to the modelThe host connects and discovers capabilities over protocol
PrimitivesCallable functionsTools, resources, prompts, lifecycle, negotiation
PortabilityProvider-specific formatsCross-host protocol surface

The simplest mental model is:

  • function calling is how the model asks
  • MCP is how the host knows what can be asked and where to send it

Function calling is a model capability

Function calling starts inside a model API request.

OpenAI's current docs say functions are usually declared in the tools parameter, and each function includes a name, description, parameters, and optional strict mode:

{
  "type": "function",
  "name": "get_weather",
  "description": "Retrieves current weather for the given location.",
  "parameters": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "City and country"
      }
    },
    "required": ["location"],
    "additionalProperties": false
  },
  "strict": true
}

Anthropic exposes the same general pattern with slightly different fields. Its tool docs define client tools in the top-level tools parameter and use input_schema to describe expected arguments.

That difference is exactly why this layer gets messy in real systems. The model behavior is similar, but the API formats are not identical.

With direct function calling:

  • you define the tools for the model
  • the model chooses a tool and arguments
  • your application executes the real work
  • your application returns the result back into the conversation loop

This can be perfectly fine when the tool set is small and the runtime is under your control.

MCP is an integration protocol around that loop

The latest MCP specification says MCP is an open protocol built on JSON-RPC 2.0 that connects hosts, clients, and servers. The latest architecture spec adds the crucial details: hosts manage multiple clients, each client maintains a 1:1 session with a server, and servers expose tools, resources, and prompts.

That means MCP adds several things function calling alone does not standardize:

  • protocol-level discovery
  • capability negotiation
  • stateful sessions
  • read-only resources
  • reusable prompts
  • transport choices such as stdio or Streamable HTTP

This is why "function calling vs MCP" is not really an either-or framing. One is a model behavior. The other is an application protocol.

A concrete OpenAI-side comparison

OpenAI's current API docs show both styles.

Direct function calling looks like this:

{
  "model": "gpt-5",
  "tools": [
    {
      "type": "function",
      "name": "get_weather",
      "description": "Get current temperature for a given location.",
      "parameters": {
        "type": "object",
        "properties": {
          "location": { "type": "string" }
        },
        "required": ["location"],
        "additionalProperties": false
      },
      "strict": true
    }
  ]
}

Remote MCP in the same API family looks different:

{
  "model": "gpt-5",
  "tools": [
    {
      "type": "mcp",
      "server_label": "weather",
      "server_url": "https://example.com/mcp",
      "require_approval": "never"
    }
  ]
}

The first gives the model a function definition directly. The second gives the host a remote MCP server to work with.

How they fit together in practice

Mermaid diagram source:
sequenceDiagram
  participant User
  participant Host
  participant Model
  participant Server as MCP Server
  participant API as Underlying API

  User->>Host: Ask for something
  Host->>Server: Discover tools and capabilities
  Host->>Model: Provide tool surface for reasoning
  Model->>Host: Choose a tool and arguments
  Host->>Server: Route the tool call
  Server->>API: Execute real work
  API-->>Server: Return data
  Server-->>Host: Return structured result
  Host-->>User: Final response or UI

The exact representation of the model's tool choice depends on the provider and host. That is where function calling or tool use lives. MCP sits around that selection step and standardizes the connection to the external capability.

What MCP adds that direct function calling does not

Discovery instead of hardcoding

With direct function calling, you usually define tools inside the request. With MCP, the host connects to a server and discovers its capabilities through the protocol.

More than callable actions

The server concepts docs define three building blocks:

  • tools for model-controlled actions
  • resources for read-only context
  • prompts for user-controlled templates

Function calling alone only covers the callable-action part of that picture.

Stateful lifecycle

The latest MCP lifecycle spec defines initialization, negotiation, operation, and shutdown. That gives hosts a consistent runtime model instead of a one-request-at-a-time tool definition loop.

Portability

This next point is an architectural inference from the standard, not a sentence the spec states verbatim: once a host understands MCP and a server speaks MCP, you avoid rewriting the same tool surface for every host-specific integration. That is the core practical value.

When direct function calling is enough

Use direct function calling when:

  • you control the whole application stack
  • you only need one model provider or one host
  • the tool set is small and fairly static
  • you want the fastest path to a prototype

For internal agents or tightly scoped assistants, this can be the right level of abstraction.

When MCP becomes the better layer

Use MCP when:

  • you want multiple hosts or clients to use the same capability
  • you want discovery rather than hardcoded tool lists
  • you need resources or prompts in addition to actions
  • you want richer UI surfaces on top of tool results
  • you care about a cleaner long-term integration contract

If richer UI is part of the goal, pair this with Building MCP Tools with Rich UIs.

The common mistake

The most common mistake is treating MCP as "function calling but better."

That framing makes people ask the wrong question. The real question is whether you only need the model to call a few local tools, or whether you need a portable host-to-capability protocol as well.

If you only need the first thing, direct function calling may be enough. If you need the second, MCP is the layer you are actually looking for.

Summary

Function calling is a model capability for structured tool requests. MCP is a protocol for hosts, clients, and servers to discover and manage external capabilities. They are different layers and often work together in the same system.

Use direct function calling when your runtime is simple and tightly scoped. Use MCP when you need discovery, session management, richer primitives, or cleaner portability across AI hosts.

FAQ

Is MCP better than function calling?

Not as a blanket statement. Function calling and MCP do different jobs. Direct function calling may be enough for a small single-provider workflow. MCP is better when you need a broader integration layer.

Does MCP replace OpenAI function calling?

No. MCP does not remove the need for a model to choose tools. It standardizes how hosts connect to external capabilities and what those capabilities expose.

Can MCP and function calling be used together?

Yes. In many real systems, the host discovers capabilities through MCP and the model still uses a tool-calling mechanism to select and invoke them.

When should I skip MCP?

Skip it when the tool set is tiny, the runtime is short-lived, and you do not expect to support multiple hosts or a richer capability surface.

What should I read after this?

Read MCP vs API if you are comparing protocols and service contracts. Read MCP Architecture Explained if you want the host-client-server internals.

If you want to move from theory to implementation, build a small direct tool loop first or jump straight to a portable setup with Build AI Apps Without Code.

Get the Builder Brief

Weekly tactical notes on shipping ChatGPT apps, MCP integrations, and product-led distribution.