mcp-dependency-version
Enables users to look up package versions, scan for vulnerabilities, and analyze dependencies across multiple registries (npm, Maven, PyPI, etc.) using exact version recommendations for security.
README
MCP Dependency Version
A Model Context Protocol (MCP) server for looking up package versions across multiple package registries.
Features
- Multi-registry support: npm, Maven Central, PyPI, crates.io, Go proxy, JSR, NuGet, Docker Hub, RubyGems, Packagist, pub.dev, Swift PM, GitHub Actions
- Version lookup: Get the latest stable (and optionally prerelease) versions
- Version listing: List all available versions with metadata
- Vulnerability scanning: Check packages against OSV and NVD databases with deduplicated, CVSS-scored results
- License lookup: Fetch the declared license for one or many packages in a single call, with explicit status for unsupported registries or undeclared licenses
- Dependency analysis: Analyze dependency files and check for updates
- Docker support: Look up image tags and analyze Dockerfile/docker-compose.yml dependencies
Security: Use Exact Versions
Always use exact versions instead of version ranges to prevent supply chain attacks.
| Bad (vulnerable) | Good (secure) |
|---|---|
^1.2.3 |
1.2.3 |
~1.2.3 |
1.2.3 |
>=1.2.3 |
1.2.3 |
1.x |
1.2.3 |
Version ranges (like ^1.2.3 or ~1.2.3) allow automatic updates when new
minor or patch versions are published. If an attacker compromises a package and
publishes a malicious version, your project could automatically pull it in
without your knowledge.
Using exact versions ensures you control exactly which code runs in your project. When you want to update, explicitly change the version and review the changes.
Docker: Use Digest-Pinned References
Docker tags are NOT immutable. Unlike package versions in npm/PyPI/etc., a Docker tag can be moved to point to a completely different image at any time.
| Bad (vulnerable) | Good (secure) |
|---|---|
nginx:1.27.3 |
nginx@sha256:1948e0c46... |
postgres:16 |
postgres@sha256:abc123... |
When you use nginx:1.27.3, the image you pull today may be different from the
one you pull tomorrow if the tag is updated. This creates a supply chain attack
vector.
Use digest-pinned references (image@sha256:...) to ensure you always pull
the exact same image. The lookup_version and list_versions tools return the
digest and secureReference fields for Docker images to make this easy.
GitHub Actions: Use Commit SHA-Pinned References
GitHub Action tags are NOT immutable. Tags like v4 can be force-pushed to
point to a different commit at any time, creating a supply chain attack vector.
| Bad (vulnerable) | Good (secure) |
|---|---|
actions/checkout@v4 |
actions/checkout@b4ffde65... # v4.2.0 |
actions/setup-node@v4 |
actions/setup-node@1a4442c... # v4.0.1 |
Use commit SHA-pinned references (owner/repo@sha) to ensure you always use
the exact same action code. The lookup_version and list_versions tools
return the digest (commit SHA) and secureReference fields for GitHub Actions
to make this easy.
Supported Registries
| Registry | API Endpoint | Package Format |
|---|---|---|
| npm | registry.npmjs.org | package-name, @scope/package |
| maven | repo1.maven.org/maven2 | groupId:artifactId |
| pypi | pypi.org | package-name |
| cargo | crates.io | crate-name |
| go | proxy.golang.org | github.com/user/repo |
| jsr | api.jsr.io | @scope/name |
| nuget | api.nuget.org | Package.Name |
| docker | hub.docker.com | image, user/image |
| rubygems | rubygems.org | gem-name |
| packagist | packagist.org | vendor/package |
| pub | pub.dev | package_name |
| swift | api.github.com | owner/repo |
| github-actions | api.github.com | owner/repo |
Installation
Prerequisites
Install one of these runtimes, depending on how you want to start the server:
- Node.js v18.18 or later for
npx - Bun v1.2 or later for
bunxor direct Bun runs - Deno v2.x or later for source-based Deno runs
Run with npx or bunx
npx -y --package github:Tripletex/mcp-dependency-version mcp-dependency-version
bunx --bun github:Tripletex/mcp-dependency-version
These commands start an MCP stdio server, so direct terminal runs wait for MCP JSON-RPC input and do not print a prompt.
Setup with Claude Code CLI
Choose one of these commands.
Using npx:
claude mcp add mcp-dependency-version -- npx -y --package github:Tripletex/mcp-dependency-version mcp-dependency-version
Using Bun:
claude mcp add mcp-dependency-version -- bunx --bun github:Tripletex/mcp-dependency-version
Using Deno from a local checkout:
claude mcp add mcp-dependency-version -- deno run --allow-net --allow-env --allow-read /path/to/mcp-dependency-version/main.ts
Setup with Codex CLI
Choose one of these commands.
Using npx:
codex mcp add mcp-dependency-version -- npx -y --package github:Tripletex/mcp-dependency-version mcp-dependency-version
Using Bun:
codex mcp add mcp-dependency-version -- bunx --bun github:Tripletex/mcp-dependency-version
Using Deno from a local checkout:
codex mcp add mcp-dependency-version -- deno run --allow-net --allow-env --allow-read /path/to/mcp-dependency-version/main.ts
Setup with Codex config.toml
Codex stores MCP configuration in ~/.codex/config.toml. You can also use a
project-scoped .codex/config.toml in trusted projects.
Using npx:
[mcp_servers."mcp-dependency-version"]
command = "npx"
args = ["-y", "--package", "github:Tripletex/mcp-dependency-version", "mcp-dependency-version"]
Using Bun:
[mcp_servers."mcp-dependency-version"]
command = "bunx"
args = ["--bun", "github:Tripletex/mcp-dependency-version"]
Using Deno from a local checkout:
[mcp_servers."mcp-dependency-version"]
command = "deno"
args = ["run", "--allow-net", "--allow-env", "--allow-read", "/path/to/mcp-dependency-version/main.ts"]
Setup with Claude Desktop using npx
{
"mcpServers": {
"mcp-dependency-version": {
"command": "npx",
"args": [
"-y",
"--package",
"github:Tripletex/mcp-dependency-version",
"mcp-dependency-version"
]
}
}
}
Setup with Claude Desktop using bunx
{
"mcpServers": {
"mcp-dependency-version": {
"command": "bunx",
"args": ["--bun", "github:Tripletex/mcp-dependency-version"]
}
}
}
Setup with Claude Desktop using Deno
Add to your Claude Desktop configuration file
(~/Library/Application Support/Claude/claude_desktop_config.json on macOS,
~/.config/claude-desktop/claude_desktop_config.json on Linux):
{
"mcpServers": {
"mcp-dependency-version": {
"command": "deno",
"args": [
"run",
"--allow-net",
"--allow-env",
"--allow-read",
"/path/to/mcp-dependency-version/main.ts"
]
}
}
}
Setup with Docker
The service is available as a Docker image using stdio transport.
Pull the image:
docker pull ghcr.io/tripletex/mcp-dependency-version:latest
Run directly:
docker run --rm -i ghcr.io/tripletex/mcp-dependency-version:latest
Claude Desktop configuration:
{
"mcpServers": {
"mcp-dependency-version": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/tripletex/mcp-dependency-version:latest"
]
}
}
}
Local Development
-
Clone the repository:
git clone https://github.com/tripletex/mcp-dependency-version.git cd mcp-dependency-version -
Run the server:
deno task startOr run it with Bun:
bun run main.ts
Configuration
The server supports custom repository configurations for each registry type. This allows you to use private registries, mirrors, or multiple repositories per registry.
Configuration File
Create a configuration file at ~/.config/mcp-dependency-version/config.json:
{
"repositories": {
"npm": {
"npmjs": {
"name": "npm",
"url": "https://registry.npmjs.org",
"default": true
},
"github": {
"name": "GitHub Packages",
"url": "https://npm.pkg.github.com",
"auth": {
"token": "ghp_xxxxxxxxxxxx"
}
}
},
"maven": {
"central": {
"name": "Maven Central",
"url": "https://repo1.maven.org/maven2",
"default": true
},
"atlassian": {
"name": "Atlassian Maven",
"url": "https://packages.atlassian.com/maven/public"
},
"jitpack": {
"name": "JitPack",
"url": "https://jitpack.io"
}
},
"pypi": {
"pypi": {
"name": "PyPI",
"url": "https://pypi.org/pypi",
"default": true
},
"private": {
"name": "Private PyPI",
"url": "https://pypi.example.com/simple",
"auth": {
"username": "user",
"password": "pass"
}
}
}
}
}
Environment Variable
You can override the config file path using the MCP_DEPENDENCY_VERSION_CONFIG
environment variable:
export MCP_DEPENDENCY_VERSION_CONFIG=/path/to/config.json
Authentication
The configuration supports two authentication methods:
Bearer Token:
{
"auth": {
"token": "your-token-here"
}
}
Basic Auth:
{
"auth": {
"username": "user",
"password": "pass"
}
}
Default Repositories
If no configuration file exists, the server uses the official public registries:
| Registry | Default URL |
|---|---|
| npm | https://registry.npmjs.org |
| maven | https://repo1.maven.org/maven2 |
| pypi | https://pypi.org/pypi |
| cargo | https://crates.io/api/v1/crates |
| go | https://proxy.golang.org |
| jsr | https://api.jsr.io |
| nuget | https://api.nuget.org/v3 |
| docker | https://hub.docker.com |
| rubygems | https://rubygems.org |
| packagist | https://repo.packagist.org |
| pub | https://pub.dev/api |
| swift | https://api.github.com |
| github-actions | https://api.github.com |
Tools
lookup_version
Look up the latest version of a package.
Parameters:
registry(required): Package registry (npm,maven,pypi,cargo,go,jsr,nuget,docker,rubygems,packagist,pub,swift,github-actions)package(required): Package nameincludePrerelease(optional): Include alpha/beta/rc versionsversionPrefix(optional): Filter versions by prefix (e.g.,"2."for 2.x)
Example:
{
"registry": "npm",
"package": "lodash"
}
Output:
{
"packageName": "lodash",
"registry": "npm",
"latestStable": "4.17.21",
"publishedAt": "2021-02-20T15:42:16.891Z"
}
Docker Output (includes digest for secure pinning):
{
"packageName": "nginx",
"registry": "docker",
"latestStable": "1.27.3",
"publishedAt": "2024-12-04T18:51:59.819Z",
"digest": "sha256:1948e0c46da16a3565a844aa65ab848e1546f85cf47e47d044a567906a3a497f",
"secureReference": "nginx@sha256:1948e0c46da16a3565a844aa65ab848e1546f85cf47e47d044a567906a3a497f",
"securityNotes": [
"WARNING: Docker tags are NOT immutable. A tag can be moved to point to a different image at any time.",
"Using the digest-pinned reference (image@sha256:...) provides protection against tag tampering.",
"Digest-pinned references ensure you always pull the exact same image, preventing supply chain attacks.",
"When updating, explicitly change the digest and verify the new image before deployment."
]
}
GitHub Actions Output (includes commit SHA for secure pinning):
{
"packageName": "actions/checkout",
"registry": "github-actions",
"latestStable": "4.2.0",
"publishedAt": "2024-10-01T12:00:00.000Z",
"digest": "b4ffde65f46336ab88eb53be808477a3936bae11",
"secureReference": "actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.2.0",
"securityNotes": [
"GitHub Action tags are NOT immutable. Tags can be force-pushed to point to different commits.",
"Use commit SHA-pinned references (owner/repo@sha) for supply chain security.",
"Secure reference: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.2.0"
]
}
list_versions
List all available versions of a package.
Parameters:
registry(required): Package registrypackage(required): Package namelimit(optional): Maximum versions to return (default: 20)
Example:
{
"registry": "pypi",
"package": "requests",
"limit": 5
}
Output:
{
"packageName": "requests",
"registry": "pypi",
"versions": [
{
"version": "2.31.0",
"publishedAt": "2023-05-22T15:12:44.000Z",
"isPrerelease": false,
"isDeprecated": false
}
],
"totalCount": 142,
"showing": 5
}
check_vulnerabilities
Check a package version for known security vulnerabilities.
Queries both OSV and NVD in parallel for comprehensive coverage. Results are deduplicated by CVE ID — when a vulnerability appears in both databases, NVD's CVSS v3.1 score is used as the authoritative severity rating.
Set the NVD_API_KEY environment variable for higher NVD rate limits (50 vs 5
requests per 30 seconds). Request a free key at
https://nvd.nist.gov/developers/request-an-api-key.
Parameters:
registry(required): Package registrypackage(required): Package nameversion(required): Version to checkseverityThreshold(optional): Minimum severity (LOW,MEDIUM,HIGH,CRITICAL)
Example:
{
"registry": "npm",
"package": "lodash",
"version": "4.17.20"
}
Output:
{
"packageName": "lodash",
"version": "4.17.20",
"registry": "npm",
"vulnerabilities": [
{
"id": "GHSA-29mw-wpgm-hmr9",
"summary": "Prototype Pollution in lodash",
"severity": "HIGH",
"cvss": 7.2,
"cveIds": ["CVE-2021-23337"],
"cweIds": ["CWE-94"],
"fixedVersions": ["4.17.21"],
"source": "osv+nvd"
}
],
"totalCount": 1,
"hasVulnerabilities": true,
"summary": {
"critical": 0,
"high": 1,
"medium": 0,
"low": 0
}
}
analyze_dependencies
Analyze a dependency file and check for available updates.
Parameters:
content(required): File content (package.json, pom.xml, build.gradle, build.gradle.kts, requirements.txt, Cargo.toml, go.mod, deno.json, .csproj, Gemfile, composer.json, pubspec.yaml, Package.swift, .github/workflows/.yml)registry(required): Package registry (usemavenfor Gradle files, usegithub-actionsfor workflow files)checkVulnerabilities(optional): Also scan for vulnerabilities (default: false)
Supported Dependency Files:
| Registry | File Formats |
|---|---|
| npm | package.json |
| maven | pom.xml, build.gradle (Groovy), build.gradle.kts (Kotlin) |
| pypi | requirements.txt |
| cargo | Cargo.toml |
| go | go.mod |
| jsr | deno.json (supports jsr: and npm: imports) |
| nuget | *.csproj (PackageReference format) |
| docker | Dockerfile, docker-compose.yml |
| rubygems | Gemfile |
| packagist | composer.json |
| pub | pubspec.yaml |
| swift | Package.swift |
| github-actions | .github/workflows/*.yml |
Note: For GitHub Actions workflow files, SHA-pinned references are skipped
since they are already secure. For Gradle files, variable references
($version, ${libs.xxx}, version catalogs) are skipped since they can't be
resolved without evaluating the build.
Example (npm):
{
"content": "{\"dependencies\": {\"lodash\": \"^4.17.20\", \"express\": \"^4.18.0\"}}",
"registry": "npm",
"checkVulnerabilities": true
}
Example (Gradle Kotlin DSL):
{
"content": "dependencies {\n implementation(\"org.springframework.boot:spring-boot-starter:3.2.0\")\n testImplementation(\"org.junit.jupiter:junit-jupiter:5.10.0\")\n}",
"registry": "maven"
}
Output:
{
"registry": "npm",
"dependencies": [
{
"name": "lodash",
"currentVersion": "4.17.20",
"latestVersion": "4.17.21",
"updateAvailable": true,
"updateType": "patch",
"vulnerabilities": [
{ "id": "GHSA-29mw-wpgm-hmr9", "summary": "Prototype Pollution" }
]
},
{
"name": "express",
"currentVersion": "4.18.0",
"latestVersion": "4.18.2",
"updateAvailable": true,
"updateType": "patch",
"vulnerabilities": []
}
],
"summary": {
"total": 2,
"outdated": 2,
"vulnerable": 1,
"deprecated": 0,
"majorUpdates": 0,
"minorUpdates": 0,
"patchUpdates": 2
}
}
get_licenses
Look up the declared license for one or more packages in a single call. Results are enriched with SPDX metadata and copyleft classification from a baked-in dataset (see License dataset).
Parameters:
packages(required): Array of{registry, package, version?}entries. Results preserve input order. Pass a single-element array for one package.
Example:
{
"packages": [
{ "registry": "npm", "package": "lodash" },
{ "registry": "cargo", "package": "serde" },
{ "registry": "go", "package": "github.com/gin-gonic/gin" }
]
}
Output (abbreviated):
{
"results": [
{
"registry": "npm",
"packageName": "lodash",
"license": "MIT",
"status": "found",
"spdx": [
{
"licenseId": "MIT",
"name": "MIT License",
"isOsiApproved": true,
"isDeprecated": false,
"category": "Permissive",
"isCopyleft": false,
"reference": "https://spdx.org/licenses/MIT.html"
}
],
"isCopyleft": false
},
{
"registry": "cargo",
"packageName": "serde",
"license": "MIT OR Apache-2.0",
"status": "found",
"spdx": [
{ "licenseId": "MIT", "category": "Permissive", "isCopyleft": false },
{
"licenseId": "Apache-2.0",
"category": "Permissive",
"isCopyleft": false
}
],
"isCopyleft": false
},
{
"registry": "go",
"packageName": "github.com/gin-gonic/gin",
"license": null,
"status": "registry-unsupported",
"note": "The go registry does not expose license metadata through this tool. Check the package's source repository or documentation."
}
],
"summary": {
"total": 3,
"withLicense": 2,
"notDeclared": 0,
"registryUnsupported": 1,
"errors": 0,
"copyleft": 0
},
"sources": [
{
"name": "SPDX License List",
"version": "3.28.0",
"license": "CC0-1.0",
"attribution": "..."
},
{
"name": "ScanCode LicenseDB",
"license": "CC-BY-4.0",
"attribution": "..."
}
]
}
Status values:
found— license string returned inlicense;spdx[]andisCopyleftpopulated when the string resolves to one or more SPDX IDsnot-declared— the package did not declare a license in its metadataregistry-unsupported— the registry does not expose license metadata (go,docker)error— metadata fetch failed; see theerrorfield
Enrichment fields (present on found results):
spdx[].licenseId— canonical SPDX short identifierspdx[].isOsiApproved— OSI-approved open source licensespdx[].isDeprecated— SPDX-deprecated identifier (use the replacement)spdx[].category— ScanCode LicenseDB category (Permissive,Copyleft,Copyleft Limited,Public Domain,Proprietary Free, etc.)spdx[].isCopyleft— shortcut forcategory∈ {Copyleft,Copyleft Limited}isCopyleft(top-level) — true if any resolved license is copyleft
A not-declared or registry-unsupported result does not mean the package
is unlicensed. Check the package's source repository or documentation instead.
Some registries return license strings that don't match a known SPDX ID
(free-form text, deprecated aliases, custom names). In that case spdx is an
empty array and isCopyleft is omitted — the raw license string is still
returned verbatim.
get_package_docs
Get README documentation for a package.
Parameters:
registry(required): Package registry (npm,maven,pypi,cargo,go,jsr,nuget,docker,rubygems,packagist,pub,swift,github-actions)package(required): Package nameversion(optional): Specific version to get documentation for
Documentation Sources:
| Registry | README Source | Repository URL Source |
|---|---|---|
| npm | Registry API | repository field |
| pypi | Registry API (description) | project_urls field |
| cargo | Registry API | repository field |
| maven | GitHub (fallback) | POM <scm> section |
| go | GitHub (fallback) | Module path (if github.com) |
| jsr | GitHub (fallback) | githubRepository field |
| nuget | GitHub (fallback) | Catalog entry |
| docker | GitHub (fallback) | Docker Hub page |
| rubygems | Registry API (info) | source_code_uri field |
| packagist | Registry API (description) | repository field |
| pub | Registry API (description) | repository field |
| swift | GitHub (fallback) | GitHub repository URL |
| github-actions | GitHub (fallback) | GitHub repository URL |
Example:
{
"registry": "npm",
"package": "lodash"
}
Output:
# lodash Documentation
Registry: npm
Source: registry
Documentation: https://www.npmjs.com/package/lodash
Repository: https://github.com/lodash/lodash
---
# lodash
A modern JavaScript utility library delivering modularity, performance & extras.
...
License dataset (data/licenses.json)
The get_licenses tool enriches each result with SPDX metadata and copyleft
classification from a baked-in dataset at data/licenses.json. Using a
committed snapshot keeps license lookups deterministic, offline-capable, and
auditable in the repo.
The dataset merges two upstream sources:
| Source | URL | License | Use |
|---|---|---|---|
| SPDX License List | https://spdx.org/licenses/licenses.json | CC0-1.0 | Canonical SPDX IDs, names, OSI approval status |
| ScanCode LicenseDB | https://scancode-licensedb.aboutcode.org/index.json | CC-BY-4.0 | License category (Permissive / Copyleft / Copyleft Limited / etc.) and copyleft classification |
Both sources — and their full attribution strings — are embedded in the
sources[] array at the root of data/licenses.json and echoed back on every
get_licenses response, so downstream consumers carry the attribution required
by ScanCode's CC-BY-4.0.
Refreshing the dataset
deno task update-licenses
This runs scripts/update-licenses.ts, which fetches both upstream lists,
merges them, and rewrites data/licenses.json. Review the diff and commit — the
upstream lists change only a few times per year. The script needs
--allow-net + --allow-write=data (already set in the task).
Development
Commands
# Type check
deno task check
# Run tests
deno task test
# Start server
deno task start
# Start with file watching
deno task dev
# Lint
deno task lint
# Format
deno task fmt
Project Structure
src/
├── config/ # Configuration loading
├── registries/ # Registry client implementations (npm, maven, pypi, etc.)
├── parsers/ # Dependency file parsers (package.json, pom.xml, etc.)
├── tools/ # MCP tool implementations
└── utils/ # Shared utilities (version parsing, caching, HTTP)
API Reference
Registry APIs
| Registry | API Endpoint | Documentation |
|---|---|---|
| npm | registry.npmjs.org/{package} |
docs |
| Maven | repo1.maven.org/maven2 |
docs |
| PyPI | pypi.org/pypi/{package}/json |
docs |
| Cargo | crates.io/api/v1/crates/{crate} |
docs |
| Go | proxy.golang.org/{module}/@v/list |
docs |
| JSR | api.jsr.io/scopes/{scope}/packages/{name} |
docs |
| NuGet | api.nuget.org/v3-flatcontainer/{id}/index.json |
docs |
| Docker | hub.docker.com/v2/repositories/{image}/tags |
docs |
| RubyGems | rubygems.org/api/v1/gems/{gem}.json |
docs |
| Packagist | repo.packagist.org/p2/{vendor}/{package}.json |
docs |
| Pub | pub.dev/api/packages/{package} |
docs |
| Swift | api.github.com/repos/{owner}/{repo}/tags |
docs |
| GitHub Actions | api.github.com/repos/{owner}/{repo}/tags |
docs |
| OSV | api.osv.dev/v1/query |
docs |
| NVD | services.nvd.nist.gov/rest/json/cves/2.0 |
docs |
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.