npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

npm-advisor-mcp

v0.1.4

Published

MCP server that searches npm registry, compares packages, and recommends libraries based on size, popularity, maintenance, and ease of use.

Readme

npm-advisor-mcp

A Model Context Protocol (MCP) server that acts as an intelligent npm package advisor. Describe the feature you need, and it will search the registry, compare candidates, audit for vulnerabilities, and recommend the best library based on bundle size, popularity, maintenance, TypeScript support, and more.


Features

  • Search by feature — describe what you need (e.g., "date manipulation", "PDF generation") and get ranked results
  • Side-by-side comparison — compare 2–5 packages on key metrics in a clean table format
  • Deep package details — full breakdown of a single package: README, dependencies, scores, links
  • Weighted recommendations — algorithm-driven pick with dynamic weights per use case (browser, Node.js, React, CLI)
  • Security audit — check for known CVEs with severity breakdown and patch availability
  • Deprecation check — detect deprecated, abandoned, or unmaintained packages with a clear verdict
  • Find alternatives — discover competing packages when migrating away from a deprecated library
  • Install command generator — copy-paste commands for npm, yarn, pnpm, and bun with peer deps included
  • Changelog viewer — fetch recent release notes from GitHub, GitLab (cloud + self-hosted), or Bitbucket
  • Technical Q&A — ask specific questions about a package and get contextual answers from its metadata
  • In-memory caching — all API responses are cached with TTL to eliminate redundant network calls

Architecture

npm-advisor-mcp/
├── package.json                  # Project manifest (ESM, Node 18+)
├── tsconfig.json                 # TypeScript strict config (ES2022/Node16)
├── mcp-config.json               # Ready-to-use Kiro MCP configuration snippet
├── src/
│   ├── index.ts                  # MCP server entry point (stdio transport)
│   ├── models/
│   │   └── types.ts              # Shared interfaces and scoring weights
│   ├── services/
│   │   ├── cache.ts              # In-memory TTL cache (2/5/10 min tiers)
│   │   ├── npm-registry.ts       # registry.npmjs.org client
│   │   ├── npm-audit.ts          # npm security advisory API client
│   │   ├── bundlephobia.ts       # Bundle size data (bundlephobia.com)
│   │   ├── npms-io.ts            # Quality/maintenance/popularity scores
│   │   └── scoring.ts            # Weighted recommendation engine + license checker
│   └── tools/
│       ├── search-packages.ts
│       ├── compare-packages.ts
│       ├── package-details.ts
│       ├── recommend.ts
│       ├── resolve-doubt.ts
│       ├── audit-package.ts
│       ├── find-alternatives.ts
│       ├── check-deprecation.ts
│       ├── generate-install-command.ts
│       └── get-changelog.ts
└── dist/                         # Compiled output (generated by `npm run build`)

Prerequisites

  • Node.js 18+ (uses native fetch)
  • npm 9+

No API keys required — all data sources are public and free.


Installation

cd C:\Users\617500221\Projects\AI-Tools\npm-advisor-mcp
npm install
npm run build

Configuration (Kiro MCP)

Add this to your ~/.kiro/settings/mcp.json inside the "mcpServers" object:

"npm-advisor": {
  "command": "node",
  "args": [
    "C:\\Users\\617500221\\Projects\\AI-Tools\\npm-advisor-mcp\\dist\\index.js"
  ],
  "disabled": false,
  "autoApprove": [
    "search_packages",
    "compare_packages",
    "get_package_details",
    "recommend_package",
    "resolve_technical_doubt",
    "audit_package",
    "find_alternatives",
    "check_deprecation",
    "generate_install_command",
    "get_changelog"
  ]
}

After saving, the server will appear in the Kiro MCP panel and reconnect automatically.


Tools Reference

1. search_packages

Search npm for packages matching a feature or keyword.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | query | string | Yes | Feature or keyword (e.g., "form validation", "state management") | | limit | number | No | Max results to return (default: 8, max: 15) |

Example prompt:

"Search for packages that handle PDF generation in Node.js"

Returns: Ranked list with description, weekly downloads, gzip size, quality/maintenance/popularity scores, and tree-shaking support.


2. compare_packages

Compare 2–5 packages side-by-side on all key metrics.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | packages | string[] | Yes | Array of package names (2–5 items) |

Example prompt:

