Denshin / Blog / AI
Model Context Protocol (MCP) explained for engineering teams
MCP is an open protocol for connecting AI clients to tools, resources and prompts, so an integration written once works across clients. What the pieces are called, when to write a server instead of a plain REST API, and why a server runs with the permissions of whoever authorised it.
Denshin Engineering · Engineering Team · 27 August 2026 · 8 min read
If your team has already written one integration to let an AI assistant read your ticketing system, and is now being asked to write the same integration again for a different assistant, you have met the problem MCP was designed to remove. This is a practical explainer for engineering teams: what the Model Context Protocol is, what the pieces are called, when writing a server is the right call versus shipping a plain REST API, and what to be careful about before you expose anything real through one.
What is the Model Context Protocol?
The Model Context Protocol (MCP) is an open protocol that standardises how AI applications connect to external tools, data and prompt templates. It was published by Anthropic in late 2024, released under an open licence, and has since been adopted by a range of AI clients and tool vendors. The point of it is simple: write the integration once as an MCP server, and any MCP-capable client can use it without you writing client-specific glue.
One caveat before anything else. MCP is developed in the open and it moves. Transports, authorisation and the exact capability set have all changed since the first release, and they may have changed again since this was written in August 2026. Treat this post as a map of the concepts and take the official specification and SDK documentation at modelcontextprotocol.io as the authority on current API shapes. We have deliberately not reproduced message formats here, because the version you read would be the version we happened to be using.
The N times M integration problem
Before a shared protocol, connecting N AI clients to M tools meant something close to N times M integrations. Each assistant had its own plugin format, its own function-calling conventions, its own auth handshake. Every new client meant re-implementing work you had already done, and every new tool meant every client had to add support for it.
A protocol collapses that into N plus M. Client authors implement the protocol once. Tool authors implement it once. This is the same trade the industry made with LSP for editors and language servers, and the same reasoning applies: the protocol has to be boring, versioned and documented, and in exchange nobody writes the same adapter twice.
The honest caveat is that a standard only pays off when there are genuinely several clients you care about. If exactly one assistant will ever talk to your system, the protocol is overhead you may not need yet.
Clients, servers and hosts: who is who
The naming trips people up, because it is the reverse of the intuition that "the AI is the server".
- Host. The AI application the user interacts with: a desktop assistant, an IDE, a coding agent, your own product. It holds the model and the conversation.
- Client. The connector inside the host that speaks MCP, typically one per connected server.
- Server. The process you write. It exposes your capabilities and knows nothing about which model is on the other end.
So your database, your ticket tracker or your internal admin API becomes the server, and the assistant is the client. Servers can run locally as a subprocess on the user's machine or remotely over HTTP. The local case is the easy one for internal tooling; the remote case is where authorisation design matters, and where the spec has evolved most, so check current docs before committing to a transport.
Tools, resources and prompts
Servers expose capabilities in a few distinct shapes, and choosing the right one is most of good server design.
| Primitive | What it is | Typically triggered by | Good example |
| Tools | Functions the model can call, with typed inputs and a result | The model, during a turn | create_ticket, search_orders |
| Resources | Readable context the application can pull in, addressed by URI | The host application or the user | A file, a schema, a record |
| Prompts | Reusable templates or workflows the server offers | The user, deliberately | A guided bug triage flow |
The rough rule: if the model should be able to decide to invoke it mid-task, it is a tool. If it is data that something else decides to put in front of the model, it is a resource. If it is a canned workflow a person picks from a menu, it is a prompt. Newer capabilities exist in both directions, including servers asking the host to run a model completion, and there is more of this over time, which is another reason to read the current spec rather than trusting any blog post's list.
When to write an MCP server, and when not to
An MCP server is not a replacement for your API. It is a facade over it, aimed at a specific consumer.
- Write an MCP server when multiple AI clients need the same access, when the natural consumer is an agent rather than a program, when the value is in discovery (the client can list what is available and read the descriptions), or when you want your customers to plug your product into whichever assistant they already use.
- Ship a plain REST API or SDK when the consumer is deterministic software, when you need fine-grained pagination, streaming or bulk semantics that a tool call is a poor fit for, or when there is one client and it is yours. A well-documented API with a thin function-calling wrapper is less work and fewer moving parts.
- Do both when the API already exists. The server should be a thin, opinionated layer on top: a handful of task-shaped operations, not a mechanical one-to-one mapping of every endpoint.
That last point is the one we would underline. A generated server that exposes 120 endpoints as 120 tools is worse than useless: the client's tool list becomes noise, selection accuracy drops, and every request burns tokens listing options the model will never pick. Expose the ten things people actually ask for.
Practical advice for building one
Scope and naming
Design tools around user intent, not around your database tables. find_overdue_invoices_for_customer beats a generic query tool with a filter object, because it constrains the model into a path you have tested. Names should be unambiguous across servers: a client may have several servers connected at once, and two tools called search is a bad day. Descriptions are prompt text, so state units, preconditions and side effects in them. The same tool design principles apply here as anywhere else, and we go deeper in AI agent architecture: tools, memory and the loop.
Auth and least privilege
Give the server its own identity with the narrowest scope that does the job, and make it act on behalf of a specific user where the underlying system supports that. Do not hand it an administrator key because it is quicker. Keep tokens out of tool arguments and out of anything that gets logged into a transcript, since transcripts end up in traces, screenshots and bug reports. For remote servers, follow the authorisation approach in the current spec rather than inventing your own header scheme.
Error surfaces
Errors from a server land directly in a model's context and steer its next move. Return a message that says what failed, why, and what would be a reasonable next step. Distinguish "you asked for something that does not exist" from "the upstream system is down", because the recovery is different. Never return an empty success where an error occurred: an empty list reads as a fact about the world.
Versioning
Treat tool names and input schemas as a public contract, because that is what they are. Add optional fields freely, avoid changing the meaning of an existing field, and where you must break something, introduce a new tool name and deprecate the old one in its description. Clients cache and users pin, so a silent semantic change is a very quiet outage.
Security: a server runs with the permissions someone gave it
This is the part that deserves a slow read. An MCP server executes with whatever access the person who installed and authorised it granted. If a user connects a server that can read their email and another that can post to the internet, the combination is a data path, whether or not anyone intended one. A few defensive habits:
- Audit what you install. A third-party server is code running with your credentials. Read it or run it in a sandbox before you point it at anything sensitive.
- Assume tool output is untrusted input. Text a server returns can contain instructions aimed at the model. Content fetched from the web, from tickets, from user-submitted records is all in that category. This is the prompt injection problem, and the defences are covered in prompt injection and AI guardrails.
- Gate destructive actions in code. Deletes, payments, outbound messages and permission changes need an approval step or a hard rule, not a line in a system prompt asking nicely.
- Log every call with an identity. If you cannot answer "which server, on whose authority, changed this record", you cannot run an incident review.
- Watch the combinations. Two individually reasonable servers can compose into an exfiltration path. Review the whole connected set, not each one alone.
Coding agents are the highest-leverage and highest-risk consumers of all this, and deserve their own guardrails, which we set out in AI coding agents: guardrails for shipping real software.
What to do next
- Count the AI clients that plausibly need access to your system. One means wait, several means a server is probably worth it.
- List the ten task-shaped operations users actually ask for, and design tools around those rather than mirroring your endpoints.
- Create a dedicated identity with least-privilege scopes before you write any code.
- Read the current specification at modelcontextprotocol.io for transport and authorisation details, since those have moved more than once.
- Write down which operations are irreversible, and gate them outside the model.
If you are deciding whether to expose your product to AI clients through MCP, or you want a second pair of eyes on what a server would expose and to whom, talk to us. We would rather help you scope it small than watch it grow into 120 tools.
Tags: MCP, Model Context Protocol, AI Agents, Tool Calling, AI Security
All posts · Work with Denshin