# I knocked on 3,000 MCP servers and most let me in

> I asked 3,000 public MCP servers what they could do, with no login. Most answered, and a third of those listed tools that delete, spend or send.

_Published 2026-11-04 · https://mashprime.dev/blog/probing-public-mcp-servers/_

I wanted to know how public MCP servers treat a stranger. So I wrote a small script, pointed it at the official MCP Registry, and asked 3,000 of them the same thing: who are you, and what can you do? No login, no API key.

More than half answered. A third of the ones that answered then showed me tools that say they can change something. Delete a database. Refund an order. Launch an ad campaign. Ring a real phone number and hold a conversation. I didn't press any of those buttons, but anyone could have seen them.

<figure style="margin: 2rem 0;">
  <div style="margin-bottom: 1rem;">
    <div style="display: flex; justify-content: space-between; gap: 1rem;"><span>Servers probed</span><span style="color: var(--text-primary); font-variant-numeric: tabular-nums;">2,894</span></div>
    <div style="margin-top: 0.4rem; height: 12px; background: var(--bg-tertiary); border-radius: 4px;"><div style="width: 100%; height: 100%; background: var(--color-signal-cyan); border-radius: 4px;"></div></div>
  </div>
  <div style="margin-bottom: 1rem;">
    <div style="display: flex; justify-content: space-between; gap: 1rem;"><span>Answered with no login</span><span style="color: var(--text-primary); font-variant-numeric: tabular-nums;">1,687</span></div>
    <div style="margin-top: 0.4rem; height: 12px; background: var(--bg-tertiary); border-radius: 4px;"><div style="width: 58.3%; height: 100%; background: var(--color-signal-cyan); border-radius: 4px;"></div></div>
  </div>
  <div style="margin-bottom: 1rem;">
    <div style="display: flex; justify-content: space-between; gap: 1rem;"><span>Listed a tool marked as able to change things</span><span style="color: var(--text-primary); font-variant-numeric: tabular-nums;">562</span></div>
    <div style="margin-top: 0.4rem; height: 12px; background: var(--bg-tertiary); border-radius: 4px;"><div style="width: 19.4%; height: 100%; background: var(--color-signal-cyan); border-radius: 4px;"></div></div>
  </div>
  <div style="margin-bottom: 1rem;">
    <div style="display: flex; justify-content: space-between; gap: 1rem;"><span>Listed a tool marked destructive</span><span style="color: var(--text-primary); font-variant-numeric: tabular-nums;">282</span></div>
    <div style="margin-top: 0.4rem; height: 12px; background: var(--bg-tertiary); border-radius: 4px;"><div style="width: 9.7%; height: 100%; background: var(--color-signal-cyan); border-radius: 4px;"></div></div>
  </div>
  <figcaption style="font-size: 0.9rem; color: var(--text-muted);">Remote MCP servers from the official registry using the current HTTP transport, probed on 1 November 2026. Each bar is a subset of the one above it.</figcaption>
</figure>

## What does a stranger get shown?

The first scan only counted tools, so on 4 November I went back to a random 60 of the 282 servers that had marked a tool destructive and asked for their tool lists again. 59 answered, still with no login. Between them they offered more than 1,600 tools, a median of 21 each, and 330 of those were marked destructive.

The names don't leave much to the imagination. I've left out which servers they came from:

- `delete_database`: "PERMANENTLY delete a database and all its data."
- `refund_order`, which issues a full refund on a paid order.
- An ad campaign tool whose description warns that "real ad money starts".
- `place_call`, which rings a real number and holds a live voice conversation on the owner's behalf.
- `send_email` and `send_text`, from the server's own address and number.
- Tools that create patient records and book appointments in a live clinic system.
- `unsubscribe_lead_globally`, `delete_api_key` and `memory__forget`.

Across the 59, 15 had tools that described deleting something permanently, and 16 had tools that spend, charge or refund money.

Seeing a tool isn't the same as being able to use it. Some of these servers probably check an account when a tool is called. At least 8 of them take a key or token as an argument on some of these tools. I didn't call anything, so I can't say how many would have worked. But an agent that connects to any of these servers sees every one of those tools, and it decides what to do with them.

## What stops an agent from pressing the button?

Mostly, a sentence in the description.

14 of the 59 servers put some kind of brake on their dangerous tools. In 10, it's plain text addressed to the model, like "Irreversible — confirm with the user first." In 6, it's a two-step pattern: call the tool once to get a summary, then call it again with `confirm: true` to make it happen.

