@mcp-guardian/server 0.3.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.
Files changed (106) hide show
  1. package/README.md +505 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +216 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/clients/nvd-client.d.ts +17 -0
  7. package/dist/clients/nvd-client.d.ts.map +1 -0
  8. package/dist/clients/nvd-client.js +64 -0
  9. package/dist/clients/nvd-client.js.map +1 -0
  10. package/dist/clients/osv-client.d.ts +19 -0
  11. package/dist/clients/osv-client.d.ts.map +1 -0
  12. package/dist/clients/osv-client.js +60 -0
  13. package/dist/clients/osv-client.js.map +1 -0
  14. package/dist/clients/pricing-client.d.ts +16 -0
  15. package/dist/clients/pricing-client.d.ts.map +1 -0
  16. package/dist/clients/pricing-client.js +171 -0
  17. package/dist/clients/pricing-client.js.map +1 -0
  18. package/dist/config-parser.d.ts +24 -0
  19. package/dist/config-parser.d.ts.map +1 -0
  20. package/dist/config-parser.js +96 -0
  21. package/dist/config-parser.js.map +1 -0
  22. package/dist/container.d.ts +12 -0
  23. package/dist/container.d.ts.map +1 -0
  24. package/dist/container.js +22 -0
  25. package/dist/container.js.map +1 -0
  26. package/dist/database/history-db.d.ts +28 -0
  27. package/dist/database/history-db.d.ts.map +1 -0
  28. package/dist/database/history-db.js +154 -0
  29. package/dist/database/history-db.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +247 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/proxy/proxy-manager.d.ts +12 -0
  35. package/dist/proxy/proxy-manager.d.ts.map +1 -0
  36. package/dist/proxy/proxy-manager.js +37 -0
  37. package/dist/proxy/proxy-manager.js.map +1 -0
  38. package/dist/proxy/proxy-server.d.ts +26 -0
  39. package/dist/proxy/proxy-server.d.ts.map +1 -0
  40. package/dist/proxy/proxy-server.js +99 -0
  41. package/dist/proxy/proxy-server.js.map +1 -0
  42. package/dist/reporter/report-generator.d.ts +9 -0
  43. package/dist/reporter/report-generator.d.ts.map +1 -0
  44. package/dist/reporter/report-generator.js +145 -0
  45. package/dist/reporter/report-generator.js.map +1 -0
  46. package/dist/scanners/auth-prober.d.ts +13 -0
  47. package/dist/scanners/auth-prober.d.ts.map +1 -0
  48. package/dist/scanners/auth-prober.js +59 -0
  49. package/dist/scanners/auth-prober.js.map +1 -0
  50. package/dist/scanners/command-validator.d.ts +15 -0
  51. package/dist/scanners/command-validator.d.ts.map +1 -0
  52. package/dist/scanners/command-validator.js +50 -0
  53. package/dist/scanners/command-validator.js.map +1 -0
  54. package/dist/scanners/cve-checker.d.ts +15 -0
  55. package/dist/scanners/cve-checker.d.ts.map +1 -0
  56. package/dist/scanners/cve-checker.js +28 -0
  57. package/dist/scanners/cve-checker.js.map +1 -0
  58. package/dist/scanners/secret-scanner.d.ts +12 -0
  59. package/dist/scanners/secret-scanner.d.ts.map +1 -0
  60. package/dist/scanners/secret-scanner.js +72 -0
  61. package/dist/scanners/secret-scanner.js.map +1 -0
  62. package/dist/scanners/typo-squat-detector.d.ts +14 -0
  63. package/dist/scanners/typo-squat-detector.d.ts.map +1 -0
  64. package/dist/scanners/typo-squat-detector.js +82 -0
  65. package/dist/scanners/typo-squat-detector.js.map +1 -0
  66. package/dist/services/cost-auditor.d.ts +14 -0
  67. package/dist/services/cost-auditor.d.ts.map +1 -0
  68. package/dist/services/cost-auditor.js +90 -0
  69. package/dist/services/cost-auditor.js.map +1 -0
  70. package/dist/services/health-monitor.d.ts +8 -0
  71. package/dist/services/health-monitor.d.ts.map +1 -0
  72. package/dist/services/health-monitor.js +51 -0
  73. package/dist/services/health-monitor.js.map +1 -0
  74. package/dist/services/security-scanner.d.ts +20 -0
  75. package/dist/services/security-scanner.d.ts.map +1 -0
  76. package/dist/services/security-scanner.js +92 -0
  77. package/dist/services/security-scanner.js.map +1 -0
  78. package/dist/types.d.ts +86 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +2 -0
  81. package/dist/types.js.map +1 -0
  82. package/dist/utils/logger.d.ts +13 -0
  83. package/dist/utils/logger.d.ts.map +1 -0
  84. package/dist/utils/logger.js +35 -0
  85. package/dist/utils/logger.js.map +1 -0
  86. package/dist/utils/mcp-client.d.ts +33 -0
  87. package/dist/utils/mcp-client.d.ts.map +1 -0
  88. package/dist/utils/mcp-client.js +182 -0
  89. package/dist/utils/mcp-client.js.map +1 -0
  90. package/dist/utils/rate-limiter.d.ts +31 -0
  91. package/dist/utils/rate-limiter.d.ts.map +1 -0
  92. package/dist/utils/rate-limiter.js +74 -0
  93. package/dist/utils/rate-limiter.js.map +1 -0
  94. package/dist/utils/scoring.d.ts +9 -0
  95. package/dist/utils/scoring.d.ts.map +1 -0
  96. package/dist/utils/scoring.js +19 -0
  97. package/dist/utils/scoring.js.map +1 -0
  98. package/dist/utils/tls-checker.d.ts +13 -0
  99. package/dist/utils/tls-checker.d.ts.map +1 -0
  100. package/dist/utils/tls-checker.js +62 -0
  101. package/dist/utils/tls-checker.js.map +1 -0
  102. package/dist/utils/token-counter.d.ts +7 -0
  103. package/dist/utils/token-counter.d.ts.map +1 -0
  104. package/dist/utils/token-counter.js +16 -0
  105. package/dist/utils/token-counter.js.map +1 -0
  106. package/package.json +52 -0