"Compare dayjs, date-fns, and moment for date manipulation"

Returns: Markdown table with version, gzip size, minified size, downloads/week, TypeScript support, tree-shaking, dependency count, maintenance score, quality score, last publish date, and license.


3. get_package_details

Deep dive into a single package with full metadata.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The npm package name |

Example prompt:

"Get details about the zod package"

Returns: Version, description, quick stats table (downloads, sizes, deps, TS support, license, publish date), quality scores, dependency list, peer dependencies, links, keywords, and a README excerpt.


4. recommend_package

Get a weighted recommendation from a list of candidates. Scoring weights automatically adjust based on your target environment.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | packages | string[] | Yes | Array of package names to evaluate (2–10) | | max_size_kb | number | No | Max acceptable gzip size in KB — packages exceeding this get penalized | | require_typescript | boolean | No | If true, packages without TS types are penalized more | | use_case | string | No | browser, node, react, cli, or general — adjusts scoring weights |

Example prompt:

"Recommend a date library from dayjs, date-fns, moment, and luxon for a browser app — must be under 10KB gzipped"

Returns: Winner with rationale, runner-up alternatives, a detailed score breakdown table, and a license compatibility column.

Default Scoring Weights (general)

| Criterion | Weight | What it measures | |-----------|--------|-----------------| | Bundle size (gzip) | 25% | Smaller is better; relative within comparison group | | Weekly downloads | 20% | Community adoption (log-scaled) | | Maintenance | 20% | npms.io maintenance score | | TypeScript support | 15% | Built-in types (100) > @types (60) > none (20) | | Dependency count | 10% | Fewer runtime deps = less risk | | Freshness | 10% | More recently published = better |

Use Case Weight Adjustments

| Criterion | browser | node | react | cli | |-----------|---------|------|-------|-----| | Bundle size | 40% | 10% | 30% | 5% | | Downloads | 15% | 20% | 20% | 20% | | Maintenance | 15% | 25% | 15% | 30% | | TypeScript | 15% | 15% | 20% | 10% | | Dependencies | 10% | 20% | 10% | 20% | | Freshness | 5% | 10% | 5% | 15% |


5. resolve_technical_doubt

Answer a specific technical question about a package.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The npm package name | | question | string | Yes | Your technical question |

Example prompts:

"Does dayjs support timezone conversion out of the box?" "Is lodash tree-shakeable?" "What are the peer dependencies of @angular/material?" "Is chalk still actively maintained?"

Returns: Contextual answer pulling from metadata, bundle analysis, dependency tree, scores, and README content. Automatically detects question category (size, TypeScript, dependencies, maintenance, tree-shaking) and surfaces relevant data.


6. audit_package

Check a package for known security vulnerabilities.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The npm package name to audit |

Example prompt:

"Are there any known vulnerabilities in lodash?"

Returns: Total vulnerability count, severity breakdown (critical/high/moderate/low), per-CVE details with affected version ranges, patch availability, advisory links, and a deprecation warning if applicable.


7. find_alternatives

Find similar or competing packages as alternatives to a given one.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The package to find alternatives for | | limit | number | No | Max alternatives to return (default: 6, max: 10) |

Example prompts:

"Find alternatives to moment.js" "What can I use instead of request?"

Returns: Ranked list of alternatives with descriptions, weekly downloads, bundle sizes, quality scores, and tree-shaking support. Flags if the original package is deprecated.


8. check_deprecation

Detect if a package is deprecated, unmaintained, or potentially abandoned.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The npm package name to check |

Example prompts:

"Is request still maintained?" "Is moment.js deprecated?"

Returns: npm deprecation flag, days since last publish, maintenance score, weekly downloads, and a clear verdict — actively maintained / moderately stale / potentially abandoned / officially deprecated.


9. generate_install_command

Generate ready-to-paste install commands across all major package managers.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The npm package name | | include_peer_deps | boolean | No | Include peer dependencies (default: true) | | dev | boolean | No | Install as a dev dependency (default: false) |

Example prompts:

"Give me the install command for @tanstack/react-query" "How do I install eslint as a dev dependency with pnpm?"

Returns: Install commands for npm, yarn, pnpm, and bun. Automatically appends peer dependencies and adds a separate @types/ install block if the package lacks built-in TypeScript types.


10. get_changelog

