What problem it solves

Before MCP, connecting a model to your systems meant writing a bespoke integration for each AI product, each with its own tool-definition format and lifecycle. The work did not transfer.

MCP standardises that boundary. You implement a server once; any MCP-capable client can use it. Anthropic published it as an open standard, and it has since been adopted well beyond one vendor.

The useful mental model: MCP is to AI tooling roughly what the Language Server Protocol is to editors. One server, many clients, instead of N×M bespoke integrations.

Hosts, clients and servers

Three roles, and the distinction between the first two matters when reasoning about security.

Host

The AI application the user interacts with — a desktop assistant, an IDE, a chat product. The host manages the model, decides which servers to connect, and owns the user's trust.

It is the host, not the server, that is responsible for asking the user's permission before a tool runs.

Use it when you are building the product the user sees.
Client

A connector inside the host that maintains a one-to-one session with a single server. Multiple servers means multiple clients within one host.

The isolation is deliberate: one server should not see another's traffic.

Use it when implementing host-side support.
Server

The thing you usually write. It exposes capabilities — a database, an internal API, a filesystem, a SaaS product — over the protocol.

Servers are meant to be small and focused. A server per system beats one server that does everything, for the same reasons a service per bounded context beats a monolith.

Use it when you want your system usable by AI applications you do not control.

The three primitives

A server offers some combination of tools, resources and prompts. The split is about who decides to use them, which is easy to get wrong.

Tools — model-controlled

Functions the model may invoke: query a database, send a message, create a record. The model chooses when, based on the name, description and input schema.

Because the model decides, tools are where the risk concentrates. Anything with a side effect should be explicit about it in the description, and gated by the host's approval flow.

Use it when the model needs to do something or fetch something dynamic.
Resources — application-controlled

Data the server can supply, addressed by URI: a file, a record, a query result. The application or user decides what gets loaded, not the model.

Use resources for context that should be attached deliberately rather than fetched on the model's initiative.

Use it when the host or user should choose what context is in play.
Prompts — user-controlled

Reusable templates the server offers, surfaced in the host as something the user picks — a slash command, a menu entry.

This is where you encode the way your system is meant to be asked about, rather than hoping each user phrases it well.

Use it when there is a right way to frame a common request against your system.

Transports and lifecycle

MCP is JSON-RPC 2.0 over a transport. Two are in common use, and the choice is mostly about where the server runs.

stdio, for local servers

The host launches the server as a subprocess and talks over standard input and output. No ports, no network, no authentication layer to get wrong — the trust boundary is the machine.

This is the right default for anything touching local files or local credentials.

Use it when the server runs on the same machine as the host.
HTTP, for remote servers

A server reachable over the network, with streaming for server-to-client messages. This is what you use for a shared or hosted server.

It brings everything network services bring: authentication, authorisation, transport security, rate limiting, and an origin to validate. None of that is optional because the client happens to be an AI.

Use it when the server is shared, hosted, or must run somewhere other than the user's machine.
Capability negotiation

Client and server exchange what they support during initialisation, so each side knows which features are available rather than assuming.

Design servers to degrade cleanly when an optional capability is absent.

Use it when always — it is part of the handshake.

Security questions to answer first

Connecting an MCP server means granting a model access to a system. The protocol does not make that decision for you.

Treat tool results as untrusted input. Content returned by a server enters the model's context and can contain instructions. That is prompt injection with a direct path to your other tools — the defence is scoped permissions and human approval on consequential actions, not a cleverer system prompt.

Explicit, informed consent

The user should understand what a server can reach before it is connected, and approve consequential actions individually. Blanket approval at install time is not meaningful consent for an action taken three weeks later.

This responsibility sits with the host, which is why host and server roles are worth keeping distinct in your head.

Use it when any server that can write, spend, send or delete.
Scope the server's own credentials

The server authenticates to your system with its own identity. Give it the narrowest one that works — read-only where reads suffice, a database user scoped to specific tables.

If the model is compromised by injected instructions, the credential scope is the thing that actually limits the damage.

Use it when always.
Do not pass tokens straight through

A server that accepts a token from the client and forwards it to a downstream API becomes a confused deputy — it can be induced to act with the user's authority on someone else's behalf.

Validate that a token was issued for your server, and exchange it for a downstream credential rather than replaying it.

Use it when the server sits in front of an API that does its own authorisation.

When MCP is the right answer

It is a good fit when the consumer is an AI application you do not control, when several clients need the same capability, or when you want users to connect your system without you shipping an integration per product.

It is the wrong answer when the consumer is your own code. If a service calls your API on a schedule, that is a normal API call — wrapping it in a protocol designed for model-driven tool selection adds a layer for nothing.

Where to read more