Here is a pattern that shows up in almost every company adopting AI seriously.
You build an assistant. It needs to read from your ticketing system, so you write an integration. Six months later a different team adopts a different AI tool that needs the same data, so they write their own integration. Then a vendor’s agent needs it too. Now three connectors hit the same API, each with its own auth handling, its own idea of what a “ticket” is, and its own bugs.
Multiply by every internal system and every AI tool. That is the N-by-M problem, and it is the reason AI pilots stall between the demo and the rollout.
What MCP actually is
The Model Context Protocol is a standard for exposing tools and data to AI models. You build one server that describes what your system can do — the operations available, the arguments they take, the permissions they require — and any MCP-capable client can use it.
N-by-M becomes N-plus-M. You write one server per system, not one connector per pairing.
The idea is not novel. It is the same argument as USB, ODBC, or the Language Server Protocol: agree on an interface once, and the combinatorics collapse. What makes it worth paying attention to now is that it has broad enough adoption to be a safe bet rather than a wager on a standard nobody else implements.
Why this matters more than it sounds
Model choice stops being a rewrite. The uncomfortable truth of the last few years is that the best model changes roughly every six months. If your integrations are welded to one vendor’s function-calling format, every switch is a migration. Behind MCP, it is a configuration change.
Permissions get a real home. In the bespoke world, what an agent can do is an emergent property of whatever the connector happened to implement. With a server, the tool surface is explicit and enumerable — you can point at a list and say these eleven things are what any agent can do, scoped this way. That is a conversation your security team can actually have.
One place to fix things. A bug in the date handling gets fixed once instead of in four connectors that drifted apart eighteen months ago.
What a good server looks like
The protocol is straightforward. Designing a server anyone wants to use is where the judgement is.
Expose intent, not endpoints. The most common mistake is mechanically wrapping a REST API — one tool per route, arguments mirroring the payload. It technically works and it is miserable to use, because the model has to chain five calls and hold state to do one obvious thing. Model the operation the caller actually wants: find_customer_orders, not GET /orders plus three lookups.
Keep the surface small. Forty tools is a worse server than twelve. Every tool is context the model must reason over, and a large surface makes it likelier the wrong one gets picked. Ruthlessly prune.
Write descriptions for the model, not for humans. The tool description is a prompt. State what it does, when to use it, when not to, and what the arguments mean in domain terms. “Returns order data” tells a model nothing. Say which orders, in what state, and how far back.
Make errors instructive. An agent that receives “400 Bad Request” retries the same call. One that receives “start_date must be within the last 90 days” fixes it. Error messages are part of your interface.
Scope permissions at the server. Do not rely on the agent to behave. If a tool should be read-only for a given caller, enforce that in the server, where it cannot be argued out of by a cleverly worded prompt.
The part worth being careful about
An MCP server is a piece of infrastructure that lets a language model take actions in your systems. Treat it that way.
Tool descriptions and returned data both enter the model’s context, which means a server returning attacker-influenced content — a ticket body, a customer note, a scraped page — can carry instructions the model may follow. This is prompt injection with a direct path to your tooling, and it is the genuine risk of the pattern.
The mitigations are ordinary engineering: least privilege on every tool, human confirmation on anything destructive or outbound, validation on arguments rather than trust in the caller, audit logs on every invocation, and clear separation between data the model reads and instructions it obeys. None of it is exotic. It just has to be deliberate, because the default posture of a helpful model is to cooperate.
Where to start
Not with your most complex system. Pick one where AI access is already wanted and the blast radius is small — internal documentation, a read-only view of a project tracker, a reporting database.
Build the server. Point one assistant at it. Learn what tool granularity feels right for your domain and where the model gets confused. Then add the second system, which will go considerably faster.
The teams that get value from this are not the ones who standardised everything up front. They are the ones who built two or three good servers and discovered that the next AI tool took an afternoon to integrate instead of a sprint.
That compounding is the whole point.