Fetch recent release notes for a package from its git repository. Supports GitHub, GitLab (cloud and self-hosted), and Bitbucket.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The npm package name | | limit | number | No | Number of recent releases to show (default: 5, max: 10) |

Example prompts:

"What changed in the last few versions of zod?" "Show me the recent releases for vite" "What's new in @ATLAS/info-panel?"

Returns: Release history with version tags, publish dates, and formatted release notes (truncated at 800 chars per release).

Git host detection

The tool reads the repository field from the package's package.json and auto-detects the host:

| Pattern in repository URL | Detected as | API used | |---------------------------|-------------|----------| | github.com/... | GitHub | GitHub Releases API | | gitlab.com/... | GitLab cloud | GitLab Releases API | | gitlab.yourcompany.com/... | Self-hosted GitLab | GitLab Releases API (same path, different base URL) | | git.yourcompany.com/... | Self-hosted GitLab | GitLab Releases API | | bitbucket.org/... | Bitbucket | Bitbucket Tags API | | None of the above | — | Falls back to npm versions page link |

Note for private/internal packages: The tool reads the repository field from the package metadata fetched from your registry. If your internal package.json doesn't include a repository field, or uses an SSH URL like git@internal-git:atlas/info-panel without a recognisable hostname, the tool won't be able to detect the host. Add a full HTTPS URL to fix this:

"repository": "https://gitlab.yourcompany.com/atlas/info-panel"

11. check_registry (diagnostic)

Shows which registry URL and auth credentials the server resolves for a given package name, based on ~/.npmrc. Run this first when debugging private registry access.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | package_name | string | Yes | The package name to check resolution for |

Example prompt:

"Check registry for @ATLAS/info-panel"

Returns: Resolved registry URL, whether an auth token was found, and guidance if it's resolving to the public registry unexpectedly.


Data Sources

| API | Base URL | What it provides | Auth | |-----|----------|-----------------|------| | npm Registry | resolved from .npmrc (default: registry.npmjs.org) | Package metadata, versions, README, deps, deprecation | Via .npmrc | | npm Downloads | api.npmjs.org/downloads | Weekly download counts | None | | npm Audit | resolved from .npmrc + /-/npm/v1/security/audits | Known CVEs and advisories | Via .npmrc | | npms.io | api.npms.io/v2 | Search + quality/maintenance/popularity scores | None | | Bundlephobia | bundlephobia.com/api | Minified size, gzip size, tree-shaking, side effects | None | | GitHub API | api.github.com | Release notes and changelog | None | | GitLab API | gitlab.com/api/v4 or self-hosted /api/v4 | Release notes and changelog | None (public) / token if private | | Bitbucket API | api.bitbucket.org/2.0 | Tags used as release history | None |

All requests include timeouts (10–15s) and graceful fallbacks — if one API is slow or unavailable, the tool still returns partial results rather than failing. Responses are cached in-memory to avoid redundant calls within a session.


Private Registry Support (.npmrc)

The server reads ~/.npmrc directly to resolve the registry URL and auth token for each package. No shell subprocess is involved — it parses the file the same way npm does, so it works regardless of how the MCP server process was spawned.

This means scoped private packages like @your-company/some-lib work out of the box as long as your .npmrc is configured correctly — for example:

@ATLAS:registry=https://your-company-registry.example.com/
//your-company-registry.example.com/:_authToken=your-token

Scope names in .npmrc are matched case-insensitively — @ATLAS, @atlas, and @Atlas all match the same entry.

Registry resolution logic

For every package fetch, the server:

  1. Reads ~/.npmrc and looks for a scoped registry override matching the package scope (e.g. @ATLAS:registry=...)
  2. If found, uses that registry URL with the corresponding auth token
  3. If not found, uses the default registry value from .npmrc (or registry.npmjs.org if not set)
  4. If the resolved registry fails and it wasn't already the public registry, automatically retries against registry.npmjs.org — so public packages always work even if a custom default registry is configured

Use the check_registry tool to verify what registry and auth the server resolves for any package before running other tools.

Public vs private package support

| Source | Public packages | Private registry packages | |--------|----------------|---------------------------| | Registry metadata | ✅ Full | ✅ Full (via .npmrc auth) | | Weekly downloads | ✅ | ✅ (npm downloads API is public) | | Bundle size | ✅ | ❌ Bundlephobia only indexes public npm | | npms.io scores | ✅ | ❌ npms.io only indexes public npm | | Security audit | ✅ | ⚠️ Also checks public npm advisory DB as fallback | | Changelog | ✅ GitHub / GitLab / Bitbucket | ✅ If repository field has a full HTTPS URL |

