MCP Server Security Testing: The Shadow API Someone Is Already Scanning

MCP server security testing treats a Model Context Protocol server, once it is exposed over the network, for what it is: an HTTP service holding credentials that, without real authentication, is reachable by anyone who completes the handshake. It gets discovered, inventoried, authenticated against, and exercised tool by tool, exactly like every other API you own.

Key takeaways

  • On July 13, 2026, the SANS Internet Storm Center reported opportunistic, internet-wide scanning that has "already added MCP servers, AI assistant credentials, and local LLM endpoints to its standard target list." In fourteen days of logs from one small host, 49 distinct source IPs sent valid MCP protocol handshakes.
  • It is not one host's bad luck. Researchers at Knostic mapped 1,862 internet-exposed MCP servers; of the 119 they manually checked, all 119 served their tool listing with no authentication.
  • Most of these are shadow MCP servers: an API nobody wrote down. It is the same class of risk OWASP ranks as API9:2023, Improper Inventory Management, now arriving for a brand new asset class.
  • The fix is not a new category of tool. It is inventory plus authenticated testing, pointed at an asset class your inventory has never heard of. The right way to adopt MCP is one governed server on purpose, not a hundred stood up as glue.

What the scanning actually looks like

The SANS Internet Storm Center diary is worth reading in full, but the shape of it is simple. An analyst pulled fourteen days of web logs from one small host and found reconnaissance that was unmistakably hunting for AI infrastructure.

The scanners sent well-formed JSON-RPC handshakes to POST /mcp, the protocol's own initialize call, complete with a declared protocol version. That is not a generic path-guessing sweep. Whoever wrote it knew what an MCP server is and how to talk to one. Forty-nine distinct source IPs did it, which the analyst notes makes it "a broad, distributed scan" rather than one curious researcher.

The same traffic reached for the things that sit around an MCP server:

  • Agent configuration files: /.claude/mcp.json, /.cursor/mcp.json, /.vscode/mcp.json. These name your servers and often your tokens.
  • Credentials directly: a HEAD request for /.claude/.credentials.json, a tell the analyst calls "a mature, wide campaign" checking whether a file exists before spending bandwidth on it.
  • Unauthenticated model endpoints: GET /v1/models for anything OpenAI-compatible, GET /api/tags for Ollama, which binds to localhost by default but is very commonly exposed by accident.
  • Cloud metadata via SSRF, the classic pivot from "I can make this thing fetch a URL" to "I have your instance credentials."

Read that list again. It is a credential hunt. The MCP handshake is how they find the door; the config files and metadata endpoints are what they came for.

An MCP server is an API, and it holds the keys

Strip away the protocol branding and an exposed MCP server is an HTTP service that accepts structured requests and does things on behalf of the caller. Read a file. Query a database. Call an internal service. Open a pull request.

One precision worth getting right, because the whole thesis rests on it. When an MCP server runs over the Streamable HTTP transport, the specification says it "MUST provide a single HTTP endpoint path" that supports both POST and GET. So it is not a sprawl of REST routes; it is one endpoint that speaks JSON-RPC, and the real surface is the set of tools reachable through it. That is exactly why the scanners POST a protocol handshake instead of fuzzing URLs. There are no per-tool paths to guess, so they ask the server to list its own.

Which means the interesting property is not the protocol. It is the capability. An MCP server exists precisely to hold the credentials and reach that an agent needs in order to be useful, and to expose that reach through its tools. An unauthenticated one hands that capability to whoever finds it first. As the SANS analyst puts it, an exposed and unauthenticated MCP server "is close to the worst case. It is a remote, machine-readable menu of everything an agent can touch, offered to anyone who completes the handshake."

This is not hypothetical past the recon stage. The implementations themselves have already produced critical, patched CVEs: remote code execution in the widely used mcp-remote proxy (CVE-2025-6514, CVSS 9.6), triggered by a crafted authorization_endpoint from a malicious server, and RCE in Anthropic's own MCP Inspector (CVE-2025-49596, CVSS 9.4), caused by missing authentication between the client and its proxy. The scanning SANS observed is the reconnaissance that precedes exactly these outcomes.

Walk the chain once, because it is short

A scanner sends the initialize handshake to POST /mcp and gets a tool list back, no credentials asked. One of those tools fetches a URL, so the attacker points it at http://169.254.169.254/latest/meta-data/ and reads back the instance's cloud credentials, the SSRF-to-metadata pivot the diary caught in progress. Another tool queries a database with whatever identifier it is handed, so the attacker walks the records. A third opens pull requests, so the attacker now writes to your source control. No exploit chain, no zero-day, no privilege escalation. The server was built to do these things on behalf of an agent, and it did them on behalf of a stranger. It is not one vulnerability. It is a set of working credentials with an API in front of them.

Shadow MCP servers: the API nobody wrote down

Here is the uncomfortable part. Your MCP servers were almost certainly not shipped the way your services are shipped.

They got stood up by a developer who wanted a coding agent to reach an internal system, in an afternoon, as glue. No architecture review, no service registration, no owner in the CMDB, no line in the API inventory. Nobody pointed a scanner at one because, as far as the inventory is concerned, it does not exist.

