MCP vs function calling: what each does and when to use which
Function calling, also called tool calling, is how a model asks your code to run a function - you send tool definitions with the request, the model answers with a call and its arguments, and your code runs it and sends back the result. MCP, the Model Context Protocol, is an open standard for putting tools in a server that any MCP app can connect to. They are not rivals - an app lists an MCP server's tools, gives them to the model through function calling, and passes each call the model makes back to the server.
Take this page into your AI
Open in ChatGPT (new tab)Open in Claude (new tab)- Function callingPart of each model maker's APIA feature of a model's API. The request carries tool definitions, the reply can carry a call to one of them, and your code runs it.Documentation
- MCPOpen standardThe Model Context Protocol, for putting tools, data and prompts in a server that any MCP app can connect to, such as Claude Code, ChatGPT or VS Code.
uv add "mcp[cli]"Documentation
Both are about one thing: letting a model do something outside its own text, such as look up an order. Function callingFunction CallingThe developer's name for tool use. The model replies with the name of a function and its arguments in a fixed format, and your code runs it. is the mechanism inside a single conversation with the model. The Model Context ProtocolModel Context ProtocolAn open standard for connecting AI applications to tools and data. A system offered once as an MCP server works in any application that speaks MCP. is a standard for packaging tools so that any app can use them. Most confusion comes from treating them as 2 answers to the same question, when each answers a different one.
Function calling: the model asks, your code runs
The model cannot run anything. With function calling you send, alongside the user's message, a list of tools: each one a name, a sentence on what it does and a JSON schema for its inputs. When the model decides a tool would help, it does not answer in text; it replies with the tool's name and the arguments it chose. Your code runs the function, and you send the result back in the next request, marked with the id of the call it answers. The model reads it and either answers or asks for another tool. That repeated round trip is the agent loop in its plainest form.
Every major model API works this way, under 2 names. Anthropic calls it tool useTool UseGiving a model a list of things it can ask to have done, such as search the web or read a file. The model asks; the program around it does the work and hands back the result., OpenAI calls it function calling or tool calling, and the shapes are close: a name, a description and a schema.
MCP: tools in a server any app can use
Function calling leaves one question open: where do the tools come from? If your agent, Claude Code and a colleague's chat app all need to look up orders, each one would need its own copy of the code. MCP answers that question. An MCP server holds the tools, and any app that speaks MCP can connect to it, ask for its list of tools with tools/list and run one with tools/call.
A server can run on your machine, started by the app and spoken to over standard input and output, or on another machine, reached over HTTP. Besides tools, a server can offer resources, which are data the app can read, and prompts, which are templates a person can pick.
How they fit together
This is the part most comparisons miss. The model never talks to an MCP server. When an app such as Claude Code connects to one, it fetches the server's tools and hands them to the model as ordinary tool definitions, through function calling. When the model asks for one of those tools, the app catches the call, sends it to the server with tools/call and puts the result back into the conversation.
So MCP decides where tools live and how apps reach them; function calling is still how the model asks for one. Even the Claude Agent SDK's own custom tools are an in-process MCP server, offered to Claude through the same tool calls.
Side by side
| Function calling | MCP | |
|---|---|---|
| What it is | Function callingA feature of a model's API. The request carries tool definitions; the reply can carry a tool call. | MCPA protocol between an AI app and a server, with JSON-RPC messages to list tools and call them. |
| Who talks to whom | Function callingYour code and the model. | MCPThe app's MCP client and the MCP server. The model never talks to the server. |
| Where a tool is defined | Function callingIn your code, as a name, a description and a JSON schema for its inputs, sent with each request. | MCPIn the server. The app asks for the list with tools/list; a Python server writes each schema from the function's type hints. |
| Who runs the tool | Function callingYour code, in the same program. | MCPThe server, on your machine over stdio or on another machine over Streamable HTTP. |
| Reuse | Function callingWritten for one app. Another app needs its own copy. | MCPWritten once. Any MCP app can connect to it. |
| Beyond tools | Function callingTools only. | MCPTools, resources (data to read) and prompts (templates), and a way for the server to ask the user for input. |
| When the tools change | Function callingYou send a different list with the next request. | MCPThe server can tell connected apps that its list changed, and they fetch it again. |
| What you must trust | Function callingYour own code. | MCPThe server's code and its tool descriptions, which reach the model. A local server runs with your permissions. |
| Best for | Function callingTools only your app uses, kept next to its own code. | MCPTools that several apps or agents share, such as access to a company system. |
The same tool both ways
The same tool, get_order, written both ways: look up order A-1042 and say what happened to it. The order data is made up so each file stands alone.
import anthropic
ORDERS = {"A-1042": "total 140.00, delivered 6 days late"}
def get_order(order_id: str) -> str:
return ORDERS.get(order_id, "no such order")
tools = [
{
"name": "get_order",
"description": "Look up an order: its total and how it was delivered.",
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}
]
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What happened to order A-1042?"}]
while True:
reply = client.messages.create(model="claude-sonnet-5-5", max_tokens=1024, tools=tools, messages=messages)
messages.append({"role": "assistant", "content": reply.content})
if reply.stop_reason != "tool_use":
break
# Your code runs each tool the model asked for and sends back what it returned.
results = [
{"type": "tool_result", "tool_use_id": block.id, "content": get_order(**block.input)}
for block in reply.content
if block.type == "tool_use"
]
messages.append({"role": "user", "content": results})
print(next(block.text for block in reply.content if block.type == "text"))
You write the tool's schema by hand and run the loop yourself - while the model stops to ask for a tool, run it and send back a tool_result with the id of the call it answers. Set ANTHROPIC_API_KEY to run it.
from mcp.server import MCPServer
ORDERS = {"A-1042": "total 140.00, delivered 6 days late"}
mcp = MCPServer("shop")
@mcp.tool()
def get_order(order_id: str) -> str:
"""Look up an order: its total and how it was delivered."""
return ORDERS.get(order_id, "no such order")
if __name__ == "__main__":
mcp.run(transport="stdio")
The server builds the same schema from the type hint and the docstring, and holds no model and no loop: the app that connects does that. Add it to Claude Code with claude mcp add shop -- python shop_server.py, or to an Agent SDK agent with mcp_servers={"shop": {"command": "python", "args": ["shop_server.py"]}}.
The function-calling file holds everything in 1 program: the schema, written by hand, the function and the loop. The MCP file holds only the tool. Its schema comes from the type hint and the docstring, and it has no model and no loop, because those belong to whichever app connects.
Which to use
A tool only my app uses
Function calling
Define it in your request and run it in your own code. There is no server to start, connect or secure.
The same tools in several apps
MCP
Write the tools once as an MCP server, and Claude Code, ChatGPT, VS Code and your own agents can all connect to it.
Let customers' AI apps use my product
MCP
A remote MCP server over Streamable HTTP lets any MCP app reach your product, with sign-in through OAuth.
A ready-made integration, such as GitHub
MCP
Many systems already have an MCP server. Connecting one is a line of setup instead of writing the tools.
The fewest moving parts
Function calling
1 program, 1 API, and a short loop. Nothing else runs, so nothing else can fail or be swapped out.
Things to watch with MCP
- A server is code you run. A local MCP server is a program on your machine with your permissions. Connect servers from sources you trust, as you would install any package.
- Tool descriptions reach the model. A server's descriptions and results go into the model's context, where text written to mislead it can act as prompt injectionPrompt InjectionAn attack that hides instructions in text a model reads, such as a web page, an email or a file, so the model follows the attacker instead of you.. Keep a person's approval on tools that change things.
- Ask for the narrowest access. A server that signs in to another system should hold only the scopes it needs, so a leaked token can do little.
- Many tools cost context. Every tool's definition takes room in the context windowContext WindowEverything a model can see at once while it writes an answer, counted in tokens. When the window is full, something has to be left out. on every request, so connect the servers a job needs, not every one you have.
To see a tool call inside a whole agent, with the loop, memory and a guardrail, follow one request through How AI agents work. To choose a framework that runs the loop for you, read LangGraph vs CrewAI vs Claude Agent SDK.
Questions
- Is MCP the same as function calling?
- No. Function calling is how a model asks for a tool to be run, inside one app's conversation with the model. MCP is a standard for where tools come from - a server that any MCP app can connect to. An MCP app takes the server's tools and offers them to the model through function calling, so the 2 work together.
- Does MCP replace function calling?
- No, it sits on top of it. When the model decides to use an MCP tool, it still makes a tool call; the app catches that call, sends it to the MCP server with tools/call, and returns the result to the model as part of the conversation.
- What is tool calling?
- Another name for function calling. OpenAI's documentation uses both names for the same thing - the model replies with the name of a tool and its arguments instead of text, your code runs the tool, and you send the result back.
- When should I build an MCP server instead of using function calling?
- Build an MCP server when the same tools should work in more than 1 app, such as your own agent and Claude Code, or when people outside your team should connect their AI apps to your product. Keep plain function calling when the tool belongs to 1 app and sits next to its code.
- Can the Claude API use an MCP server directly?
- Yes. The MCP connector in the Messages API, in beta, connects to a remote MCP server by its address with no MCP client of your own. It supports tool calls only, and only servers reachable over HTTP; a local stdio server needs an MCP client such as Claude Code or the Agent SDK.
- Is MCP safe to use?
- As safe as the servers you connect. A local server is a program running with your permissions, and a server's tool descriptions and results reach the model, where text written to mislead it can act as prompt injection. Connect servers you trust, give each the narrowest access it needs, and keep a person's approval on tools that change things.
Sources
Where each fact comes from
- 1How tool use works
- 2Define tools
- 3Handle tool calls
- 4Function calling
- 5What is the Model Context Protocol (MCP)?
- 6Architecture overview
- 7Tools
- 8Build an MCP server
- 9Security best practices
- 10MCP connector
- 11Connect Claude Code to tools via MCP
- 12Connect to external tools with MCP
- 13Give Claude custom tools
- 14Tool use with Claude