For private packages, tools that depend on bundlephobia or npms.io (search_packages, find_alternatives, bundle size in comparisons) will show N/A for those fields but will still return all registry metadata correctly.


Caching

All API responses are cached in-memory with tiered TTLs:

| Tier | TTL | Used for | |------|-----|---------| | Short | 2 min | Download counts, npms.io scores, search results | | Medium | 5 min | npm registry metadata, GitHub releases | | Long | 10 min | Bundle sizes, security audit results |

The cache is process-scoped — it resets when the MCP server restarts.


Development

# Watch mode (recompiles on save)
npm run dev

# Single build
npm run build

# Run directly
npm start

Project Scripts

| Script | Command | Description | |--------|---------|-------------| | build | tsc | Compile TypeScript to dist/ | | start | node dist/index.js | Run the MCP server | | dev | tsc --watch | Watch mode for development |


Tech Stack

| Technology | Version | Purpose | |------------|---------|---------| | Node.js | 18+ | Runtime (native fetch) | | TypeScript | ~5.5 | Type safety | | @modelcontextprotocol/sdk | ^1.12 | MCP server framework | | zod | ^3.23 | Schema validation for tool inputs |

Zero runtime dependencies beyond the MCP SDK and zod. No database, no external auth.


How It Works

  1. User asks a question in Kiro (e.g., "find me a library for CSV parsing")
  2. Kiro routes to the appropriate tool based on the prompt
  3. The tool checks the in-memory cache — returns instantly if data is fresh
  4. On cache miss, fetches live data from npm registry, npms.io, bundlephobia, and GitHub in parallel
  5. Results are scored, formatted, and returned as structured markdown
  6. Kiro presents the answer in the chat with tables, scores, and actionable recommendations

The server runs as a stdio process — Kiro spawns it on demand and communicates via JSON-RPC over stdin/stdout.


Extending

To add a new tool:

  1. Create src/tools/your-tool.ts with a handler function
  2. Register it in src/index.ts using server.tool(name, description, zodSchema, handler)
  3. Add the tool name to autoApprove in mcp-config.json
  4. Rebuild: npm run build

To add a new data source:

  1. Create src/services/your-source.ts with fetch functions
  2. Wrap responses with cache.set / cache.get from services/cache.ts
  3. Import and use it in the relevant tool handlers
  4. Add timeout + graceful fallback for resilience

Troubleshooting

| Issue | Solution | |-------|----------| | Server doesn't appear in Kiro | Check mcp.json path is correct; ensure dist/index.js exists | | "Cannot find module" errors | Run npm run build after any source changes | | Timeout errors from APIs | Normal behind corporate proxies — results will be partial | | Bundle size shows "N/A" | Bundlephobia can't analyze all packages (native addons, etc.) | | Audit returns no results | npm advisory API may not have data for that package version | | Changelog shows no releases | Package may not use GitHub/GitLab releases, or repository field is missing/SSH-only in package.json | | Private package returns "not found" | Run check_registry to verify the registry URL and auth token are resolving correctly from ~/.npmrc | | check_registry shows wrong registry | Check ~/.npmrc has @SCOPE:registry=https://... and //host/:_authToken=... entries |

If running behind a corporate proxy that intercepts HTTPS (e.g., Zscaler), add your corporate CA certificate to the MCP config:

"env": {
  "NODE_EXTRA_CA_CERTS": "C:\\path\\to\\your\\corporate-ca.pem"
}

This is the recommended fix. Node's native fetch does not respect NODE_TLS_REJECT_UNAUTHORIZED=0 in all cases, and disabling TLS verification entirely is a security risk. Using NODE_EXTRA_CA_CERTS adds your corporate CA to Node's trust store without disabling verification for everything else.

To find your corporate CA cert path, check with your IT team or look in your system certificate store. On Windows it is typically exported from certmgr.msc → Trusted Root Certification Authorities.

If you also need an explicit proxy:

"env": {
  "NODE_EXTRA_CA_CERTS": "C:\\path\\to\\your\\corporate-ca.pem",
  "HTTPS_PROXY": "http://your-proxy:8080"
}

License

ISC