DEV Community

The Ops Log
The Ops Log

Posted on

MCP server uptime isn't a spectrum: 78% never miss a day, 5.5% never answer

Everyone quotes MCP server health as one number. I have been quoting one too: about 92% of a fixed set of servers answer on any given day.

That number is real and it is also useless, because there is no server that behaves like it. I probed the same 400 MCP endpoints every day for a month, and the population is not a bell curve around 92% — it is two clumps with almost nothing between them.

What I did

On 2026-07-30 I took every endpoint in the official MCP registry that completed an anonymous handshake, and froze 400 of them as a fixed cohort. Every day since, the same 400 get the same probe: open a session, ask for the tool list, record what came back.

This is deliberately not a fresh sample. A fresh sample each day tells you what the registry looks like today. A fixed cohort tells you what happens to servers as they age, and those turn out to be different questions with opposite answers.

Clean window: 2026-08-04 → 2026-08-27, 23 days. Three runs are excluded and I would rather say why than quietly not mention them:

  • 8/02 and 8/03 — the snapshot schema had no answered field yet. Those runs recorded protocol and tool counts but not a pass/fail boolean, so they cannot be scored. They are not zeros; they are unscoreable.
  • 8/09 — the probe returned 0 answered out of 400. Four hundred servers do not fail simultaneously; the probe did. The run is void.

That last one nearly poisoned this entire post, and the near-miss is in the method section at the bottom.

Finding 1: uptime is bimodal, not a spectrum

Of the 400 servers, here is how many days each one was unreachable:

days unreachable (of 23) servers
0 313
1 41
2 5
3 5
5 2
7 2
8 2
10 2
13 1
17 1
18 4
23 (every day) 22

313 servers (78.2%) never missed a single day. 22 (5.5%) never answered once. Everything else — every degree of partial reliability there is — accounts for 65 servers — 16.25%.

The 92% daily average implies a population of somewhat-flaky servers. That population is mostly not there. What exists is a large reliable block, a small dead block, and a thin tail.

Sensitivity check, because two days deserve suspicion. 8/05 and 8/08 had 38 and 41 servers down against neighbouring days of 23–28. If I drop both, "never missed a day" rises to 341 (85.2%) and "down at least once" falls to 59 (14.8%). I am not dropping them in the headline: those same absolute counts (38, 41) recur on 8/26 and 8/27 as part of a steady rise, so elevation alone does not convict them. Either way the shape holds, and the two figures below do not move at all.

Finding 2: "never answered" is not "dead"

Those 22 servers that never once answered in 23 days — here is what they actually returned on the final day:

response count
HTTP 404 7
HTTP 401 6
handshake failed after connecting 5
HTTP 405 2
HTTP 500 1
connection error 1

Six of the 22 are returning 401. They are running. They are reachable. They are refusing me, because my probe is anonymous and they want a token. Filing those under "dead" would be wrong, and it is the specific error I have criticised other people's MCP numbers for making. The genuinely-gone bucket is the seven 404s plus, arguably, the four transport failures.

So: 5.5% never answered an anonymous probe. Something under 3% look actually gone.

Finding 3: a one-day snapshot overstates death by about a quarter

Three ways of asking "how many are down", same cohort, same final day:

  • down on the final day: 41 (10.2%)
  • down on the final 5 consecutive days: 33 (8.2%)
  • down on the final 10 consecutive days: 29 (7.2%)

And in the other direction: 87 servers were down at least once, but 46 of them were back up on the final day. Half of all observed failure was transient.

If you probe once and publish the result, you will call roughly 41 servers broken when about 33 are persistently broken — an overstatement of ~24%. Two probes a week apart costs nothing and removes most of that error.

Finding 4: the registry got healthier while its servers got worse

This is the part I did not expect, and it only shows up because the fixed cohort and the fresh sample run side by side.

Every day I also draw a fresh random 400 from a full walk of the live registry. Over the same window:

first half second half change
fixed cohort (same 400 servers) 92.6% up (sd 1.3) 91.5% up (sd 0.8) −1.0pp
fresh sample (new 400 daily) 51.9% up (sd 3.1) 55.6% up (sd 2.7) +3.6pp
registry size 10,352 14,210 +37.3%

The registry grew by more than a third in 23 days, and it rose on every one of the 21 consecutive day-pairs (the 8/05 walk returned a partial population of 4,190 and is excluded). Over exactly that stretch, the servers I had been watching since July got slightly worse, while the registry as a whole looked better.

Nothing was repaired. The aggregate improved because new arrivals outnumber and outperform the decaying stock. It is a composition effect, and it means registry-wide health trends tell you about the growth rate, not about durability.

I want to be careful about how hard I lean on this. The cohort decline is small but tight (sd 0.8–1.3, and it is monotone across most of the second half). The fresh-sample rise of +3.6pp sits at roughly 1.2 standard deviations — suggestive, not established. The +37.3% growth and the cohort decline are the two solid numbers; the direction of the third is consistent with them but I would not publish it alone.

What this changes if you depend on MCP servers

  • Do not read a fleet-wide uptime average as a per-server expectation. Your specific server is very probably in the 78–85% block that never fails, or in the 5.5% that never works. The average describes neither.
  • Probe twice before you declare anything broken. Half of observed downtime came back.
  • Treat 401 as a configuration fact, not a health fact. Six of my 22 worst-performing endpoints are healthy servers that want a token.
  • Distrust improving registry health. Ours improved while every server we tracked got worse.

Method, and the mistake that nearly shipped

The probe is anonymous, read-only, one session per endpoint per day, no retries within a run. Cohort seeded from the 7/30 up-set; it is a fixed list, not blind and not re-randomised, so it answers "what happened to these 400" and not "what happens to the registry".

The mistake: my first pass at this analysis excluded the void 8/09 run by matching the string 2026-08-09, but the snapshots store dates as 20260809. The filter silently matched nothing, the failed run stayed in, and every server inherited one artificial down-day. The result was a clean, dramatic, completely false headline — "0 of 400 servers went a single month without an outage." It survived until I asked why the distribution had no zero bucket.

I am writing that down because it is the same failure this whole series keeps finding in other people's numbers: not a wrong measurement, but a filter that quietly did nothing while reporting success. A check that cannot fail is not a check. Mine failed silently, and the only reason it got caught is that the output was too striking.

Raw daily snapshots, the probe, and the licence are here — it is read-only and it voids bad runs rather than reporting from them:

github.com/operatorsheets/mcp-observatory · data and prior findings at operatorsheets.github.io/state-of-mcp

If you run one of the 22, I will happily re-probe it and correct the record.

Top comments (0)