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

Seven stdio MCP servers, run verbatim: three answered initialize

A field test by the Anclum team, November 12, 2026.


An install line on an MCP directory is a promise: paste this, and a server starts. We wanted to know how often that promise holds for the servers that speak stdio, so we took the command exactly as extracted from each README and ran it — no corrections, no added flags, no "you obviously meant".

This page covers seven servers. A single JSON-RPC initialize request was sent to each, and we recorded what came back within 45 seconds. That is the entire test: if the process can complete a handshake, it started; if it cannot, the reason it cannot is the interesting part.

Three of the seven completed the handshake. The other four failed for three different reasons, and none of them failed because the package was broken.

What we counted

VerdictCountWhat it means
STARTED3A JSON-RPC reply with id=1 and serverInfo.name / serverInfo.version
NEEDS_ARGS1Exited with a usage line or a list of required arguments
NEEDS_DATA1Exited non-zero; stderr points at a missing external data file
NEEDS_AUTH2Exited, or is waiting, for a credential we did not supply
CRASHED0Exited non-zero with an error in its own code or dependencies

Handshake rate for this group: 3 of 7 = 42.9%.

That percentage describes these seven stdio servers and nothing else. The wider catalog list mixes transports: 17 entries document an HTTP transport, 2 are registration commands rather than launch commands, and 12 carry no transport signal at all. HTTP and registration entries are not applicable to a stdio probe, no-transport entries are not assumed to be stdio, and none of them sit in the denominator above.

The seven

ServerCommand, run verbatimVerdictFirst decisive lineTime (+08:00)
atomno-mcp-mcp-egruluvx atomno-mcp-egrulSTARTEDserverInfo {"name":"mcp-egrul","version":"3.4.11"}02:34:21
archerkattri-mathlasuvx mathlas-mcpSTARTEDserverInfo {"name":"mathlas","version":"1.5.0"}, protocol 2025-06-1802:36:41
ihuzaifashoukat-x-useuvx x-use-mcp==3.2.0STARTEDserverInfo {"name":"x-use","version":"3.2.0"}02:37:29
getpoststack-mcpnpx @poststack.dev/mcpNEEDS_AUTHPOSTSTACK_API_KEY environment variable is required02:23:41
gitmotion-ntfy-me-mcpnpx ntfy-me-mcpNEEDS_AUTH[NTFYME-LOG-ERROR]: NTFY_TOPIC environment variable is required.02:24:28
jeanfrancoisgagne-crapkituvx crapkitNEEDS_ARGScrapkit: error: the following arguments are required: command02:35:54
lizhuojunx86-chinese-history-mcpuvx chinese-history-mcpNEEDS_DATAFileNotFoundError: 找不到语料库: /root/data/corpus.db02:35:07

Two notes on that table, because both are easy to misread:

  • The crapkit command in the catalog is incomplete. Its own usage line lists mcp as a subcommand, so the working shape is uvx crapkit mcp. Run verbatim, it exits 2 and asks for the subcommand.
  • The chinese-history-mcp stderr starts with Traceback (most recent call last):. The decisive line is the FileNotFoundError above: the code and its dependencies loaded fine, and what is missing is a corpus file at /root/data/corpus.db (the package documents STORYEXTRACTOR_DB for pointing elsewhere).

How we judged

Each verdict needs the stderr (or stdout, for a handshake) first line quoted — a label alone is not evidence. Three boundary rules decided the close calls:

  1. An exception class is not the criterion; the object it points at is. FileNotFoundError raised from a package's own entry point is still NEEDS_DATA when the missing object is an external data file. ImportError naming a package module is CRASHED.
  2. When two labels both explain the exit, follow what the reader has to do next. Go fetch data → NEEDS_DATA. Go change the command → NEEDS_ARGS.
  3. STARTED requires a parsed JSON-RPC result, not merely output that looks like JSON: id=1 plus serverInfo.name and serverInfo.version. Staying alive without a handshake is not a start.

One gap we are keeping visible: the two NEEDS_AUTH rows never exited with a recorded rc — the process was still waiting when the probe stopped, so rc is null for both. Their verdict rests on the stderr line above plus the absence of a handshake. A rerun should record rc for those two.

What we did not do

Each command was executed once, verbatim, and nothing else was tried for it: no retry with added arguments, no credential injection, no second attempt after a failure. The working shape we note for crapkit is a reading of its own usage text, not a run we counted. The 45-second limit is a probe deadline, not a verdict — a stdio server that stays alive is expected to be killed by it.

This page adds no executions beyond those seven. The HTTP, registration and no-transport entries in the catalog are outside this count; they are neither passes nor failures here, and no combined rate is implied.


Probe environment: Linux host, Node and Python available through npx / uvx; uv 0.13.7; a throwaway cache under /tmp with UV_PYTHON_DOWNLOADS=never. Servers that need credentials were not given any.

Also in the lab: We told Google not to index 10,538 of our 24,667 pages. Two batches of those were our mistake.