Back to Blog
AI Engineering11 min readJun 2026

Model Context Protocol (MCP): The USB-C of AI Tools

Every LLM-to-tool integration used to be a bespoke one-off. MCP is the 2025 standard that fixes that, one protocol for connecting models to tools, data, and prompts.

AIMCPAgentsTools
SB

Sri Balaji

Founder · TheSimplifiedTech

On this page

Every integration was a one-off

You wired Claude up to your Postgres database. It took an afternoon, a custom function, a hand-rolled JSON schema, a glue script to shuttle rows back into the prompt. Then you wanted it to read GitHub issues too. Different SDK, different auth, a second bespoke adapter. Then Slack. Then your internal wiki. Each one a snowflake. Now your teammate is building the *same* integrations for *their* agent, from scratch, because nothing you wrote was reusable across apps.

This is the M×N problem: M AI applications each need to talk to N tools and data sources, so the industry kept rebuilding M×N bespoke connectors. The Model Context Protocol (MCP) collapses that to M+N, write a connector once, and every MCP-aware app can use it.

Who this is for

Engineers who have called an LLM and maybe wired up one tool by hand, and now want a durable, reusable way to connect models to real systems. You should be comfortable with JSON and a little Python or TypeScript. No prior MCP knowledge assumed.

What MCP actually is

MCP is an open protocol that standardizes how applications provide context to large language models, a universal way to connect AI models to tools and data sources.
modelcontextprotocol.io

Read that twice: MCP is a protocol, not a library or a framework. It defines the *messages* an AI app and a tool provider exchange, what a tool looks like, how it is listed, how it is called, how results come back. Because it is a wire format and not a language binding, an MCP server written in Python works with a client written in TypeScript, and vice versa.

USB-C port on your laptopMCP client built into the AI host
Any USB-C device (drive, monitor, charger)Any MCP server (database, GitHub, filesystem)
The USB-C spec everyone agrees onThe MCP protocol everyone implements
Plug in a new device, it just worksPoint the host at a new server, its tools appear
MCP is the USB-C of AI: one standard port, many devices.

Before USB-C, every device had its own connector and you carried a bag of adapters. After USB-C, one port drives a monitor, charges a phone, and mounts a drive. MCP does the same for AI: instead of a bag of bespoke adapters, the model gets one standard port and any compliant server can plug in.

The picture: host, client, servers

ownsMCPMCPMCP
AI Host

Claude Desktop / IDE / agent

MCP Client

Embedded in the host

Filesystem Server

resources

Postgres Server

tools + resources

GitHub Server

tools + prompts

One AI host with an embedded MCP client connects to many independent MCP servers, each exposing tools, resources, and prompts.

The host is the AI application the user interacts with (Claude Desktop, an IDE plugin, your agent). The host embeds one or more clients, and each client holds a dedicated 1:1 connection to a server. Servers are small, independent programs that expose capabilities. The host stays simple; the ecosystem of servers grows around it.

  1. 1

    Host launches a client

    When you enable an MCP server in your config, the host spins up a client and connects to that server.

  2. 2

    Client and server handshake

    They exchange a JSON-RPC `initialize` message, agreeing on protocol version and which capabilities each side supports.

  3. 3

    Client discovers capabilities

    It calls `tools/list`, `resources/list`, and `prompts/list` to learn what the server offers, no hardcoding.

  4. 4

    Model decides to act

    Given the user's request, the model picks a tool. The client sends `tools/call` with the arguments.

  5. 5

    Server runs and replies

    The server executes (queries the DB, hits an API) and returns a structured result the model folds into its answer.

The three primitives

Everything a server exposes is one of three primitives. The distinction matters because they have different control models: who decides when each is used.

PrimitiveWhat it isControlled by
ToolsFunctions the model can call to take action or fetch data (run a query, create an issue, send a message).Model, it chooses when to invoke them.
ResourcesRead-only data the server exposes by URI (a file, a table, a doc) for the model to read as context.Application, the host decides what to attach.
PromptsReusable, parameterized prompt templates the server offers (e.g. "summarize this PR").User, typically surfaced as slash commands or menu items.
The MCP server primitives and who is in control of each.

A useful mental model: tools are verbs the model can do, resources are nouns the app can hand it, and prompts are pre-written recipes the user can trigger. Most servers start with one or two tools, that alone is hugely useful.

