hound-mcp 0.2.0 → 0.2.2
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 +60 -169
- package/dist/index.js +103 -86
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -6,45 +6,9 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
6
6
|
// src/server.ts
|
|
7
7
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
|
|
9
|
-
// src/prompts/
|
|
9
|
+
// src/prompts/package_evaluation.ts
|
|
10
10
|
import { z } from "zod/v4";
|
|
11
|
-
function
|
|
12
|
-
server.registerPrompt(
|
|
13
|
-
"security_audit",
|
|
14
|
-
{
|
|
15
|
-
description: "Run a full security audit on the current project's dependencies. Scans for vulnerabilities, license issues, and typosquat risks across your entire dependency tree.",
|
|
16
|
-
argsSchema: {
|
|
17
|
-
ecosystem: z.string().optional().describe("Package ecosystem (npm, pypi, cargo, etc). Auto-detected if omitted.")
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
({ ecosystem }) => {
|
|
21
|
-
const ecoNote = ecosystem ? ` The project uses ${ecosystem}.` : "";
|
|
22
|
-
return {
|
|
23
|
-
messages: [
|
|
24
|
-
{
|
|
25
|
-
role: "user",
|
|
26
|
-
content: {
|
|
27
|
-
type: "text",
|
|
28
|
-
text: `Please run a comprehensive security audit on this project's dependencies.${ecoNote}
|
|
29
|
-
|
|
30
|
-
Follow these steps:
|
|
31
|
-
1. Use \`hound_popular\` to check the most commonly used packages in this ecosystem for known vulnerabilities \u2014 this gives a quick baseline.
|
|
32
|
-
2. For any specific packages you can identify in the project, use \`hound_vulns\` to check each one for CVEs and advisories.
|
|
33
|
-
3. Use \`hound_inspect\` on the 3-5 most critical dependencies to check their licenses, OpenSSF Scorecard, and GitHub health.
|
|
34
|
-
4. For any package names that look unusual or unfamiliar, use \`hound_typosquat\` to check for potential typosquatting.
|
|
35
|
-
5. If any vulnerabilities are found, use \`hound_advisories\` to get full details and fix guidance.
|
|
36
|
-
|
|
37
|
-
Summarize findings as:
|
|
38
|
-
- **Critical / High** vulnerabilities that need immediate attention
|
|
39
|
-
- **License risks** (copyleft licenses, unknown licenses)
|
|
40
|
-
- **Health concerns** (abandoned packages, low Scorecard scores)
|
|
41
|
-
- **Recommended actions** with specific version upgrades where available`
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
]
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
);
|
|
11
|
+
function packageEvaluationRegisterPrompt(server) {
|
|
48
12
|
server.registerPrompt(
|
|
49
13
|
"package_evaluation",
|
|
50
14
|
{
|
|
@@ -80,12 +44,17 @@ Give me a clear **GO / NO-GO / CONDITIONAL** recommendation with reasoning. If c
|
|
|
80
44
|
};
|
|
81
45
|
}
|
|
82
46
|
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/prompts/pre_release_check.ts
|
|
50
|
+
import { z as z2 } from "zod/v4";
|
|
51
|
+
function preReleaseCheckRegisterPrompt(server) {
|
|
83
52
|
server.registerPrompt(
|
|
84
53
|
"pre_release_check",
|
|
85
54
|
{
|
|
86
55
|
description: "Run a pre-release dependency scan before shipping. Checks for vulnerabilities and license issues that could block a release.",
|
|
87
56
|
argsSchema: {
|
|
88
|
-
version:
|
|
57
|
+
version: z2.string().optional().describe("The version you are about to release, e.g. 1.2.0")
|
|
89
58
|
}
|
|
90
59
|
},
|
|
91
60
|
({ version }) => {
|
|
@@ -119,8 +88,56 @@ End with a clear **SAFE TO RELEASE** or **BLOCKED \u2014 fix these issues first*
|
|
|
119
88
|
);
|
|
120
89
|
}
|
|
121
90
|
|
|
91
|
+
// src/prompts/security_audit.ts
|
|
92
|
+
import { z as z3 } from "zod/v4";
|
|
93
|
+
function securityAuditRegisterPrompt(server) {
|
|
94
|
+
server.registerPrompt(
|
|
95
|
+
"security_audit",
|
|
96
|
+
{
|
|
97
|
+
description: "Run a full security audit on the current project's dependencies. Scans for vulnerabilities, license issues, and typosquat risks across your entire dependency tree.",
|
|
98
|
+
argsSchema: {
|
|
99
|
+
ecosystem: z3.string().optional().describe("Package ecosystem (npm, pypi, cargo, etc). Auto-detected if omitted.")
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
({ ecosystem }) => {
|
|
103
|
+
const ecoNote = ecosystem ? ` The project uses ${ecosystem}.` : "";
|
|
104
|
+
return {
|
|
105
|
+
messages: [
|
|
106
|
+
{
|
|
107
|
+
role: "user",
|
|
108
|
+
content: {
|
|
109
|
+
type: "text",
|
|
110
|
+
text: `Please run a comprehensive security audit on this project's dependencies.${ecoNote}
|
|
111
|
+
|
|
112
|
+
Follow these steps:
|
|
113
|
+
1. Use \`hound_popular\` to check the most commonly used packages in this ecosystem for known vulnerabilities \u2014 this gives a quick baseline.
|
|
114
|
+
2. For any specific packages you can identify in the project, use \`hound_vulns\` to check each one for CVEs and advisories.
|
|
115
|
+
3. Use \`hound_inspect\` on the 3-5 most critical dependencies to check their licenses, OpenSSF Scorecard, and GitHub health.
|
|
116
|
+
4. For any package names that look unusual or unfamiliar, use \`hound_typosquat\` to check for potential typosquatting.
|
|
117
|
+
5. If any vulnerabilities are found, use \`hound_advisories\` to get full details and fix guidance.
|
|
118
|
+
|
|
119
|
+
Summarize findings as:
|
|
120
|
+
- **Critical / High** vulnerabilities that need immediate attention
|
|
121
|
+
- **License risks** (copyleft licenses, unknown licenses)
|
|
122
|
+
- **Health concerns** (abandoned packages, low Scorecard scores)
|
|
123
|
+
- **Recommended actions** with specific version upgrades where available`
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/prompts/index.ts
|
|
133
|
+
function registerPrompts(server) {
|
|
134
|
+
securityAuditRegisterPrompt(server);
|
|
135
|
+
packageEvaluationRegisterPrompt(server);
|
|
136
|
+
preReleaseCheckRegisterPrompt(server);
|
|
137
|
+
}
|
|
138
|
+
|
|
122
139
|
// src/tools/advisories.ts
|
|
123
|
-
import { z as
|
|
140
|
+
import { z as z4 } from "zod/v4";
|
|
124
141
|
|
|
125
142
|
// src/api/depsdev.ts
|
|
126
143
|
var BASE_URL = "https://api.deps.dev/v3";
|
|
@@ -307,7 +324,7 @@ function register(server) {
|
|
|
307
324
|
{
|
|
308
325
|
description: "Get full details for a security advisory by ID (GHSA, CVE, or OSV ID). Returns title, severity, affected versions, fix versions, and references.",
|
|
309
326
|
inputSchema: {
|
|
310
|
-
id:
|
|
327
|
+
id: z4.string().describe("Advisory ID \u2014 e.g. GHSA-rv95-896h-c2vc, CVE-2024-29041, or any OSV ID")
|
|
311
328
|
}
|
|
312
329
|
},
|
|
313
330
|
async ({ id }) => {
|
|
@@ -402,7 +419,7 @@ function register(server) {
|
|
|
402
419
|
}
|
|
403
420
|
|
|
404
421
|
// src/tools/inspect.ts
|
|
405
|
-
import { z as
|
|
422
|
+
import { z as z5 } from "zod/v4";
|
|
406
423
|
var ECOSYSTEM_VALUES = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
407
424
|
function register2(server) {
|
|
408
425
|
return server.registerTool(
|
|
@@ -410,9 +427,9 @@ function register2(server) {
|
|
|
410
427
|
{
|
|
411
428
|
description: "Get a comprehensive profile of a package version: licenses, vulnerabilities, OpenSSF scorecard, GitHub stats, and dependency count \u2014 all in one call.",
|
|
412
429
|
inputSchema: {
|
|
413
|
-
name:
|
|
414
|
-
version:
|
|
415
|
-
ecosystem:
|
|
430
|
+
name: z5.string().describe("Package name"),
|
|
431
|
+
version: z5.string().describe("Package version"),
|
|
432
|
+
ecosystem: z5.enum(ECOSYSTEM_VALUES).default("npm").describe("Package ecosystem (default: npm)")
|
|
416
433
|
}
|
|
417
434
|
},
|
|
418
435
|
async ({ name, version, ecosystem }) => {
|
|
@@ -504,7 +521,7 @@ function scorecardGrade(score) {
|
|
|
504
521
|
}
|
|
505
522
|
|
|
506
523
|
// src/tools/popular.ts
|
|
507
|
-
import { z as
|
|
524
|
+
import { z as z6 } from "zod/v4";
|
|
508
525
|
var ECOSYSTEM_VALUES2 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
509
526
|
var POPULAR_DEFAULTS = {
|
|
510
527
|
npm: [
|
|
@@ -561,8 +578,8 @@ function register3(server) {
|
|
|
561
578
|
{
|
|
562
579
|
description: "Scan a list of popular (or user-specified) packages for known vulnerabilities. Quickly surface which widely-used packages in an ecosystem have open security issues.",
|
|
563
580
|
inputSchema: {
|
|
564
|
-
ecosystem:
|
|
565
|
-
packages:
|
|
581
|
+
ecosystem: z6.enum(ECOSYSTEM_VALUES2).default("npm").describe("Package ecosystem (default: npm)"),
|
|
582
|
+
packages: z6.array(z6.string()).optional().describe(
|
|
566
583
|
"Specific package names to check. If omitted, uses a curated list of popular packages for the ecosystem."
|
|
567
584
|
)
|
|
568
585
|
}
|
|
@@ -640,7 +657,7 @@ function register3(server) {
|
|
|
640
657
|
}
|
|
641
658
|
|
|
642
659
|
// src/tools/tree.ts
|
|
643
|
-
import { z as
|
|
660
|
+
import { z as z7 } from "zod/v4";
|
|
644
661
|
var ECOSYSTEM_VALUES3 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
645
662
|
function register4(server) {
|
|
646
663
|
return server.registerTool(
|
|
@@ -648,10 +665,10 @@ function register4(server) {
|
|
|
648
665
|
{
|
|
649
666
|
description: "Show the full resolved dependency tree for a package version, including all transitive dependencies with their depth and relation type.",
|
|
650
667
|
inputSchema: {
|
|
651
|
-
name:
|
|
652
|
-
version:
|
|
653
|
-
ecosystem:
|
|
654
|
-
maxDepth:
|
|
668
|
+
name: z7.string().describe("Package name"),
|
|
669
|
+
version: z7.string().describe("Package version"),
|
|
670
|
+
ecosystem: z7.enum(ECOSYSTEM_VALUES3).default("npm").describe("Package ecosystem (default: npm)"),
|
|
671
|
+
maxDepth: z7.number().int().min(1).max(10).default(3).describe("Maximum depth to display (default: 3, max: 10)")
|
|
655
672
|
}
|
|
656
673
|
},
|
|
657
674
|
async ({ name, version, ecosystem, maxDepth }) => {
|
|
@@ -670,8 +687,8 @@ function register4(server) {
|
|
|
670
687
|
}
|
|
671
688
|
const nodes = deps.nodes;
|
|
672
689
|
const edges = deps.edges;
|
|
673
|
-
const directCount = nodes.filter((n) => n.
|
|
674
|
-
const indirectCount = nodes.filter((n) => n.
|
|
690
|
+
const directCount = nodes.filter((n) => n.relation === "DIRECT").length;
|
|
691
|
+
const indirectCount = nodes.filter((n) => n.relation === "INDIRECT").length;
|
|
675
692
|
const totalCount = directCount + indirectCount;
|
|
676
693
|
const children = /* @__PURE__ */ new Map();
|
|
677
694
|
for (const edge of edges) {
|
|
@@ -709,7 +726,7 @@ function renderNode(lines, nodes, children, nodeIndex, depth, maxDepth, visited)
|
|
|
709
726
|
const isRoot = depth === 0;
|
|
710
727
|
const prefix = isRoot ? "" : "\u251C\u2500\u2500 ";
|
|
711
728
|
const errorSuffix = node.errors.length > 0 ? " \u26A0\uFE0F" : "";
|
|
712
|
-
lines.push(`${indent}${prefix}${node.
|
|
729
|
+
lines.push(`${indent}${prefix}${node.versionKey.name}@${node.versionKey.version}${errorSuffix}`);
|
|
713
730
|
if (depth >= maxDepth) {
|
|
714
731
|
const childCount = children.get(nodeIndex)?.length ?? 0;
|
|
715
732
|
if (childCount > 0) {
|
|
@@ -723,7 +740,7 @@ function renderNode(lines, nodes, children, nodeIndex, depth, maxDepth, visited)
|
|
|
723
740
|
}
|
|
724
741
|
|
|
725
742
|
// src/tools/typosquat.ts
|
|
726
|
-
import { z as
|
|
743
|
+
import { z as z8 } from "zod/v4";
|
|
727
744
|
var ECOSYSTEM_VALUES4 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
728
745
|
function generateTypos(name) {
|
|
729
746
|
const variants = /* @__PURE__ */ new Set();
|
|
@@ -756,8 +773,8 @@ function register5(server) {
|
|
|
756
773
|
{
|
|
757
774
|
description: "Check if a package name looks like a typosquat of a popular package. Generates likely typo variants and checks which ones exist in the registry.",
|
|
758
775
|
inputSchema: {
|
|
759
|
-
name:
|
|
760
|
-
ecosystem:
|
|
776
|
+
name: z8.string().describe("Package name to check"),
|
|
777
|
+
ecosystem: z8.enum(ECOSYSTEM_VALUES4).default("npm").describe("Package ecosystem (default: npm)")
|
|
761
778
|
}
|
|
762
779
|
},
|
|
763
780
|
async ({ name, ecosystem }) => {
|
|
@@ -804,7 +821,7 @@ function register5(server) {
|
|
|
804
821
|
}
|
|
805
822
|
|
|
806
823
|
// src/tools/audit.ts
|
|
807
|
-
import { z as
|
|
824
|
+
import { z as z9 } from "zod/v4";
|
|
808
825
|
|
|
809
826
|
// src/parsers/index.ts
|
|
810
827
|
function parseLockfile(filename, content) {
|
|
@@ -958,8 +975,8 @@ function register6(server) {
|
|
|
958
975
|
{
|
|
959
976
|
description: "Scan a project's lockfile for dependency risks. Parses package-lock.json, yarn.lock, pnpm-lock.yaml, requirements.txt, Cargo.lock, or go.sum and batch-queries OSV for vulnerabilities across all dependencies.",
|
|
960
977
|
inputSchema: {
|
|
961
|
-
lockfile_content:
|
|
962
|
-
lockfile_name:
|
|
978
|
+
lockfile_content: z9.string().describe("Full text content of the lockfile"),
|
|
979
|
+
lockfile_name: z9.string().describe(
|
|
963
980
|
"Filename to determine format: package-lock.json, yarn.lock, pnpm-lock.yaml, requirements.txt, Cargo.lock, go.sum"
|
|
964
981
|
)
|
|
965
982
|
}
|
|
@@ -1081,7 +1098,7 @@ ${icon} ${sev} (${group.length})`);
|
|
|
1081
1098
|
}
|
|
1082
1099
|
|
|
1083
1100
|
// src/tools/compare.ts
|
|
1084
|
-
import { z as
|
|
1101
|
+
import { z as z10 } from "zod/v4";
|
|
1085
1102
|
var ECOSYSTEM_VALUES5 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
1086
1103
|
var COPYLEFT_LICENSES = /* @__PURE__ */ new Set([
|
|
1087
1104
|
"GPL-2.0",
|
|
@@ -1162,9 +1179,9 @@ function register7(server) {
|
|
|
1162
1179
|
{
|
|
1163
1180
|
description: "Side-by-side comparison of two packages: vulnerabilities, OpenSSF Scorecard, GitHub stars, release recency, and license. Returns a recommendation.",
|
|
1164
1181
|
inputSchema: {
|
|
1165
|
-
package_a:
|
|
1166
|
-
package_b:
|
|
1167
|
-
ecosystem:
|
|
1182
|
+
package_a: z10.string().describe("First package name"),
|
|
1183
|
+
package_b: z10.string().describe("Second package name"),
|
|
1184
|
+
ecosystem: z10.enum(ECOSYSTEM_VALUES5).default("npm").describe("Package ecosystem (default: npm)")
|
|
1168
1185
|
}
|
|
1169
1186
|
},
|
|
1170
1187
|
async ({ package_a, package_b, ecosystem }) => {
|
|
@@ -1272,7 +1289,7 @@ function register7(server) {
|
|
|
1272
1289
|
}
|
|
1273
1290
|
|
|
1274
1291
|
// src/tools/license-check.ts
|
|
1275
|
-
import { z as
|
|
1292
|
+
import { z as z11 } from "zod/v4";
|
|
1276
1293
|
var COPYLEFT_LICENSES2 = /* @__PURE__ */ new Set([
|
|
1277
1294
|
"GPL-2.0",
|
|
1278
1295
|
"GPL-2.0-only",
|
|
@@ -1353,9 +1370,9 @@ function register8(server) {
|
|
|
1353
1370
|
{
|
|
1354
1371
|
description: "Scan a lockfile for license compliance. Resolves licenses for every dependency and flags packages that violate the chosen policy (permissive, copyleft, or none).",
|
|
1355
1372
|
inputSchema: {
|
|
1356
|
-
lockfile_content:
|
|
1357
|
-
lockfile_name:
|
|
1358
|
-
policy:
|
|
1373
|
+
lockfile_content: z11.string().describe("Full text content of the lockfile"),
|
|
1374
|
+
lockfile_name: z11.string().describe("Filename: package-lock.json, yarn.lock, pnpm-lock.yaml, requirements.txt, Cargo.lock, go.sum"),
|
|
1375
|
+
policy: z11.enum(["permissive", "copyleft", "none"]).default("permissive").describe(
|
|
1359
1376
|
"License policy to enforce: 'permissive' (MIT/Apache/BSD only), 'copyleft' (allows GPL but not AGPL), 'none' (report only, no violations)"
|
|
1360
1377
|
)
|
|
1361
1378
|
}
|
|
@@ -1472,7 +1489,7 @@ Supported: package-lock.json, yarn.lock, pnpm-lock.yaml, requirements.txt, Cargo
|
|
|
1472
1489
|
}
|
|
1473
1490
|
|
|
1474
1491
|
// src/tools/preinstall.ts
|
|
1475
|
-
import { z as
|
|
1492
|
+
import { z as z12 } from "zod/v4";
|
|
1476
1493
|
var ECOSYSTEM_VALUES6 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
1477
1494
|
var COPYLEFT_LICENSES3 = /* @__PURE__ */ new Set([
|
|
1478
1495
|
"GPL-2.0",
|
|
@@ -1501,9 +1518,9 @@ function register9(server) {
|
|
|
1501
1518
|
{
|
|
1502
1519
|
description: "Safety check before installing a package. Checks known vulnerabilities, typosquatting risk, abandonment, and license concerns. Returns a go/no-go verdict.",
|
|
1503
1520
|
inputSchema: {
|
|
1504
|
-
name:
|
|
1505
|
-
version:
|
|
1506
|
-
ecosystem:
|
|
1521
|
+
name: z12.string().describe("Package name"),
|
|
1522
|
+
version: z12.string().optional().describe("Package version (defaults to latest)"),
|
|
1523
|
+
ecosystem: z12.enum(ECOSYSTEM_VALUES6).default("npm").describe("Package ecosystem (default: npm)")
|
|
1507
1524
|
}
|
|
1508
1525
|
},
|
|
1509
1526
|
async ({ name, version, ecosystem }) => {
|
|
@@ -1661,7 +1678,7 @@ function register9(server) {
|
|
|
1661
1678
|
}
|
|
1662
1679
|
|
|
1663
1680
|
// src/tools/score.ts
|
|
1664
|
-
import { z as
|
|
1681
|
+
import { z as z13 } from "zod/v4";
|
|
1665
1682
|
var ECOSYSTEM_VALUES7 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
1666
1683
|
var COPYLEFT_LICENSES4 = /* @__PURE__ */ new Set([
|
|
1667
1684
|
"GPL-2.0",
|
|
@@ -1711,9 +1728,9 @@ function register10(server) {
|
|
|
1711
1728
|
{
|
|
1712
1729
|
description: "Compute a 0-100 Hound Score for a package version combining vulnerability severity, OpenSSF Scorecard, release recency, and license risk. Returns a letter grade (A-F) with a breakdown.",
|
|
1713
1730
|
inputSchema: {
|
|
1714
|
-
name:
|
|
1715
|
-
version:
|
|
1716
|
-
ecosystem:
|
|
1731
|
+
name: z13.string().describe("Package name"),
|
|
1732
|
+
version: z13.string().describe("Package version"),
|
|
1733
|
+
ecosystem: z13.enum(ECOSYSTEM_VALUES7).default("npm").describe("Package ecosystem (default: npm)")
|
|
1717
1734
|
}
|
|
1718
1735
|
},
|
|
1719
1736
|
async ({ name, version, ecosystem }) => {
|
|
@@ -1827,7 +1844,7 @@ function register10(server) {
|
|
|
1827
1844
|
}
|
|
1828
1845
|
|
|
1829
1846
|
// src/tools/upgrade.ts
|
|
1830
|
-
import { z as
|
|
1847
|
+
import { z as z14 } from "zod/v4";
|
|
1831
1848
|
var ECOSYSTEM_VALUES8 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
1832
1849
|
function parseVersion(v) {
|
|
1833
1850
|
return v.split(".").map((p) => parseInt(p.replace(/[^0-9]/g, ""), 10) || 0);
|
|
@@ -1847,9 +1864,9 @@ function register11(server) {
|
|
|
1847
1864
|
{
|
|
1848
1865
|
description: "Find the minimum version upgrade that resolves all known vulnerabilities for a package. Checks every published version and returns the nearest safe one.",
|
|
1849
1866
|
inputSchema: {
|
|
1850
|
-
name:
|
|
1851
|
-
version:
|
|
1852
|
-
ecosystem:
|
|
1867
|
+
name: z14.string().describe("Package name (e.g. express, lodash)"),
|
|
1868
|
+
version: z14.string().describe("Current vulnerable version (e.g. 4.17.20)"),
|
|
1869
|
+
ecosystem: z14.enum(ECOSYSTEM_VALUES8).default("npm").describe("Package ecosystem (default: npm)")
|
|
1853
1870
|
}
|
|
1854
1871
|
},
|
|
1855
1872
|
async ({ name, version, ecosystem }) => {
|
|
@@ -1932,7 +1949,7 @@ This may be the latest version already.`
|
|
|
1932
1949
|
}
|
|
1933
1950
|
|
|
1934
1951
|
// src/tools/vulns.ts
|
|
1935
|
-
import { z as
|
|
1952
|
+
import { z as z15 } from "zod/v4";
|
|
1936
1953
|
var ECOSYSTEM_VALUES9 = ["npm", "pypi", "go", "maven", "cargo", "nuget", "rubygems"];
|
|
1937
1954
|
var SEVERITY_ICON2 = {
|
|
1938
1955
|
CRITICAL: "\u{1F534}",
|
|
@@ -1947,9 +1964,9 @@ function register12(server) {
|
|
|
1947
1964
|
{
|
|
1948
1965
|
description: "List all known vulnerabilities for a specific package version, grouped by severity with fix versions and advisory links.",
|
|
1949
1966
|
inputSchema: {
|
|
1950
|
-
name:
|
|
1951
|
-
version:
|
|
1952
|
-
ecosystem:
|
|
1967
|
+
name: z15.string().describe("Package name (e.g. express, lodash)"),
|
|
1968
|
+
version: z15.string().describe("Package version (e.g. 4.18.2)"),
|
|
1969
|
+
ecosystem: z15.enum(ECOSYSTEM_VALUES9).default("npm").describe("Package ecosystem (default: npm)")
|
|
1953
1970
|
}
|
|
1954
1971
|
},
|
|
1955
1972
|
async ({ name, version, ecosystem }) => {
|