Both are written for the model, and the model is the one deciding whether to follow them. A careful agent will stop and ask. A confused one, or one that has read a malicious web page telling it otherwise, can pass `confirm: true` on the first call. The two-step pattern at least gives a client somewhere to show the person a summary, which is better than nothing. It still isn't a permission. I wrote about that difference in [a prompt is not a permission system](/blog/a-prompt-is-not-a-permission-system/), and these tool lists are a good example of it in the wild.

In the other 45, I found nothing like that in the descriptions. Whatever protection they have isn't visible to the agent.

## What about the Origin header I set out to check?

That's what started this. The MCP spec says servers must check the `Origin` header, which tells a server which website a browser request came from. The rule exists to stop DNS rebinding, where a web page tricks your browser into talking to a server on your own machine or office network. Since the [2025-11-25 revision](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports), a bad `Origin` must get a `403`.

81% of open servers happily answered a request claiming to come from `https://evil.example`. Only 18% refused it.

That turned out to be the least interesting finding. A public server on the internet can already be reached by anyone with `curl`, so for a public server with no logins, the `Origin` check protects very little. Mine accepts any `https` origin on purpose. The check matters for servers on your laptop or inside a private network, and this scan couldn't reach those.

One number did catch my eye. Servers with tools that can change things rejected `evil.example` 22% of the time. Servers whose tools were all read-only rejected it 24% of the time. If people were adding the check because their server could do damage, those numbers would differ. They barely do. My guess is that the check usually comes with whatever framework the server was built on, rather than being a decision about that particular server.

Two smaller things. 30% of open servers didn't annotate their tools at all, which leaves a client to assume every tool can change things. And only about 6% sent any rate-limit headers, though that doesn't mean the rest have no limits.

My own server didn't come out spotless either. It sent no annotations, even though all five tools are read-only. Version 1.1.2 now marks every one of them `readOnlyHint: true`.

## What should you do about it?

**If you're connecting an agent to a remote MCP server**, look at its tool list before you trust it, not at whether it checks `Origin`. If it offers tools that delete, spend or send, make sure your client asks you before it calls them, and give it a credential scoped to what it needs.

**If you're building a remote server**:

- Decide your `Origin` policy on purpose. If your server uses cookies or other ambient credentials, or can reach anything private, validate `Origin` and return `403`. If it's public and read-only, accepting any origin is defensible, but write that decision down.
- Annotate every tool. It's one line per tool, and clients can only build sensible approval rules from what you tell them.
- Don't expose tools that change things without authentication. Least privilege applies to servers as much as agents, which is the point of [a prompt is not a permission system](/blog/a-prompt-is-not-a-permission-system/).
- Rate limit tool calls, and consider sending `RateLimit` headers so well-behaved clients can slow down before they hit a `429`.

## How did I run the scan?

On 1 November the [MCP Registry API](https://registry.modelcontextprotocol.io/) listed 53,922 servers. The ones with a remote URL sat on 26,335 different hosts. A few platforms host thousands of URLs each, so I picked one URL per host, then a random 3,000 hosts. 2,945 resolved in DNS, and 2,894 of those used the current Streamable HTTP transport.

Each server got a handful of requests at most: `initialize` with no credentials, the same again with a foreign `Origin` and with `Origin: null`, and `tools/list` if it let me in. The scanner never called a tool. It sent at most four requests at a time and never two at once to the same host, paused between requests, and identified itself with a User-Agent pointing back to this site. It refused anything that resolved to a private address.

I haven't published the per-server results.

## What can't this tell you?

- **It's one sample, on one day.** I probed 3,000 of 26,335 hosts, so the headline shares should be within about two percentage points of a full scan. The registry isn't every MCP server either.
- **It shows what tools say, not what they do.** Annotations and descriptions are self-reported, and I didn't call anything.
- **Servers behind a login, and local servers, are a blank.** I can't see their tools, or whether they check `Origin` after you sign in.

## Sources

- [Model Context Protocol: Transports (2025-03-26)](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports)
- [Model Context Protocol: Transports (2025-11-25)](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports)
- [Model Context Protocol: Streamable HTTP (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http)
- [Model Context Protocol: Tools (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools)
- [Official MCP Registry](https://registry.modelcontextprotocol.io/)
