Skip to content
ISSUE 001·LIVE·03:35 IL
← Journal/2026-06-10·10 min·mcp

What Is MCP? The Model Context Protocol, Explained by Someone Who Ships Servers

MCP is the USB-C of LLM tooling: one protocol that lets any model talk to any tool or data source. Here's what it is, why it exists, and how I think about building a server.

By Harel Asaf·AI Builder·Tel Aviv

Before MCP, every time you wanted an LLM to touch a real system — your database, your file system, GitHub, a SaaS API — you wrote a bespoke integration. The model needed a tool, the tool needed glue code, the glue code was specific to that one model's tool-calling format and that one application's runtime. Want the same capability in a different app? Rewrite it. Want a different model? Rewrite it again. Everyone was building the same N-times-M integrations over and over.

The Model Context Protocol is the answer to that combinatorial mess. MCP is an open standard for connecting LLM applications to tools and data through one common interface. The analogy that stuck — and it's a good one — is USB-C. Before USB-C, every device had its own connector. After, one port talks to everything. MCP is that port for LLM tooling: build a capability once as an MCP server, and any MCP-aware client can use it.

I build these. So let me give you the version that's actually useful, not the spec tour.

The shape of the protocol

There are three roles, and keeping them straight clears up most of the confusion.

The host is the LLM application the user interacts with — a coding agent, a desktop assistant, an agent you wrote. It's the thing with the model in it.

The client lives inside the host and speaks MCP. There's one client per server connection; it's the protocol-level adapter.

The server is the thing you build. It exposes capabilities — tools, data, prompts — over the protocol, and it knows nothing about which model or which host is calling it. That ignorance is the entire point. Your server is decoupled from the consumer, which is why one server works everywhere.

A server can expose three kinds of things:

  • Tools — actions the model can invoke. "Run this query," "create this issue," "deploy this script." This is the one people reach for first, and it's where most of the value is.
  • Resources — data the host can read into context. Files, records, documents. Read-oriented rather than action-oriented.
  • Prompts — reusable prompt templates the server offers to the host, often surfaced as user-triggerable commands.

Most servers I write are mostly tools, sometimes with a few resources. Prompts are the least-used of the three in my experience, but they're there.

Why a protocol beats a plugin

You might reasonably ask: tool calling already exists. Models can already call functions. Why add a protocol on top?

Because function calling solves the model side and leaves the integration side untouched. Yes, the model can emit a tool call. But who defines the tool, executes it, handles its auth, and feeds the result back? In a plugin world, that's all bespoke per application. MCP standardizes the contract between the host and the capability, so the capability becomes portable.

Concretely, that portability buys you three things:

1. Write once, run in many hosts. The same MCP server works in a coding agent, a desktop client, and a custom agent you built last week, with no per-host code.

2. Swap models without rewriting tools. Because the server doesn't know or care which model is calling, upgrading the model — or running several — changes nothing about your integration.

3. A real ecosystem. Because servers are decoupled, people publish them. You can pull in a server for a service you don't want to integrate yourself, and your host just uses it.

This is the difference between a feature and an interface. Function calling is a feature. MCP is an interface, and interfaces are what let ecosystems form.

How a connection actually runs

Under the hood it's a structured message exchange (JSON-RPC) between client and server, and there are two main transports depending on where the server lives.

Local servers run as a subprocess and talk over standard input and output. This is how a lot of developer tooling works — the host spawns the server on your machine, and it can touch your local file system, your local database, your local environment. Nothing leaves the box.

Remote servers run somewhere else and talk over HTTP (the Streamable HTTP transport). This is how hosted, multi-tenant servers work — a service publishes an MCP endpoint at a URL, and any host points at it.

The flow is roughly: the host starts a client, the client connects to the server, they negotiate what the server can do (the server advertises its tools, resources, and prompts), and from then on the model can invoke those capabilities through the client. When the model calls a tool, the request goes to the server, the server executes it, and the result comes back into the model's context.

