installed-version-mcp
# installed-version-mcp
> Ground your coding agent on the versions it *actually* has, not the blend of every version it was trained on.
An [MCP](https://modelcontextprotocol.io) server that tells Claude, Cursor, and any MCP client the **exact version of each dependency installed in the current project** — read from `node_modules` and the lockfile, fully offline. Studies put AI-generated deprecated-API usage at **25–38%**; the root cause is that the model doesn't know which version is on disk. This fixes that.
## Why this exists
Ask an agent to use a library and it writes code against a smear of every version it ever saw — calling methods that were renamed, passing options that were removed. The truth is sitting in your `node_modules`. This server reads it and pins the agent to the real number *before* it writes the call. It complements [`pkg-api-mcp`](https://github.com/Anicodeth/pkg-api-mcp) (what the API *is*) and [`breaking-changes-mcp`](https://github.com/Anicodeth/breaking-changes-mcp) (what changed between versions).
## Tools
| Tool | What it does |
|------|--------------|
| `installed_version` | Exact installed version of one package (from `node_modules`, else lockfile) + declared range + drift vs npm latest. |
| `resolve_imports` | Pass the packages you're about to import; get each one's installed version in a single grounding call. |
| `project_versions` | Every dependency's installed version from the lockfile — whole tree or direct-only, with a substring filter. |
Core resolution is **100% local**. Only the optional `latest` drift check touches the network.
## Quick start
```bash
npx installed-version-mcp
```
### Claude Code
```bash
# point it at the project you're working in
claude mcp add installed-version -e INSTALLED_VERSION_PROJECT="$(pwd)" -- npx -y installed-version-mcp
```
### Claude Desktop / Cursor / Windsurf / any MCP client
```json
{
"mcpServers": {
"installed-version": {
"command": "npx",
"args": ["-y", "installed-version-mcp"],
"env": { "INSTALLED_VERSION_PROJECT": "/abs/path/to/your/project" }
}
}
}
```
Or skip the env var and pass `projectDir` on each call.
## Example prompts
- *"Before you touch the router code, check the installed version of react-router-dom with installed-version."*
- *"What version of zod is actually installed here, and is it behind latest?"*
- *"Resolve the installed versions of everything I'm importing in this file first."*
## Config
| Env var | Default | Purpose |
|---------|---------|---------|
| `INSTALLED_VERSION_PROJECT` | server cwd | Default project root (folder with `package.json`). Overridable per call via `projectDir`. |
| `NPM_REGISTRY` | `https://registry.npmjs.org` | Registry for the optional latest-version drift check. |
## How it works
```
package name + projectDir
│
├─ node_modules/<pkg>/package.json ── authoritative installed version
│ └─ else package-lock.json (v2/v3 packages map, or v1 tree)
├─ package.json ── declared range
└─ (optional) registry /latest ── drift
```
## Develop
```bash
npm install
npm run build
node dist/index.js
```
## Caveats
- `installed_version` works from `node_modules` alone; `project_versions` needs an npm `package-lock.json`. Yarn/pnpm lockfiles aren't parsed yet (PRs welcome) — but `node_modules` lookups still work under any package manager.
- Transitive dependencies show `source: lockfile` and no declared range — that's expected.
## License
MIT © Anicodeth
TDQS
Scored across 3 tools
The three tools are largely distinct: installed_version targets a single dependency with detailed context, resolve_imports handles a batch of imports, and project_versions provides a full project-wide audit. Minor overlap exists between installed_version and resolve_imports when checking specific packages, but the singular/batch distinction and differing output detail make boundaries clear.
All names use snake_case, but the structure is inconsistent: installed_version is adjective_noun, resolve_imports is verb_noun, and project_versions is noun_noun. A more consistent verb_noun pattern (e.g., get_installed_version, resolve_versions, list_versions) would improve predictability.
With 3 tools, the server is well-scoped for its narrow purpose of reporting installed dependency versions. Each tool earns its place: one for single-package detail, one for import-time grounding, and one for full-project auditing.
The tool surface covers the domain comprehensively: specific version lookup (installed_version), batch lookup for imports (resolve_imports), and all installed versions including transitive deps (project_versions). No obvious gaps exist for the stated purpose of grounding on installed versions.