modelmarket.dev · blog

We installed 12,915 MCP servers and started each one. 41% never answered.

2026-10-14 · 8 min read #mcp#ai#security#opensource

7,656 of 12,915 MCP servers answered tools/list; 1,239 only with a placeholder key or start argument they asked for; 5,259 never answered.

MCP registries list tens of thousands of servers. Most of what is written about their safety comes from reading them: the tool descriptions, the README, the code. We wanted the other half. What happens when you actually install one and start it, the way a client does? Does it answer? What does it ask for? What does it touch while it starts?

So HISTOR, our public log of MCP servers, now installs the npm and PyPI servers it finds, starts each one in a sandbox and writes down what happened. The registries it follows list 47,586 npm and PyPI packages; it runs up to 8,000 per crawl. This post is the state on 13 October 2026, after 12,915 of them.

How we ran them

59% answered

7,656 of 12,915 answered initialize and tools/list: 64% on npm, 52% on PyPI. Between them they listed 182,157 tool definitions, a median of 10 per server (one listed 3,631).

1,239 of those started only with something they asked for: 1,039 with a placeholder key, 177 with a start argument, 23 with both. A client config would have given them that, so we count them as working. But look at the 1,039 again. A key that works nowhere was enough for every one of them to tell us its tools. None needed a real key to do that; they just refused to start without one.

Why 5,259 never answered

Why 5,259 never answered, by what each package printed as it exited: usage text 924, crash 874, key or setting 793, not a stdio server 666, will not install 636, hangs or wrong protocol 490, MCP SDK 1.x on 2.x 292, needs something the machine lacks 236, cannot run as published 184, serves HTTP by default 164.

We read what each package printed as it exited, last run first.

MCP SDK 2.0 broke 292 PyPI servers

MCP SDK 2.0: 207 of 269 PyPI servers start again with mcp<2. Placeholders: 1,039 started with a key, 177 with an argument, 23 with both.

mcp 2.0.0 (28 July 2026) renamed FastMCP and changed the low-level server's decorators. A PyPI server that depends on mcp with no upper bound installs 2.x today and dies on import: cannot import name 'FastMCP', or 'Server' object has no attribute 'list_tools'. We started 269 of them again with pip held to mcp<2, and 207 (77%) answered. Anyone who installs them today gets the crash, not the server.

What they did in the sandbox

What they did: 2,239 ran npm install scripts; 1,484 reached for the network at startup; 580 while installing; 295 opened a decoy credential file; 73 runs sent the placeholder key over the network.

11,891 runs carry a gVisor trace.

Testing the tester

Six of our own mistakes: 880 "silent" servers had printed help on stdout; about 400 "install failed" needed Python 3.13 or 3.14; 1,917 Python servers flagged for asyncio's own socketpair; 126 "persistence" writes were relative paths; one red-team case missed under load; one real package credited with our own fixture's request.

A sandbox that reports wrong things is worse than none, so here is what we got wrong on the way.

If you publish an MCP server

Check what you run

Every package's record is public on histor.modelmarket.dev: its tools, what it asked for, what it touched, which image it ran in. WARDEN reads the same log. npx -y @aimarket/warden@0.15.0 scan --histor asks HISTOR, for every server in your Claude, Cursor or VS Code config, whether you get the tool set HISTOR recorded, and shows what its package did in the sandbox. For a package, that is the set its sandbox got. A launcher whose program is installed on your machine lists another one; its publisher can now declare that set in the server's registry entry, and HISTOR shows it as the publisher's word.

Try it on a server of yours, in the browser: look up its history in HISTOR, scan its tools/list with WARDEN, or count what its tool list costs per model request. Free, no account. That last one answers a question in the comments below; the numbers for all 34,374 lists are in What an MCP server's tool list costs.

We build HISTOR and WARDEN. The numbers are a snapshot of 13 October 2026; the crawl continues, so the site will have moved on. No package is named here. The method and the observer's code are in alexar76/histor (docs/architecture.md, sandbox/histor_observe.py).

Edited 14 October 2026: the WARDEN sentence above said it checks "whether you get the tool set everyone else gets". For a launcher package that is not one set, as a reader pointed out in the comments; it now says what HISTOR compares with.

Questions or corrections? The discussion is on dev.to.