About
About this project
mcp-pin is an independent open-source project built and run by Gautam Khosla, a student. It is not affiliated with, endorsed by, or connected to Anthropic, the Model Context Protocol project, npm, GitHub, or any of the servers listed in the log.
What this site publishes
A record of the tool metadata that public MCP servers return when asked. Names, descriptions, input schemas, and annotations, along with a cryptographic hash of each and the date it was observed. All of it is information those servers publish openly to any client that connects.
Nothing here is a security assessment. A badge reading unchanged 91d means the fingerprint has not moved in 91 days. It does not mean a server is safe, well written, or trustworthy, and it should never be read that way.
Pagination recrawl, 4 September 2026
Versions of the crawler at 0.1.0 and earlier issued one tools/list and
ignored nextCursor. That is a real bug. A truncated server would have shown a stable
badge against an incomplete toolset. On 4 September 2026 every server already in the log
was re-probed with a crawler that follows pagination.
18 of 248 recorded servers had a higher tool count. 0 of those 18 currently
return nextCursor: the extra tools were already on page 1. The count changes are
not pagination recovery: none of the 18 returns nextCursor. A controlled re-probe on
4 September reproduced all 18 counts exactly, so they are stable rather than probe noise.
For 17 of them the increase is ordinary package drift between crawls. One,
@novalux12/spotify-mcp, is still unexplained; see below. Five servers failed the
re-probe and are unknown. Historical responses did not store nextCursor or probe env.
The machine-readable
record is pagination-recrawl.json) and controlled-recrawl-2026-09-04.json.
A signed log that quietly corrected itself would be worse than one that did not need correcting. Publishing this is the correction.
Incomplete crawl, 4 September 2026 10:53 UTC
The signed head at 52d6ac1 (tree_size 281, signed 10:53 UTC) was produced
by a failed scheduled crawl. The Crawl step failed; Sign, Verify, and Commit still ran
because those steps used if: always() in a single job that also executed untrusted
packages. Eighteen entries were appended. last-crawl.json was not updated. The chain
verifies; the coverage does not. The log was not rewritten. Machine-readable note:
incomplete-crawl-2026-09-04.json.
Tool listings recorded without their environment
Some MCP servers choose which tools to register based on environment variables.
@novalux12/spotify-mcp reads SPOTIFY_MCP_TOOLSETS: unset or all registers 551 tools,
playback,library registers 207, and an unrecognised value registers 4. The crawler did not
record the environment a probe ran with, so a tool count in this log cannot be read as the
server’s full surface, only as what the server exposed to one probe.
A second defect compounds it. When a server reports that it needs environment
variables, the probe retried with the literal string mcp-pin-probe-placeholder for each one.
The detector did not distinguish credentials from feature flags, so a placeholder could be
written into a variable that selects which tools register.
One case is unresolved. Entry 60 (3 September 2026) records 50 tools for
@novalux12/spotify-mcp. No published version of that package exposes 50 tools under any
toolset value reproduced on 4 September: published versions expose 96, 99, 100, 101, 154,
313, 550 or 551, and the placeholder value exposes 4. All 50 logged names are a subset of the
551. The mechanism that produced 50 is unknown, and it is recorded here as unknown rather
than explained away. Machine-readable note:
env-conditioned-listings-2026-09-04.json.
Crawl paused, 4 September to 5 October 2026
The daily crawl was switched off on 4 September 2026 because of the two problems above: listings did not record the environment they were taken under, and placeholders could reach variables that decide which tools register. It was switched back on on 5 October 2026, once placeholders could only reach credential-shaped variables. The crawler also passed each listing's probe environment to the log by then, but the log dropped that field until 0.2.0, so the entries of 5 October do not have it. The changelog records the correction.
Nothing was observed in between. A change first seen when the crawl resumed could have happened on any day of that gap, so it reads changed since 4 Sep, not changed today. Badges also stop counting when the crawler stops looking: a server that has not been checked for more than three days reads last checked and a date, never a number that kept growing while nobody looked.
What this does not protect against
mcp-pin detects when a server's tool definitions change between sessions,
including changes the server did not announce. It does not protect you from a malicious
program running as the same user: that program can delete ~/.mcp-pin and
re-pin itself. That is an architectural limit, not a bug. Day-one malice that never
changes is also invisible. Do not read a pin, or a badge, as a safety rating.
How the crawler behaves
These are commitments, not aspirations. If the crawler ever violates one, that is a bug and I want to hear about it.
- It identifies itself as
mcp-pin-crawlerwith a link to the source repository. - It calls
initializeandtools/list. It never invokes a tool, never sends arguments, and never causes a side effect on anyone's system. - It runs at most once per server per day. This is a daily record, not real-time monitoring: a change can sit unrecorded for up to 24 hours.
- It never supplies a real credential and never attempts to bypass authentication.
When a server exits because an environment variable is unset, the crawler reads the variable
name the server itself printed and retries once with the obvious placeholder
mcp-pin-probe-placeholder. Any server that validates that value rejects it. If a server still refuses, it is recorded as unindexable and left alone. - A server that errors is not retried until the next day.
- Probing runs on disposable cloud infrastructure, never on a personal machine, and holds no credentials.
Opting out
If you maintain a server here and do not want it crawled, say so and it stops.
Add it to OPTOUT.txt, open an issue titled
opt out: your-server-name, or email me. No justification is requested and
none is required. You will not be asked to explain yourself and I will not try to
talk you out of it.
It takes effect on the next crawl and the pages come down. One thing stated honestly rather than glossed over: the log is append-only by design, so entries already written stay in the file. If you need existing entries removed as well, ask, and I will publish a signed note explaining what was removed and why, because silently editing a transparency log would defeat its entire purpose.
Corrections
If anything here is wrong about your server, tell me and I will fix it and say what changed. Accuracy matters more to this project than completeness.
No warranty
This is provided as is, without warranty of any kind, under the MIT licence. It is a hobby research project run by one person alongside university study. Do not treat it as a commercial service, and do not build a compliance process on it. The log and the badges are meant to keep running; if that ever changes, this page will say so before anything is switched off. The threat model is explicit about what the tool does not defend against.
Contact
Security issues: see SECURITY.md and use GitHub's private reporting rather than a public issue. Everything else: open an issue. For anything you would rather not discuss in public, my contact details are on my GitHub profile.