Skip to content

Configuration

Create a registry-stats.config.json in your project root:

Terminal window
registry-stats --init

Example config:

{
"registries": ["npm", "pypi", "nuget", "vscode", "docker"],
"packages": {
"mcpt": {
"npm": "mcpt",
"pypi": "mcpt"
},
"tool-compass": {
"npm": "@mcptoolshop/tool-compass",
"vscode": "mcp-tool-shop.tool-compass"
}
},
"cache": true,
"cacheTtlMs": 300000,
"concurrency": 5
}

Run registry-stats with no arguments to fetch stats for all configured packages. The CLI walks up from cwd to find the nearest config file.

import { loadConfig, defaultConfig, starterConfig } from '@mcptoolshop/registry-stats';
const config = loadConfig(); // finds nearest config file, or null
const defaults = defaultConfig(); // returns default Config object
const template = starterConfig(); // returns starter JSON string

In-memory cache with 5-minute TTL (default):

const cache = createCache();
await stats('npm', 'express', { cache });

The StatsCache interface supports custom backends:

interface StatsCache {
get(key: string): Promise<PackageStats | null>;
set(key: string, value: PackageStats): Promise<void>;
}

Add support for registries not built in:

import { registerProvider, type RegistryProvider } from '@mcptoolshop/registry-stats';
const cargo: RegistryProvider = {
name: 'cargo',
async getStats(pkg) {
const res = await fetch(`https://crates.io/api/v1/crates/${pkg}`);
const json = await res.json();
return {
registry: 'cargo' as any,
package: pkg,
downloads: { total: json.crate.downloads },
fetchedAt: new Date().toISOString(),
};
},
};
registerProvider(cargo);
await stats('cargo', 'serde');
  • Automatic retry with exponential backoff on 429/5xx errors
  • Respects Retry-After headers
  • Concurrency limiting for bulk requests (default: 5)