Build it: a tiny MCP server

Here is a complete MCP server in Python using the official SDK. It exposes a single tool, get_weather, that the model can call. The SDK handles the JSON-RPC plumbing, schema generation from your type hints, and discovery, you just write the function.

weather_server.py
python
# pip install "mcp[cli]"
from mcp.server.fastmcp import FastMCP

# Name shows up to the client during discovery.
mcp = FastMCP("weather")

@mcp.tool()
def get_weather(city: str) -> str:
    """Return the current weather for a city.

    Args:
        city: Name of the city, e.g. "Amsterdam".
    """
    # In real life you'd call a weather API here.
    # The docstring + type hints become the tool's schema
    # that the model reads to decide how to call it.
    return f"It is 18°C and lightly raining in ${city}."

if __name__ == "__main__":
    # stdio transport: the host launches this as a subprocess
    # and talks to it over stdin/stdout.
    mcp.run(transport="stdio")

Notice what you did *not* write: no message parser, no tools/list handler, no JSON schema by hand. The decorator inspects the signature and docstring and publishes a tool the model can discover and call. To use it, point your host's MCP config at python weather_server.py and the get_weather tool appears.

Test before you wire it up

Run `mcp dev weather_server.py` to open the MCP Inspector, a browser UI that lists your tools and lets you call them by hand. Confirm the tool works in isolation before debugging it through a model.

Clients, servers, and transport

The client lives inside the host and speaks MCP on the model's behalf: it discovers capabilities, forwards tools/call requests, and returns results. The server is the thing you write, it owns the actual capability and the credentials to reach the underlying system. One client, one server, one connection.

Between them sits the transport, and there are two standard ones. stdio is for local servers: the host launches the server as a subprocess and they exchange JSON-RPC over stdin/stdout, zero network, ideal for filesystem or local-DB access. Streamable HTTP is for remote servers: the server runs as a web service the client reaches over HTTP, with Server-Sent Events for streaming, this is how hosted, multi-user MCP servers work. Either way the messages are identical JSON-RPC 2.0; only the pipe changes.

  • stdio, local subprocess, no auth needed, fastest to start. Use for personal tools and local data.
  • Streamable HTTP, networked, needs real auth (OAuth is the standard), supports many clients. Use for shared/hosted servers.

Common mistakes that cost hours

  1. Over-broad tool scope. A single run_sql(query) tool that accepts any SQL is a foot-gun, the model can DROP TABLE. Expose narrow, intentional tools (get_user_by_id, list_open_orders) so the blast radius is bounded by design.
  2. No auth on a remote server. stdio is local and safe; the moment you put a server on HTTP it is reachable. An unauthenticated remote MCP server is an open API to your data. Use OAuth and scope tokens to least privilege.
  3. Trusting server output blindly. Tool results flow straight into the model's context, so a compromised or malicious server can inject instructions (prompt injection). Treat server output as untrusted input: validate it, and keep destructive tools behind human confirmation.
  4. Dumping everything as tools. Read-only data belongs in resources, reusable workflows belong in prompts. Cramming all of it into tools bloats the model's choices and hurts accuracy. Match the capability to the right primitive.
  5. Vague tool descriptions. The model picks tools from their names and descriptions alone. "Gets data" tells it nothing; a precise docstring with argument meaning is the difference between a tool that gets called correctly and one that gets ignored.

Takeaways

MCP in seven lines

  • MCP is an open protocol, a wire format, for connecting LLMs to tools, data, and prompts.
  • It turns the M×N integration problem into M+N: write a connector once, reuse it everywhere.
  • Architecture: a host embeds a client; each client connects 1:1 to a server.
  • Three primitives: tools (model-controlled), resources (app-controlled), prompts (user-controlled).
  • Two transports: stdio for local subprocesses, Streamable HTTP for remote services.
  • An SDK like FastMCP generates schemas and handles plumbing, you just write the function.
  • Security is on you: narrow tool scope, authenticate remote servers, never trust output blindly.

Where to go next

MCP is how agents reach the outside world, so it sits right between two skills. If the mechanics of a model calling a function are still fuzzy, start with the fundamentals; if you're ready to put MCP servers behind an autonomous loop, move up to agents.

Want to go deeper?

This article covers concepts taught hands-on in the Cloud Engineer and DevOps career paths, with real terminal labs, production scenarios, and structured lessons.