MCP is how LLMs Are Learning to Act
MCP lets AI models act, not just talk. Discover how this open protocol connects LLMs to real tools and why success depends on clean JSON, good proxies, and the right model.
Large language models have become everyday tools, trusted to write emails, summarize documents, and brainstorm ideas. Yet for all their capabilities, they remain fundamentally passive. These models can inform, suggest, and predict, but they can’t act. They generate language, but they don’t interact.
That limitation is starting to shift with the arrival of the Model Context Protocol, or MCP. Introduced by Anthropic in late 2024 and quickly adopted by other players like OpenAI and Microsoft, MCP provides a standard way for language models to access tools, data sources, and services. It has been described as the USB C of AI, a single open interface that lets models connect with the outside world.
This article looks at three ideas: what MCP is, what it enables models to do (or not), and how it’s being used today to push AI beyond the prompt.
What Is MCP?
The Model Context Protocol, or MCP, is an open standard that lets large language models interact with external systems in a structured, secure way. On the surface, it resembles a simplified API interface, but its real power lies in how it presents tools to the model. Instead of calling a black box, the model is given a full description of what a tool does and how it should be used. This allows the model not only to access functionality, but to reason about when and how to use it.
Each tool is defined in JSON, with names, parameters, and expected types. The model reads these definitions as part of its context. When it decides to use a tool, it outputs a structured call in JSON, which is handed off to a proxy. That proxy handles execution — calling an API, running code, or talking to a system — and then returns the result. The model incorporates the result into its next response.
This architecture separates intent (from the model) from execution (by the proxy), giving developers full control over what actually runs while preserving the flexibility of natural language interfaces.
Building an MCP
Imagine a developer wants to give a language model the ability to explore the contents of a S3 bucket. The task is straight forward: list the files under a given prefix. But it highlights each part of the protocol in action: how the model learns about the tool, how it decides to use it, and how the system responds.
This interaction has three parts: the tool definition the model sees, the request the model sends, and the backend code that actually performs the action.
The first step is to define the tool using JSON. This is what the model receives as context. It is not executable code, just a description of what the tool does and how to use it.
{
"name": "list_s3_objects",
"description": "Lists the objects in a specified Amazon S3 bucket and optional prefix.",
"parameters": {
"type": "object",
"properties": {
"bucket_name": {
"type": "string",
"description": "Name of the S3 bucket to list from."
},
"prefix": {
"type": "string",
"description": "Optional path prefix within the bucket."
}
},
"required": ["bucket_name"]
}
}
MCP definition of a tool to interact with S3
This definition gives the model everything it needs to reason about the tool: its name, purpose, and how to structure input. From there, it can decide whether and how to use it during a conversation.
When the model decides that calling this tool is the best course of action—for example, after a prompt like “Can you show me what’s in the backups folder?”—it generates a JSON payload describing the call.
{
"tool_name": "list_s3_objects",
"parameters": {
"bucket_name": "my-project-backups",
"prefix": "2025-logs/"
}
}
Query an LLM might send to a MCP proxy
This output is passed to the MCP proxy, a piece of middleware that interprets and executes the tool call outside the model. The proxy handles authentication, error checking, and any post-processing, returning results that the model can use in its next message.
On the backend, the actual work happens in code. For an S3 bucket, that usually means calling the AWS API using a library like boto3. The proxy can implement this in any way, as long as it returns output in a form the model understands.
import boto3
def list_s3_objects(bucket_name, prefix=""):
s3 = boto3.client("s3")
response = s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
return [obj["Key"] for obj in response.get("Contents", [])]
Example of a simple MCP Proxy to list the content of a S3 bucket
The result, a list of filenames, is returned to the model, which uses it to answer the user’s original question. From the model’s perspective, it has just learned something new. From the system’s perspective, it has just completed a safe, delegated API call on the model’s behalf.
How MCP Succeed and Fail
The strength of MCP is that it gives language models the ability to act. With the right tools in place, a model can list files, query APIs, send messages, or control software. This unlocks entirely new use cases: AI agents that manage infrastructure, coding assistants that modify projects directly, or virtual helpers that automate tasks across local or cloud environments.
But the model doesn’t magically know how to use these tools. Its understanding comes entirely from the tool definitions it receives. These JSON documents are more than API wrappers — they’re how the model learns what a tool does and when to use it. A clear definition gives the model a reliable way to plan and act. A vague or inconsistent one leads to uncertainty, errors, or hallucinated tool calls.
> Give me the list of files in the backup buckets?
I can help you with that. Please provide the list of files in the backup bucket.
In this example, the LLM does not understand the role of the MCP or how to use it.
This is where MCP reveals its limits. If the model misunderstands a tool, it may call it incorrectly or not at all. Worse, a poorly scoped definition might cause the model to misuse it in ways that are hard to detect. Unlike traditional code, there’s no compiler to catch these issues before runtime — just the model’s own reasoning, shaped entirely by the context it’s given.
The quality of the language model matters just as much. Larger, more capable models are better at interpreting tool definitions, filling in gaps, and recovering from ambiguity. Smaller or local models may struggle, even with clean definitions. MCP can only go as far as the model allows.
In practice, this makes tool design just as important as tool functionality. Developers must write precise, descriptive definitions. Proxies must enforce strict scoping and handle failures gracefully. And the model must be capable enough to reason about actions based on abstract descriptions alone. When it works, the experience is seamless. When it doesn’t, the breakdown is rarely obvious.
Using MCP
Using MCP today starts with one critical component: an MCP proxy. This is the system that listens for tool calls from the model, executes them safely, and sends the results back. There are both official and community-built proxies available. A great place to start is the MCP server repository on GitHub, which includes several reference implementations. For a broader view, PulseMCP offers a curated list of news, tools and servers contributed by the community.
Some service providers, like Atlassian, are also beginning to offer direct MCP support. In these cases, the MCP proxy is bundled into the service, allowing LLMs to interact with the provider’s API surface without additional setup. This makes it easier to wire up real functionality, especially for workflow-heavy applications.
The second requirement is model support. Claude Desktop, for example, includes built-in options to configure and connect to MCP proxies. Many of the early integrations assume a local setup, where the model, proxy, and user environment all live on the same machine. That’s beginning to shift, but local-first remains a common default.
OpenAI’s ChatGPT does not yet support MCP natively. However, developers working with the OpenAI Agent SDK can adopt the protocol as part of a custom agent system. Meanwhile, tools like OpenWebUI has bridges that connect local or hosted models to MCP proxies, enabling practical use of the protocol across a variety of environments.
MCP is still young, and some integrations are rough around the edges. Tool definitions vary in quality. Proxy implementations differ in scope. And support across models is uneven. But the pace of adoption is striking. In less than a year, MCP has gone from experimental idea to active standard, embraced by major platforms and a growing open-source community. That kind of momentum is rare, and it speaks to the underlying promise of the protocol.