package/dist/cli.js ADDED
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { ConfigParser } from './config-parser.js';
5
+ import { HistoryDatabase } from './database/history-db.js';
6
+ import { ReportGenerator } from './reporter/report-generator.js';
7
+ import { calculateOverallScore } from './utils/scoring.js';
8
+ import { ProxyManager } from './proxy/proxy-manager.js';
9
+ import { createContainer } from './container.js';
10
+ // ── Shared helpers ────────────────────────────────────────────────────
11
+ function loadConfigs(options) {
12
+ if (options.all) {
13
+ return ConfigParser.parseAll();
14
+ }
15
+ const paths = options.config ? [options.config] : ConfigParser.findConfigPaths();
16
+ if (paths.length === 0)
17
+ return { servers: [], sourcePaths: [] };
18
+ return { servers: ConfigParser.parse(paths[0]), sourcePaths: [paths[0]] };
19
+ }
20
+ function checkAlertThresholds(reports, opts) {
21
+ if ('failOnCritical' in opts && opts.failOnCritical && reports.some((r) => r.cves.some((c) => c.severity === 'CRITICAL'))) {
22
+ console.error(chalk.red('\n⚠ Critical CVE(s) detected'));
23
+ process.exit(1);
24
+ }
25
+ if ('failOnSecrets' in opts && opts.failOnSecrets && reports.some((r) => r.secretsFound.length > 0)) {
26
+ console.error(chalk.red('\n⚠ Hardcoded secrets detected'));
27
+ process.exit(1);
28
+ }
29
+ if (opts.thresholdScore !== undefined) {
30
+ const below = reports.filter((r) => r.score < opts.thresholdScore);
31
+ if (below.length > 0) {
32
+ console.error(chalk.red(`\n⚠ ${below.length} server(s) below score threshold ${opts.thresholdScore}: ${below.map((r) => `${r.serverName} (${r.score})`).join(', ')}`));
33
+ process.exit(2);
34
+ }
35
+ }
36
+ }
37
+ // ── CLI commands ──────────────────────────────────────────────────────
38
+ const program = new Command();
39
+ program
40
+ .name('mcp-guardian')
41
+ .description('Security, cost, and health audit for MCP infrastructure')
42
+ .version('0.3.0');
43
+ program
44
+ .command('scan')
45
+ .description('Run security scan on MCP servers')
46
+ .option('-c, --config <path>', 'Path to an MCP config file')
47
+ .option('-a, --all', 'Aggregate all discoverable config files')
48
+ .option('--threshold-score <number>', 'Exit code 2 if any server score drops below threshold', parseInt)
49
+ .option('--fail-on-critical', 'Exit code 1 if any critical CVE found')
50
+ .option('--fail-on-secrets', 'Exit code 1 if any hardcoded secrets detected')
51
+ .action(async (opts) => {
52
+ const { servers, sourcePaths } = loadConfigs(opts);
53
+ if (servers.length === 0) {
54
+ console.error(chalk.yellow('No servers found in config.'));
55
+ process.exit(0);
56
+ }
57
+ if (opts.all && sourcePaths.length > 1) {
58
+ console.error(chalk.dim(`Aggregated ${sourcePaths.length} configs: ${sourcePaths.join(', ')}`));
59
+ }
60
+ else {
61
+ console.error(chalk.dim(`Using config: ${sourcePaths[0] || 'auto-detected'}`));
62
+ }
63
+ const container = createContainer();
64
+ const reports = await Promise.all(servers.map((s) => container.securityScanner.scanServer(s)));
65
+ await Promise.all(reports.map((r) => container.db.addSecurityScan(r.serverName, r.score, r.cves.length, r)));
66
+ container.db.close();
67
+ console.log(new ReportGenerator().formatSecurityReports(reports));
68
+ checkAlertThresholds(reports, opts);
69
+ });
70
+ program
71
+ .command('audit')
72
+ .description('Audit token costs for MCP servers')
73
+ .option('-c, --config <path>', 'Path to an MCP config file')
74
+ .option('-a, --all', 'Aggregate all discoverable config files')
75
+ .option('-s, --server <name>', 'Filter to a specific server')
76
+ .option('--threshold-cost <number>', 'Exit code 2 if total cost exceeds threshold (USD)', parseFloat)
77
+ .action(async (opts) => {
78
+ const { servers } = loadConfigs(opts);
79
+ const filtered = opts.server ? servers.filter((s) => s.name === opts.server) : servers;
80
+ if (filtered.length === 0) {
81
+ console.error(chalk.yellow('No servers found.'));
82
+ process.exit(0);
83
+ }
84
+ const container = createContainer();
85
+ const results = await Promise.all(filtered.map((s) => container.costAuditor.auditServer(s)));
86
+ container.costAuditor.dispose();
87
+ await Promise.all(results.map((r) => container.db.addCostRecord(r.serverName, r.tokensUsed, r.estimatedCostUSD)));
88
+ container.db.close();
89
+ console.log(new ReportGenerator().formatCostReports(results));
90
+ if (opts.thresholdCost) {
91
+ const total = results.reduce((s, r) => s + r.estimatedCostUSD, 0);
92
+ if (total > opts.thresholdCost) {
93
+ console.error(chalk.red(`\n⚠ Total cost $${total.toFixed(4)} exceeds threshold $${opts.thresholdCost.toFixed(4)}`));
94
+ process.exit(2);
95
+ }
96
+ }
97
+ });
98
+ program
99
+ .command('health')
100
+ .description('Check health of MCP servers')
101
+ .option('-c, --config <path>', 'Path to an MCP config file')
102
+ .option('-a, --all', 'Aggregate all discoverable config files')
103
+ .option('-s, --server <name>', 'Filter to a specific server')
104
+ .option('--threshold-latency <ms>', 'Exit code 2 if any server exceeds latency threshold', parseInt)
105
+ .option('--fail-on-overload', 'Exit code 1 if any server has tool overload')
106
+ .action(async (opts) => {
107
+ const { servers } = loadConfigs(opts);
108
+ const filtered = opts.server ? servers.filter((s) => s.name === opts.server) : servers;
109
+ if (filtered.length === 0) {
110
+ console.error(chalk.yellow('No servers found.'));
111
+ process.exit(0);
112
+ }
113
+ const container = createContainer();
114
+ const results = await Promise.all(filtered.map((s) => container.healthMonitor.checkServer(s)));
115
+ await Promise.all(results.map((r) => container.db.addHealthCheck(r.serverName, r.latencyMs, r.successRate > 0.5, r.toolCount)));
116
+ container.db.close();
117
+ console.log(new ReportGenerator().formatHealthReports(results));
118
+ if (opts.failOnOverload && results.some((r) => r.overloadWarning)) {
119
+ console.error(chalk.red('\n⚠ One or more servers have tool overload'));
120
+ process.exit(1);
121
+ }
122
+ if (opts.thresholdLatency !== undefined) {
123
+ const slow = results.filter((r) => r.latencyMs > opts.thresholdLatency);
124
+ if (slow.length > 0) {
125
+ console.error(chalk.red(`\n⚠ ${slow.length} server(s) exceed ${opts.thresholdLatency}ms latency: ${slow.map((r) => r.serverName).join(', ')}`));
126
+ process.exit(2);
127
+ }
128
+ }
129
+ });
130
+ program
131
+ .command('report')
132
+ .description('Generate a full MCP Guardian report')
133
+ .option('-c, --config <path>', 'Path to an MCP config file')
134
+ .option('-a, --all', 'Aggregate all discoverable config files')
135
+ .option('-f, --format <format>', 'Output format: text (default), markdown, or json', 'text')
136
+ .option('--output <path>', 'Save report to a file instead of stdout')
137
+ .option('--threshold-score <number>', 'Exit code 2 if overall score drops below threshold', parseInt)
138
+ .action(async (opts) => {
139
+ const { servers, sourcePaths } = loadConfigs(opts);
140
+ if (servers.length === 0) {
141
+ console.error(chalk.yellow('No servers found in config.'));
142
+ process.exit(0);
143
+ }
144
+ if (opts.all && sourcePaths.length > 1) {
145
+ console.error(chalk.dim(`Aggregated ${sourcePaths.length} configs: ${sourcePaths.join(', ')}`));
146
+ }
147
+ else {
148
+ console.error(chalk.dim(`Using config: ${sourcePaths[0] || 'auto-detected'}`));
149
+ }
150
+ const container = createContainer();
151
+ const [security, costs, health] = await Promise.all([
152
+ Promise.all(servers.map((s) => container.securityScanner.scanServer(s))),
153
+ Promise.all(servers.map((s) => container.costAuditor.auditServer(s))),
154
+ Promise.all(servers.map((s) => container.healthMonitor.checkServer(s))),
155
+ ]);
156
+ container.costAuditor.dispose();
157
+ await Promise.all([
158
+ ...security.map((r) => container.db.addSecurityScan(r.serverName, r.score, r.cves.length, r)),
159
+ ...costs.map((r) => container.db.addCostRecord(r.serverName, r.tokensUsed, r.estimatedCostUSD)),
160
+ ...health.map((r) => container.db.addHealthCheck(r.serverName, r.latencyMs, r.successRate > 0.5, r.toolCount)),
161
+ ]);
162
+ container.db.close();
163
+ const overallScore = calculateOverallScore(security, health);
164
+ const configPath = opts.all ? `aggregated (${sourcePaths.length} files)` : (sourcePaths[0] || 'auto-detected');
165
+ const fullReport = { timestamp: new Date().toISOString(), configPath, security, costs, health, overallScore };
166
+ const reporter = new ReportGenerator();
167
+ let output;
168
+ if (opts.format === 'json')
169
+ output = JSON.stringify(fullReport, null, 2);
170
+ else if (opts.format === 'markdown')
171
+ output = reporter.toMarkdown(fullReport);
172
+ else
173
+ output = reporter.formatFullReport(fullReport);
174
+ if (opts.output) {
175
+ const fs = await import('fs');
176
+ fs.writeFileSync(opts.output, output);
177
+ console.error(chalk.green(`Report saved to ${opts.output}`));
178
+ }
179
+ else {
180
+ console.log(output);
181
+ }
182
+ checkAlertThresholds(security, opts);
183
+ });
184
+ program
185
+ .command('proxy')
186
+ .description('Start MCP Guardian proxy to capture real token usage data')
187
+ .option('-c, --config <path>', 'Path to MCP config file')
188
+ .action(async (opts) => {
189
+ const paths = opts.config ? [opts.config] : ConfigParser.findConfigPaths();
190
+ if (paths.length === 0) {
191
+ console.error(chalk.red('No MCP config files found. Use --config to specify a path.'));
192
+ process.exit(1);
193
+ }
194
+ const servers = ConfigParser.parse(paths[0]);
195
+ if (servers.length === 0) {
196
+ console.error(chalk.yellow('No servers found in config.'));
197
+ process.exit(0);
198
+ }
199
+ const db = new HistoryDatabase();
200
+ const manager = new ProxyManager(db);
201
+ await manager.startAll(servers);
202
+ console.error(chalk.green('MCP Guardian proxy running. Press Ctrl+C to stop.'));
203
+ const cleanup = () => { manager.stopAll(); db.close(); process.exit(0); };
204
+ process.on('SIGINT', cleanup);
205
+ process.on('SIGTERM', cleanup);
206
+ const proxies = manager.getProxies();
207
+ if (proxies.length > 0) {
208
+ process.stdin.setEncoding('utf-8');
209
+ process.stdin.on('data', (chunk) => {
210
+ for (const proxy of proxies)
211
+ proxy.handleClientInput(chunk.trim());
212
+ });
213
+ }
214
+ });
215
+ program.parse();
216
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { CveFinding } from '../types.js';
2
+ /**
3
+ * Client for NIST NVD API (https://services.nvd.nist.gov/rest/json/cves/2.0).
4
+ * Requires an API key for production use (set via NVD_API_KEY env var).
5
+ */
6
+ export declare class NvdClient {
7
+ private baseUrl;
8
+ private apiKey?;
9
+ constructor(baseUrl?: string);
10
+ /**
11
+ * Search for CVEs by keyword (package name, product, etc.).
12
+ * Returns up to 20 results.
13
+ */
14
+ search(keyword: string): Promise<CveFinding[]>;
15
+ private mapCvssSeverity;
16
+ }
17
+ //# sourceMappingURL=nvd-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-client.d.ts","sourceRoot":"","sources":["../../src/clients/nvd-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,GAAE,MAA2D;IAKhF;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAqCpD,OAAO,CAAC,eAAe;CAOxB"}
@@ -0,0 +1,64 @@
1
+ import axios from 'axios';
2
+ import { Logger } from '../utils/logger.js';
3
+ import { nvdLimiter, nvdApiKeyLimiter } from '../utils/rate-limiter.js';
4
+ /**
5
+ * Client for NIST NVD API (https://services.nvd.nist.gov/rest/json/cves/2.0).
6
+ * Requires an API key for production use (set via NVD_API_KEY env var).
7
+ */
8
+ export class NvdClient {
9
+ baseUrl;
10
+ apiKey;
11
+ constructor(baseUrl = 'https://services.nvd.nist.gov/rest/json/cves/2.0') {
12
+ this.baseUrl = baseUrl;
13
+ this.apiKey = process.env['NVD_API_KEY'];
14
+ }
15
+ /**
16
+ * Search for CVEs by keyword (package name, product, etc.).
17
+ * Returns up to 20 results.
18
+ */
19
+ async search(keyword) {
20
+ try {
21
+ const params = {
22
+ keywordSearch: keyword,
23
+ resultsPerPage: '20',
24
+ };
25
+ const headers = {};
26
+ if (this.apiKey) {
27
+ headers['apiKey'] = this.apiKey;
28
+ }
29
+ const limiter = this.apiKey ? nvdApiKeyLimiter : nvdLimiter;
30
+ await limiter.acquire();
31
+ const response = await axios.get(this.baseUrl, {
32
+ params,
33
+ headers,
34
+ timeout: 15000,
35
+ });
36
+ const vulnerabilities = response.data?.vulnerabilities ?? [];
37
+ return vulnerabilities.map((entry) => {
38
+ const cve = entry.cve ?? {};
39
+ const metrics = cve.metrics?.cvssMetricV31?.[0]?.cvssData ?? cve.metrics?.cvssMetricV30?.[0]?.cvssData;
40
+ return {
41
+ id: cve.id ?? 'unknown',
42
+ severity: this.mapCvssSeverity(metrics?.baseSeverity ?? 'MEDIUM'),
43
+ summary: cve.descriptions?.[0]?.value?.substring(0, 200) ?? 'No description',
44
+ fixedVersion: undefined,
45
+ };
46
+ });
47
+ }
48
+ catch (error) {
49
+ Logger.warn(`NVD search failed for "${keyword}": ${error?.message ?? 'Unknown error'}`);
50
+ return [];
51
+ }
52
+ }
53
+ mapCvssSeverity(severity) {
54
+ const upper = severity.toUpperCase();
55
+ if (upper === 'CRITICAL')
56
+ return 'CRITICAL';
57
+ if (upper === 'HIGH')
58
+ return 'HIGH';
59
+ if (upper === 'LOW')
60
+ return 'LOW';
61
+ return 'MEDIUM';
62
+ }
63
+ }
64
+ //# sourceMappingURL=nvd-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nvd-client.js","sourceRoot":"","sources":["../../src/clients/nvd-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAExE;;;GAGG;AACH,MAAM,OAAO,SAAS;IACZ,OAAO,CAAS;IAChB,MAAM,CAAU;IAExB,YAAY,UAAkB,kDAAkD;QAC9E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAA2B;gBACrC,aAAa,EAAE,OAAO;gBACtB,cAAc,EAAE,IAAI;aACrB,CAAC;YACF,MAAM,OAAO,GAA2B,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;YAClC,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC;YAC5D,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAExB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE;gBAC7C,MAAM;gBACN,OAAO;gBACP,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,EAAE,eAAe,IAAI,EAAE,CAAC;YAC7D,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE;gBACxC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;gBACvG,OAAO;oBACL,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,SAAS;oBACvB,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,YAAY,IAAI,QAAQ,CAAC;oBACjE,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,gBAAgB;oBAC5E,YAAY,EAAE,SAAS;iBACxB,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,0BAA0B,OAAO,MAAM,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;YACxF,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,QAAgB;QACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,KAAK,KAAK,UAAU;YAAE,OAAO,UAAU,CAAC;QAC5C,IAAI,KAAK,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QACpC,IAAI,KAAK,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import { CveFinding } from '../types.js';
2
+ /**
3
+ * Client for the OSV.dev API (https://api.osv.dev).
4
+ * Queries known vulnerabilities for open-source packages.
5
+ */
6
+ export declare class OsvClient {
7
+ private baseUrl;
8
+ constructor(baseUrl?: string);
9
+ /**
10
+ * Check for known vulnerabilities in a package.
11
+ * @param packageName - npm package name (e.g. '@modelcontextprotocol/sdk')
12
+ * @param version - Optional version string
13
+ * @returns Array of CVE findings
14
+ */
15
+ check(packageName: string, version?: string): Promise<CveFinding[]>;
16
+ private toPurl;
17
+ private mapSeverity;
18
+ }
19
+ //# sourceMappingURL=osv-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osv-client.d.ts","sourceRoot":"","sources":["../../src/clients/osv-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAiC;IAItD;;;;;OAKG;IACG,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAuBzE,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,WAAW;CAUpB"}
@@ -0,0 +1,60 @@
1
+ import axios from 'axios';
2
+ import { Logger } from '../utils/logger.js';
3
+ import { osvLimiter } from '../utils/rate-limiter.js';
4
+ /**
5
+ * Client for the OSV.dev API (https://api.osv.dev).
6
+ * Queries known vulnerabilities for open-source packages.
7
+ */
8
+ export class OsvClient {
9
+ baseUrl;
10
+ constructor(baseUrl = 'https://api.osv.dev/v1') {
11
+ this.baseUrl = baseUrl;
12
+ }
13
+ /**
14
+ * Check for known vulnerabilities in a package.
15
+ * @param packageName - npm package name (e.g. '@modelcontextprotocol/sdk')
16
+ * @param version - Optional version string
17
+ * @returns Array of CVE findings
18
+ */
19
+ async check(packageName, version) {
20
+ try {
21
+ await osvLimiter.acquire();
22
+ // Normalize to purl-compatible format
23
+ const purl = this.toPurl(packageName, version);
24
+ const response = await axios.post(`${this.baseUrl}/query`, {
25
+ package: { purl },
26
+ }, {
27
+ timeout: 10000,
28
+ });
29
+ const vulns = response.data?.vulns ?? [];
30
+ return vulns.map((v) => ({
31
+ id: v.id ?? 'unknown',
32
+ severity: this.mapSeverity(v.severity),
33
+ summary: v.summary ?? v.details?.substring(0, 200) ?? 'No description',
34
+ fixedVersion: v.affected?.[0]?.ranges?.[0]?.events?.find((e) => e.fixed)?.fixed,
35
+ }));
36
+ }
37
+ catch (error) {
38
+ Logger.warn(`OSV lookup failed for ${packageName}: ${error?.message ?? 'Unknown error'}`);
39
+ return [];
40
+ }
41
+ }
42
+ toPurl(packageName, version) {
43
+ // npm purl: pkg:npm/package@version
44
+ const encoded = encodeURIComponent(packageName);
45
+ const versionSuffix = version ? `@${encodeURIComponent(version)}` : '';
46
+ return `pkg:npm/${encoded}${versionSuffix}`;
47
+ }
48
+ mapSeverity(severity) {
49
+ if (!severity)
50
+ return 'MEDIUM';
51
+ const map = {
52
+ CRITICAL: 'CRITICAL',
53
+ HIGH: 'HIGH',
54
+ MODERATE: 'MEDIUM',
55
+ LOW: 'LOW',
56
+ };
57
+ return map[severity.toUpperCase()] ?? 'MEDIUM';
58
+ }
59
+ }
60
+ //# sourceMappingURL=osv-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osv-client.js","sourceRoot":"","sources":["../../src/clients/osv-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;;GAGG;AACH,MAAM,OAAO,SAAS;IACZ,OAAO,CAAS;IAExB,YAAY,UAAkB,wBAAwB;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,WAAmB,EAAE,OAAgB;QAC/C,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;YAC3B,sCAAsC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,QAAQ,EAAE;gBACzD,OAAO,EAAE,EAAE,IAAI,EAAE;aAClB,EAAE;gBACD,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YACH,MAAM,KAAK,GAAU,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;gBAC5B,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,SAAS;gBACrB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtC,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,gBAAgB;gBACtE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK;aACrF,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,yBAAyB,WAAW,KAAK,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;YAC1F,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,WAAmB,EAAE,OAAgB;QAClD,oCAAoC;QACpC,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,WAAW,OAAO,GAAG,aAAa,EAAE,CAAC;IAC9C,CAAC;IAEO,WAAW,CAAC,QAAiB;QACnC,IAAI,CAAC,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC/B,MAAM,GAAG,GAA2D;YAClE,QAAQ,EAAE,UAAU;YACpB,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,QAAQ;YAClB,GAAG,EAAE,KAAK;SACX,CAAC;QACF,OAAO,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,QAAQ,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ export declare class PricingClient {
2
+ private prices;
3
+ constructor();
4
+ /** Calculate estimated cost for a given number of tokens. */
5
+ calculateCost(tokens: number, model: string, isOutput?: boolean): number;
6
+ /** Get the full pricing record for a model, or null if unknown. */
7
+ getPricingForModel(model: string): {
8
+ input: number;
9
+ output: number;
10
+ } | null;
11
+ /** List all known model pricing entries. */
12
+ listModels(): string[];
13
+ /** Add or update pricing for a model at runtime. */
14
+ addPricing(model: string, inputCost: number, outputCost: number): void;
15
+ }
16
+ //# sourceMappingURL=pricing-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing-client.d.ts","sourceRoot":"","sources":["../../src/clients/pricing-client.ts"],"names":[],"mappings":"AA6JA,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoD;;IAOlE,6DAA6D;IAC7D,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAe,GAAG,MAAM;IAW/E,mEAAmE;IACnE,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI3E,4CAA4C;IAC5C,UAAU,IAAI,MAAM,EAAE;IAItB,oDAAoD;IACpD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAGvE"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Comprehensive token pricing for all major LLM providers.
3
+ * Rates per 1M tokens (as of mid-2025).
4
+ * Override via PRICING_OVERRIDES env var (JSON): {"model-name": {"input": N, "output": N}}
5
+ */
6
+ const DEFAULT_PRICING_TABLE = {
7
+ // ── OpenAI ──────────────────────────────────────────
8
+ 'gpt-4o': { input: 5.0, output: 15.0 },
9
+ 'gpt-4o-mini': { input: 0.15, output: 0.6 },
10
+ 'gpt-4.5-preview': { input: 75.0, output: 150.0 },
11
+ 'gpt-4-turbo': { input: 10.0, output: 30.0 },
12
+ 'gpt-4': { input: 30.0, output: 60.0 },
13
+ 'gpt-4-32k': { input: 60.0, output: 120.0 },
14
+ 'gpt-3.5-turbo': { input: 0.5, output: 1.5 },
15
+ 'gpt-3.5-turbo-16k': { input: 3.0, output: 4.0 },
16
+ 'o1': { input: 15.0, output: 60.0 },
17
+ 'o1-mini': { input: 1.1, output: 4.4 },
18
+ 'o3-mini': { input: 1.1, output: 4.4 },
19
+ 'o3': { input: 10.0, output: 40.0 },
20
+ 'o4-mini': { input: 1.1, output: 4.4 },
21
+ 'gpt-4o-realtime-preview': { input: 5.0, output: 20.0 },
22
+ // ── Anthropic ───────────────────────────────────────
23
+ 'claude-3-5-sonnet': { input: 3.0, output: 15.0 },
24
+ 'claude-3-opus': { input: 15.0, output: 75.0 },
25
+ 'claude-3-sonnet': { input: 3.0, output: 15.0 },
26
+ 'claude-3-haiku': { input: 0.25, output: 1.25 },
27
+ 'claude-3-5-haiku': { input: 0.8, output: 4.0 },
28
+ 'claude-2.1': { input: 8.0, output: 24.0 },
29
+ 'claude-2.0': { input: 8.0, output: 24.0 },
30
+ 'claude-instant': { input: 0.8, output: 2.4 },
31
+ // ── Google DeepMind ─────────────────────────────────
32
+ 'gemini-2.0-flash': { input: 0.1, output: 0.4 },
33
+ 'gemini-2.0-flash-lite': { input: 0.075, output: 0.3 },
34
+ 'gemini-2.5-pro': { input: 1.25, output: 10.0 },
35
+ 'gemini-2.5-flash': { input: 0.15, output: 0.6 },
36
+ 'gemini-1.5-pro': { input: 1.25, output: 5.0 },
37
+ 'gemini-1.5-flash': { input: 0.075, output: 0.3 },
38
+ 'gemini-1.5-flash-8b': { input: 0.0375, output: 0.15 },
39
+ 'gemini-1.0-pro': { input: 0.5, output: 1.5 },
40
+ 'gemini-1.0-ultra': { input: 0.5, output: 1.5 },
41
+ 'gemma-2-27b': { input: 0.27, output: 0.27 },
42
+ 'gemma-2-9b': { input: 0.1, output: 0.1 },
43
+ 'gemma-3-27b': { input: 0.15, output: 0.15 },
44
+ // ── DeepSeek ────────────────────────────────────────
45
+ 'deepseek-chat': { input: 0.14, output: 0.28 },
46
+ 'deepseek-reasoner': { input: 0.55, output: 2.19 },
47
+ 'deepseek-v3': { input: 0.27, output: 1.1 },
48
+ 'deepseek-r1': { input: 0.55, output: 2.19 },
49
+ // ── xAI (Grok) ──────────────────────────────────────
50
+ 'grok-3': { input: 3.0, output: 15.0 },
51
+ 'grok-3-mini': { input: 0.3, output: 0.5 },
52
+ 'grok-2': { input: 2.0, output: 10.0 },
53
+ 'grok-2-vision': { input: 2.0, output: 10.0 },
54
+ 'grok-1.5': { input: 5.0, output: 15.0 },
55
+ // ── Meta (Llama via Cloud APIs) ─────────────────────
56
+ 'llama-4-maverick': { input: 0.2, output: 0.6 },
57
+ 'llama-4-scout': { input: 0.15, output: 0.4 },
58
+ 'llama-3.3-70b': { input: 0.59, output: 0.79 },
59
+ 'llama-3.1-405b': { input: 2.0, output: 6.0 },
60
+ 'llama-3.1-70b': { input: 0.59, output: 0.79 },
61
+ 'llama-3.1-8b': { input: 0.06, output: 0.06 },
62
+ 'llama-3-70b': { input: 0.59, output: 0.79 },
63
+ 'llama-3-8b': { input: 0.06, output: 0.06 },
64
+ // ── Mistral ─────────────────────────────────────────
65
+ 'mistral-large': { input: 2.0, output: 6.0 },
66
+ 'mistral-medium': { input: 2.7, output: 8.1 },
67
+ 'mistral-small': { input: 0.2, output: 0.6 },
68
+ 'mistral-nemo': { input: 0.15, output: 0.15 },
69
+ 'mistral-7b': { input: 0.08, output: 0.08 },
70
+ 'mixtral-8x7b': { input: 0.24, output: 0.24 },
71
+ 'mixtral-8x22b': { input: 1.0, output: 1.0 },
72
+ 'codestral': { input: 0.2, output: 0.6 },
73
+ 'pixtral-large': { input: 2.0, output: 6.0 },
74
+ // ── Cohere ──────────────────────────────────────────
75
+ 'command-r-plus': { input: 2.5, output: 10.0 },
76
+ 'command-r': { input: 0.5, output: 1.5 },
77
+ 'command': { input: 0.5, output: 1.5 },
78
+ 'command-light': { input: 0.3, output: 0.6 },
79
+ // ── AI21 Labs ───────────────────────────────────────
80
+ 'jamba-1.5-large': { input: 2.0, output: 8.0 },
81
+ 'jamba-1.5-mini': { input: 0.2, output: 0.4 },
82
+ 'jamba-instruct': { input: 0.5, output: 1.5 },
83
+ // ── Reka ────────────────────────────────────────────
84
+ 'reka-core': { input: 3.0, output: 10.0 },
85
+ 'reka-flash': { input: 0.25, output: 1.0 },
86
+ 'reka-edge': { input: 0.4, output: 1.0 },
87
+ // ── Amazon (Bedrock) ────────────────────────────────
88
+ 'amazon-titan-text-premier': { input: 0.5, output: 1.5 },
89
+ 'amazon-titan-text-lite': { input: 0.15, output: 0.2 },
90
+ 'amazon-titan-text-express': { input: 0.2, output: 0.6 },
91
+ 'amazon-nova-pro': { input: 2.0, output: 8.0 },
92
+ 'amazon-nova-lite': { input: 0.15, output: 0.4 },
93
+ 'amazon-nova-micro': { input: 0.05, output: 0.1 },
94
+ // ── Alibaba (Qwen) ──────────────────────────────────
95
+ 'qwen-max': { input: 2.0, output: 6.0 },
96
+ 'qwen-plus': { input: 0.4, output: 1.2 },
97
+ 'qwen-turbo': { input: 0.2, output: 0.4 },
98
+ 'qwen-coder-plus': { input: 0.7, output: 1.4 },
99
+ 'qwen-2.5-72b': { input: 0.58, output: 1.16 },
100
+ 'qwen-2.5-32b': { input: 0.27, output: 0.54 },
101
+ 'qwen-2.5-7b': { input: 0.07, output: 0.07 },
102
+ // ── Zhipu AI (GLM) ──────────────────────────────────
103
+ 'glm-4-plus': { input: 2.0, output: 6.0 },
104
+ 'glm-4-air': { input: 0.5, output: 1.0 },
105
+ 'glm-4-flash': { input: 0.05, output: 0.1 },
106
+ // ── 01.AI (Yi) ──────────────────────────────────────
107
+ 'yi-large': { input: 2.0, output: 6.0 },
108
+ 'yi-medium': { input: 0.5, output: 1.0 },
109
+ 'yi-small': { input: 0.1, output: 0.1 },
110
+ // ── Writer ──────────────────────────────────────────
111
+ 'palmyra-x-004': { input: 3.0, output: 10.0 },
112
+ 'palmyra-med': { input: 0.5, output: 1.5 },
113
+ // ── Perplexity ──────────────────────────────────────
114
+ 'sonar-pro': { input: 5.0, output: 15.0 },
115
+ 'sonar': { input: 2.0, output: 5.0 },
116
+ 'sonar-reasoning': { input: 3.0, output: 15.0 },
117
+ // ── HuggingFace ─────────────────────────────────────
118
+ 'zephyr-7b-beta': { input: 0.05, output: 0.05 },
119
+ 'falcon-180b': { input: 1.0, output: 1.0 },
120
+ 'falcon-40b': { input: 0.5, output: 0.5 },
121
+ };
122
+ function loadCustomPricing() {
123
+ const overrides = process.env['PRICING_OVERRIDES'];
124
+ if (!overrides)
125
+ return {};
126
+ try {
127
+ const parsed = JSON.parse(overrides);
128
+ const result = {};
129
+ for (const [model, rates] of Object.entries(parsed)) {
130
+ const r = rates;
131
+ if (typeof r.input === 'number' && typeof r.output === 'number') {
132
+ result[model] = { input: r.input, output: r.output };
133
+ }
134
+ }
135
+ return result;
136
+ }
137
+ catch {
138
+ return {};
139
+ }
140
+ }
141
+ export class PricingClient {
142
+ prices;
143
+ constructor() {
144
+ const custom = loadCustomPricing();
145
+ this.prices = { ...DEFAULT_PRICING_TABLE, ...custom };
146
+ }
147
+ /** Calculate estimated cost for a given number of tokens. */
148
+ calculateCost(tokens, model, isOutput = false) {
149
+ const price = this.prices[model];
150
+ if (!price) {
151
+ // Unknown model — use a conservative default of $10/M input, $30/M output
152
+ const rate = isOutput ? 30.0 : 10.0;
153
+ return (tokens / 1_000_000) * rate;
154
+ }
155
+ const rate = isOutput ? price.output : price.input;
156
+ return (tokens / 1_000_000) * rate;
157
+ }
158
+ /** Get the full pricing record for a model, or null if unknown. */
159
+ getPricingForModel(model) {
160
+ return this.prices[model] ?? null;
161
+ }
162
+ /** List all known model pricing entries. */
163
+ listModels() {
164
+ return Object.keys(this.prices);
165
+ }
166
+ /** Add or update pricing for a model at runtime. */
167
+ addPricing(model, inputCost, outputCost) {
168
+ this.prices[model] = { input: inputCost, output: outputCost };
169
+ }
170
+ }
171
+ //# sourceMappingURL=pricing-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing-client.js","sourceRoot":"","sources":["../../src/clients/pricing-client.ts"],"names":[],"mappings":"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"}