Services Case Studies Insights About Start a project →

Securing MCP servers before they reach production.

Security Published July 12, 2026 8 min read

The protocol that got adopted faster than it got secured

In under two years the Model Context Protocol has gone from an Anthropic release note to the default way AI systems talk to tools and data. Every major vendor now supports it, the public registry lists more than ten thousand servers, and surveys put roughly a quarter of large enterprises somewhere on the adoption curve, with a meaningful share already running MCP servers in limited or broad production. The appeal is obvious. Instead of writing a bespoke integration for every model and every tool, you expose a capability once and any MCP-aware client can use it.

The problem is that adoption outran security. In early 2026 researchers catalogued around thirty critical vulnerabilities in the space of two months, most of them the same two mistakes repeated across widely copied reference servers: path traversal and argument injection. In plain terms, servers were taking strings the model supplied and feeding them straight into filesystem paths or shell commands. The good news is that the ecosystem has started to catch up. In July 2026 the protocol's Enterprise-Managed Authorization extension reached stable status, giving organisations a standard way to put MCP access behind their own identity provider. The tooling to run this safely now exists. Whether a given team uses it is the difference between a useful integration and a quiet hole in the perimeter.

What an MCP server actually hands over

It helps to be blunt about what you are deploying. An MCP server exposes a set of tools, and a tool is a capability the model can invoke: read a file, query a database, call an internal API, run a command. From a security point of view you are handing a non-deterministic client a menu of actions it can take against your systems, and letting it decide when to take them.

Two things about that arrangement are routinely underestimated. The first is that the model chooses when and how to call a tool based partly on text it reads from other places, including the very data your tools return, which means the caller's intent is not fully under your control. The second is that every tool is a new endpoint with its own input handling, and it deserves the same scrutiny you would give any other externally reachable API. The vulnerabilities of early 2026 were not exotic. They were ordinary injection bugs in code that treated model output as trusted.

Ask the blast-radius question first

Before a server goes anywhere near production, work out what the worst a single misled or malicious call can do.

  • What can it reach. Map every system, file path, and network destination a tool can touch, and assume anything reachable will eventually be reached.
  • What can it change. Separate read-only tools from anything that writes, deletes, spends money, or sends a message, because those carry a completely different risk.
  • What it runs as. Identify the identity and permissions the server executes with, since that, not the model's good intentions, is the real ceiling on damage.

Authentication is no longer optional

For most of the protocol's short life, authentication was left as an exercise for the implementer, and a lot of implementers skipped it. That is what the Enterprise-Managed Authorization work is meant to end. It brings OAuth, role-based access control, and audit logging into the protocol in a standard way, so access to an MCP server flows through the same identity provider that governs the rest of your estate rather than a bespoke scheme bolted on per server.

The principles are the ones you already apply to sensitive services, and they matter more here, not less.

  • Propagate real identity. A tool call should run as the actual user behind it, not a shared service account that grants everyone the union of all permissions.
  • Scope to least privilege. Give each tool and each caller the narrowest set of permissions that lets the feature work, and nothing that merely might be convenient later.
  • Keep tokens short-lived. Prefer short-lived, narrowly scoped credentials over long-lived keys sitting in configuration, and rotate them through your existing secrets management.
  • Refuse ambient authority. A server that authenticates the caller but then acts with its own broad credentials has simply moved the problem, so bind what the tool can do to who is calling it.

Put a gateway in front of everything

The single most useful architectural decision is to stop exposing servers directly and route every call through a gateway. A gateway is the aggregation and control layer that sits between clients and your MCP servers, and it turns a sprawl of individually configured endpoints into one place where policy actually lives. This is the pattern the maturing enterprise tooling has converged on, and it is worth adopting even if you only run a handful of servers today.

  • One policy point. Authentication, authorisation, and allow-lists are enforced in a single layer rather than reimplemented, inconsistently, in every server.
  • Rate limits and quotas. A gateway can cap how often and how expensively any caller invokes a tool, which contains both runaway agents and abusive ones.
  • Inventory and governance. You cannot secure servers you do not know about, and a gateway gives you the register of what exists, who owns it, and what it can reach.
  • A kill switch. When something misbehaves you want one lever that cuts access immediately, not a scramble to find and stop every server by hand.

Treat every tool result as untrusted input

This is the part that catches teams who are otherwise careful. In an MCP setup, the text a tool returns can end up steering the model's next action. A document fetched from a shared drive, a row pulled from a database, a web page read through a tool: any of these can contain text that reads like an instruction, and if your system lets tool output flow back as authoritative direction, you have built a channel for prompt injection straight through your own tools.

The defences are concrete and mostly familiar to anyone who has secured an API.

  • Validate inputs against a schema. Every tool argument the model supplies is external input, so type it, bound it, and reject anything that does not fit before it reaches your code.
  • Never interpolate model strings into commands. Use parameterised queries and argument arrays rather than building shell or SQL strings by concatenation, which is what killed the vulnerable reference servers.
  • Jail the filesystem. Constrain file tools to an explicit directory and resolve paths before use, so a crafted path cannot climb out into the rest of the disk.
  • Do not let output become instruction with authority. Keep retrieved content clearly separated from trusted instructions, and require an explicit, checked step before a tool result can trigger a consequential action.

Watch it, log it, and keep a human in the loop

An MCP call you cannot see is an incident you will hear about from someone else. Because tool calls are actions against real systems, they deserve at least the audit trail you keep for any privileged operation. Log every invocation with the caller identity, the tool, the arguments, and the outcome, and route those logs to the same place your security team already watches. That record is what lets you answer, after the fact, exactly what an agent did and with whose authority.

Logging is necessary but not sufficient. For anything irreversible, a write, a payment, a deletion, an outbound message, put a human approval step in front of the action rather than trusting the model to be cautious. The teams that run agents comfortably in production are not the ones with the cleverest prompts. They are the ones who decided in advance which actions a model is allowed to take on its own and which require a person to say yes.

Start restrictive, then widen

The pattern that works is to default to deny and earn your way out. Ship a server read-only first, behind a gateway, with real authentication and full logging, and prove it is useful and well-behaved before you grant it anything that can change state. Add write capabilities one at a time, each with its own scope and, where it matters, its own approval gate. Keep the inventory current and revisit what each server can reach as it evolves, because the blast radius grows quietly as tools are added.

None of this is a reason to avoid MCP. The protocol is genuinely useful and it is not going away. It is a reason to treat an MCP server as what it is, a piece of production infrastructure with real access to your systems, and to engineer it with the same discipline you apply everywhere else. That is the work we do with clients through our AI consultancy practice: mapping the blast radius, putting the authentication and gateway in place, and deciding deliberately which actions an AI system is trusted to take. Get those decisions right early and MCP becomes one more well-governed integration rather than the exception that keeps your security team awake.

Keep reading

Putting an MCP server into production?

Start a conversation →
KT Solutions Assistant

Before we start, please share a few details so we can follow up with you.

Please enter your name and a valid email address.

End this conversation? Your chat will be emailed to us.