Independent by design · no pay-to-rank placements  · How we evaluate tools →
Anclum Submit

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.

Update, 2026-11-12. This post counted what our pipeline could see. Hours after it went up we found the pipeline read only one of the two forms that MCP READMEs use, so the number below is the floor it found, not the number of commands that exist. After fixing the parser the floor became 1,909. The rest of this page is left exactly as published; the follow-up covers what we got wrong and how we found it.


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 have no command we could extract. 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 <package>                       19
uvx <package>                          16
pnpm dlx <package>                      1   → 36 fetch and run a package  (58.1%)

claude mcp add <name> -- ...            2   → 2 register the server      (3.2%)

pip install <pkg>                      13
npm install <pkg>                       4
cargo install <crate>                   3
brew install <formula>                  2   → 24 need two steps or more  (38.7%)
go install / python3 <script>           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/<package>. 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:

packageconsole scripts exposed
mcptoonmcptoon
touchpoint-pytouchpoint-mcp
permisapi-mcppermisapi-mcp, permisapi-mcp-sse
mcp-repo-graphmcp-repo-graph, repo-graph, repo-graph-init
mainbook-mcpmainbook-mcp
project-tesseratessera, tessera-api, tessera-mcp
agent-aegisaegis, aegis-mcp-server, aegis-mcp-proxy
graphifyygraphify, graphify-mcp
scraplingscrapling, 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:

  1. 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.
  2. 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.
  3. 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.

And then we checked our own extractor

Everything above counts what our pipeline could find. After publishing, we asked what it could not find — and the answer made the 62 look different.

Our extractor matches npx <package> written as a shell line. It does not parse the form that every MCP client actually uses:

{"mcpServers": {"name": {"command": "npx", "args": ["-y", "package"]}}}

There npx is followed by "args", not by a package name, so the pattern never fires.

In 3,911 of the 6,480 "no command" entries, the README we stored contains npx or mcpServers. We opened three at random. Two had real install commands we had missed — one written out as npx bothire-mcp, one only as a JSON block. The third was a hosted endpoint with nothing to install, so that one was correctly empty.

So 62 is a floor, not a count. The number that matters is not how few commands exist in the ecosystem — it is how few our extractor can see, and we did not know that number until we went looking for our own blind spot.


Numbers and where they came from

#NumberCommand / fileOutput
06,542SELECT count(*) FROM items WHERE kind='mcp' AND COALESCE(hidden,0)=0;6542 (all kind='mcp': 6,939, of which 397 hidden)
162SELECT count(*) FROM items WHERE kind='mcp' AND COALESCE(hidden,0)=0 AND COALESCE(TRIM(install_cmd),'')<>'';62
230 / 84 / 141 / 195 / 63 / 16six candidate definitions of "commands before the 2026-11-11 cleanup"six different counts; none equals the 68 written earlier, so no rate is quoted
30.9477SELECT 62.0*100.0/6542; on the same connection0.9477
419 / 16 / 1 / 2on the 62: LIKE 'npx %' / LIKE 'uvx %' AND install_conf='high' / LIKE 'pnpm dlx %' / LIKE 'claude mcp add%'19 / 16 / 1 / 2
536one query, the union of the three fetch-and-run conditions36 (58.1%)
638derived: 36 fetch-and-run + 2 registration38 (61.3%)
73×0the three pairwise intersections, as separate queries0 / 0 / 0, so 36 + 2 + 24 = 62
824the rest of the 62: pip 13 + npm 4 + cargo 3 + brew 2 + go 1 + python3 124 (38.7%)
99changed rows: 6 blanked, 3 punctuation-onlyinstall_cmd_backup_20261111, 9 rows, why filled; 2 local paths + 4 unrelated packages
109 / 9PyPI wheels with [console_scripts] among the nine two-step Python entriesentry_points.txt read from each wheel
111npm package with no bin@mobile-reality/mdma-parser → bin=NONE
1210unknown classification after metadata checkinstall-classify-20261111.json → Counter({'unknown': 10, ...})
130uv installed on the measurement hostcommand -v uv → empty
140commands executed against any of the 62 entriesnone; classification is install_cmd shape plus install_conf, no boot test
153,911no-command entries whose stored README contains npx or mcpServers... and (readme_body like '%npx %' or readme_body like '%mcpServers%')
163,165no-command entries whose readme_body is exactly 6,000 charactersgroup by length(readme_body) -> 6000: 3165
172 / 3spot check of three of those entriesbothire-mcp (shell form) and neon-mcp-gateway (JSON form) were real; moltline-mcp is a hosted endpoint with nothing to install

Also in the lab: We ran 20 MCP install commands verbatim. Ten started.