@yawlabs/npmjs-mcp 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +295 -100
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21087,6 +21087,78 @@ function downloadsGet(path) {
|
|
|
21087
21087
|
function replicateGet(path) {
|
|
21088
21088
|
return request(REPLICATE_URL, path);
|
|
21089
21089
|
}
|
|
21090
|
+
function parseSemver(v) {
|
|
21091
|
+
const m = v.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
21092
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
|
|
21093
|
+
}
|
|
21094
|
+
function cmpSemver(a, b) {
|
|
21095
|
+
for (let i = 0; i < 3; i++) {
|
|
21096
|
+
if (a[i] < b[i]) return -1;
|
|
21097
|
+
if (a[i] > b[i]) return 1;
|
|
21098
|
+
}
|
|
21099
|
+
return 0;
|
|
21100
|
+
}
|
|
21101
|
+
function maxSatisfying(versions, range) {
|
|
21102
|
+
const r = range.trim().replace(/^v/, "");
|
|
21103
|
+
if (versions.includes(r)) return r;
|
|
21104
|
+
let minInclusive = null;
|
|
21105
|
+
let maxExclusive = null;
|
|
21106
|
+
if (r.startsWith("^")) {
|
|
21107
|
+
const base = parseSemver(r.slice(1));
|
|
21108
|
+
if (!base) return null;
|
|
21109
|
+
minInclusive = base;
|
|
21110
|
+
if (base[0] > 0) maxExclusive = [base[0] + 1, 0, 0];
|
|
21111
|
+
else if (base[1] > 0) maxExclusive = [0, base[1] + 1, 0];
|
|
21112
|
+
else maxExclusive = [0, 0, base[2] + 1];
|
|
21113
|
+
} else if (r.startsWith("~")) {
|
|
21114
|
+
const base = parseSemver(r.slice(1));
|
|
21115
|
+
if (!base) return null;
|
|
21116
|
+
minInclusive = base;
|
|
21117
|
+
maxExclusive = [base[0], base[1] + 1, 0];
|
|
21118
|
+
} else if (r.startsWith(">=")) {
|
|
21119
|
+
const base = parseSemver(r.slice(2));
|
|
21120
|
+
if (!base) return null;
|
|
21121
|
+
minInclusive = base;
|
|
21122
|
+
} else if (r.startsWith("<=")) {
|
|
21123
|
+
const base = parseSemver(r.slice(2));
|
|
21124
|
+
if (!base) return null;
|
|
21125
|
+
maxExclusive = [base[0], base[1], base[2] + 1];
|
|
21126
|
+
} else {
|
|
21127
|
+
const xm = r.match(/^(\d+)(?:\.(\d+|x)(?:\.(\d+|x))?)?$/);
|
|
21128
|
+
if (xm) {
|
|
21129
|
+
const major = Number(xm[1]);
|
|
21130
|
+
const minor = xm[2] !== void 0 && xm[2] !== "x" ? Number(xm[2]) : null;
|
|
21131
|
+
if (minor === null) {
|
|
21132
|
+
minInclusive = [major, 0, 0];
|
|
21133
|
+
maxExclusive = [major + 1, 0, 0];
|
|
21134
|
+
} else {
|
|
21135
|
+
const patch = xm[3] !== void 0 && xm[3] !== "x" ? Number(xm[3]) : null;
|
|
21136
|
+
if (patch === null) {
|
|
21137
|
+
minInclusive = [major, minor, 0];
|
|
21138
|
+
maxExclusive = [major, minor + 1, 0];
|
|
21139
|
+
} else {
|
|
21140
|
+
return null;
|
|
21141
|
+
}
|
|
21142
|
+
}
|
|
21143
|
+
} else {
|
|
21144
|
+
return null;
|
|
21145
|
+
}
|
|
21146
|
+
}
|
|
21147
|
+
let best = null;
|
|
21148
|
+
let bestParsed = null;
|
|
21149
|
+
for (const v of versions) {
|
|
21150
|
+
if (v.includes("-") && !r.includes("-")) continue;
|
|
21151
|
+
const parsed = parseSemver(v);
|
|
21152
|
+
if (!parsed) continue;
|
|
21153
|
+
if (minInclusive && cmpSemver(parsed, minInclusive) < 0) continue;
|
|
21154
|
+
if (maxExclusive && cmpSemver(parsed, maxExclusive) >= 0) continue;
|
|
21155
|
+
if (!bestParsed || cmpSemver(parsed, bestParsed) > 0) {
|
|
21156
|
+
best = v;
|
|
21157
|
+
bestParsed = parsed;
|
|
21158
|
+
}
|
|
21159
|
+
}
|
|
21160
|
+
return best;
|
|
21161
|
+
}
|
|
21090
21162
|
|
|
21091
21163
|
// src/tools/access.ts
|
|
21092
21164
|
var accessTools = [
|
|
@@ -21184,12 +21256,9 @@ var analysisTools = [
|
|
|
21184
21256
|
handler: async (input) => {
|
|
21185
21257
|
const results = await Promise.all(
|
|
21186
21258
|
input.packages.map(async (name) => {
|
|
21187
|
-
const [pkgRes, dlRes
|
|
21259
|
+
const [pkgRes, dlRes] = await Promise.all([
|
|
21188
21260
|
registryGet(`/${encPkg(name)}`),
|
|
21189
|
-
downloadsGet(`/downloads/point/last-week/${encPkg(name)}`)
|
|
21190
|
-
registryPost("/-/npm/v1/security/advisories/bulk", {
|
|
21191
|
-
[name]: ["latest"]
|
|
21192
|
-
})
|
|
21261
|
+
downloadsGet(`/downloads/point/last-week/${encPkg(name)}`)
|
|
21193
21262
|
]);
|
|
21194
21263
|
if (!pkgRes.ok) {
|
|
21195
21264
|
return { name, error: pkgRes.error };
|
|
@@ -21198,6 +21267,15 @@ var analysisTools = [
|
|
|
21198
21267
|
const latest = pkg["dist-tags"]?.latest;
|
|
21199
21268
|
const latestVersion = latest ? pkg.versions[latest] : void 0;
|
|
21200
21269
|
const versionKeys = Object.keys(pkg.versions);
|
|
21270
|
+
let vulnerabilities = 0;
|
|
21271
|
+
if (latest) {
|
|
21272
|
+
const auditRes = await registryPost("/-/npm/v1/security/advisories/bulk", {
|
|
21273
|
+
[name]: [latest]
|
|
21274
|
+
});
|
|
21275
|
+
if (auditRes.ok && auditRes.data?.[name]) {
|
|
21276
|
+
vulnerabilities = auditRes.data[name].length;
|
|
21277
|
+
}
|
|
21278
|
+
}
|
|
21201
21279
|
return {
|
|
21202
21280
|
name,
|
|
21203
21281
|
description: pkg.description,
|
|
@@ -21212,7 +21290,7 @@ var analysisTools = [
|
|
|
21212
21290
|
hasReadme: !!(pkg.readme && pkg.readme.length > 0),
|
|
21213
21291
|
repository: pkg.repository,
|
|
21214
21292
|
homepage: pkg.homepage,
|
|
21215
|
-
vulnerabilities
|
|
21293
|
+
vulnerabilities
|
|
21216
21294
|
};
|
|
21217
21295
|
})
|
|
21218
21296
|
);
|
|
@@ -21243,6 +21321,16 @@ var analysisTools = [
|
|
|
21243
21321
|
const latest = pkg["dist-tags"]?.latest;
|
|
21244
21322
|
const latestVersion = latest ? pkg.versions[latest] : void 0;
|
|
21245
21323
|
const versionKeys = Object.keys(pkg.versions);
|
|
21324
|
+
let vulnerabilityCount = null;
|
|
21325
|
+
if (latest) {
|
|
21326
|
+
const auditRes = await registryPost("/-/npm/v1/security/advisories/bulk", {
|
|
21327
|
+
[input.name]: [latest]
|
|
21328
|
+
});
|
|
21329
|
+
if (auditRes.ok) {
|
|
21330
|
+
const advisories = auditRes.data?.[input.name];
|
|
21331
|
+
vulnerabilityCount = Array.isArray(advisories) ? advisories.length : 0;
|
|
21332
|
+
}
|
|
21333
|
+
}
|
|
21246
21334
|
const publishDates = versionKeys.map((v) => pkg.time[v]).filter(Boolean).map((d) => new Date(d).getTime()).sort((a, b) => b - a);
|
|
21247
21335
|
const now = Date.now();
|
|
21248
21336
|
const daysSinceLastPublish = publishDates.length > 0 ? Math.floor((now - publishDates[0]) / 864e5) : null;
|
|
@@ -21274,6 +21362,7 @@ var analysisTools = [
|
|
|
21274
21362
|
versionCount: versionKeys.length,
|
|
21275
21363
|
daysSinceLastPublish,
|
|
21276
21364
|
avgDaysBetweenReleases,
|
|
21365
|
+
vulnerabilityCount,
|
|
21277
21366
|
hasLicense,
|
|
21278
21367
|
hasReadme,
|
|
21279
21368
|
hasRepo,
|
|
@@ -21454,7 +21543,6 @@ var authTools = [
|
|
|
21454
21543
|
data: {
|
|
21455
21544
|
total: data.total,
|
|
21456
21545
|
tokens: data.objects.map((t) => ({
|
|
21457
|
-
token: t.token,
|
|
21458
21546
|
key: t.key,
|
|
21459
21547
|
readonly: t.readonly,
|
|
21460
21548
|
cidrWhitelist: t.cidr_whitelist,
|
|
@@ -21464,6 +21552,38 @@ var authTools = [
|
|
|
21464
21552
|
}
|
|
21465
21553
|
};
|
|
21466
21554
|
}
|
|
21555
|
+
},
|
|
21556
|
+
{
|
|
21557
|
+
name: "npm_user_packages",
|
|
21558
|
+
description: "List all packages published by a specific npm user. Shows package names and the user's access level for each. Requires authentication.",
|
|
21559
|
+
annotations: {
|
|
21560
|
+
title: "List user packages",
|
|
21561
|
+
readOnlyHint: true,
|
|
21562
|
+
destructiveHint: false,
|
|
21563
|
+
idempotentHint: true,
|
|
21564
|
+
openWorldHint: true
|
|
21565
|
+
},
|
|
21566
|
+
inputSchema: external_exports.object({
|
|
21567
|
+
username: external_exports.string().describe("npm username")
|
|
21568
|
+
}),
|
|
21569
|
+
handler: async (input) => {
|
|
21570
|
+
const authErr = requireAuth();
|
|
21571
|
+
if (authErr) return authErr;
|
|
21572
|
+
const res = await registryGetAuth(
|
|
21573
|
+
`/-/user/org.couchdb.user:${encodeURIComponent(input.username)}/package`
|
|
21574
|
+
);
|
|
21575
|
+
if (!res.ok) return res;
|
|
21576
|
+
const packages = Object.entries(res.data).map(([name, access]) => ({ name, access }));
|
|
21577
|
+
return {
|
|
21578
|
+
ok: true,
|
|
21579
|
+
status: 200,
|
|
21580
|
+
data: {
|
|
21581
|
+
username: input.username,
|
|
21582
|
+
packageCount: packages.length,
|
|
21583
|
+
packages
|
|
21584
|
+
}
|
|
21585
|
+
};
|
|
21586
|
+
}
|
|
21467
21587
|
}
|
|
21468
21588
|
];
|
|
21469
21589
|
|
|
@@ -21541,8 +21661,8 @@ var dependencyTools = [
|
|
|
21541
21661
|
else queue.push(run);
|
|
21542
21662
|
});
|
|
21543
21663
|
}
|
|
21544
|
-
async function resolve(name,
|
|
21545
|
-
const hintKey = `${name}@${
|
|
21664
|
+
async function resolve(name, versionHint2, currentDepth) {
|
|
21665
|
+
const hintKey = `${name}@${versionHint2}`;
|
|
21546
21666
|
if (resolved.has(hintKey) || currentDepth > maxDepth) return;
|
|
21547
21667
|
resolved.add(hintKey);
|
|
21548
21668
|
let pkg = packumentCache.get(name);
|
|
@@ -21550,19 +21670,21 @@ var dependencyTools = [
|
|
|
21550
21670
|
const res = await runLimited(() => registryGetAbbreviated(`/${encPkg(name)}`));
|
|
21551
21671
|
if (!res.ok) {
|
|
21552
21672
|
warnings.push(`Failed to fetch ${name}: ${res.error}`);
|
|
21553
|
-
tree[hintKey] = { version:
|
|
21673
|
+
tree[hintKey] = { version: versionHint2, dependencies: {} };
|
|
21554
21674
|
return;
|
|
21555
21675
|
}
|
|
21556
21676
|
pkg = res.data;
|
|
21557
21677
|
packumentCache.set(name, pkg);
|
|
21558
21678
|
}
|
|
21559
21679
|
let resolvedVersion;
|
|
21560
|
-
if (pkg.versions[
|
|
21561
|
-
resolvedVersion =
|
|
21562
|
-
} else if (pkg["dist-tags"][
|
|
21563
|
-
resolvedVersion = pkg["dist-tags"][
|
|
21680
|
+
if (pkg.versions[versionHint2]) {
|
|
21681
|
+
resolvedVersion = versionHint2;
|
|
21682
|
+
} else if (pkg["dist-tags"][versionHint2]) {
|
|
21683
|
+
resolvedVersion = pkg["dist-tags"][versionHint2];
|
|
21564
21684
|
} else {
|
|
21565
|
-
|
|
21685
|
+
const available = Object.keys(pkg.versions);
|
|
21686
|
+
const matched = maxSatisfying(available, versionHint2);
|
|
21687
|
+
resolvedVersion = matched ?? pkg["dist-tags"]?.latest ?? versionHint2;
|
|
21566
21688
|
}
|
|
21567
21689
|
const resolvedKey = `${name}@${resolvedVersion}`;
|
|
21568
21690
|
if (tree[resolvedKey]) return;
|
|
@@ -21578,12 +21700,14 @@ var dependencyTools = [
|
|
|
21578
21700
|
await Promise.all(tasks);
|
|
21579
21701
|
}
|
|
21580
21702
|
}
|
|
21581
|
-
|
|
21703
|
+
const versionHint = input.version ?? "latest";
|
|
21704
|
+
await resolve(input.name, versionHint, 1);
|
|
21705
|
+
const rootKey = Object.keys(tree).find((k) => k.startsWith(`${input.name}@`)) ?? `${input.name}@${versionHint}`;
|
|
21582
21706
|
return {
|
|
21583
21707
|
ok: true,
|
|
21584
21708
|
status: 200,
|
|
21585
21709
|
data: {
|
|
21586
|
-
root:
|
|
21710
|
+
root: rootKey,
|
|
21587
21711
|
depth: maxDepth,
|
|
21588
21712
|
totalPackages: Object.keys(tree).length,
|
|
21589
21713
|
tree,
|
|
@@ -21604,14 +21728,17 @@ var dependencyTools = [
|
|
|
21604
21728
|
},
|
|
21605
21729
|
inputSchema: external_exports.object({
|
|
21606
21730
|
name: external_exports.string().describe("Package name"),
|
|
21607
|
-
version: external_exports.string().optional().describe("Semver version or dist-tag (default: 'latest')")
|
|
21731
|
+
version: external_exports.string().optional().describe("Semver version or dist-tag (default: 'latest')"),
|
|
21732
|
+
allowed: external_exports.array(external_exports.string()).optional().describe(
|
|
21733
|
+
"SPDX license identifiers to treat as allowed (default: MIT, ISC, BSD-2-Clause, BSD-3-Clause, Apache-2.0, 0BSD, Unlicense)"
|
|
21734
|
+
)
|
|
21608
21735
|
}),
|
|
21609
21736
|
handler: async (input) => {
|
|
21610
21737
|
const ver = input.version ?? "latest";
|
|
21611
21738
|
const res = await registryGet(`/${encPkg(input.name)}/${ver}`);
|
|
21612
21739
|
if (!res.ok) return res;
|
|
21613
21740
|
const pkg = res.data;
|
|
21614
|
-
const
|
|
21741
|
+
const depEntries = Object.entries(pkg.dependencies ?? {});
|
|
21615
21742
|
const MAX_CONCURRENT = 10;
|
|
21616
21743
|
let active = 0;
|
|
21617
21744
|
const queue = [];
|
|
@@ -21629,25 +21756,32 @@ var dependencyTools = [
|
|
|
21629
21756
|
});
|
|
21630
21757
|
}
|
|
21631
21758
|
const depLicenses = await Promise.all(
|
|
21632
|
-
|
|
21633
|
-
const
|
|
21759
|
+
depEntries.map(async ([depName, depRange]) => {
|
|
21760
|
+
const abbrevRes = await runLimited(() => registryGetAbbreviated(`/${encPkg(depName)}`));
|
|
21761
|
+
if (!abbrevRes.ok) return { name: depName, version: depRange, license: "FETCH_ERROR" };
|
|
21762
|
+
const abbrev = abbrevRes.data;
|
|
21763
|
+
const available = Object.keys(abbrev.versions);
|
|
21764
|
+
const resolved = maxSatisfying(available, depRange) ?? abbrev["dist-tags"]?.latest;
|
|
21765
|
+
if (!resolved) return { name: depName, version: depRange, license: "UNKNOWN" };
|
|
21766
|
+
const verRes = await runLimited(() => registryGet(`/${encPkg(depName)}/${resolved}`));
|
|
21634
21767
|
return {
|
|
21635
21768
|
name: depName,
|
|
21636
|
-
|
|
21769
|
+
version: resolved,
|
|
21770
|
+
license: verRes.ok ? verRes.data?.license ?? "UNKNOWN" : "FETCH_ERROR"
|
|
21637
21771
|
};
|
|
21638
21772
|
})
|
|
21639
21773
|
);
|
|
21640
|
-
const
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
const flagged = results.filter((r) => !PERMISSIVE.has(r.license));
|
|
21774
|
+
const allowedSet = new Set(
|
|
21775
|
+
input.allowed ?? ["MIT", "ISC", "BSD-2-Clause", "BSD-3-Clause", "Apache-2.0", "0BSD", "Unlicense"]
|
|
21776
|
+
);
|
|
21777
|
+
const results = [{ name: pkg.name, version: pkg.version, license: pkg.license ?? "UNKNOWN" }, ...depLicenses];
|
|
21778
|
+
const flagged = results.filter((r) => !allowedSet.has(r.license));
|
|
21646
21779
|
return {
|
|
21647
21780
|
ok: true,
|
|
21648
21781
|
status: 200,
|
|
21649
21782
|
data: {
|
|
21650
21783
|
total: results.length,
|
|
21784
|
+
allowed: [...allowedSet],
|
|
21651
21785
|
flagged: flagged.length,
|
|
21652
21786
|
packages: results,
|
|
21653
21787
|
issues: flagged.length > 0 ? flagged : void 0
|
|
@@ -21728,61 +21862,12 @@ var downloadTools = [
|
|
|
21728
21862
|
openWorldHint: true
|
|
21729
21863
|
},
|
|
21730
21864
|
inputSchema: external_exports.object({
|
|
21731
|
-
name: external_exports.string().describe("Package name")
|
|
21732
|
-
|
|
21733
|
-
handler: async (input) => {
|
|
21734
|
-
return downloadsGet(`/versions/${encPkg(input.name)}/last-week`);
|
|
21735
|
-
}
|
|
21736
|
-
}
|
|
21737
|
-
];
|
|
21738
|
-
|
|
21739
|
-
// src/tools/hooks.ts
|
|
21740
|
-
var hookTools = [
|
|
21741
|
-
{
|
|
21742
|
-
name: "npm_hooks",
|
|
21743
|
-
description: "List all npm webhooks configured for the authenticated user. Shows hook type (package, scope, or owner), endpoint URL, delivery status, and last response code.",
|
|
21744
|
-
annotations: {
|
|
21745
|
-
title: "List npm hooks",
|
|
21746
|
-
readOnlyHint: true,
|
|
21747
|
-
destructiveHint: false,
|
|
21748
|
-
idempotentHint: true,
|
|
21749
|
-
openWorldHint: true
|
|
21750
|
-
},
|
|
21751
|
-
inputSchema: external_exports.object({
|
|
21752
|
-
package: external_exports.string().optional().describe("Filter hooks by package name"),
|
|
21753
|
-
limit: external_exports.number().min(1).max(100).optional().describe("Max results (default: 25)"),
|
|
21754
|
-
offset: external_exports.number().min(0).optional().describe("Pagination offset")
|
|
21865
|
+
name: external_exports.string().describe("Package name"),
|
|
21866
|
+
period: external_exports.string().optional().describe("Period: 'last-day', 'last-week', 'last-month' (default: 'last-week')")
|
|
21755
21867
|
}),
|
|
21756
21868
|
handler: async (input) => {
|
|
21757
|
-
const
|
|
21758
|
-
|
|
21759
|
-
const params = new URLSearchParams();
|
|
21760
|
-
if (input.package) params.set("package", input.package);
|
|
21761
|
-
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
21762
|
-
if (input.offset !== void 0) params.set("offset", String(input.offset));
|
|
21763
|
-
const qs = params.toString();
|
|
21764
|
-
const path = `/-/npm/v1/hooks${qs ? `?${qs}` : ""}`;
|
|
21765
|
-
const res = await registryGetAuth(path);
|
|
21766
|
-
if (!res.ok) return res;
|
|
21767
|
-
const data = res.data;
|
|
21768
|
-
return {
|
|
21769
|
-
ok: true,
|
|
21770
|
-
status: 200,
|
|
21771
|
-
data: {
|
|
21772
|
-
total: data.total,
|
|
21773
|
-
hooks: data.objects.map((h) => ({
|
|
21774
|
-
id: h.id,
|
|
21775
|
-
type: h.type,
|
|
21776
|
-
name: h.name,
|
|
21777
|
-
endpoint: h.endpoint,
|
|
21778
|
-
status: h.status,
|
|
21779
|
-
lastDelivery: h.last_delivery,
|
|
21780
|
-
lastResponseCode: h.response_code,
|
|
21781
|
-
created: h.created,
|
|
21782
|
-
updated: h.updated
|
|
21783
|
-
}))
|
|
21784
|
-
}
|
|
21785
|
-
};
|
|
21869
|
+
const period = input.period ?? "last-week";
|
|
21870
|
+
return downloadsGet(`/versions/${encPkg(input.name)}/${period}`);
|
|
21786
21871
|
}
|
|
21787
21872
|
}
|
|
21788
21873
|
];
|
|
@@ -22011,7 +22096,7 @@ var packageTools = [
|
|
|
22011
22096
|
},
|
|
22012
22097
|
{
|
|
22013
22098
|
name: "npm_versions",
|
|
22014
|
-
description: "List
|
|
22099
|
+
description: "List published versions of a package with their publish dates, ordered newest first. Returns up to `limit` versions (default 50). Set limit=0 to return all.",
|
|
22015
22100
|
annotations: {
|
|
22016
22101
|
title: "List versions",
|
|
22017
22102
|
readOnlyHint: true,
|
|
@@ -22020,25 +22105,29 @@ var packageTools = [
|
|
|
22020
22105
|
openWorldHint: true
|
|
22021
22106
|
},
|
|
22022
22107
|
inputSchema: external_exports.object({
|
|
22023
|
-
name: external_exports.string().describe("Package name")
|
|
22108
|
+
name: external_exports.string().describe("Package name"),
|
|
22109
|
+
limit: external_exports.number().min(0).optional().describe("Max versions to return, newest first (default 50, 0 = all)")
|
|
22024
22110
|
}),
|
|
22025
22111
|
handler: async (input) => {
|
|
22026
22112
|
const res = await registryGet(`/${encPkg(input.name)}`);
|
|
22027
22113
|
if (!res.ok) return res;
|
|
22028
22114
|
const pkg = res.data;
|
|
22029
|
-
const
|
|
22115
|
+
const limit = input.limit ?? 50;
|
|
22116
|
+
const allVersions = Object.keys(pkg.versions).map((v) => ({
|
|
22030
22117
|
version: v,
|
|
22031
22118
|
date: pkg.time[v],
|
|
22032
22119
|
deprecated: pkg.versions[v].deprecated,
|
|
22033
22120
|
npmUser: pkg.versions[v]._npmUser?.name
|
|
22034
22121
|
})).sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
22122
|
+
const versions = limit > 0 ? allVersions.slice(0, limit) : allVersions;
|
|
22035
22123
|
return {
|
|
22036
22124
|
ok: true,
|
|
22037
22125
|
status: 200,
|
|
22038
22126
|
data: {
|
|
22039
22127
|
name: pkg.name,
|
|
22040
22128
|
distTags: pkg["dist-tags"],
|
|
22041
|
-
total:
|
|
22129
|
+
total: allVersions.length,
|
|
22130
|
+
showing: versions.length,
|
|
22042
22131
|
versions
|
|
22043
22132
|
}
|
|
22044
22133
|
};
|
|
@@ -22083,6 +22172,61 @@ var packageTools = [
|
|
|
22083
22172
|
handler: async (input) => {
|
|
22084
22173
|
return registryGet(`/-/package/${encPkg(input.name)}/dist-tags`);
|
|
22085
22174
|
}
|
|
22175
|
+
},
|
|
22176
|
+
{
|
|
22177
|
+
name: "npm_types",
|
|
22178
|
+
description: "Check TypeScript type support for a package \u2014 whether it ships built-in types (types/typings field) or has a DefinitelyTyped companion (@types/* package).",
|
|
22179
|
+
annotations: {
|
|
22180
|
+
title: "Check TypeScript types",
|
|
22181
|
+
readOnlyHint: true,
|
|
22182
|
+
destructiveHint: false,
|
|
22183
|
+
idempotentHint: true,
|
|
22184
|
+
openWorldHint: true
|
|
22185
|
+
},
|
|
22186
|
+
inputSchema: external_exports.object({
|
|
22187
|
+
name: external_exports.string().describe("Package name (e.g. 'express' or '@anthropic-ai/sdk')"),
|
|
22188
|
+
version: external_exports.string().optional().describe("Semver version or dist-tag (default: 'latest')")
|
|
22189
|
+
}),
|
|
22190
|
+
handler: async (input) => {
|
|
22191
|
+
const ver = input.version ?? "latest";
|
|
22192
|
+
let typesPackage;
|
|
22193
|
+
if (input.name.startsWith("@")) {
|
|
22194
|
+
const withoutAt = input.name.slice(1);
|
|
22195
|
+
typesPackage = `@types/${withoutAt.replace("/", "__")}`;
|
|
22196
|
+
} else {
|
|
22197
|
+
typesPackage = `@types/${input.name}`;
|
|
22198
|
+
}
|
|
22199
|
+
const [versionRes, typesRes] = await Promise.all([
|
|
22200
|
+
registryGet(`/${encPkg(input.name)}/${ver}`),
|
|
22201
|
+
registryGet(`/${encPkg(typesPackage)}`)
|
|
22202
|
+
]);
|
|
22203
|
+
if (!versionRes.ok) return versionRes;
|
|
22204
|
+
const v = versionRes.data;
|
|
22205
|
+
const hasBuiltinTypes = !!(v.types || v.typings);
|
|
22206
|
+
const typesEntry = hasBuiltinTypes ? v.types ?? v.typings : void 0;
|
|
22207
|
+
const hasTypesPackage = typesRes.ok;
|
|
22208
|
+
const typesPackageLatest = hasTypesPackage ? typesRes.data?.["dist-tags"]?.latest : void 0;
|
|
22209
|
+
let recommendation;
|
|
22210
|
+
if (hasBuiltinTypes) {
|
|
22211
|
+
recommendation = "Built-in types included \u2014 no additional install needed.";
|
|
22212
|
+
} else if (hasTypesPackage) {
|
|
22213
|
+
recommendation = `Install types separately: npm install -D ${typesPackage}`;
|
|
22214
|
+
} else {
|
|
22215
|
+
recommendation = "No TypeScript types available (built-in or @types).";
|
|
22216
|
+
}
|
|
22217
|
+
return {
|
|
22218
|
+
ok: true,
|
|
22219
|
+
status: 200,
|
|
22220
|
+
data: {
|
|
22221
|
+
name: v.name,
|
|
22222
|
+
version: v.version,
|
|
22223
|
+
builtinTypes: hasBuiltinTypes,
|
|
22224
|
+
typesEntry,
|
|
22225
|
+
typesPackage: hasTypesPackage ? { name: typesPackage, latest: typesPackageLatest } : null,
|
|
22226
|
+
recommendation
|
|
22227
|
+
}
|
|
22228
|
+
};
|
|
22229
|
+
}
|
|
22086
22230
|
}
|
|
22087
22231
|
];
|
|
22088
22232
|
|
|
@@ -22149,7 +22293,7 @@ var registryTools = [
|
|
|
22149
22293
|
},
|
|
22150
22294
|
{
|
|
22151
22295
|
name: "npm_recent_changes",
|
|
22152
|
-
description: "Get the most recent package publishes/updates from the npm registry via the CouchDB changes feed.",
|
|
22296
|
+
description: "Get the most recent package publishes/updates from the npm registry via the CouchDB changes feed. Note: uses replicate.npmjs.com which may have intermittent availability.",
|
|
22153
22297
|
annotations: {
|
|
22154
22298
|
title: "Recent registry changes",
|
|
22155
22299
|
readOnlyHint: true,
|
|
@@ -22162,21 +22306,20 @@ var registryTools = [
|
|
|
22162
22306
|
}),
|
|
22163
22307
|
handler: async (input) => {
|
|
22164
22308
|
const limit = input.limit ?? 25;
|
|
22165
|
-
const dbRes = await
|
|
22166
|
-
|
|
22167
|
-
|
|
22168
|
-
|
|
22309
|
+
const [dbRes, changesRes] = await Promise.all([
|
|
22310
|
+
replicateGet("/"),
|
|
22311
|
+
replicateGet(`/_changes?limit=${limit}&descending=true`)
|
|
22312
|
+
]);
|
|
22169
22313
|
if (!changesRes.ok) return changesRes;
|
|
22170
22314
|
const changes = changesRes.data.results.map((r) => ({
|
|
22171
22315
|
package: r.id,
|
|
22172
|
-
seq: r.seq,
|
|
22173
22316
|
rev: r.changes[0]?.rev
|
|
22174
22317
|
}));
|
|
22175
22318
|
return {
|
|
22176
22319
|
ok: true,
|
|
22177
22320
|
status: 200,
|
|
22178
22321
|
data: {
|
|
22179
|
-
totalPackages: dbRes.data.doc_count,
|
|
22322
|
+
totalPackages: dbRes.ok ? dbRes.data.doc_count : null,
|
|
22180
22323
|
changes
|
|
22181
22324
|
}
|
|
22182
22325
|
};
|
|
@@ -22219,12 +22362,10 @@ var searchTools = [
|
|
|
22219
22362
|
description: obj.package.description,
|
|
22220
22363
|
date: obj.package.date,
|
|
22221
22364
|
license: obj.package.license,
|
|
22222
|
-
publisher: obj.package.publisher
|
|
22365
|
+
publisher: obj.package.publisher,
|
|
22223
22366
|
keywords: obj.package.keywords,
|
|
22224
22367
|
links: obj.package.links,
|
|
22225
|
-
score: obj.score.detail
|
|
22226
|
-
downloads: obj.downloads,
|
|
22227
|
-
dependents: obj.dependents
|
|
22368
|
+
score: obj.score.detail
|
|
22228
22369
|
}));
|
|
22229
22370
|
return { ok: true, status: 200, data: { total: res.data.total, results } };
|
|
22230
22371
|
}
|
|
@@ -22235,7 +22376,7 @@ var searchTools = [
|
|
|
22235
22376
|
var securityTools = [
|
|
22236
22377
|
{
|
|
22237
22378
|
name: "npm_audit",
|
|
22238
|
-
description: "
|
|
22379
|
+
description: "Quick vulnerability check for specific packages and versions using the bulk advisory API. Returns matching advisories with severity, CVEs, and patched versions. For richer detail (CVSS scores, CWEs, fix recommendations), use npm_audit_deep instead.",
|
|
22239
22380
|
annotations: {
|
|
22240
22381
|
title: "Audit packages",
|
|
22241
22382
|
readOnlyHint: true,
|
|
@@ -22252,7 +22393,7 @@ var securityTools = [
|
|
|
22252
22393
|
},
|
|
22253
22394
|
{
|
|
22254
22395
|
name: "npm_audit_deep",
|
|
22255
|
-
description: "
|
|
22396
|
+
description: "Full security audit on a dependency set \u2014 returns detailed advisories with CVSS scores, CWEs, affected version ranges, fix recommendations, and full vulnerability metadata. Uses the npm audit v1 endpoint which provides richer detail than the bulk advisory API (npm_audit). Requires you to provide the dependency map (use npm_dependencies to get it first).",
|
|
22256
22397
|
annotations: {
|
|
22257
22398
|
title: "Deep security audit",
|
|
22258
22399
|
readOnlyHint: true,
|
|
@@ -22294,6 +22435,60 @@ var securityTools = [
|
|
|
22294
22435
|
}
|
|
22295
22436
|
];
|
|
22296
22437
|
|
|
22438
|
+
// src/tools/trust.ts
|
|
22439
|
+
var trustTools = [
|
|
22440
|
+
{
|
|
22441
|
+
name: "npm_trusted_publishers",
|
|
22442
|
+
description: "List trusted publishing configurations for a package. Shows OIDC trust relationships with CI/CD providers (GitHub Actions, GitLab CI, CircleCI) that allow tokenless publishing. Requires authentication with write access to the package.",
|
|
22443
|
+
annotations: {
|
|
22444
|
+
title: "List trusted publishers",
|
|
22445
|
+
readOnlyHint: true,
|
|
22446
|
+
destructiveHint: false,
|
|
22447
|
+
idempotentHint: true,
|
|
22448
|
+
openWorldHint: true
|
|
22449
|
+
},
|
|
22450
|
+
inputSchema: external_exports.object({
|
|
22451
|
+
name: external_exports.string().describe("Package name (e.g. 'express' or '@yawlabs/npmjs-mcp')")
|
|
22452
|
+
}),
|
|
22453
|
+
handler: async (input) => {
|
|
22454
|
+
const authErr = requireAuth();
|
|
22455
|
+
if (authErr) return authErr;
|
|
22456
|
+
const res = await registryGetAuth(`/-/package/${encPkg(input.name)}/trust`);
|
|
22457
|
+
if (!res.ok) return res;
|
|
22458
|
+
const configs = (res.data ?? []).map((c) => {
|
|
22459
|
+
const result = {
|
|
22460
|
+
id: c.id,
|
|
22461
|
+
provider: c.type
|
|
22462
|
+
};
|
|
22463
|
+
if (c.type === "github") {
|
|
22464
|
+
result.repository = c.claims?.repository;
|
|
22465
|
+
const workflowRef = c.claims?.workflow_ref;
|
|
22466
|
+
result.workflowFile = workflowRef?.file;
|
|
22467
|
+
result.environment = c.claims?.environment;
|
|
22468
|
+
} else if (c.type === "gitlab") {
|
|
22469
|
+
result.project = c.claims?.project_path;
|
|
22470
|
+
const configRef = c.claims?.ci_config_ref_uri;
|
|
22471
|
+
result.configFile = configRef?.file;
|
|
22472
|
+
result.environment = c.claims?.environment;
|
|
22473
|
+
} else if (c.type === "circleci") {
|
|
22474
|
+
result.project = c.claims?.project_id;
|
|
22475
|
+
result.context = c.claims?.context_ids;
|
|
22476
|
+
}
|
|
22477
|
+
return result;
|
|
22478
|
+
});
|
|
22479
|
+
return {
|
|
22480
|
+
ok: true,
|
|
22481
|
+
status: 200,
|
|
22482
|
+
data: {
|
|
22483
|
+
package: input.name,
|
|
22484
|
+
trustedPublisherCount: configs.length,
|
|
22485
|
+
trustedPublishers: configs
|
|
22486
|
+
}
|
|
22487
|
+
};
|
|
22488
|
+
}
|
|
22489
|
+
}
|
|
22490
|
+
];
|
|
22491
|
+
|
|
22297
22492
|
// src/tools/workflows.ts
|
|
22298
22493
|
var workflowTools = [
|
|
22299
22494
|
{
|
|
@@ -22568,7 +22763,7 @@ var workflowTools = [
|
|
|
22568
22763
|
];
|
|
22569
22764
|
|
|
22570
22765
|
// src/index.ts
|
|
22571
|
-
var version2 = true ? "0.
|
|
22766
|
+
var version2 = true ? "0.4.0" : (await null).createRequire(import.meta.url)("../package.json").version;
|
|
22572
22767
|
var subcommand = process.argv[2];
|
|
22573
22768
|
if (subcommand === "version" || subcommand === "--version") {
|
|
22574
22769
|
console.log(version2);
|
|
@@ -22586,7 +22781,7 @@ var allTools = [
|
|
|
22586
22781
|
...orgTools,
|
|
22587
22782
|
...accessTools,
|
|
22588
22783
|
...provenanceTools,
|
|
22589
|
-
...
|
|
22784
|
+
...trustTools,
|
|
22590
22785
|
...workflowTools
|
|
22591
22786
|
];
|
|
22592
22787
|
var server = new McpServer({
|
package/package.json
CHANGED