Last week I ran a passive OAuth 2.1 audit on 277 public MCP servers. This week the scanner got four new passive checks that read response headers and authorization server metadata without a single extra request. I re-scanned the same host list. 130 were reachable in both sweeps.
One number stuck out.
One check, 121 of 125 reachable servers
HEADERS-001 fires when the initialize response is missing one of four standard transport-security headers:
- Strict-Transport-Security on HTTPS
- X-Frame-Options or a Content-Security-Policy frame-ancestors directive
- X-Content-Type-Options: nosniff
- a wildcard Access-Control combination
121 of the 125 servers that were reachable this week trigger at least one. That is 96.8 percent. Only 4 servers had clean transport-security headers.
These are not expensive checks. Each header is one line of configuration on the reverse proxy or in the response code. The reason the count is this high is that nobody is used to treating an MCP endpoint as a web service that lives in a browser threat model. Agents do not live in browsers today, but the endpoint is still reachable from one.
The three smaller surprises
| Check | Last week | This week |
|---|---|---|
| RESOURCE-001 (Protected Resource Metadata missing) | 0 | 6 |
| ISS-001 (RFC 9207 iss parameter not advertised) | 0 | 6 |
| AUTH-007 (invalid bearer returns wrong HTTP status) | 0 | 3 |
Three low-cost fixes, each catching a narrower class of servers. The counts are low because the servers these catch are specific: RESOURCE-001 only on servers that advertise OAuth and still omit the Protected Resource Metadata document, ISS-001 only on metadata clean enough to read, AUTH-007 only on servers that bother to reject an invalid token at all. The code did not get worse. The scanner got a new eye.
Ten hosts lost a grade purely from the new signals
No new check fires on code these servers did not already have. The grade shift is only the four passive signals that used to be invisible to the scanner.
| Host | Last week | This week |
|---|---|---|
| api.githubcopilot.com/mcp | A | C |
| mcp.sentry.io | A | C |
| crashstory.com/mcp | A | C |
| mcp.supabase.com/mcp | A | B |
| mcp.sentry.dev/mcp | A | B |
| mcp.deepwiki.com/mcp | A | B |
| mcp.semgrep.ai/mcp | A | B |
| mcp-server.egnyte.com/sse | A | B |
| game.spacemolt.com/mcp | A | B |
| mcp.roundtable.now/mcp | D | F |
The pattern is consistent: HEADERS-001 for almost everyone, plus RESOURCE-001 or AUTH-007 on top.
What this is not
These numbers are not a benchmark of MCP server quality. They are a measurement of what four cheap checks catch on a public cohort today. A grade is an aggregate: a server with strong authentication and weak transport headers ends up next to one with weak authentication and strong transport headers. The report page for each host is where the details live.
The sweep also did not run the four new active checks against anyone. Those probes register clients and send crafted /authorize requests. They are safe against your own server and rude against someone else's. Opt-in only.
Run your own
npx -y @patchbay-nebius/agent audit https://mcp.example.com/mcp No credentials, no flags, no account. Eight-second scan, report page public for 90 days.
Full write-up with every check explained on the original blog: patchbay-mcp.dev/blog/mcp-transport-security-one-week-later