ScriptDocs MCP Server
A Model Context Protocol (MCP) server that gives AI coding agents real,
live, source-cited documentation for npm and PyPI packages β pulled
directly from registry.npmjs.org and pypi.org at call time.
Built by ScriptMaster Labs.
What this actually does (and doesn't)
Every tool call makes a real HTTP request to the actual registry. There is
no cached demo data, no fabricated example output, and no guessing. If a
package or its docs can't be found, the tool returns an explicit error β
never a plausible-looking made-up answer. Every successful response
includes source_url and fetched_at so the caller can verify exactly
where the data came from and how fresh it is.
Not yet built (honest status, not hype):
- Payment/licensing (Stripe, API keys, usage tiers) β this is scaffolding
work that needs your real Stripe account and pricing decisions. Nothing
in this repo simulates a working payment system.
- GitHub-source doc fetching beyond README/long-description (e.g. specific
guide pages, versioned doc sites) β README/long-description only in v0.1.
| Tool | What it does |
|---|
docs_get_package_info | Live metadata: latest version, description, homepage, repo β npm, PyPI, or Cargo (crates.io), right now. |
docs_get_readme | The verbatim README (npm), long description (PyPI), or README-derived text (Cargo β see note below) for a package/version. |
docs_search_docs | Keyword search inside a package's real docs (any of the 3 ecosystems, optionally a specific version), returns verbatim matching snippets with context β not a summary. |
docs_check_vulnerabilities | Checks a specific package+version against OSV.dev. When a fix exists, automatically fetches that fixed version's README in the same call β "here's what's wrong" and "here's what upgrading looks like," one round trip. |
docs_resolve_library | Fuzzy name β real candidates, via npm's and crates.io's actual search APIs. PyPI has no official search API (confirmed: XML-RPC search was killed in 2022, never replaced) β calling this for PyPI returns an honest explanation, not a scraped or fabricated result. |
Note on Cargo READMEs: crates.io stores READMEs pre-rendered as HTML, not the original markdown source β there's no raw-source endpoint. docs_get_readme/docs_search_docs return that HTML converted to plain text (tags stripped, entities decoded) β a mechanical transformation, not a summary; no content is invented or dropped.
Project layout
scriptdocs-mcp-server/
βββ package.json
βββ tsconfig.json
βββ Dockerfile
βββ src/
β βββ index.ts # server entry point, transport selection
β βββ constants.ts
β βββ types.ts
β βββ services/
β β βββ npm.ts # real npm registry client
β β βββ npmSearch.ts # real npm search API (fuzzy resolution)
β β βββ pypi.ts # real PyPI registry client (supports version pinning)
β β βββ cargo.ts # real crates.io client (metadata, readme, search)
β β βββ osv.ts # real OSV.dev vulnerability database client
β β βββ versionCompare.ts # best-effort numeric version comparator
β β βββ access.ts # founder always-free guarantee
β β βββ docSearch.ts # keyword/snippet extraction over fetched text
β βββ tools/
β βββ getPackageInfo.ts
β βββ getReadme.ts
β βββ searchDocs.ts
β βββ checkVulnerabilities.ts
β βββ resolveLibrary.ts
βββ dist/ # build output (git-ignored)
Run it locally (stdio β for Claude Desktop / Cursor)
npm install
npm run build
node dist/index.js
To wire it into Claude Desktop or Cursor, point their MCP config at:
{
"mcpServers": {
"scriptdocs": {
"command": "node",
"args": ["/absolute/path/to/scriptdocs-mcp-server/dist/index.js"]
}
}
}
Run it as a remote server (HTTP β for Render, same pattern as your other services)
npm install
npm run build
TRANSPORT=http PORT=3000 node dist/index.js
- Health check:
GET /health
- MCP endpoint:
POST /mcp
Deploy to Render
The included Dockerfile builds and runs the HTTP transport. Point a
Render Web Service at this repo with:
- Environment: Docker
- Health check path:
/health
This mirrors how mcp-x402 and squeezeos-api are already deployed.
Verified working (tested against live registries and APIs)
-
v0.3.1 fixed a real published-package bug: dist/index.js had no
#!/usr/bin/env node shebang and wasn't marked executable, so running
it as a bin (exactly what npx/Claude Code do) failed β on Linux with
a shell syntax error, and this was very likely the cause of the
"Failed to connect" a real Windows user hit via Claude Code. Root
cause confirmed by directly executing the packed tarball's bin file
before and after the fix, not assumed. postbuild now runs
chmod +x dist/index.js so this can't silently regress.
-
docs_get_package_info β express (npm), serde (cargo) returned real
current metadata straight from their respective registries.
-
docs_get_readme β zod (npm, jsDelivr fallback), requests (PyPI,
latest + version-pinned), and serde (cargo) all returned real README
content. The cargo path hit a real bug during testing β crates.io's
README endpoint varies its response by Accept header and was
returning a JSON pointer instead of HTML β caught and fixed, verified
again after the fix.
-
docs_search_docs β keyword search over real docs verified across
npm and cargo.
-
docs_check_vulnerabilities β express@4.17.1 correctly returned 2
real advisories (incl. CVE-2024-43796) and automatically fetched the
real README for 4.20.0 (the fixed version) in the same call β the
vuln-to-fix bridge, verified working end-to-end.
-
docs_resolve_library β real fuzzy search verified for npm ("react"
β react, react-is, ...) and cargo ("http client" β real candidates).
PyPI correctly returns an honest limitation message instead of a
fabricated result (verified: PyPI has had no official search API
since 2022).
-
Nonexistent package name β correctly returns an explicit
isError: true response instead of fabricating a plausible answer.
-
Both stdio and TRANSPORT=http modes verified against the actual
MCP JSON-RPC protocol (initialize, tools/list, tools/call).
Founder always-free guarantee
ScriptMaster Labs (you) always gets full, unmetered, free access to every
tool this server exposes β no matter what paid tiers get built later.
This is baked into the architecture now, before any billing exists, not
retrofitted after the fact:
src/services/access.ts exports isOwnerRequest(), checked against a
secret in the SCRIPTDOCS_OWNER_KEY environment variable (never
hardcoded β this repo is public, so a hardcoded bypass would give
everyone free access, not just you).
- The HTTP transport already tags every request with an
x-scriptdocs-access-tier response header (owner-unlimited or
standard) β verified working, not just written.
- Rule for any future billing/rate-limit code: call
isOwnerRequest() first and skip all limits/charges when it returns
true.
To use it once deployed: set SCRIPTDOCS_OWNER_KEY as an environment
variable on your Render service, then send requests with header
x-scriptdocs-owner-key: <that value>. Keep the value secret β it's
not in this repo, and shouldn't be.
Getting listed as a real alternative (not hype β the actual mechanics)
There's no "beat Context7's ranking" button. There's one source-of-truth
feed and a handful of directories that read from it. This is the real,
current (as of July 2026) process, verified against the official docs at
modelcontextprotocol.io/registry:
- The official MCP Registry (
registry.modelcontextprotocol.io) is
what a growing number of AI clients read to discover servers. There's
no review queue β you publish a server.json record under a namespace
you prove you own, and it's live.
- Discovery directories β Smithery, Glama, PulseMCP, mcp.so β crawl
GitHub and the registry on their own. You may already show up there
unclaimed once this is public; claiming ownership is what lets you
control the description instead of a bot's guess.
What's already prepped in this repo
package.json has "mcpName": "io.github.Timwal78/scriptdocs-mcp-server"
and is renamed to the scoped package @scriptmasterlabs/scriptdocs-mcp-server
(under the existing @scriptmasterlabs org scope β same one publishing
mcp-x402 and mcp-x402-sdk β rather than a personal scope, since this
sits alongside your other MCP infrastructure)
server.json is written and validated against the real, live official
schema (static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json)
β not guessed at.
.github/workflows/publish-mcp.yml auto-publishes to npm and the MCP
Registry every time you push a v* tag, using the official OIDC flow
(no registry secret needed β just an NPM_TOKEN).
- License changed from
UNLICENSED to MIT β a package meant for
strangers to install needs a license that actually lets them use it.
What only you can do (needs your accounts/credentials β I don't have them)
- Push this to a public GitHub repo at
github.com/Timwal78/scriptdocs-mcp-server
(or wherever you want it β update repository in package.json and
server.json to match if the path differs).
- Add an
NPM_TOKEN secret to that repo (Settings β Secrets β Actions)
from an npm access token tied to your npm account.
- Tag and push a release:
git tag v0.2.0 && git push origin v0.2.0 β
the workflow handles npm publish + MCP Registry publish automatically
from there.
- Claim your listing on Smithery,
Glama, and PulseMCP once
the registry record is live β they crawl and often list you
automatically, but claiming moves you from "anonymous crawl result" to
a verified, owner-controlled listing.
Being honest about "replacing Context7"
Context7 has real scale (tens of thousands of installs, broad ecosystem
coverage) built over time. What actually makes a server "a viable
alternative" in these registries isn't a claim in a README β it's real
uptime, a working install, and accurate tool descriptions, which is what
steps 1-4 above get you: correctly listed, discoverable, and functioning.
Nothing here fabricates traction that doesn't exist yet.
Other next steps (your call)
- Licensing/monetization β needs your real Stripe/x402 decisions
and pricing before anything gets built here. Research so far:
Context7 (the main comparable) keeps public docs lookup free
indefinitely and monetizes private-library support + team seats +
compliance, not public lookups. Freemium dev-tools convert
freeβpaid at 2-4% typically (8-12% is considered great).
- Private/internal library support β the one proven lever in this
category (see above) β needs a hosted service (see #6 below), not
yet built.
- PyPI fuzzy resolution β not buildable against PyPI's official
API (confirmed: no search API has existed since 2022). Only real
option is leaning on an unofficial third-party index/mirror, with
the tradeoffs that implies.
- Go modules β metadata support (versions, checksums) would follow
the same pattern as npm/PyPI/Cargo. Fuzzy resolution would not:
confirmed
proxy.golang.org has no search endpoint at all.
- Real relevance ranking (semantic search, not keyword substring)
β buildable, but the real version needs an embeddings API (real
ongoing cost) and a vector store β a spend decision, not built yet.
- Remote (HTTP) registry listing + hosted deployment β needed as
the foundation for private-library support and any future rate
limiting;
server.json supports adding a remotes entry once this
is deployed to Render with a public URL.
- Caching layer β currently every call hits the live registry fresh
(correct for accuracy, but means repeated calls for the same package
in one session re-fetch). A short in-memory TTL cache would cut
latency without sacrificing truthfulness β not yet built.