What is MCP? How AI Agents Plug Into the World (MCP Series, Part 1)
What is MCP? How AI Agents Plug Into the World (MCP Series, Part 1) Introduction Not so long ago, every phone brand shipped with its own charger. Nokia had its pins, Samsung had a different port, and Apple h
What is MCP? How AI Agents Plug Into the World (MCP Series, Part 1)
Introduction
Not so long ago, every phone brand shipped with its own charger. Nokia had its pins, Samsung had a different port, and Apple had yet another. Leave yours at home and you were stuck, even in a room full of chargers.
AI applications ran into the same problem. Every app that wanted to read a file, query a database, or call an API needed its own custom connector, built for that one pairing of app and service. The Model Context Protocol (MCP) fixes that: one standard "charging port" for connecting AI applications to tools and data.
This is the first article in a series on MCP. Over the next few parts, we will cover:
- What is MCP? (this article)
- The difference between MCP and an API
- What changed in the new MCP version: sampling, logging (and the OpenTelemetry workaround), roots being deprecated, and others
- The new MCP version deep dive: handling state in a stateless infrastructure (HTTP+SSE vs Streamable HTTP)
- MCP on AWS: event functions or web functions, and why
- Handling MCP auth in web functions
- AWS infrastructure MCP
In this article, we focus on the foundation: how an agent connects to resources through MCP, the roles involved, what a server can offer, and how one MCP server works with several clients at once.
Prerequisite: You should have a basic idea of what an LLM is and have called an HTTP API before. No MCP experience needed.
Note: Everything here is based on the current MCP specification, revision 2026-07-28. If you read MCP tutorials from 2025, a few things (like the
initializehandshake and sessions) have changed. I will point them out as we go.
How Agents Reached Tools Before MCP
An LLM on its own only knows what it learned during training. It cannot check today's exchange rate, read your Jira board, or query your Postgres database. To do anything useful in the real world, an agent needs a way to reach out to resources.
Before MCP, the usual approach was function calling (also called tool use). You describe a function to the model in your request, the model replies with "call this function with these arguments", your code executes it, and you send the result back. That works, but all the wiring (tool definitions, execution, auth, retries) lives inside that one application.
Now multiply that. Say your company has 4 AI applications (a chat assistant, an IDE plugin, an internal agent, and a support bot) and 5 services they need (GitHub, Slack, a database, Google Drive, and your billing API). Without a shared standard, you are looking at up to 4 ร 5 = 20 separate integrations, each built and maintained on its own.
This is the classic N ร M integration problem. MCP turns it into N + M: each AI application implements the protocol once, each service implements it once, and they can all talk to each other. In our example, that is 4 + 5 = 9 implementations instead of 20.
Before we dive deep, let's define MCP properly.
So, What Is MCP?
The Model Context Protocol (MCP) is an open standard that defines how AI applications discover and use external tools, data, and prompt templates through one common interface.
Notice the word protocol. MCP is not a library, a framework, or a product. It is a set of rules, the same way HTTP is a set of rules. It defines:
- Who talks to whom: a host, its clients, and servers (more on these shortly).
- What a server can offer: tools, resources, and prompts.
- How messages are encoded: every message is JSON-RPC 2.0.
- How messages travel: stdio for local servers, Streamable HTTP for remote ones.
- How remote servers are secured: an OAuth-based authorization framework.
The official MCP docs compare it to a USB-C port for AI applications, which is the grown-up version of my charger story. Build one MCP server for your service, and any MCP-compatible application (Claude, ChatGPT, Cursor, VS Code, or your own agent) can use it.
The Three Roles: Host, Client, and Server
MCP has three roles. Once you get these, everything else falls into place.
- Host: The AI application the user actually interacts with: Claude Desktop, Cursor, VS Code, or a custom agent you built yourself. The host owns the conversation, the model, and the user's trust.
- Client: A connector that lives inside the host. The host creates one client for each server it connects to, and each client keeps a one-to-one relationship with its server.
- Server: A program that exposes capabilities. It might wrap a database, a file system, a SaaS product like GitHub, or your own HTTP API.
Going back to the charger analogy: the host is your phone, each client is a port on the phone, and each server is whatever you plug into that port.
Here is the key point people often miss: the model never talks to the server directly. When it wants to use a tool, it tells the host, and the host's client makes the call. The host stays in control of what gets called and what the user sees. That separation is deliberate; it is where user consent and security checks happen.
Host A runs two clients, one per server it uses. The billing server is shared: Host A's Client 2 and Host B's Client 1 both talk to it.
What an MCP Server Can Offer
An MCP server exposes its features through three primitives. The difference that matters most is who decides when each one gets used.
| Primitive | Controlled by | What it is | Example |
|---|---|---|---|
| Tools | The model | Functions the model can call, each with a name, description, and JSON Schema input |
calculate, create_invoice, search_issues
|
| Resources | The application | Read-only context identified by a URI |
file:///project/README.md, a customer record |
| Prompts | The user | Reusable prompt templates, often shown as slash commands | "Summarize this incident", "Draft a release note" |
Tools are by far the most used. When people say "we built an MCP server for our API", they almost always mean a set of tools that call API endpoints.
There is also one feature that flows the other way, from client to server: elicitation. It lets a server ask the user for missing input in the middle of a request, for example "which account should I debit?" before a transfer goes through.
Note: Earlier spec revisions also had roots, sampling, and logging as client-side features. The 2026-07-28 revision deprecated all three. They keep working for at least twelve months under the new deprecation policy, but new implementations should not adopt them. We will dig into this, and the workarounds, in Part 3 of this series.
How a Request Flows, End to End
Let's say we built a Calculator MCP server. It exposes a single tool, calculate. Here is how the server describes that tool when a client asks with tools/list:
{
"name": "calculate",
"title": "Calculator",
"description": "Performs basic arithmetic on two numbers. Use it whenever an exact result is needed instead of estimating.",
"inputSchema": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"],
"description": "The operation to perform"
},
"a": { "type": "number", "description": "First operand" },
"b": { "type": "number", "description": "Second operand" }
},
"required": ["operation", "a", "b"]
},
"annotations": { "readOnlyHint": true }
}
That definition is all the model will ever know about our server. It never sees our code, so the name, description, and schema have to explain the tool on their own. A vague description means wrong calls.
Now, when you ask an agent "What is 1,250 multiplied by 12?" and it uses the calculator server to answer. Here is what happens under the hood:
- Connect: You add the server to your host, either as a local command (stdio) or a URL (Streamable HTTP).
-
Discover: The client asks the server what it offers with
tools/list(and, where relevant,resources/listandprompts/list). This is where it receives thecalculatedefinition above. - Present: The host passes the tool names, descriptions, and input schemas to the model alongside your message.
- Decide: The model decides a tool would help and produces arguments that match the tool's input schema. For our question, that is a multiply with a = 1250 and b = 12.
- Confirm: The host can ask you to approve the call. The spec expects hosts to keep a human in the loop and let users deny tool calls.
-
Call: The client sends
tools/callto the server. - Return: The server does the work (1,250 ร 12 = 15,000) and returns the result. The host adds it to the conversation, and the model writes its answer.
Here is step 6 on the wire. Over Streamable HTTP, the client sends this request:
POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: calculate
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "calculate",
"arguments": { "operation": "multiply", "a": 1250, "b": 12 },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
Two things are worth noticing in that request:
-
Every request is self-contained. Look at the
_metafield carrying the protocol version and client capabilities, plus theMcp-MethodandMcp-Nameheaders. In older revisions, the client and server first did aninitializehandshake and shared anMcp-Session-Id. In 2026-07-28, both are gone. A client that wants to know what a server supports up front can call the newserver/discovermethod. -
Errors are results, not crashes. If the model asks the calculator to divide by zero, the server should return a normal result with
isError: trueand a readable message. The model can read it and try again with better arguments.
One Server, Many Clients
Inside a host, each client talks to exactly one server. But the reverse is not true: a single MCP server can serve many clients at the same time.
Take a remote MCP server for your company's billing API. On a normal workday:
- Babalola has it connected in Claude Desktop.
- Aina has it connected in Cursor.
- An internal support agent running in the cloud calls it on every ticket.
That is three hosts, three separate clients, and one server. Each client discovers the same tools, but each one sends its own requests with its own credentials.
How the server handles this depends on the transport:
- stdio servers are one-to-one by nature. The host launches the server as a subprocess, so every host gets its own private copy of the server process. Three users means three processes. Client and server must be running on the same machine.
-
Streamable HTTP servers are shared. One deployment exposes a single endpoint, like
https://billing.example.com/mcp, and every client sends its requests there.
For remote servers, the 2026-07-28 revision made this a lot easier. Since every request now carries everything the server needs, any request can land on any server instance. You no longer need sticky routing or a shared session store just to keep the protocol working. Put three instances behind a load balancer and let any of them answer.
What if a tool genuinely needs memory between calls, like a shopping cart or a multi-step booking? State becomes explicit. The tool returns a handle (say, a cartId), and the client passes that handle back as an argument in later calls. The connection itself is no longer a session.
The new stateless design makes MCP fits serverless platforms like AWS Lambda, and it is the main subject of Parts 4 and 5.
Transports: stdio vs Streamable HTTP
The same JSON-RPC messages can travel over two standard transports. The protocol is identical on both; only the delivery changes.
| stdio | Streamable HTTP | |
|---|---|---|
| Where the server runs | A local subprocess launched by the host | An independent web service |
| How messages travel | Newline-delimited JSON over stdin/stdout | Each message is its own HTTP POST to one endpoint |
| How responses come back | Written to stdout | A single JSON response, or an SSE stream scoped to that one request |
| Credentials | Environment variables | OAuth-based authorization framework |
| Best for | Local files, CLIs, local databases, development | Shared, hosted, multi-user servers |
You may also come across tutorials that open a GET /sse stream on a separate endpoint. That is the older HTTP+SSE transport from the 2024-11-05 revision, and it is now formally deprecated. We will break down HTTP+SSE vs Streamable HTTP properly in Part 4.
Conclusion
MCP did not make AI agents smarter. It made them connectable.
With MCP, a service builds one server, and any compliant host can use it. The host stays in control, the model gets a clean menu of tools, and the server does the actual work.
Next up is Part 2: MCP vs API. If most MCP servers call an API under the hood, do the two complement each other, or is one replacing the other? Weโll break down where they differ and when you need each.
References
- Model Context Protocol: official documentation and specification
- MCP 2026-07-28 changelog
- MCP transports (2026-07-28)
- MCP tools specification (2026-07-28)
- Anthropic: Introducing the Model Context Protocol
โโโโโโโโโโโโโโ
For more articles, follow my social handles:
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ full credit and traffic to the original publisher.