Flat vector illustration of an AI agent connected to several tool servers, one of them unverified, on a pale ice-blue ground
TABLE Of CONTENTS

MCP Is the New Attack Surface: Securing the Tool-Chain Your Agents Reach

Omair
2026-09-22
9
min read

Open the config for one agent running in production and count the tool servers it can reach. Then answer three questions. Who wrote each one. What it is allowed to do right now. When it last changed.

Most teams get through the first question. Almost nobody gets through the third, because nothing in the stack is built to tell them.

The Model Context Protocol is now the default way agents reach the outside world, which makes it a security boundary whether or not anyone has treated it as one. Not a model problem — an integration problem, the kind security engineers already know how to test.

Why the tool-chain became the interesting part

MCP is deliberately thin: JSON-RPC over one of two standard transports, stdio for a locally launched subprocess and Streamable HTTP for a remote endpoint. A server advertises tools; the model picks one; the client calls it. Three properties of that shape matter to an attacker.

Tool metadata is model-visible text supplied by a third party. A tool's name, description, and JSON Schema field descriptions all land in the model's context. That text is documentation to a human and instruction to a model, and the protocol does not distinguish. The spec is blunt about it: clients MUST consider tool annotations untrusted unless they come from trusted servers. A server's claim that its tool is read-only is a claim, not a constraint.

Authorization is optional, and on the local transport absent by design. The authorization spec builds on OAuth 2.1 and is strict where it applies: servers MUST validate that tokens were issued for them as the intended audience, and MUST NOT accept or transit any other tokens. That is for HTTP transports. Implementations on stdio are told not to follow it and to take credentials from the environment instead, so a local tool server's authority is whatever sits in an environment variable, at the privilege of the process that launched it.

The tool set is not fixed. Servers declare a `listChanged` capability, emit `notifications/tools/list_changed`, and hand clients a TTL to cache the list against. The manifest you reviewed at integration time is a snapshot of a mutable object.

Those are the mechanism behind the point our first post in this series made: a tool server can change behavior after approval, and nothing in the transcript looks different. So treat the tool-chain like any other third-party integration and supply chain — enumerate it, scope it, re-verify it on a schedule.

mcp security — boundaries

What this looks like when it goes wrong

A composite, illustrative, assembled from patterns we see. Not any one client.

An internal agent triages incidents across four tool servers: ticketing, log search, a knowledge server fed by a wiki anyone can edit, and one an engineer wrote in an afternoon to restart services. Three run on Streamable HTTP behind company SSO; the fourth is stdio, launched from a config file with a platform API key in its environment.

Nobody has done anything wrong yet. But the log search tool calls itself read-only and the client renders that as a badge, built from a string the server sent. The ticketing server gives no scope guidance on its first challenge, so the client requests every scope it publishes — the documented fallback. The restart server has no concept of a caller; it does whatever the process that started it can do. And when the agent hands work to a second agent, nothing downstream records which human started the chain. On a questionnaire this environment scores well. Under adversarial conditions there are three ways to make the agent act outside its mandate, and one ends in command execution on a host.

mcp security — drill

Three boundaries, and a test for each

First: you cannot test a tool-chain you have not enumerated. Shadow MCP servers have their own entry in the OWASP MCP Top 10, and the official MCP Registry helps less than teams assume — it authenticates a publisher's namespace by DNS or GitHub ownership and leaves scanning of the code to package registries. Verified publisher is not vetted code. The test is a sweep, not a survey: pull client configuration from source control and endpoint management, hunt local processes launched as tool servers, and watch egress for unregistered MCP traffic.

What the agent reads. Tool and schema-field descriptions are an injection surface that never passes through a user prompt, which is not the same problem as ordinary prompt injection through content. A compromised server can place instructions there that steer the model's use of *other* servers' tools. The test has two halves. Stand up a benign tool server, put instructions in its description and one schema field, and see whether they reach a consequential call on a different server. Then test for drift: hash each tool's name, description, and input schema on a schedule, and alert on any diff you did not approve. If nobody holds a baseline hash today, that is the finding.

What the agent can reach. Over-permissioning here is quiet, because the grant happens once, in one consent screen, for a bundle. The spec's own scope minimization guidance warns against wildcard scopes, and notes that a challenge carrying no scope guidance directs the client to request every scope the server publishes. The test is three attempts. Present a token issued for one MCP server to another and see whether audience validation happens. Call a privileged tool with a token scoped below it and confirm you get a 403 scope challenge, not a result. Then replay a state handle minted for one user as another; handles travel as ordinary tool arguments, and possession of one MUST NOT be treated as authentication. It is API authorization testing aimed at a layer nobody owns.

Who the agent believes. When one agent calls another, or a gateway fronts several servers, identity flattens: the downstream server sees the gateway, not the human, and chained calls carry no record of who originated them. The test is a provenance trace. Take one consequential action and reconstruct from evidence alone which principal initiated it, which agent forwarded it, which server executed it. Where the chain breaks, seed a synthetic marker — the canary technique works for call provenance as well as for data. Then register two servers exposing a same-named tool and see which one the client resolves to.

mcp security — quote

The honest close

Frameworks help organize this, but the OWASP MCP Top 10 is a beta release and a map rather than a test, and aligning to one is not certification — even where certification exists, as for ISO/IEC 42001, it certifies a management system, not that a control held. None of this removes risk from an agent that acts on the world. It reduces and reveals it, which matters more in a layer this new. It also ages: the tool-chain moves, so a review of it goes stale the way any point-in-time test does, only faster.

For a self-check, take one agent that is live today. Can you list the tool servers it reaches, and say how you know the list is complete? Can you show that instructions placed in a tool description do not reach a call on a different server? Can you show a token issued for one server refused by another, and a state handle refused when replayed by a different user? Can you reconstruct, from evidence, the chain behind one consequential action it took last week?

If those come back as "probably," that is normal. It is also a gap, and gaps here are cheap to find deliberately and expensive to find otherwise.

How ioSENTRIX can help

We trust-assess the MCP and tool-chain layer the way we assess any other integration boundary: enumerate what an agent can actually reach, test the authorization boundaries between tools and agents, and hand back the attempt, the observed result, the artifact, and the conditions — not a spreadsheet of "implemented." A governance review tells you the control exists; a platform's telemetry is the vendor grading its own homework. Independent adversarial testing produces the evidence, whoever performs it. We stay services-first and assure the stack you chose.

If you want a second set of eyes on your agent tool-chain, we're happy to have that conversation.

Keep reading

#
Penetration Testing
#
Generative AI Security
Contact us

Similar Blogs

View All