ScriptDocs MCP Server
# 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.
## Tools
| 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)
```bash
npm install
npm run build
node dist/index.js
```
To wire it into Claude Desktop or Cursor, point their MCP config at:
```json
{
"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)
```bash
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`:
1. **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.
2. **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)
1. **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).
2. **Add an `NPM_TOKEN` secret** to that repo (Settings → Secrets → Actions)
from an npm access token tied to your npm account.
3. **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.
4. **Claim your listing** on [Smithery](https://smithery.ai),
[Glama](https://glama.ai/mcp), and [PulseMCP](https://pulsemcp.com) 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)
1. **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).
2. **Private/internal library support** — the one proven lever in this
category (see above) — needs a hosted service (see #6 below), not
yet built.
3. **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.
4. **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.
5. **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.
6. **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.
7. **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.
TDQS
Scored across 5 tools
Each tool has a clear, non-overlapping purpose: resolving names, fetching metadata, retrieving READMEs, searching within docs, and checking vulnerabilities. No two tools could be easily confused.
All tools share the docs_ prefix and follow a consistent verb_noun pattern (check, get, get, search, resolve). The naming is uniform and predictable.
Five tools is well-scoped for a focused documentation server covering metadata, README, search, name resolution, and vulnerability checks. Each tool earns its place with no redundancy.
The server covers the full workflow: resolving package names, fetching package info and READMEs, searching within docs, and checking vulnerabilities with fix documentation. No obvious gaps for the stated purpose.