The part everyone underestimates: auth and trust

The moment your server is remote and touches anything private, authentication stops being a footnote. A local stdio server inherits your machine's permissions — fine. A hosted server that reaches a third-party API on the user's behalf needs the user's credentials, and you do not want those credentials sitting in the model's context where a prompt injection could exfiltrate them.

The pattern that works is to keep secrets out of the prompt entirely and inject them at the edge. In well-designed setups, the server declares which service it talks to but holds no credential itself; the credential lives in a separate secured store and is attached to the request after it leaves the model's reach. The model sees a tool it can call. It never sees the token that authorizes the call.

If you take one security idea from this: **the model should be able to trigger an authenticated action without ever being able to read the thing that authenticates it.** Design your server so a compromised or manipulated model can't leak the keys, because eventually someone will try.

How I think about building one

When I write an MCP server, the design questions are mostly about the tool surface, not the protocol plumbing — the protocol is the easy part.

  • Name and describe tools for the model, not for humans. The model decides whether to call a tool from its description. Be prescriptive about when to use it, not just what it does. "Call this when the user asks about current inventory" earns far more correct calls than a terse "gets inventory."
  • Keep the tool set focused. A server with 40 tools confuses the model about which to reach for. Fewer, sharper tools beat a sprawling surface. If you have a huge library, that's an argument for dynamic discovery, not for dumping every schema into context.
  • Decide the security boundary per tool. Read-only lookups can run freely. Anything destructive or hard to reverse — sending a message, deleting data, deploying — is a candidate for a confirmation gate. The protocol gives the host a typed, inspectable call it can intercept; use that.
  • Return results the model can actually use. Typed, scoped, and trimmed. A tool that dumps a hundred thousand tokens of raw output back into the window is a context problem wearing a tool's clothes.

That's most of it. The protocol handles transport, negotiation, and message format. Your job is the capability and its contract — and that's where a server is good or bad.

The one-sentence version

MCP is an open protocol that turns "integrate this tool with this model in this app" from an N-times-M rewrite into a write-once server any host can use — the USB-C port for LLM tooling.

FAQ

What is the Model Context Protocol (MCP)?

MCP is an open standard that lets LLM applications connect to external tools and data through one common interface. Instead of writing a bespoke integration for every model-and-app combination, you build a capability once as an MCP server and any MCP-aware host can use it.

What problem does MCP solve?

It eliminates the N-times-M integration explosion. Before MCP, connecting M tools to N applications meant building roughly N times M custom integrations. MCP standardizes the contract, so a tool built once works across hosts and models without rewriting.

What are MCP tools, resources, and prompts?

They're the three things an MCP server can expose. Tools are actions the model can invoke; resources are data the host can read into context; prompts are reusable templates the server offers, often surfaced as commands. Most servers are primarily tools.

How is MCP different from function calling?

Function calling handles the model side — the model emitting a tool call. MCP standardizes the integration side: who defines, executes, authenticates, and returns the tool. That standardization makes capabilities portable across hosts and models, which function calling alone does not.

What transports does MCP use?

Two main ones. Local servers run as a subprocess and communicate over standard input and output, good for tooling that touches your machine. Remote servers run elsewhere and communicate over HTTP (Streamable HTTP transport), good for hosted, multi-tenant services published at a URL.

How should I handle authentication in an MCP server?

Keep credentials out of the model's context. A well-designed server declares which service it calls but holds no secret itself; the credential lives in a separate secured store and is injected after the request leaves the model's reach. The model can trigger an authenticated action without ever reading the token.

How do I build a good MCP server?

Focus on the tool surface, not the plumbing. Write tool descriptions for the model with explicit guidance on when to call each one, keep the set small and focused, gate destructive actions behind confirmation, and return trimmed, typed results rather than dumping raw output into the context window.

Build log

Get an email when I ship a new prototype or essay. No funnel — just the work.