6,542 MCP servers, 62 install commands, 38 one-liners
Numbers from one directory's catalogue, anclum.com, measured 2026-11-11. Commands and queries are at the end. A directory's most trust-building artefact is not the description. It is the install line. Everything else is opinion; the command either runs or it does not. We list MCP servers, agent skills and AI tools. For a while we rendered an "install" button on any entry with a command we could extract from its README. We never counted how many of those commands work as printed, and we never counted the other side either: how many entries have no command at all. This week we counted both. Of 6,542 MCP servers in the catalogue, 62 carry an install command. That is 0.9477%; the other 6,480 carry no command at all. Of those 62, 38 fit on one command line — 36 fetch and run a package, 2 only register the server. The other 24 need a second step, and six of the commands we had were simply wrong. The distribution, by command shape npx -y 19 uvx 16 pnpm dlx 1 → 36 fetch and run a package (58.1%) claude mcp add -- ... 2 → 2 register the server (3.2%) pip install 13 npm install 4 cargo install 3 brew install 2 → 24 need two steps or more (38.7%) go install / python3 2 The three buckets are disjoint: we ran the three pairwise intersection queries and all three return 0. So 36 + 2 + 24 = 62, nothing counted twice. That split is the whole point. 58.1% fetch and run a package in one line. Another 3.2% are one line too, but they only register the server — claude mcp add writes a config entry, it does not start anything. And 38.7% need a second step or more, because the command we extracted answers how do I install this when the client needs how do I start this. This is a classification of command shape, not a record of executions — see the limit at the end. A README install section usually answers how do I get this package. An MCP client needs what do I run to start a server. For an npm package with a bin entry, those collapse into one npx line. For a Python package, they do not: pip install mcptoon installs a package, and then something like mcptoon has to be started — a second line, usually not stated. We did not guess the second line. We read it off the package. For the entries that need a second step, we asked the registries directly: npm: the bin field in registry.npmjs.org/. No bin means the package is a library, not a program. PyPI: download the wheel, read .dist-info/entry_points.txt, and look at [console_scripts]. That file is what pip install actually puts on your PATH. Results for the nine Python entries we checked this way: package console scripts exposed mcptoon mcptoon touchpoint-py touchpoint-mcp permisapi-mcp permisapi-mcp, permisapi-mcp-sse mcp-repo-graph mcp-repo-graph, repo-graph, repo-graph-init mainbook-mcp mainbook-mcp project-tessera tessera, tessera-api, tessera-mcp agent-aegis aegis, aegis-mcp-server, aegis-mcp-proxy graphifyy graphify, graphify-mcp scrapling scrapling, scrapling-mcp Nine of nine ship a server entry point. So the command exists — it just cannot be one line, because the package has to be installed first. One npm package we checked (@mobile-reality/mdma-parser) has no bin at all: it is a library that something else imports. Six of them were wrong, and one number we could not settle Before the split above we went through every command we had. Nine rows changed: six were blanked because they would not have started the thing the entry described, and three only needed a period removed from the end of a sentence. The six: Four were unrelated packages. One README's install block, extracted by our pipeline, produced pip install pre-commit for a project that has nothing to do with pre-commit. Another produced npx @modelcontextprotocol/inspector — that installs the inspector, not the server. Two more produced npx skills, a package that shares a word with the entry and nothing else. Two were absolute paths from someone else's machine — one /Users/.../.hai-browser/mcp/index.mjs from a Mac, one C:/Users/.../npm/node_modules/agentic-recall/index.js from Windows. They can never work for a reader. And three were one punctuation character away from working — uvx crapkit. with the period the sentence ended with. We blanked the six — a backup row each, with the reason — and stripped the trailing period from the other three; those keep a backup row too. Nine rows, nine reasons. A command that does not run is worse than an empty cell, because the empty cell is honest about what the source did not give us. The number we did not print We were going to write "nine out of sixty-eight" — one query told us the pool was 68. Then we tried to reproduce that 68, and could not. Six definitions that all look like they should count the same thing give 30, 84, 141, 195, 63 and 16. None of them is 68. So the percentage would be arithmetic on a number we can no longer derive, which makes it an opinion wearing a number's clothes. We dropped it. What survives is the part measured row by row: six commands that would not have started the server the entry described, three that would have died on a stray period, nine backup rows with a reason on each. If you cannot reproduce your denominator, do not quote your rate — quote the rows. What this means if you run a directory Three things, in order of cost: Separate "install" from "run". They are different sentences, and one field cannot hold both honestly. If you only have one field, you have to choose which lie you are telling. Verify the entry point, not the README. entry_points.txt and npm's bin cost one HTTP request each and cannot be wrong about what pip or npx will put on disk. A README can be stale for years without anyone noticing. Count your broken commands by the row, not by the rate. We can name six that would not have started the server and three that needed a period removed; we cannot name the pool they came from, so we quote no percentage. And that is only what a name-match and a human eye found. We still have 10 commands we classify as unknown: three crates with no binary metadata, two Homebrew formulae with no exported command, four packages whose scripts are not server-named, and one whose npm registry entry no longer resolves. The limit on this study We did not execute a single one of these 62 commands. Every claim above about one line versus two is a claim about the shape of the command, checked against what the package ships: npm's bin field, PyPI's entry_points.txt. That is a real check — it tells you whether a server entry point exists — and it is not a boot test. The sharpest illustration is the sixteen uvx entries: the host we measured on has no uv installed, so even a manual attempt was out of reach on that machine. But the honest sentence applies to all 62, not just those sixteen: metadata tells you the file exists, not that the process comes up. So the correct sentence for the whole set is "the package exposes a server entry point", not "it starts". You will see that distinction in our entries once the labels land. If you want to trust an install line, the cheapest thing you can do is run it once, on a clean machine, and paste the output. Everything above is the next best thing. Numbers and where they came from # Number Command / file Output 0 6,542 SELECT count(*) FROM items WHERE kind='mcp' AND COALESCE(hidden,0)=0; 6542 (all kind='mcp': 6,939, of which 397 hidden) 1 62 SELECT count(*) FROM items WHERE kind='mcp' AND COALESCE(hidden,0)=0 AND COALESCE(TRIM(install_cmd),'')''; 62 2 30 / 84 / 141 / 195 / 63 / 16 six candidate definitions of "commands before the 2026-11-11 cleanup" six different counts; none equals the 68 written earlier, so no rate is quoted 3 0.9477 SELECT 62.0*100.0/6542; on the same connection 0.9477 4 19 / 16 / 1 / 2 on the 62: LIKE 'npx %' / LIKE 'uvx %' AND install_conf='high' / LIKE 'pnpm dlx %' / LIKE 'claude mcp add%' 19 / 16 / 1 / 2 5 36 one query, the union of the three fetch-and-run conditions 36 (58.1%) 6 38 derived: 36 fetch-and-run + 2 registration 38 (61.3%) 7 3×0 the three pairwise intersections, as separate queries 0 / 0 / 0, so 36 + 2 + 24 = 62 8 24 the rest of the 62: pip 13 + npm 4 + cargo 3 + brew 2 + go 1 + python3 1 24 (38.7%) 9 9 changed rows: 6 blanked, 3 punctuation-only install_cmd_backup_20261111, 9 rows, why filled; 2 local paths + 4 unrelated packages 10 9 / 9 PyPI wheels with [console_scripts] among the nine two-step Python entries entry_points.txt read from each wheel 11 1 npm package with no bin @mobile-reality/mdma-parser → bin=NONE 12 10 unknown classification after metadata check install-classify-20261111.json → Counter({'unknown': 10, ...}) 13 0 uv installed on the measurement host command -v uv → empty 14 0 commands executed against any of the 62 entries none; classification is install_cmd shape plus install_conf, no boot test
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to