📑 Table of contents

MCP, Function Calling, Tool Use: The Complete Guide

MCP, Function Calling, Tool Use: The Complete Guide

Agents IA 🟡 Intermediate ⏱️ 15 min read 📅 2026-02-24

MCP, Function Calling, Tool Use: the complete guide

Large language models (LLMs) are powerful, but they have a fundamental limitation: they can only generate text. For an AI agent to truly act — search the web, query a database, send an email — it needs a mechanism that allows it to call external tools. This is exactly what MCP (Model Context Protocol), Function Calling (OpenAI), and Tool Use (Anthropic) offer.

In this guide, we break down each approach, compare their architectures, and provide ready-to-use code examples to integrate tools into your AI agents.

The essentials

  • Function Calling (OpenAI): proprietary mechanism integrated into the GPT API, where you declare functions in JSON Schema and the model decides to call them. Simple and quick to set up.
  • Tool Use (Anthropic): similar approach for Claude, with native error handling (is_error) and the ability for the model to visibly "think" before calling a tool.
  • MCP (Model Context Protocol): open protocol launched in late 2024 by Anthropic, which standardizes the connection of LLMs to tools and data, much like USB for peripherals.
  • In 2025, the trend is towards interoperability: define your tools once and make them usable regardless of the LLM.

🧠 Why LLMs need tools

An LLM alone cannot:

  • Access real-time data (weather, stock prices, news)
  • Perform precise calculations (complex arithmetic, conversions)
  • Interact with external systems (APIs, databases, files)
  • Execute code or system commands

Without a tool calling mechanism, an LLM is doomed to hallucinate answers to these questions. Tool calling protocols solve this problem by allowing the model to declare that it wants to use a tool, and then receive the result to formulate its final response.

The general flow is always the same:

  1. The user asks a question
  2. The model identifies that a tool is needed
  3. The model produces a structured call (tool name + parameters)
  4. The host system executes the tool
  5. The result is returned to the model
  6. The model formulates its final response

What changes between approaches is how steps 3 to 5 are implemented.

🔧 Function Calling (OpenAI)

Principle

Function Calling is the approach introduced by OpenAI in June 2023. The idea is simple: you describe available functions in your system prompt as JSON schemas, and the model can decide to call one instead of responding directly.

Architecture

The execution flow follows a cascading logic: the user request is sent to the OpenAI API along with the function definitions. The model analyzes the request, chooses to call a function, and returns a structured JSON call. It is then up to your code to intercept this JSON, execute the corresponding local function, and then return the result to the model so it can formulate its final response.

Function definitions

Each function is described via a JSON Schema comprising a name, a detailed textual description, and a parameters object defining the expected properties (type, enumerations, required fields). The tool described here takes a city and a temperature unit, then returns the weather conditions.

Complete example in Python

The Python implementation uses the OpenAI SDK: you declare the available tools, send the conversation to the model with tool_choice="auto", and then intercept the tool_calls in the response. For each call, you execute the local function, return the result via a tool role message with the tool_call_id, and make another call to obtain the final formatted response.

Calling modes

OpenAI offers three modes via the tool_choice parameter:

Mode Behavior
"auto" The model decides on its own whether to call a function
"none" The model cannot call a function
"required" The model must call at least one function
{"type": "function", "function": {"name": "X"}} Forces the call of a specific function

Parallel calls

Since late 2023, GPT-4 and GPT-3.5-turbo can trigger multiple function calls in parallel in a single response. For example, if the user asks for "the weather in Paris and in Lyon", the model will produce two simultaneous tool_calls that your code can process independently in a loop. You can disable this behavior with parallel_tool_calls: false.

Strengths and limitations

Advantages:
- Simple and well-documented syntax
- Native support for parallel calls
- Large ecosystem of examples
- Compatible with all recent GPT models

Limitations:
- Proprietary to OpenAI (although the format is adopted by others)
- Function definitions consume tokens
- No official open standard

🛠️ Tool Use (Anthropic)

Principle

Anthropic introduced Tool Use for Claude in April 2024. The concept is similar to OpenAI's Function Calling, but with a few notable architectural differences, particularly in the message format and result handling.

Architecture

Anthropic's flow is close to OpenAI's, but the message format differs: the user request is sent to the Anthropic API with the tool definitions. Claude chooses a tool and returns a tool_use block integrated into its content. Your code executes the tool, then returns the result via a tool_result type message. The model receives this result and produces the final response.

Tool definitions

Anthropic also uses JSON Schema but with a slightly different structure: the input_schema key replaces parameters. The tool takes the same parameters (city and unit), with detailed descriptions to guide the model in its choice.

Complete example in Python

The implementation with the Anthropic SDK follows the same pattern: declaring tools, initial call, then detecting stop_reason == "tool_use". You then extract the tool_use block from response.content, execute the function, and return the result in a user message containing a tool_result type block with the corresponding tool_use_id. A second call to the model produces the final response.

