DEV Community

The Ops Log
The Ops Log

Posted on

Where you host your MCP server decides whether it still works in three months

I probed every remote MCP server listed in the official registry — 10,716 endpoints — and then asked a question the aggregate numbers hide: when a listing is dead, where is it hosted?

The answer is not evenly distributed. It is not close to evenly distributed.

Failure rate by hosting platform

Counting an endpoint as failing if it returns a hard 404, fails DNS, times out, refuses the connection, or 5xxs:

Host Endpoints Failing Rate
ngrok 6 6 100%
smithery.ai 217 191 88%
trycloudflare tunnels 115 85 74%
railway.app 297 197 66%
onrender.com 164 86 52%
fly.dev 68 29 43%
workers.dev 327 79 24%
vercel.app 198 16 8%

An MCP server on Vercel is roughly eleven times more likely to still answer than one behind a Cloudflare quick tunnel, and about ten times more likely than one on Smithery.

That is not a statement about engineering quality. It is a statement about what each of those things is.

The pattern is ephemerality, not quality

trycloudflare.com URLs come from quick tunnels — they are designed to be temporary and the hostname changes every time you restart. ngrok free tunnels are the same idea. Railway and Render free tiers sleep and can be reclaimed. A URL from any of these is a development convenience that someone pasted into a permanent public directory.

Vercel and workers.dev behave differently: the URL is stable, the free tier does not expire the hostname, and a deployment that stops receiving traffic still resolves.

So the registry is not full of abandoned projects so much as projects whose front door was never permanent to begin with. The code may be fine. The listing points at a door that has moved.

It concentrates hard

1,490 endpoints in the registry are dead in the strongest sense — hard 404 at the advertised path, or DNS that no longer resolves. Those spread across only 343 domains, and the top ten domains account for 67% of them:

191  smithery.ai
173  railway.app
125  wishpool.app
109  mctx.ai
100  klymax402.com
 84  trycloudflare.com
 63  onrender.com
 63  apify.com
 62  workers.dev
 34  alpic.live
Enter fullscreen mode Exit fullscreen mode

Several of those are platforms that generate MCP endpoints in bulk. When one of them changes a URL scheme or expires a tier, hundreds of registry entries break at once. This is the failure mode of a directory that stores URLs rather than resolving them.

177 listings never had a real URL at all

While bucketing failures I found entries whose URLs still contain unsubstituted template variables:

https://{api_host}/mcp
https://{HAPI_FQDN}:{HAPI_PORT}/mcp
https://{ATLAS_MCP_URL}
https://{roster_host}/mcp
Enter fullscreen mode Exit fullscreen mode

177 listings contain a placeholder, a localhost, or an example.com. 73 of them fail DNS for the obvious reason.

The interesting subset is the other half: 14 of these are up. URLs like https://mcp.cardog.io/mcp?api_key={api_key} work because the placeholder is in a query parameter the server ignores when absent. The author meant it as documentation — "put your key here" — and the registry stored it as a literal endpoint. Both readings are reasonable. Only one of them is a URL.

What I would do with this

If you are publishing an MCP server: the hosting choice is a durability decision about your listing, not just about your app. A quick tunnel in a permanent directory has an expected life measured in hours. Use something with a stable hostname before you publish the URL somewhere you cannot easily update.

If you are consuming the registry: do not treat a listing as an endpoint. About a quarter of them will not serve you, the failures cluster by platform, and roughly one in sixty contains a placeholder someone forgot to fill in. Resolve before you depend.

If you maintain a directory of URLs: this is the argument for periodic revalidation. A registry that never re-checks its entries converges on being a list of things that used to exist.

Method

Every active remote entry in registry.modelcontextprotocol.io, deduplicated by URL — 10,716 endpoints. One anonymous JSON-RPC initialize each, 10s timeout, classified by actual response. Transport-aware: the registry declares 9,647 streamable-http and 1,068 legacy sse remotes, and the legacy transport opens with a GET rather than a POST, so probing everything with one verb inflates the 405/404 count. I checked that specifically — it changed almost nothing, but I checked before publishing rather than after.

Anonymous probing is a lower bound. A server that requires a key is counted as alive-but-gated, not dead, and I cannot see whether it is healthy behind the key.

Counts are one moment in time. Re-running is the point; single snapshots of a moving system are anecdotes with decimal places.


Previously: I checked every MCP server in the official registry — the census this analysis is built on, including the correction where my first attempt covered 3% of the registry and I published it as 'every'.

Top comments (1)

Collapse
 
valentin_monteiro profile image
Valentin Monteiro

The trycloudflare and ngrok rows are the interesting ones because those hostnames are self-identifying: you can tell the URL is ephemeral by construction at submission time, no probe required. That makes the cheapest fix a write-time check on known-ephemeral hostname patterns rather than periodic revalidation after the fact, since revalidation still leaves a window where the directory is confidently wrong. Does the registry accept a *.trycloudflare.com endpoint silently today, or is there already a warning people are clicking past?