Over the past few weeks we’ve been running Operation:MCP – sharing pieces of research on how MCP is being adopted, disclosing critical vulnerabilities we’ve found in popular MCP servers, and introducing ‘MCP Inspector’ – a free community tool that scans an MCP server for risks before it is being installed.

MCP keeps improving how teams work, and prior posts in this series covered what a serious vulnerability in a local MCP server can cost its user, from a malicious webpage hijacking an agent’s own authenticated calls to a silent takeover that reads or rewrites a data scientist’s notebook. But what happens when an MCP server stops running for one employee and starts running remotely, wired into a whole team’s internal systems?

Too often, they go up without the access controls that deployment deserves. Dozens of them are sitting wide open on the internet right now, easy to find with ordinary network-scanning tools, wired into internal company systems and reachable by anyone who looks. In plenty of cases, that means unauthenticated read and write access to highly sensitive systems.

TL;DR

  • Unauthenticated MCP servers are not a corner case. We confirmed 147 of them wide open on the internet, answering any caller with no login, token, or session check at all.
  • What follows walks through the levels of exposure we found in the wild: a single machine, a large company’s production stack, a government one, and more. The blast radius scales at every step. The mistake behind it never changes.
  • Sitting in the open were private details of residents, a company’s internal financial statements, its subscriber base, and root on production servers with payment and cloud credentials in plaintext. None of it needed a sophisticated 0-day. Ordinary browsing led us straight to all of it, and if we could get there, so can an attacker.
  • Every finding here has the same root cause: a server that never checked who was asking. MCP’s own discovery step, tools/list, doesn’t require it to.
  • The details, and the three controls that stop this, are below.

Every confirmed finding is plotted below, by location and severity.

MCP Radar, an interactive 3D globe visualization plotting findings by location and severity, with filter and corpus panels
MCP Radar. Explore it live here.

No Exploit Needed, Just a Search

MCP gives an AI client a way to ask a server what it can do before deciding whether to use it. That discovery call, tools/list, is unauthenticated by design in most implementations. In practice, that means a server’s entire tool catalog sits exposed to anyone who finds the port: no login wall, no 404, just a plain-English inventory of everything the assistant behind it is allowed to touch.

So we started wondering how easily that could be turned into a list. If a server will tell anyone who asks what it can do, then finding the interesting ones stops being an exploitation problem and becomes a search problem. We went and checked.

Shodan search results for MCP servers, showing total results, top countries, ports, and organizations
One Shodan facet search for MCP servers, IPs and organization names redacted.

No Login Screen, Straight to Root

The most severe pattern in the corpus was also the most common one, and it needs no exploit at all. Plenty of the servers we found listed the same tool in their catalog: exec, described in plain English as running a shell command on the server. On its own, that is a perfectly reasonable thing to build. An admin who wants their assistant to tail a log, restart a stuck process or reload nginx needs exactly that tool, and it makes sense that they should be able to call it. The question is whether they are the only one who can.

So we checked what stands between the open internet and that tool. Spoiler: nothing.

Here’s what one of them handed back the moment we asked, no credentials attached:

Tool What it says it does
exec Run a shell command on the server. Use for system operations, file ops, package management, logs, etc.
system_info Get system info: uptime, load, memory, disk usage, network stats.
pm2_status List all PM2 processes with their status, CPU, and memory usage.
nginx_reload Reload nginx configuration. Use after making config changes.
nginx_logs View recent nginx access logs. Use for debugging, traffic analysis, error investigation.
pm2_logs View recent PM2 logs for a specific process.
Terminal screenshot: the tools/list response, host redacted
The full tools/list response. No login, no scopes, nothing hidden.

We started with benign commands, just to see whether the tool did what its description claimed. It did. Calling exec with id came back as uid=0(root), and on five servers across three unrelated operators, the answer was the same.

Terminal screenshot: exec('id') returning uid=0(root), host redacted
The exec('id') response.