Tool use control

Anthropic offers a similar tool_choice parameter:

Mode Behavior
{"type": "auto"} Claude decides on its own
{"type": "any"} Claude must use a tool (any tool)
{"type": "tool", "name": "X"} Forces the use of a specific tool

Anthropic's specificities

"Thinking" before the tool: Claude can include text (reflection) before the tool call in the same message. This provides transparency into its reasoning.

Error results: You can signal that a tool has failed by setting the is_error field to true in the tool_result block, accompanied by a message describing the error. Claude will adapt its response accordingly, potentially by reformulating its request or informing the user.

Strengths and limitations

Advantages:
- Visible reflection before the tool call
- Native error handling with is_error
- Highly detailed tool descriptions for better choices
- Streaming support with tool_use blocks

Limitations:
- Slightly more verbose format
- Smaller ecosystem of examples (but growing rapidly)
- The tool result must be in a user message (specific architecture)

🌐 MCP (Model Context Protocol)

Principle

MCP is an open protocol created by Anthropic and published in late 2024. Unlike Function Calling and Tool Use, which are API mechanisms specific to each provider, MCP aims to be a universal standard for connecting LLMs to data sources and tools.

The analogy often used: MCP is to LLMs what USB is to peripherals. A single protocol to connect everything.

Architecture

MCP introduces a client-server architecture structured around three components. The host application (Claude Desktop, an IDE, or your agent) encapsulates one or more MCP clients. Each client maintains a 1:1 connection with a distinct MCP server — for example, a server for local file access, another for the GitHub API. Servers expose tools, resources, and prompts in a standardized way, allowing the host to consume them without worrying about their internal implementation.

The three MCP primitives

MCP is not limited to tools. It exposes three types of capabilities:

Primitive Description Example
Tools Functions callable by the LLM Search the web, execute SQL
Resources Queryable data (read-only) File content, query result
Prompts Reusable prompt templates Summary template, analysis template

Example MCP server in Python

With the official Python SDK, you create a server via FastMCP("weather-server"). The get_weather tool is declared with the @mcp.tool() decorator, a read-only resource via @mcp.resource() with a URI of type weather://current/{city}, and a reusable prompt via @mcp.prompt(). The server is then launched with mcp.run() on the stdio transport.

Example MCP server in TypeScript

In TypeScript, the SDK provides the McpServer class to which you attach tools via server.tool(). Each tool receives a name, a description, and a Zod schema for parameter validation. The result is returned as JSON text content. The server then listens on the StdioServerTransport.

Transports

MCP supports two transport modes:

Transport Usage Communication
stdio Local servers The client launches the server as a child process
SSE (Server-Sent Events) Remote servers HTTP communication, ideal for cloud services

Configuration in Claude Desktop

Configuration is done in Claude Desktop's JSON file, under the mcpServers key. Each server is defined by a command (python, npx, etc.), arguments, and optionally environment variables like API tokens. For example, you can launch a weather server in Python and the GitHub server via npx with a GITHUB_TOKEN.

MCP server ecosystem

One of the great advantages of MCP is its growing ecosystem of off-the-shelf servers:

  • Files: Reading/writing local files
  • GitHub: Repos, issues, pull requests
  • Databases: PostgreSQL, SQLite, MongoDB
  • Web: Brave Search, Fetch
  • Productivity: Google Drive, Slack, Notion
  • Development: Docker, Kubernetes

Strengths and limitations

Advantages:
- Open and interoperable standard
- Three primitives (tools, resources, prompts)
- Ecosystem of reusable servers
- Clear client/server separation
- Works with any LLM (not tied to a provider)

Limitations:
- More complex to set up than simple function calling
- Still young (evolving spec)
- Requires a runtime for servers
- Overhead for simple use cases

📊 Complete comparison table

Criterion Function Calling (OpenAI) Tool Use (Anthropic) MCP
Type Proprietary API Proprietary API Open protocol
Creator OpenAI Anthropic Anthropic (open source)
Definition format JSON Schema (parameters) JSON Schema (input_schema) Decorators / SDK
Parallel calls ✅ Native ✅ Possible ✅ Via the client
Error handling Via message content Native is_error Via the protocol
Streaming
Multi-provider ❌ (format adopted by others)
Resources (data)
Reusable prompts
Setup complexity ⭐ Low ⭐ Low ⭐⭐⭐ Medium
Maturity ⭐⭐⭐ ⭐⭐ ⭐⭐
Documentation Excellent Very good Good (growing)

🔀 When to use what?

Use Function Calling (OpenAI) if:

  • You are already using GPT models
  • Your use case is simple (a few functions)
  • You want the fastest possible setup
  • You don't need to share your tools across projects

Use Tool Use (Anthropic) if:

  • You use Claude as your main model
  • You need the model's visible reasoning
  • Fine-grained error handling is important
  • You want a model that excels at choosing complex tools