This is the same failure mode as the shadow and zombie endpoints that have been quietly widening API attack surface for years, the problem OWASP ranks as API9:2023, Improper Inventory Management, and the same one that AI coding assistants accelerate by generating routes in bulk. The endpoint is real long before it is recorded anywhere, and the gap between those two moments is where the risk lives. The only thing new is that this time the undocumented endpoint is the one holding an access token for your source control.

Not every MCP server is exposed: know your transport

Before you test anything, answer one question for each server: does it listen, and who can reach it? The MCP specification defines two transports, and they have completely different exposure.

  • stdio. The client launches the server as a subprocess and talks to it over standard in and standard out. There is no port and no network listener, so there is nothing on the internet to scan. The spec says clients "SHOULD support stdio whenever possible," and in practice this is the common local case.
  • Streamable HTTP. The server is a real HTTP endpoint on POST and GET, which is exactly the POST /mcp the diary caught being probed. This is the surface an attacker can reach.

And a local HTTP server is not automatically safe. The same spec section warns implementers to validate the Origin header and to bind to localhost (127.0.0.1) rather than all interfaces (0.0.0.0), "without these protections, attackers could use DNS rebinding to interact with local MCP servers from remote websites." The MCP Inspector RCE above was precisely that mistake.

Deployment postureInternet-reachable listenerIn scope for the SANS scanThe question to ask
stdio (local subprocess)NoNoIs it really stdio, or an HTTP server on localhost?
Local HTTP (localhost-bound)No, unless bound to 0.0.0.0Only via DNS rebindingOrigin validated? Bound to 127.0.0.1?
Remote HTTP, authenticatedYesYes, but rebuffed at the 401Enforced on every tool, not just the handshake?
Remote HTTP, unauthenticatedYesYes, fullyWhy does this exist?

The bottom row is the one the scanners are counting on. And they can count on it because the spec permits it: authorization is "OPTIONAL for MCP implementations." When it is implemented on an HTTP transport, "correct" is well defined and worth knowing so you can tell whether yours qualifies: the server acts as an OAuth 2.1 resource server, answers an unauthenticated request with 401 Unauthorized and a WWW-Authenticate header, and validates that "access tokens were issued specifically for them as the intended audience" (RFC 8707 resource indicators). The failure the scanners exploit is simpler than any of that. A server authenticates the handshake loosely, or not at all, and then runs every tool for whoever got in. Handshake auth is not tool auth.

How to test an MCP server for vulnerabilities

The good news is that nothing here requires a new discipline. An exposed MCP server is an API, so the existing playbook applies. It just has to be pointed at an asset you have not been pointing it at.

  1. Inventory it. You cannot test what you have not listed. Find every MCP server in your estate: search your deployment configs and agent configuration files for MCP endpoints, and for the internal REST APIs a server fronts, derive them from source, for supported languages and frameworks, deterministically and locally, with no source code sent to an external model. The point is to get each server onto the list your scanner reads from.
  2. Authenticate, then test the tools, not just the handshake. The dangerous surface is behind auth, so a scan that cannot log in and hold a session will not reach it. Exercise each tool for the failures that actually occur here:
    • Missing or handshake-only auth. A tool that runs for anyone who completed the handshake is an unauthenticated capability. Test each tool, not the front door.
    • Broken access control, including cross-tenant isolation. A read_file or query tool that honors any path or record identifier it is handed is IDOR wearing a friendlier name.
    • Command injection. The tool is usually a thin wrapper over a shell, a database, or an HTTP client. The injection lands wherever the wrapper lands.
    • SSRF in fetch-style tools. Any tool that retrieves a URL is a candidate for the metadata pivot the scanners are already trying.
  3. Link findings back to the line that caused them. A finding on an internal glue service is only actionable if the developer who wrote it can see the file and line. That is the argument in Source-Linked DAST: The Answer to Findings AI Can't Reproduce Twice, and it applies with more force here, because the person who stood up the server may not think of themselves as owning a production service at all.

What endpoint testing does not catch

Be honest about the boundary. Authenticated testing of the endpoint finds the exposed, unauthenticated, injectable, SSRF-able server. It does not find the failures that live at the agent and OAuth layers, and a knowledgeable reader will expect you to name them: tool poisoning, where a malicious tool description carries instructions the model reads as trusted; the confused-deputy and token-passthrough problems the MCP authorization specification explicitly forbids; over-broad tool scopes and context over-sharing. Those need controls at the client, the OAuth flow, and the approval step, not a scan of the port. Naming the whole landscape and then testing the part testing can actually reach is the difference between a security program and a checkbox.

What good MCP governance looks like (ours, for example)

The failure mode above is a server nobody chose: stood up as glue, on a listener, with a token, off the books. The opposite of that is a server someone chose on purpose. A security team that specifies one vetted MCP server, centrally, for every developer is doing inventory management by construction, which is the OWASP API9 remediation the rest of this post argues for.

