MCP Explained
This post explains MCP for software developers, by a software developer.
After reading this post, you will understand what exactly is MCP, what problems does it solve, how it relates to Function Calling, why not just use OpenAPI over HTTP as the protocol, etc.
What is Model Context Protocol (MCP)?
MCP is a protocol that enables seamless integration between agents and external services.
Think MCP as a plugin system for agents.
MCP allows Service Providers to easily make plugins that connect to their services. It also allows Agent Developers to easily use plugins to extend capabilities of their agents.
As long as the plugins made conform to the MCP standard interface, they can be readily used by agents — no custom wiring and integrations required.
What do we mean by agents
In this post, agents just mean AI applications. They use models (aka, LLM) to make decision, and use tools to take actions to interact with external services.
Example agents:
A general agent like Claude, ChatGPT, Manus (can be web/mobile/desktop app)
A coding agent in the form of IDE or extension like Cursor, Windsurf, Cline, etc.
An AI-powered standalone SaaS or embedded workflow in a larger app
In the MCP context, agents are referred as the MCP Hosts.
What do we mean services
Services provide specific functionality such as getting weather information or creating a refund. Services expose functionality through APIs.
Example services:
Slack or Stripe via REST API Endpoint
GitHub via GraphQL API Endpoint
Git via Command Line Interface
Local Filesystem via POSIX System Call
In the MCP context, services are referred as the Local Data Sources and Remote Services.
How agents connect to services, prior to MCP
Connecting agents to services isn’t something we can’t do before MCP.
Agent Developers have been writing custom function tools to connect agents to any services, leveraging the LLM’s Function Calling capability.
Tools are lightweight integration code that enable agents to use external services. For example, a Slack Tool might enable an agent to send messages using Slack API, while a GitHub Tool could allow an agent to manage repositories using the GitHub API.
However, without MCP, agent developers often face the following challenges:
Redundant work: Every agent developer needs to build and maintain their own custom connectors (tools) for each service, even when others have done it before.
Fragmented ecosystem: Each agent or agent framework builds its own incompatible plugin or tool system, making it hard to share tools across agents.
Tight coupling: Tools must be wired into agents at build time and executed locally to the agents, making it difficult to change or update integrations without redeploying the agent.
How agents connect to services, with MCP
MCP comes in and addresses these challenges. With MCP,
Service Providers can easily author tools for their services
Agent Developers (or even the Agent Users) can easily extend agents with tools
Agents can easily discover tools at run time, and execute those tools locally or remotely
In the MCP context, tools are implemented and executed in MCP Servers, while tool interfaces are exposed and invoked through the connected MCP Clients.
This is classic client-sever architecture.
What benefits does MCP bring?
MCP increases interoperability and reusability of agent to services integration.
This leads to an important impact: (1) building agents are easier, and (2) agents are more powerful and extensible. This impact will compound as MCP ecosystem continues to grow.
That’s it—you’ve just grasped the core idea of MCP, especially if you’ve built AI apps before.
Still feeling unsure? New to AI apps development? No worries. In the next section, we’ll walk you through an analogy to help make MCP clear and show why it matters.
Explaining MCP using the USB analogy
The official MCP documentation uses a USB analogy. Here, we expand on it to give you a deeper understanding of MCP’s purpose and its connection to USB.
The above diagram is from norahsakal.com.
Think Agents as computers, and Services as devices
In the USB analogy, an agent is like a computer—your PC, MacBook, or smartphone. A service is like external device—monitor, external hard drive, printer, speaker, and so on.
Services expose functionality through APIs—just like devices expose capabilities via ports
APIs vary widely; some use REST, some use GraphQL, and others can be libraries or system calls. Similarly, devices use HDMI, VGA, Lightning, or USB-C ports. There's no single standard.
Agents struggle with arbitrary APIs but excel at one: Function
Before MCP, all leading LLMs already excel at using functions, given the function schema.
Think function schema as a JSON representation of the interface (or signature) of a function in a programming language, along with proper documentations of function and its parameters.
For instance, the function schema object of a get_weather
function might look like this:
{
"name": "get_weather",
"description": "Get current temperature for a given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country e.g. Bogotá, Colombia"
}
},
"required": [
"location"
],
"additionalProperties": False
},
"strict": True
}
parameters
, Claude calls it input_schema
. But the shape of parameters
are the same.LLMs can understand function schema, and generate function calls based on the schema.
A function call object of the get_weather
function might look like this.
{
"name": "get_weather",
"arguments": {
"location": "Tokyo, Japan"
}
}
arguments
, Claude calls it inputs
and Gemini calls it args
. But the shape of arguments
are the same.The takeaway is that Function Schema is already the de facto standard for LLM to interact with service. It is like the USB port.
Function tools are basically adapters, like X-to-USB adapter cables
Most services API, however, are not in the form of function schema (i.e., they don’t "speak USB" natively). For examples, services may expose REST HTTP endpoints instead.
So in practices, function tools act like adapter cables—they are lightweight integration code that convert from function schema (USB port) to whatever API format the service exposes (HDMI, Lightning, etc.).
These X-to-USB adapter cables are known as the function tools (aka, Function Calling tools).
Below is a function tool example using the OpenAI Agents SDK framework. It’s essentially an adapter between a Python function interface to a remote REST API endpoint interface.
from agents import function_tool
import httpx
@function_tool
async def get_weather(location: str) -> str:
"""Fetch the weather for a given location.
Args:
location: The location to get the weather for.
"""
# Construct a REST request to a remote weather endpoint
url = ...
headers = { ... }
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers)
response.raise_for_status()
return response.json()
except Exception:
return None
Agents use function calling tools to interact with service API, just like a devices with different ports use a X-to-USB adapter to connect to computer that only accept USB.
But without MCP, building agent with Function Calling can be messy
Function Calling solves agent-to-tool connectivity, but using Function Calling alone have two main problems:
Reusability – Every agent developer builds their own adapter (tool) from scratch for the same service. Building 100 agents that can use Slack = building 100 ad-hoc, redundant Slack adapters.
Manageability – Agent developers have to maintain all those adapters individually. Imagine hand maintain 20 adapter cables each directly plug into to the computer.
In the early date of AI apps development, developers even write their own “boilerplate code” to register and execute tools, while they are busy building their agentic apps. This is like every web app developer writes their own HTTP server rather than using a web framework.
Then Agent Frameworks (like LangChain, AutoGen) come along to push these “boilerplate code” inside the framework. This has greatly simplified agent development because developer can focus on building their agents rather than writing the framework-level code.
Some of these frameworks go further and ship a dozen of pre-built tools which mitigate the reusability problem. However agent frameworks are still fragmented; a Service Provider like Slack would need to maintain a Slack for LangChain, a Slack tool for AutoGen, and maybe 10 other frameworks to come.
Enter MCP: the Universal Device Hub for Agents
With MCP, it’s like giving your agent a USB-C hub.
The services connect to the hub, through the MCP Servers. The MCP servers are the custom adapters that convert service API calls from/to standard MCP tool calls.
The agent connects once to the hub, using a MCP Client. MCP Client can convert MCP tool calls from/to standard Function Calling tool calls, which agent can send over to LLM.
Below is a MCP server example. This server contains one MCP tool (but it can contain more). It’s basically the same as the function tool we have using the OpenAI Agents SDK framework, but just write it with the MCP Server SDK. It’s still an adapter from function to service API.
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
@mcp.tool()
async def get_weather(location: str) -> str:
"""Fetch the weather for a given location.
Args:
location: The location to get the weather for.
"""
# Construct a REST request to a remote weather endpoint
url = ...
headers = { ... }
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers)
response.raise_for_status()
return response.json()
except Exception:
return None
if __name__ == "__main__":
mcp.run(transport='stdio')
MCP: Interoperability with reduced integration complexity
One agent can discover and invoke multiple connected services, through the hub and the adapters.
Similarly, through the same hub and the adapters, one service can be discovered and invoked by multiple connected agents.
MCP, as a extra layer of indirection, has reduced the NxM integrations to N+M integrations.
MCP solves the reusability problem for agent developers, because the hub provides prebuilt reusable adapters to a large growing list of services. These adapters are authored by the Service Providers or community, unlike previously agents developers repeatedly write their own adapters for each service.
MCP solves the manageability problem for agent developers, because now agent connects to the hub once, and the hub handles the connections to individual services. Services are automatically discoverable and interoperable across agents.
MCP: Upgrading communication capabilities (like USB-C)
Beyond reusability and manageability, MCP provides additional benefits over using Function Calling alone.
One major benefit is MCP enables plug and unplug services at runtime — no need to recompile, redeploy, or even restart the agents in order to add a service.
Before MCP, tools are usually defined and discovered during agent (AI app) build time. This is like having fixed wiring of all devices when your computer is built. MCP provides functionality to achieve that at scale.
This is a big deal because it open up the possibility for the Agent’s users (like the users of Claude or Cursor) to easily extend agents with new functionality after the agent (AI app) has released.
The MCP tools also enable other sophisticated communication, such as remote tool execution, two-way communication, tool result streaming, and more.
If we think computer expose USB-B port (Function Calling tools), then the MCP hub effectively exposes the more advanced USB-C port (MCP tools).
USB analogy recap
Let’s recap the relationship between components in MCP and USB.
MCP Terminology | USB Terminology | Agent Terminology |
MCP Host | Computer | Agent |
MCP Client | USB-C Driver installed on the Computer | Tool Integration Module |
MCP Server | X-to-MCP Adapter (X is HDMI, Lightning, VGA, etc.) | Tool |
Service or Data Source | Device (exposing HDMI, Lightning, VGA, etc.) | Service |
Frequently Asked Questions
Now that we understand MCP concept, let’s answer some of the most asked questions. If you have the same questions, congrats - you are a critical thinker.
Does MCP replace Function Calling?
Not exactly. MCP and Function Calling still work together.
Agents use Function Calling to decide when to use which tool with what arguments. That doesn’t change with or without MCP. In fact, the Function Calling support among LLM providers has standardized the interface between model and tools using function schema.
However, the tool integration aspects such as tool authoring, tool registry, tool discovery, and tool execution were all left unspecified by the LLM.
Agent frameworks (like LangChain, CrewAI, OpenAI Agents SDK) have their own tool integration module that manage these aspects. What MCP really replaces are such modules of the agent frameworks.
Does MCP replace API?
No, MCP does not eliminate the need for APIs—it builds a standardized layer on top of them.
APIs are still how services expose their functionality. MCP simply makes those APIs easier for agents to discover, understand, and use at runtime.
Think of MCP as the bridge between an agent’s Function Calling and a service’s underlying API—regardless of whether it’s REST, GraphQL, SDKs, or system calls.
Why not just let AI write the service API integration code on the fly?
AI is already good at coding. So, why not just have AI write the API integration code, by throwing it the API docs? Then agent developers don’t need to write and maintain them right?
The short answer is AI is not advanced enough to reliably do it yet. API formats are heterogeneous, API usage can vary, docs may be insufficient, auth might be difficult, and more.
The most reliable integration is still through code authored and tested, ideally by the Service Providers. Plus it’s way more economical - there is no reason to produce the same integration code on the fly.
Why not just use OpenAPI? Why the need separate layer?
One may ask why not just describe service APIs via OpenAPI protocol, have LLM generates the API calls based on OpenAPI schema, and have agents execute the API calls.
This will mitigate the heterogeneous API concern right? Do we still need an extra MCP layer? After all, that’s what OpenAI’s Custom GPT does, isn’t it?
One limitation of OpenAPI is that it was designed for invocation of remote HTTP endpoints. But agent needs to invoke local API which can be in the form of CLI, local library, or system call.
There also exist remote API that are not REST such as GraphQL endpoints. Or the remote API may not even be HTTP-based such as database wire protocol.
MCP also offers purpose-built, AI-native protocol design, stateful connections, native streaming, and dynamic tool discovery—things OpenAPI wasn’t built for.
Therefore, OpenAPI alone is not a sufficient solution.
Why not just have a repo of pre-built tools? Why the need of client-server?
One may ask why not simply implement “MCP Servers” as local functions, say, a collection of Python tools in a central repo, installable as a library? After all, these servers are just lightweight integration code. Why introduce the complexity of a client-server model with a transport layer in between?
It’s a deliberate design trade-off—similar to choosing between local libraries and remote services. The client-server approach offers several key advantages:
Language decoupling: servers can be written in any language, independent of the client’s.
Decentralized deployment: tools can run where they’re most effective.
Runtime flexibility: servers can be updated or swapped without redeploying the client.
Stateful and streaming support: easier to handle advanced interactions that don’t fit well into stateless function calls.
What’s clever about Anthropic’s design is that MCP supports standard I/O (STDIO) as a transport, enabling local deployment via subprocesses. This makes it easy and cost-effective to spin up MCP servers without needing full infrastructure orchestration.
How can I use MCP in my agents (AI applications)?
If you build agents using an agent framework, refer to your framework’s guides on MCP integration. For example, OpenAI has a guide on using MCP in its Agents SDK.
If you build agents directly using the LLM APIs, refer to the Official MCP Quickstart Guide for Client Developer.
The below diagram illustrates the user query handling flow that involves using MCP tools. The ClientSession
is the key abstraction offered by the MCP SDK that you agent needs to use.