Use MCP if:

  • You are building an agent that must work with multiple LLMs
  • You want an ecosystem of reusable tools across projects
  • You need more than just tools (resources, prompts)
  • You are building a platform or an agent framework
  • Standardization and interoperability are top priorities

Combining approaches

In practice, many developers combine these approaches. For example:

  • Using MCP to define and share tools
  • Translating MCP tools into Function Calling or Tool Use depending on the LLM used
  • Frameworks like LangChain and OpenClaw do this translation automatically

A typical universal agent instantiates an MCP client connected to tool servers, then dynamically converts the list of MCP tools to the Function Calling or Tool Use format based on the selected LLM provider. When a tool call is detected in the LLM's response, the agent executes it via the MCP client and returns the result to the model.

🚀 Common best practices

Regardless of the chosen approach, certain best practices always apply:

1. Clear and precise descriptions

The model chooses its tools based on descriptions. Be explicit: a vague description like "Search for stuff" will yield poor results. Prefer a detailed description that specifies the source, return format, and limitations, for example "Searches articles in the database by keyword. Returns the 10 most recent results with title, date, and summary."

2. Validate parameters

Never trust the parameters generated by the model without validation. For each tool, systematically check types, value ranges, and path security (for example, block paths containing .. or starting with / for file operations).

3. Handle errors gracefully

Return clear error messages so the model can adapt: structure your error returns with a success indicator, the error message, and ideally a suggestion for correction. This allows the LLM to reformulate its request or inform the user usefully.

4. Limit the number of tools

The more tools you expose, the more likely the model is to make mistakes. Keep a focused and relevant set for the task.

Number of tools Recommendation
1-5 ✅ Ideal
6-15 ⚠️ Acceptable with good descriptions
15-30 ⚠️ Group into categories
30+ ❌ Too many — use a router or a tool selector

5. Test with edge cases

Models can hallucinate parameters or call the wrong tool. Systematically test:

  • Ambiguous requests ("search for this" → which tool?)
  • Missing parameters
  • Empty results or errors
  • Call chains (tool A → tool B)

🔮 The future of LLM-tool interactions

The ecosystem is evolving rapidly:

  • MCP is gaining adoption and could become the de facto standard
  • OpenAI and Google are working on their own tool protocols
  • Frameworks (LangChain, CrewAI, OpenClaw) abstract these differences
  • The trend is towards interoperability: a tool defined once, usable everywhere

The important thing is not to choose "the best" protocol, but to understand the underlying principles. The fundamental mechanism — the model declares it wants to use a tool, your code executes it, the result goes back to the model — remains the same everywhere.

Master this pattern, and you will be able to build AI agents capable of interacting with any system.

Common mistakes

  • Descriptions too vague: the model doesn't know when to use the tool and ends up hallucinating or ignoring the tool. Always specify the context of use, expected parameters, and return format.
  • Forgetting parameter validation: an LLM can generate unexpected values (file path with ../, negative integer for an ID, etc.). Systematically validate on the server side before execution.
  • Not handling errors: if a tool fails silently or returns a raw error, the model cannot adapt. Use is_error with Anthropic or a structured format with OpenAI.
  • Too many tools available: beyond about fifteen tools, selection performance drops. Add a router or a tool selector upstream.
  • Confusing MCP and Function Calling: MCP is a transport and definition protocol, not a direct calling mechanism by the LLM. An adapter is needed between the two.

FAQ

Does MCP replace OpenAI's Function Calling?
No, MCP is a definition and transport protocol. You can use MCP to define your tools, then translate them into Function Calling for the OpenAI API. The two are complementary.

Can you use multiple tools at the same time with Anthropic?
Yes, Claude can call multiple tools in a single response, but unlike OpenAI, this is not the default behavior. You need to handle it in your orchestration logic.

What is the maximum number of tools you can declare?
There is no strict limit on the API side, but selection performance degrades beyond 15-20 tools. Prefer a router or a selector for complex cases.

Does MCP work with LLMs other than Claude?
Yes, that's the whole point of the protocol. MCP servers can be consumed by any client, including GPT, Gemini, or open-source models via adapters.

What is the difference between a resource and a tool in MCP?
A tool is an executable function (with possible side effects), whereas a resource is read-only queryable data, such as the contents of a file or the result of a query.

Conclusion

MCP, Function Calling, and Tool Use share a fundamental principle: enabling an LLM to go beyond text to interact with the real world. OpenAI's Function Calling remains the simplest way to get started with GPT. Anthropic's Tool Use brings visible reasoning and finer error handling. MCP, for its part, paves the way for interoperability—a tool defined once, usable everywhere. In 2025, the right strategy is often to combine these approaches: MCP for definition and sharing, Function Calling or Tool Use for execution depending on the chosen model. Master this pattern, and you will build AI agents that don't just talk, but act.