NightVision's own MCP server is one example of that pattern, and it would be dishonest not to say we ship one. It runs locally, next to the developer's coding assistant, and makes outbound calls to the NightVision API. It does not sit on a public port waiting for a JSON-RPC handshake from a stranger, so the reconnaissance in the SANS diary has nothing to knock on. It is how an agent pulls source-linked runtime findings and drafts a fix, with a human approving the pull request. Agent-ready, explicitly not autonomous.

And to close the loop on the fear this post opens with: a config file on a developer's laptop is not the exposure the diary is about. The exposure is a config or credentials file that a deployed, public-facing service serves from its web root. Centrally specifying one vetted, outbound-only MCP server is how a team gives developers agent capability without standing up a listener for a stranger to find. Exposure is a choice someone makes, usually without meaning to. Governance is making that choice on purpose.

The questions to ask your platform team this week

None of these require a tool to answer. They require someone to go and look.

  • How many MCP servers do we run, and who owns each one?
  • Which of them listen on a network interface, and which are reachable from outside our network?
  • Which ones require authentication, and is it enforced on every tool, not just the handshake?
  • What credentials does each server hold, and what is the blast radius if the tools are called by a stranger?
  • Is any of them in the API inventory? Is a scan pointed at any of them?
  • Are agent config files such as .claude/mcp.json or .cursor/mcp.json reachable from the web root of anything we deploy?

If the honest answer to the last two is no, that is the finding. You do not need a vulnerability report to act on it.

Related readingPart of our series on modern application security testing. Start with What You Should Know About Application Security Testing, see how source-derived discovery supports API inventory integrity, and read the wider trust argument in Autonomous Penetration Testing: A CISO Reality Check.

Frequently asked questions

What is MCP server security testing?

MCP server security testing means treating a Model Context Protocol server, once it is exposed over the network, as the HTTP API it is: discovering it, inventorying it, authenticating against it, and exercising every tool for real vulnerabilities such as missing authentication, broken access control, command injection, and server-side request forgery. It is not a new discipline. It is API security testing applied to an asset class most teams have not inventoried.

What is a shadow MCP server?

A shadow MCP server is a Model Context Protocol server connected to an AI agent or coding assistant without formal approval, inventory entry, or security review. It is usually stood up by a developer as glue for an agent, never registered as a service, and never scanned. It is the newest form of the improper inventory management problem OWASP has long ranked in its API Security Top 10.

Are attackers actually scanning for MCP servers?

Yes. The SANS Internet Storm Center reported opportunistic, internet-wide scanning for MCP servers, AI assistant credential files, and local LLM endpoints. In fourteen days of logs from a single small web host, 49 distinct source IPs sent valid MCP protocol handshakes. Separately, researchers at Knostic mapped 1,862 internet-exposed MCP servers and found that every one of the 119 they manually checked served its tool listing with no authentication.

Do MCP servers require authentication?

No. The MCP specification makes authorization OPTIONAL, so a server exposed over an HTTP transport can become an unauthenticated endpoint. Any tools and credentials it holds are then reachable by anyone who completes the protocol handshake, which is why enforcing authentication on every tool, not just the initial handshake, is the first control.

Does using an MCP server mean exposing one to the internet?

No. The MCP specification defines two transports. Over stdio, the server runs as a local subprocess with no network listener at all, which the spec recommends clients support whenever possible. Over Streamable HTTP, the server is a real HTTP endpoint that can be exposed. Exposure is a deployment choice, not a property of the protocol, so the question to ask about any MCP server is whether it listens, and who can reach it.

How is MCP security testing different from normal API security testing?

The endpoint testing is the same: an exposed MCP server is an HTTP service, so authenticated DAST looks for missing auth, broken access control, command injection, and SSRF. The difference is a set of MCP-specific and AI-layer failures layered on top, such as tool poisoning and confused-deputy token misuse, which endpoint testing does not catch and which need controls at the agent and OAuth layers.

What is tool poisoning in MCP?

Tool poisoning is when a malicious or compromised MCP server embeds instructions in its tool descriptions or metadata that manipulate the AI model consuming them. Because clients often pass tool metadata straight into the model's context, a poisoned description can redirect the agent's behavior. It is an agent-layer trust problem, not something authenticated endpoint testing detects.

How do you find shadow MCP servers you do not know about?

Inventory first. Search your deployment configs and agent configuration files for MCP endpoints, and derive the internal REST APIs an MCP server fronts from source, for supported languages and frameworks, deterministically and locally, without sending code to an external model. The goal is to get every server onto the list a scanner reads from before an attacker's scanner finds it first.

Put it in the inventory, then point a scan at it

The scanning is already happening, and it is looking for exactly the asset your inventory does not list. NightVision discovers REST APIs from source for supported codebases, then tests the discovered surface with authenticated DAST, with findings anchored to the source line that caused them. The internal APIs an MCP server fronts are exactly that surface: get them into the inventory and run the same chain against them, for the same reason every other API needs it. NightVision is SOC 2 Type II attested; report available under NDA.

Find the APIs nobody wrote down.

Start free, or book a demo to see the documented and undocumented API surface in your own codebase.