Then we had to rule out the boring explanation. Some of what looks like a live MCP server on the wire is a honeypot, built specifically to pass a shallow probe, and a honeypot can print “root” as easily as a real shell can. So we pointed the same exec tool at a fresh, unique webhook URL and watched our own inbox. The request landed within seconds. It was a real machine.

Terminal screenshot next to a webhook.site inbox showing a real inbound GET request, host redacted
A real inbound request, seconds later, geolocated to the target’s own country.

That box was running eleven production services under one root user, and its environment files were sitting there in plaintext: a stripe_secret_key, a github_token, AWS access keys, a domain-registrar credential, all one exec call away.

This is what root on a shared box actually means in practice: control over every process running as that user, every client site behind it, and every third-party account whose keys happened to be sitting in that environment. It’s the same decision, made independently by different operators: wrap a shell in an MCP server because the assistant needs to restart something or read a log, then never revisit whether the endpoint should be public once it’s bound to 0.0.0.0.

A Nine-Figure Company, Wide Open

One of the exposed servers we found belonged to a digital media company doing an estimated nine figures in annual revenue. Its tool catalog, thirty tools deep, answered without a single credential.

The server’s own whoami tool, callable with no session and no credentials, confirmed it wasn’t a demo: a named production environment, a private storage bucket, a live report domain, and confirmation that the company’s paid Gemini and ChatGPT integrations were connected and reachable through the same unauthenticated path.

Browser view of the exposed MCP server's root JSON banner, with the host and company name redacted
The endpoint accepted the connection and returned its own banner with no authentication at all. Host and company name redacted.

A few of the thirty tools stood out:

Tool What it could do
list_reports Enumerate an entire private report bucket, zero arguments needed
download_report Pull any file out of that bucket, full body, not a metadata stub
execute_sql Run SQL directly against production data
create_email_list Build a bulk email list straight from a data-warehouse query
update_cms_content Write live content and paywall flags to the public site

Calling list_reports alone returned every object in the bucket: financial statements, ad-sales snapshots, subscriber analytics, podcast metrics, organized into folders that read like an org chart. download_report on one of them came back as a full document, proving the read path all the way through. Anyone who found this endpoint could have pulled the company’s complete financial and audience data, rewritten its public site, or exported its subscriber base to a mailing list, without ever authenticating.

We stopped at read-only calls, enough to prove the impact without touching anything write-shaped. The write-shaped tools were sitting right there in the same unauthenticated catalog: SQL against production, live CMS and paywall edits, a bulk email list built off a warehouse query. The finding was reported to the company. Their CISO’s response is below.

Email reply from the affected company thanking the researcher and scheduling a remediation call, names redacted
The company’s response after disclosure, names redacted.

A Government Citizen Registry, Open to Anyone Who Asked

Another server we found belonged to a Swiss municipality, running an AI agent built to automate citizen-administration processes: residence certificates, ID card and passport applications, address changes, move-in and move-out registration. It called itself ags-daemon, and its own banner said as much outright: built to be wired into a Claude Desktop connector, not opened in a browser.

Nothing in front of it asked who was calling. initialize returned a live session with zero credentials attached. tools/list came back with four tools, also unauthenticated, one of which dumps the agent’s entire process catalog: eight administrative processes, six of them citizen-facing and two of them internal to the municipality’s own operations.

Process Who can trigger it
Passport application citizen or staff
ID card application citizen or staff
Residence certificate citizen or staff
Move-in registration citizen or staff
Move-out registration citizen or staff
Address change citizen or staff
Council-meeting prep staff only
Council minutes processing staff only

The same unauthenticated endpoint that processes a passport application also reaches into the town’s internal governance workflow.

The tool that actually does the work, ags_anliegen, takes a resident’s AHV number, Switzerland’s national social-insurance ID, as a direct lookup key (or an internal person ID). Its own description instructs the calling model to act on it immediately, for every process in that table, without asking the user to confirm anything first.

Calling ags_anliegen with the text 'I need a proof of residence' and a person key, with no authentication, returning a real orchestration response
Calling ags_anliegen unauthenticated: a plain-language request routed straight into the residence-certificate process. Person key redacted.

