Over the last six months, every AI project we have shipped to production has run into the same problem, sooner or later: the agent has to talk to the CRM. To the ERP. To Slack, to a database, to a custom endpoint the client wrote back in 2019. And every time the model changes — Claude becomes GPT, Gemini becomes Llama — the entire tool calling layer has to be rewritten.
MCP, Model Context Protocol, solves this. It is an open protocol, launched by Anthropic, that decouples the agent from its tools. Think of it as LSP for tools: a client (the agent) speaks to a server (the tool) through a standardised set of messages. The model changes, the tools stay.
What came before
Before MCP, every agent framework had its own way of exposing tools. OpenAI functions with JSON schema, LangChain with its Tool objects, Anthropic with the "tool_use" content block. Tool-calling code was duplicated across providers, and every model swap meant recompiling the adapter.
In a recent project for a law firm, the contract drafting agent had 12 tools: case law search, internal DMS reads, identity verification, final document generation. The first version was written using OpenAI function calling. When the client asked to move to Claude because of rate limit issues, we had to rewrite 800 lines of adapter code. One week of work, for zero new value.
What changes with MCP
With MCP, tools become stand-alone servers. Each tool runs as a Node, Python or Go process — whichever you prefer — exposing a handful of endpoints over JSON-RPC on stdio or HTTP. The agent is an MCP client. It connects to the server, discovers the available tools, and calls them. That is it.
For us, this means three things:
1. Reusable tools. The MCP server that talks to a hotel chain's PMS was written once and is now used in three different projects, with three different models. 2. Instant provider swap. When a client wants to test whether Gemini saves 40% on the monthly bill, we change two lines in the orchestrator. The MCP servers stay up. 3. Better security. The MCP server is a natural trust boundary. We isolate it, we monitor it, and we hand it only the secrets it needs. The agent never sees credentials.
What we learned by trial and error
Three lessons from our first integrations.
Schema first, always. MCP SDKs let you expose tools with detailed JSON Schema. Invest time in describing every argument. The model does what you tell it, and if the description is ambiguous it will call the tool badly. An extra day on the schema saves three days of runtime debugging.
Idempotency keys everywhere. Agents retry. If you call "create invoice" without an idempotency key and the agent decides it timed out, you end up with two identical invoices. Every tool that writes needs one.
Structured logging of tool calls. Save every call: input, output, latency, error. Without this, debugging an agent is impossible. We push everything into an append-only database with three indexes: by agent, by tool, by timestamp.
When NOT to use MCP
MCP is excellent for agents that orchestrate many tools. For simpler use cases — a single model generating text, a batch pipeline processing documents — it is over-engineering. If you have just one tool, expose it directly with the provider's native function calling and be done with it.
In production
Today, all our "Ring 3 — Orchestration" agents run on MCP. The typical pipeline is: a Claude or GPT orchestrator connected to 4-8 MCP servers, each one responsible for a client system. The servers sit inside the client's tenant when possible (so data never leaves their perimeter), or inside ours when the client has no infrastructure.
The protocol is moving fast — we are already at v2 — but backward compatibility has been respected. It is worth investing in.