@yawlabs/npmjs-mcp 0.11.14 → 0.12.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/README.md +1 -1
- package/dist/index.js +56 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
Built and maintained by [Yaw Labs](https://yaw.sh).
|
|
11
11
|
|
|
12
|
-
[](yaw
|
|
12
|
+
[](https://yaw.sh/mcp/install?name=npm&command=npx&args=-y%2C%40yawlabs%2Fnpmjs-mcp&description=npm%20registry%20-%20package%20intel%2C%20security%2C%20dependency%20analysis%2C%20write%20ops&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Fnpmjs-mcp)
|
|
13
13
|
|
|
14
14
|
One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.
|
|
15
15
|
|
package/dist/index.js
CHANGED
|
@@ -31347,12 +31347,23 @@ function translateError(res, context) {
|
|
|
31347
31347
|
...res,
|
|
31348
31348
|
error: `Rate limited${opPart}. Retried automatically and still failed \u2014 wait longer and retry, or contact npm support if this persists. Raw: ${res.error}`
|
|
31349
31349
|
};
|
|
31350
|
+
case 409:
|
|
31351
|
+
return {
|
|
31352
|
+
...res,
|
|
31353
|
+
error: `Version conflict${pkgPart}${opPart}. The package metadata changed between read and write (a concurrent publish, deprecate, or registry _rev bump). Re-run the operation \u2014 it re-fetches the current _rev each call. Raw: ${res.error}`
|
|
31354
|
+
};
|
|
31350
31355
|
case 0:
|
|
31351
31356
|
return {
|
|
31352
31357
|
...res,
|
|
31353
31358
|
error: `Network error${opPart}. Could not reach the registry. Raw: ${res.error}`
|
|
31354
31359
|
};
|
|
31355
31360
|
default:
|
|
31361
|
+
if (res.status >= 500) {
|
|
31362
|
+
return {
|
|
31363
|
+
...res,
|
|
31364
|
+
error: `Registry server error${pkgPart}${opPart} (HTTP ${res.status}). Retried automatically and still failed \u2014 the registry is likely having a transient outage. Wait and retry; check https://status.npmjs.org if it persists. Raw: ${res.error}`
|
|
31365
|
+
};
|
|
31366
|
+
}
|
|
31356
31367
|
return res;
|
|
31357
31368
|
}
|
|
31358
31369
|
}
|
|
@@ -31383,7 +31394,7 @@ var accessTools = [
|
|
|
31383
31394
|
if (authErr) return authErr;
|
|
31384
31395
|
const res = await registryGetAuth(`/-/package/${encPkg(input.name)}/collaborators`);
|
|
31385
31396
|
if (!res.ok) return translateError(res, { pkg: input.name, op: "collaborators" });
|
|
31386
|
-
const collaborators = Object.entries(res.data).map(([username, permissions]) => ({
|
|
31397
|
+
const collaborators = Object.entries(res.data ?? {}).map(([username, permissions]) => ({
|
|
31387
31398
|
username,
|
|
31388
31399
|
permissions
|
|
31389
31400
|
}));
|
|
@@ -31431,7 +31442,7 @@ var accessTools = [
|
|
|
31431
31442
|
result.access = accessRes.data;
|
|
31432
31443
|
}
|
|
31433
31444
|
if (collabRes.ok) {
|
|
31434
|
-
result.collaborators = Object.entries(collabRes.data).map(([username, permissions]) => ({
|
|
31445
|
+
result.collaborators = Object.entries(collabRes.data ?? {}).map(([username, permissions]) => ({
|
|
31435
31446
|
username,
|
|
31436
31447
|
permissions
|
|
31437
31448
|
}));
|
|
@@ -31499,7 +31510,10 @@ var analysisTools = [
|
|
|
31499
31510
|
latest,
|
|
31500
31511
|
license: pkg.license ?? latestVersion?.license,
|
|
31501
31512
|
maintainers: pkg.maintainers?.map((m) => m.name),
|
|
31502
|
-
|
|
31513
|
+
// Guard on data presence, not just .ok: a 2xx with an empty body yields
|
|
31514
|
+
// ok:true with no data (api.ts), and dlRes.data!.downloads would throw
|
|
31515
|
+
// and crash the whole compare. Degrade to null instead.
|
|
31516
|
+
weeklyDownloads: dlRes.ok && dlRes.data ? dlRes.data.downloads : null,
|
|
31503
31517
|
versionCount: versionKeys.length,
|
|
31504
31518
|
created: pkg.time.created,
|
|
31505
31519
|
lastPublish: latest ? pkg.time[latest] : void 0,
|
|
@@ -31578,8 +31592,10 @@ var analysisTools = [
|
|
|
31578
31592
|
name: pkg.name,
|
|
31579
31593
|
latest,
|
|
31580
31594
|
signals: {
|
|
31581
|
-
|
|
31582
|
-
|
|
31595
|
+
// Guard on data presence, not just .ok: an empty-body 2xx yields
|
|
31596
|
+
// ok:true with no data (api.ts); degrade to null rather than throw.
|
|
31597
|
+
weeklyDownloads: dlWeekRes.ok && dlWeekRes.data ? dlWeekRes.data.downloads : null,
|
|
31598
|
+
monthlyDownloads: dlMonthRes.ok && dlMonthRes.data ? dlMonthRes.data.downloads : null,
|
|
31583
31599
|
maintainerCount: pkg.maintainers?.length ?? 0,
|
|
31584
31600
|
versionCount: versionKeys.length,
|
|
31585
31601
|
daysSinceLastPublish,
|
|
@@ -31813,12 +31829,20 @@ var authTools = [
|
|
|
31813
31829
|
error: `Token failed /-/whoami check. Token is invalid, expired, or revoked. Create a new one at https://www.npmjs.com/settings/~/tokens. Raw: ${whoami.error}`
|
|
31814
31830
|
};
|
|
31815
31831
|
}
|
|
31816
|
-
|
|
31817
|
-
|
|
31818
|
-
|
|
31819
|
-
|
|
31820
|
-
|
|
31821
|
-
|
|
31832
|
+
let tfa;
|
|
31833
|
+
if (!profile.ok) {
|
|
31834
|
+
tfa = {
|
|
31835
|
+
unknown: true,
|
|
31836
|
+
warning: `2FA status unknown: profile lookup failed (HTTP ${profile.status}). Token is valid (whoami passed) but write-readiness could not be fully assessed. Raw: ${profile.error}`
|
|
31837
|
+
};
|
|
31838
|
+
} else {
|
|
31839
|
+
const tfaData = profile.data?.tfa;
|
|
31840
|
+
tfa = tfaData ? {
|
|
31841
|
+
enabled: !tfaData.pending,
|
|
31842
|
+
mode: tfaData.mode,
|
|
31843
|
+
...tfaData.pending ? { pending: true } : {}
|
|
31844
|
+
} : { enabled: false };
|
|
31845
|
+
}
|
|
31822
31846
|
return {
|
|
31823
31847
|
ok: true,
|
|
31824
31848
|
status: 200,
|
|
@@ -32753,7 +32777,7 @@ var provenanceTools = [
|
|
|
32753
32777
|
`/-/npm/v1/attestations/${encPkg(input.name)}@${encodeURIComponent(input.version)}`
|
|
32754
32778
|
);
|
|
32755
32779
|
if (!res.ok) return translateError(res, { pkg: input.name, op: `provenance ${input.version}` });
|
|
32756
|
-
const attestations = (res.data
|
|
32780
|
+
const attestations = (res.data?.attestations ?? []).map((a) => ({
|
|
32757
32781
|
predicateType: a.predicateType,
|
|
32758
32782
|
bundle: a.bundle
|
|
32759
32783
|
}));
|
|
@@ -32814,7 +32838,7 @@ var registryTools = [
|
|
|
32814
32838
|
replicateGet(`/_changes?limit=${limit}&descending=true`)
|
|
32815
32839
|
]);
|
|
32816
32840
|
if (!changesRes.ok) return translateError(changesRes, { op: "recent_changes" });
|
|
32817
|
-
const changes = changesRes.data
|
|
32841
|
+
const changes = (changesRes.data?.results ?? []).map((r) => ({
|
|
32818
32842
|
package: r.id,
|
|
32819
32843
|
rev: r.changes[0]?.rev
|
|
32820
32844
|
}));
|
|
@@ -32822,7 +32846,13 @@ var registryTools = [
|
|
|
32822
32846
|
ok: true,
|
|
32823
32847
|
status: 200,
|
|
32824
32848
|
data: {
|
|
32825
|
-
totalPackages
|
|
32849
|
+
// `totalPackages` is the registry doc-count from replicate.npmjs.com
|
|
32850
|
+
// (the entire npm registry, ~3M) -- NOT the count of returned
|
|
32851
|
+
// changes. `changes.length` is the per-call result size. The field
|
|
32852
|
+
// name reads as if it were a per-call count; this comment pins the
|
|
32853
|
+
// semantic so a consumer reading "totalPackages: 50" doesn't assume
|
|
32854
|
+
// only 50 packages exist on the registry.
|
|
32855
|
+
totalPackages: dbRes.data?.doc_count ?? null,
|
|
32826
32856
|
changes
|
|
32827
32857
|
}
|
|
32828
32858
|
};
|
|
@@ -32921,6 +32951,13 @@ var searchTools = [
|
|
|
32921
32951
|
maintenance: external_exports.number().min(0).max(1).optional().describe("Weight for maintenance score (0-1)")
|
|
32922
32952
|
}),
|
|
32923
32953
|
handler: async (input) => {
|
|
32954
|
+
if (input.query.trim() === "") {
|
|
32955
|
+
return {
|
|
32956
|
+
ok: false,
|
|
32957
|
+
status: 400,
|
|
32958
|
+
error: "Query cannot be empty. Provide a search term or qualifier (e.g. 'mcp', 'keywords:react')."
|
|
32959
|
+
};
|
|
32960
|
+
}
|
|
32924
32961
|
const params = new URLSearchParams({ text: input.query });
|
|
32925
32962
|
if (input.size !== void 0) params.set("size", String(input.size));
|
|
32926
32963
|
if (input.from !== void 0) params.set("from", String(input.from));
|
|
@@ -32929,7 +32966,8 @@ var searchTools = [
|
|
|
32929
32966
|
if (input.maintenance !== void 0) params.set("maintenance", String(input.maintenance));
|
|
32930
32967
|
const res = await registryGet(`/-/v1/search?${params}`);
|
|
32931
32968
|
if (!res.ok) return translateError(res, { op: `search "${input.query}"` });
|
|
32932
|
-
const
|
|
32969
|
+
const objects = res.data?.objects ?? [];
|
|
32970
|
+
const results = objects.map((obj) => ({
|
|
32933
32971
|
name: obj.package.name,
|
|
32934
32972
|
version: obj.package.version,
|
|
32935
32973
|
description: obj.package.description,
|
|
@@ -32940,7 +32978,7 @@ var searchTools = [
|
|
|
32940
32978
|
links: obj.package.links,
|
|
32941
32979
|
score: obj.score.detail
|
|
32942
32980
|
}));
|
|
32943
|
-
return { ok: true, status: 200, data: { total: res.data.
|
|
32981
|
+
return { ok: true, status: 200, data: { total: res.data?.total ?? objects.length, results } };
|
|
32944
32982
|
}
|
|
32945
32983
|
}
|
|
32946
32984
|
];
|
|
@@ -34081,7 +34119,7 @@ var writeTools = [
|
|
|
34081
34119
|
// ───────────────────────────────────────────────────────
|
|
34082
34120
|
{
|
|
34083
34121
|
name: "npm_team_delete",
|
|
34084
|
-
description: "Delete a team. Team is passed as '@scope:team'. Revokes all package permissions that team held. Requires confirm: true \u2014 this removes the team and all its package grants in one call.",
|
|
34122
|
+
description: "Delete a team. Team is passed as '@scope:team'. Revokes all package permissions that team held, and team memberships are also removed. Requires confirm: true \u2014 this removes the team and all its package grants in one call. List the team's current grants with npm_team_packages first if you need to preserve them.",
|
|
34085
34123
|
annotations: {
|
|
34086
34124
|
title: "Delete team",
|
|
34087
34125
|
readOnlyHint: false,
|
|
@@ -34293,7 +34331,7 @@ var writeTools = [
|
|
|
34293
34331
|
];
|
|
34294
34332
|
|
|
34295
34333
|
// src/index.ts
|
|
34296
|
-
var version2 = true ? "0.
|
|
34334
|
+
var version2 = true ? "0.12.0" : (await null).createRequire(import.meta.url)("../package.json").version;
|
|
34297
34335
|
var subcommand = process.argv[2];
|
|
34298
34336
|
if (subcommand === "version" || subcommand === "--version" || subcommand === "-v" || subcommand === "-V") {
|
|
34299
34337
|
console.log(version2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yawlabs/npmjs-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"mcpName": "io.github.YawLabs/npmjs-mcp",
|
|
5
5
|
"description": "npm registry MCP server — package intelligence, security audits, and dependency analysis for AI assistants",
|
|
6
6
|
"license": "MIT",
|