The call was accepted, classified with 0.99 confidence, and routed straight into the residence-certificate process. Reachable with no credential of any kind: the citizen-administration workflow itself, keyed on the national social-insurance number a Swiss resident’s records hang off, on a system whose other six processes issue passports and ID cards. This is the most severe class of exposure in the corpus, and it is a municipal government service.

This finding was disclosed to Switzerland’s National Cyber Security Centre (NCSC), and the case is now closed.

Email from NCSC's Vulnerability Management Team confirming they reviewed the reported endpoint
NCSC’s response after we reported the finding.

The Numbers Behind All of It

These anonymized cases are only a few examples from the hundreds of publicly reachable MCP endpoints we identified over a matter of weeks. Attackers can find the same servers just as easily with ordinary internet search and scanning tools.

Across every pass so far, our tracked corpus stands at 179 confirmed findings, the same 179 plotted on MCP Radar above. 147 of them, 82%, checked out as genuinely unauthenticated once we tested the tools directly, not just at first scan.

Severity, after manual verification, breaks down as 26 critical, 19 high, 24 medium, 110 low. 140 are still live and reachable right now. 39 have gone dark since we first found them.

Manual severity assessment across all 179 confirmed findings.

Geography tells its own story. Across the full 179-finding corpus, the US leads with 89, Germany is next at 22, then China (11), Canada (10), and Japan (8).

Severity is our judgment of how bad an exposure would be if somebody used it. It says nothing about what an unauthenticated caller could actually do on the other end, so we classified that separately: for every finding, what the exposed tools would have let a stranger touch.

Across the 166 of 179 findings where we had full tool visibility.

Why This Keeps Happening

Every finding here traces back to one omission: nobody checked who was calling before letting them call. MCP makes that easy to miss, because a tools/list response reads like documentation, not an attack surface, right up until someone scans the port it’s listening on. A shell tool bound to 0.0.0.0, a tools/call endpoint left open because “it’s only for our internal assistant,” a tool description that tells the model to act without confirmation: none of these are exotic mistakes. They’re the same shortcut, taken independently, at every scale we tested, personal machine, company, and government service alike. Some of it isn’t even a standing decision: someone opens a port for a quick test or a local demo, moves on, and the server just keeps listening, unauthenticated, long after anyone remembers it’s there.

Email reply from an affected operator explaining the exposed MCP server was left public during testing and calling it an oversight, name redacted
One operator’s own explanation after disclosure: left public during testing, then never revisited.

What Security Teams Can Actually Do About It

  • Authenticate tools/call, not just the transport. Discovery can reasonably stay open. Execution and data retrieval shouldn’t.
  • Scan your own external attack surface for MCP fingerprints. If a server is reachable from the outside, you want to be the one who finds it first.
  • Authorize per tool, not per server. Reading a public index is not the same privilege as executing a shell command or writing to a citizen registry, and the authorization model should say so explicitly.

None of this is theoretical. Any organization can have a server like these live right now, quietly bridging internal systems to the open internet, stood up by someone who just needed their assistant to reach one more thing. By the time a server like that shows up on a search engine like Shodan, it’s already too late.

Instead, this is exactly the kind of gap Pluto’s AI Workspace Security Platform, already protecting 1,000,000+ endpoints, is built to close. It gives you visibility into every MCP server running across your environment: who built it, what it can reach, and whether it’s actually authenticated, so you catch it before anyone else does. Curious what’s running in yours? Talk to us.

Conclusion

None of this came from a novel exploit. We asked servers what they could do, then checked whether anything was gating the answer, and almost every time nothing was. We found hundreds of publicly reachable MCP endpoints in only a few weeks, and attackers can run the same searches continuously. Once an MCP server can reach a shell, a data warehouse, a CMS or a citizen registry, it is a privileged production interface, and it needs the identity, authorization and logging every other privileged interface gets. The mistake is cheap to make and cheap to fix. The expensive part is not knowing the server is there until somebody else finds it first.