@inkog-io/mcp 1.0.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/LICENSE +190 -0
- package/README.md +265 -0
- package/dist/api/client.d.ts +108 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +288 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/types.d.ts +286 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +21 -0
- package/dist/api/types.js.map +1 -0
- package/dist/config.d.ts +68 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +130 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +203 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/audit-a2a.d.ts +20 -0
- package/dist/tools/audit-a2a.d.ts.map +1 -0
- package/dist/tools/audit-a2a.js +382 -0
- package/dist/tools/audit-a2a.js.map +1 -0
- package/dist/tools/audit-mcp.d.ts +16 -0
- package/dist/tools/audit-mcp.d.ts.map +1 -0
- package/dist/tools/audit-mcp.js +259 -0
- package/dist/tools/audit-mcp.js.map +1 -0
- package/dist/tools/compliance.d.ts +14 -0
- package/dist/tools/compliance.d.ts.map +1 -0
- package/dist/tools/compliance.js +255 -0
- package/dist/tools/compliance.js.map +1 -0
- package/dist/tools/explain.d.ts +14 -0
- package/dist/tools/explain.d.ts.map +1 -0
- package/dist/tools/explain.js +202 -0
- package/dist/tools/explain.js.map +1 -0
- package/dist/tools/governance.d.ts +16 -0
- package/dist/tools/governance.d.ts.map +1 -0
- package/dist/tools/governance.js +200 -0
- package/dist/tools/governance.js.map +1 -0
- package/dist/tools/index.d.ts +50 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +94 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mlbom.d.ts +18 -0
- package/dist/tools/mlbom.d.ts.map +1 -0
- package/dist/tools/mlbom.js +344 -0
- package/dist/tools/mlbom.js.map +1 -0
- package/dist/tools/scan.d.ts +15 -0
- package/dist/tools/scan.d.ts.map +1 -0
- package/dist/tools/scan.js +270 -0
- package/dist/tools/scan.js.map +1 -0
- package/dist/utils/file-reader.d.ts +55 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +269 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkog_generate_mlbom Tool
|
|
3
|
+
*
|
|
4
|
+
* P1 - Machine Learning Bill of Materials (MLBOM) Generation
|
|
5
|
+
*
|
|
6
|
+
* Generates a comprehensive inventory of all ML/AI components in an agent system:
|
|
7
|
+
* - Models (OpenAI, Anthropic, local models, etc.)
|
|
8
|
+
* - Tools (function calls, APIs, integrations)
|
|
9
|
+
* - Data sources (databases, vector stores, file systems)
|
|
10
|
+
* - Frameworks (LangChain, CrewAI, LangGraph, etc.)
|
|
11
|
+
* - Dependencies (pip, npm packages)
|
|
12
|
+
*
|
|
13
|
+
* Output formats: CycloneDX (recommended), SPDX, JSON
|
|
14
|
+
* Gartner-recommended capability for AI supply chain visibility.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { getClient, InkogAuthError, InkogNetworkError } from '../api/client.js';
|
|
18
|
+
import { getRelativePaths, readDirectory } from '../utils/file-reader.js';
|
|
19
|
+
// =============================================================================
|
|
20
|
+
// Schema
|
|
21
|
+
// =============================================================================
|
|
22
|
+
const MlbomArgsSchema = z.object({
|
|
23
|
+
path: z.string().describe('Path to agent codebase to analyze'),
|
|
24
|
+
format: z
|
|
25
|
+
.enum(['cyclonedx', 'spdx', 'json'])
|
|
26
|
+
.optional()
|
|
27
|
+
.default('cyclonedx')
|
|
28
|
+
.describe('Output format: cyclonedx (recommended), spdx, or json'),
|
|
29
|
+
include_vulnerabilities: z
|
|
30
|
+
.boolean()
|
|
31
|
+
.optional()
|
|
32
|
+
.default(true)
|
|
33
|
+
.describe('Include known vulnerabilities for detected components'),
|
|
34
|
+
});
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// Helpers
|
|
37
|
+
// =============================================================================
|
|
38
|
+
function formatComponentType(type) {
|
|
39
|
+
switch (type) {
|
|
40
|
+
case 'model':
|
|
41
|
+
return '🧠 Model';
|
|
42
|
+
case 'tool':
|
|
43
|
+
return '🔧 Tool';
|
|
44
|
+
case 'data-source':
|
|
45
|
+
return '💾 Data Source';
|
|
46
|
+
case 'framework':
|
|
47
|
+
return '📦 Framework';
|
|
48
|
+
case 'dependency':
|
|
49
|
+
return '📚 Dependency';
|
|
50
|
+
default:
|
|
51
|
+
return type;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function formatSeverityIcon(severity) {
|
|
55
|
+
switch (severity) {
|
|
56
|
+
case 'CRITICAL':
|
|
57
|
+
return '🔴';
|
|
58
|
+
case 'HIGH':
|
|
59
|
+
return '🟠';
|
|
60
|
+
case 'MEDIUM':
|
|
61
|
+
return '🟡';
|
|
62
|
+
case 'LOW':
|
|
63
|
+
return '🟢';
|
|
64
|
+
default:
|
|
65
|
+
return '⚪';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function formatRiskScore(score) {
|
|
69
|
+
if (score >= 90) {
|
|
70
|
+
return `✅ ${score}/100 (Low Risk)`;
|
|
71
|
+
}
|
|
72
|
+
else if (score >= 70) {
|
|
73
|
+
return `🟢 ${score}/100 (Moderate Risk)`;
|
|
74
|
+
}
|
|
75
|
+
else if (score >= 50) {
|
|
76
|
+
return `🟡 ${score}/100 (Elevated Risk)`;
|
|
77
|
+
}
|
|
78
|
+
else if (score >= 30) {
|
|
79
|
+
return `🟠 ${score}/100 (High Risk)`;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return `🔴 ${score}/100 (Critical Risk)`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function formatComponent(component, detailed) {
|
|
86
|
+
const typeLabel = formatComponentType(component.type);
|
|
87
|
+
let output = `${typeLabel}: ${component.name}`;
|
|
88
|
+
if (component.version !== undefined) {
|
|
89
|
+
output += ` v${component.version}`;
|
|
90
|
+
}
|
|
91
|
+
output += '\n';
|
|
92
|
+
if (component.provider !== undefined) {
|
|
93
|
+
output += ` Provider: ${component.provider}\n`;
|
|
94
|
+
}
|
|
95
|
+
if (component.license !== undefined) {
|
|
96
|
+
output += ` License: ${component.license}\n`;
|
|
97
|
+
}
|
|
98
|
+
output += ` 📍 ${component.location}`;
|
|
99
|
+
if (component.line !== undefined) {
|
|
100
|
+
output += `:${component.line}`;
|
|
101
|
+
}
|
|
102
|
+
output += '\n';
|
|
103
|
+
if (detailed && component.properties !== undefined && Object.keys(component.properties).length > 0) {
|
|
104
|
+
output += ' Properties:\n';
|
|
105
|
+
for (const [key, value] of Object.entries(component.properties)) {
|
|
106
|
+
output += ` • ${key}: ${value}\n`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (component.vulnerabilities !== undefined && component.vulnerabilities.length > 0) {
|
|
110
|
+
output += ' ⚠️ Vulnerabilities:\n';
|
|
111
|
+
for (const vuln of component.vulnerabilities) {
|
|
112
|
+
const icon = formatSeverityIcon(vuln.severity);
|
|
113
|
+
output += ` ${icon} ${vuln.id}: ${vuln.description}\n`;
|
|
114
|
+
if (vuln.cve !== undefined) {
|
|
115
|
+
output += ` CVE: ${vuln.cve}\n`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return output;
|
|
120
|
+
}
|
|
121
|
+
function groupComponentsByType(components) {
|
|
122
|
+
const groups = {};
|
|
123
|
+
for (const component of components) {
|
|
124
|
+
const existing = groups[component.type];
|
|
125
|
+
if (existing === undefined) {
|
|
126
|
+
groups[component.type] = [component];
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
existing.push(component);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return groups;
|
|
133
|
+
}
|
|
134
|
+
// =============================================================================
|
|
135
|
+
// Handler
|
|
136
|
+
// =============================================================================
|
|
137
|
+
async function mlbomHandler(rawArgs) {
|
|
138
|
+
// Validate arguments
|
|
139
|
+
const parseResult = MlbomArgsSchema.safeParse(rawArgs);
|
|
140
|
+
if (!parseResult.success) {
|
|
141
|
+
return {
|
|
142
|
+
content: [
|
|
143
|
+
{
|
|
144
|
+
type: 'text',
|
|
145
|
+
text: `Invalid arguments: ${parseResult.error.message}`,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
isError: true,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const args = parseResult.data;
|
|
152
|
+
try {
|
|
153
|
+
// Read files from path
|
|
154
|
+
const readResult = readDirectory(args.path);
|
|
155
|
+
if (readResult.files.length === 0) {
|
|
156
|
+
return {
|
|
157
|
+
content: [
|
|
158
|
+
{
|
|
159
|
+
type: 'text',
|
|
160
|
+
text: `No files found in: ${args.path}`,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
isError: true,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// Get relative paths
|
|
167
|
+
const files = getRelativePaths(readResult.files, args.path);
|
|
168
|
+
// Call Inkog API
|
|
169
|
+
const client = getClient();
|
|
170
|
+
const response = await client.generateMlbom(files, {
|
|
171
|
+
format: args.format,
|
|
172
|
+
includeVulnerabilities: args.include_vulnerabilities,
|
|
173
|
+
});
|
|
174
|
+
// If format is CycloneDX or SPDX, return the pre-formatted content
|
|
175
|
+
if (args.format !== 'json' && response.bomContent !== undefined) {
|
|
176
|
+
let output = '╔══════════════════════════════════════════════════════╗\n';
|
|
177
|
+
output += '║ 📋 ML Bill of Materials (MLBOM) ║\n';
|
|
178
|
+
output += '╚══════════════════════════════════════════════════════╝\n\n';
|
|
179
|
+
output += `📦 Format: ${args.format.toUpperCase()}\n`;
|
|
180
|
+
output += `📅 Generated: ${response.generatedAt}\n`;
|
|
181
|
+
output += `📊 Components: ${response.components.length}\n`;
|
|
182
|
+
output += `⚠️ Vulnerabilities: ${response.vulnerabilityCount}\n`;
|
|
183
|
+
output += `🔒 Risk Score: ${formatRiskScore(response.riskScore)}\n\n`;
|
|
184
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
185
|
+
output += `${args.format.toUpperCase()} Output:\n\n`;
|
|
186
|
+
output += '```' + (args.format === 'cyclonedx' ? 'json' : 'xml') + '\n';
|
|
187
|
+
output += response.bomContent + '\n';
|
|
188
|
+
output += '```\n';
|
|
189
|
+
return {
|
|
190
|
+
content: [
|
|
191
|
+
{
|
|
192
|
+
type: 'text',
|
|
193
|
+
text: output,
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// Build human-readable output for JSON format
|
|
199
|
+
let output = '╔══════════════════════════════════════════════════════╗\n';
|
|
200
|
+
output += '║ 📋 ML Bill of Materials (MLBOM) ║\n';
|
|
201
|
+
output += '╚══════════════════════════════════════════════════════╝\n\n';
|
|
202
|
+
output += `📦 Version: ${response.version}\n`;
|
|
203
|
+
output += `📅 Generated: ${response.generatedAt}\n`;
|
|
204
|
+
output += `📊 Total Components: ${response.components.length}\n`;
|
|
205
|
+
output += `⚠️ Total Vulnerabilities: ${response.vulnerabilityCount}\n`;
|
|
206
|
+
output += `🔒 Supply Chain Risk Score: ${formatRiskScore(response.riskScore)}\n\n`;
|
|
207
|
+
// Component summary by type
|
|
208
|
+
const groups = groupComponentsByType(response.components);
|
|
209
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
210
|
+
output += '📊 COMPONENT SUMMARY\n\n';
|
|
211
|
+
const typeOrder = ['model', 'tool', 'data-source', 'framework', 'dependency'];
|
|
212
|
+
for (const type of typeOrder) {
|
|
213
|
+
const components = groups[type];
|
|
214
|
+
if (components !== undefined && components.length > 0) {
|
|
215
|
+
output += `${formatComponentType(type)}: ${components.length}\n`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
output += '\n';
|
|
219
|
+
// Detailed component list
|
|
220
|
+
if (response.components.length > 0) {
|
|
221
|
+
// Models first (most important)
|
|
222
|
+
if (groups.model !== undefined && groups.model.length > 0) {
|
|
223
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
224
|
+
output += '🧠 MODELS\n\n';
|
|
225
|
+
for (const component of groups.model) {
|
|
226
|
+
output += formatComponent(component, true) + '\n';
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Tools
|
|
230
|
+
if (groups.tool !== undefined && groups.tool.length > 0) {
|
|
231
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
232
|
+
output += '🔧 TOOLS\n\n';
|
|
233
|
+
for (const component of groups.tool) {
|
|
234
|
+
output += formatComponent(component, true) + '\n';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Data sources
|
|
238
|
+
if (groups['data-source'] !== undefined && groups['data-source'].length > 0) {
|
|
239
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
240
|
+
output += '💾 DATA SOURCES\n\n';
|
|
241
|
+
for (const component of groups['data-source']) {
|
|
242
|
+
output += formatComponent(component, true) + '\n';
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Frameworks
|
|
246
|
+
if (groups.framework !== undefined && groups.framework.length > 0) {
|
|
247
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
248
|
+
output += '📦 FRAMEWORKS\n\n';
|
|
249
|
+
for (const component of groups.framework) {
|
|
250
|
+
output += formatComponent(component, false) + '\n';
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Dependencies (less detailed)
|
|
254
|
+
if (groups.dependency !== undefined && groups.dependency.length > 0) {
|
|
255
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
256
|
+
output += '📚 DEPENDENCIES\n\n';
|
|
257
|
+
// Only show vulnerable dependencies in detail
|
|
258
|
+
const vulnerableDeps = groups.dependency.filter((d) => d.vulnerabilities !== undefined && d.vulnerabilities.length > 0);
|
|
259
|
+
const safeDeps = groups.dependency.filter((d) => d.vulnerabilities === undefined || d.vulnerabilities.length === 0);
|
|
260
|
+
if (vulnerableDeps.length > 0) {
|
|
261
|
+
output += '⚠️ Vulnerable Dependencies:\n\n';
|
|
262
|
+
for (const component of vulnerableDeps) {
|
|
263
|
+
output += formatComponent(component, true) + '\n';
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (safeDeps.length > 0) {
|
|
267
|
+
output += 'Other Dependencies: ';
|
|
268
|
+
output += safeDeps.map((d) => `${d.name}${d.version !== undefined ? `@${d.version}` : ''}`).join(', ');
|
|
269
|
+
output += '\n';
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
// Footer with export hint
|
|
274
|
+
output += '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
|
|
275
|
+
output += '💡 TIP: Use format="cyclonedx" or format="spdx" for standard export\n';
|
|
276
|
+
output += 'MLBOM generation powered by Inkog AI Security Platform\n';
|
|
277
|
+
output += 'Learn more: https://inkog.io/mlbom\n';
|
|
278
|
+
return {
|
|
279
|
+
content: [
|
|
280
|
+
{
|
|
281
|
+
type: 'text',
|
|
282
|
+
text: output,
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
if (error instanceof InkogAuthError) {
|
|
289
|
+
return {
|
|
290
|
+
content: [
|
|
291
|
+
{
|
|
292
|
+
type: 'text',
|
|
293
|
+
text: '🔐 API Key Required\n\nGet your free key at https://app.inkog.io',
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
isError: true,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
if (error instanceof InkogNetworkError) {
|
|
300
|
+
return {
|
|
301
|
+
content: [
|
|
302
|
+
{
|
|
303
|
+
type: 'text',
|
|
304
|
+
text: `Network error: ${error.message}`,
|
|
305
|
+
},
|
|
306
|
+
],
|
|
307
|
+
isError: true,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// =============================================================================
|
|
314
|
+
// Tool Definition
|
|
315
|
+
// =============================================================================
|
|
316
|
+
export const mlbomTool = {
|
|
317
|
+
tool: {
|
|
318
|
+
name: 'inkog_generate_mlbom',
|
|
319
|
+
description: 'Generate a Machine Learning Bill of Materials (MLBOM) for AI agents. Lists all models, tools, data sources, frameworks, and dependencies with known vulnerabilities. Supports CycloneDX and SPDX formats for supply chain compliance.',
|
|
320
|
+
inputSchema: {
|
|
321
|
+
type: 'object',
|
|
322
|
+
properties: {
|
|
323
|
+
path: {
|
|
324
|
+
type: 'string',
|
|
325
|
+
description: 'Path to agent codebase to analyze',
|
|
326
|
+
},
|
|
327
|
+
format: {
|
|
328
|
+
type: 'string',
|
|
329
|
+
enum: ['cyclonedx', 'spdx', 'json'],
|
|
330
|
+
default: 'cyclonedx',
|
|
331
|
+
description: 'Output format: cyclonedx (recommended), spdx, or json',
|
|
332
|
+
},
|
|
333
|
+
include_vulnerabilities: {
|
|
334
|
+
type: 'boolean',
|
|
335
|
+
default: true,
|
|
336
|
+
description: 'Include known vulnerabilities for detected components',
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
required: ['path'],
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
handler: mlbomHandler,
|
|
343
|
+
};
|
|
344
|
+
//# sourceMappingURL=mlbom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mlbom.js","sourceRoot":"","sources":["../../src/tools/mlbom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkog_scan Tool
|
|
3
|
+
*
|
|
4
|
+
* P0 - Core vulnerability scanning tool
|
|
5
|
+
*
|
|
6
|
+
* Scans AI agent code for security vulnerabilities including:
|
|
7
|
+
* - Prompt injection
|
|
8
|
+
* - Infinite loops / token bombing
|
|
9
|
+
* - SQL injection via LLM
|
|
10
|
+
* - Hardcoded credentials
|
|
11
|
+
* - Missing governance controls
|
|
12
|
+
*/
|
|
13
|
+
import type { ToolDefinition } from './index.js';
|
|
14
|
+
export declare const scanTool: ToolDefinition;
|
|
15
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/tools/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAyR7D,eAAO,MAAM,QAAQ,EAAE,cA+BtB,CAAC"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkog_scan Tool
|
|
3
|
+
*
|
|
4
|
+
* P0 - Core vulnerability scanning tool
|
|
5
|
+
*
|
|
6
|
+
* Scans AI agent code for security vulnerabilities including:
|
|
7
|
+
* - Prompt injection
|
|
8
|
+
* - Infinite loops / token bombing
|
|
9
|
+
* - SQL injection via LLM
|
|
10
|
+
* - Hardcoded credentials
|
|
11
|
+
* - Missing governance controls
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { getClient, InkogAuthError, InkogNetworkError } from '../api/client.js';
|
|
15
|
+
import { getRelativePaths, readDirectory } from '../utils/file-reader.js';
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// Schema
|
|
18
|
+
// =============================================================================
|
|
19
|
+
const ScanArgsSchema = z.object({
|
|
20
|
+
path: z.string().describe('File or directory path to scan'),
|
|
21
|
+
policy: z
|
|
22
|
+
.enum(['low-noise', 'balanced', 'comprehensive', 'governance', 'eu-ai-act'])
|
|
23
|
+
.optional()
|
|
24
|
+
.default('balanced')
|
|
25
|
+
.describe('Security policy: low-noise (proven vulnerabilities only), balanced (default), comprehensive (all findings), governance (Article 14 focused), eu-ai-act (compliance mode)'),
|
|
26
|
+
output: z
|
|
27
|
+
.enum(['summary', 'detailed', 'sarif'])
|
|
28
|
+
.optional()
|
|
29
|
+
.default('summary')
|
|
30
|
+
.describe('Output format: summary (default), detailed (full findings), sarif (for CI/CD)'),
|
|
31
|
+
});
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Helpers
|
|
34
|
+
// =============================================================================
|
|
35
|
+
function formatSeverityIcon(severity) {
|
|
36
|
+
switch (severity) {
|
|
37
|
+
case 'CRITICAL':
|
|
38
|
+
return '🔴';
|
|
39
|
+
case 'HIGH':
|
|
40
|
+
return '🟠';
|
|
41
|
+
case 'MEDIUM':
|
|
42
|
+
return '🟡';
|
|
43
|
+
case 'LOW':
|
|
44
|
+
return '🟢';
|
|
45
|
+
default:
|
|
46
|
+
return '⚪';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function formatRiskTier(tier) {
|
|
50
|
+
switch (tier) {
|
|
51
|
+
case 'vulnerability':
|
|
52
|
+
return 'Exploitable Vulnerability';
|
|
53
|
+
case 'risk_pattern':
|
|
54
|
+
return 'Risk Pattern';
|
|
55
|
+
case 'hardening':
|
|
56
|
+
return 'Hardening Recommendation';
|
|
57
|
+
default:
|
|
58
|
+
return tier;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function formatFinding(finding, detailed) {
|
|
62
|
+
const icon = formatSeverityIcon(finding.severity);
|
|
63
|
+
const tierLabel = formatRiskTier(finding.riskTier);
|
|
64
|
+
const location = `${finding.file}:${finding.line}`;
|
|
65
|
+
let output = `${icon} [${finding.severity}] ${finding.message}\n`;
|
|
66
|
+
output += ` 📍 ${location}\n`;
|
|
67
|
+
output += ` 📊 ${tierLabel}`;
|
|
68
|
+
if (finding.cwe !== undefined) {
|
|
69
|
+
output += ` | ${finding.cwe}`;
|
|
70
|
+
}
|
|
71
|
+
if (finding.inputTainted && finding.taintSource !== undefined) {
|
|
72
|
+
output += `\n ⚠️ Taint source: ${finding.taintSource}`;
|
|
73
|
+
}
|
|
74
|
+
if (detailed && finding.remediation !== undefined) {
|
|
75
|
+
output += `\n 💡 ${finding.remediation}`;
|
|
76
|
+
}
|
|
77
|
+
if (detailed && finding.codeSnippet !== undefined) {
|
|
78
|
+
output += `\n \`\`\`\n ${finding.codeSnippet}\n \`\`\``;
|
|
79
|
+
}
|
|
80
|
+
return output;
|
|
81
|
+
}
|
|
82
|
+
function formatSummary(findings, riskScore, filesScanned, policy) {
|
|
83
|
+
const critical = findings.filter((f) => f.severity === 'CRITICAL').length;
|
|
84
|
+
const high = findings.filter((f) => f.severity === 'HIGH').length;
|
|
85
|
+
const medium = findings.filter((f) => f.severity === 'MEDIUM').length;
|
|
86
|
+
const low = findings.filter((f) => f.severity === 'LOW').length;
|
|
87
|
+
const vulnerabilities = findings.filter((f) => f.riskTier === 'vulnerability').length;
|
|
88
|
+
const riskPatterns = findings.filter((f) => f.riskTier === 'risk_pattern').length;
|
|
89
|
+
const hardening = findings.filter((f) => f.riskTier === 'hardening').length;
|
|
90
|
+
let output = '╔══════════════════════════════════════════════════════╗\n';
|
|
91
|
+
output += '║ 🔍 AI Agent Risk Assessment ║\n';
|
|
92
|
+
output += '╚══════════════════════════════════════════════════════╝\n\n';
|
|
93
|
+
output += `📁 Files scanned: ${filesScanned}\n`;
|
|
94
|
+
output += `📊 Risk score: ${riskScore}/100\n`;
|
|
95
|
+
output += `🔒 Policy: ${policy}\n\n`;
|
|
96
|
+
if (findings.length === 0) {
|
|
97
|
+
output += '✅ No security findings detected!\n';
|
|
98
|
+
return output;
|
|
99
|
+
}
|
|
100
|
+
output += `📋 Total findings: ${findings.length}\n`;
|
|
101
|
+
output += ` 🔴 Critical: ${critical} | 🟠 High: ${high} | 🟡 Medium: ${medium} | 🟢 Low: ${low}\n\n`;
|
|
102
|
+
if (vulnerabilities > 0) {
|
|
103
|
+
output += `🔴 EXPLOITABLE VULNERABILITIES (${vulnerabilities})\n`;
|
|
104
|
+
output +=
|
|
105
|
+
' Require immediate attention - proven attack paths\n\n';
|
|
106
|
+
}
|
|
107
|
+
if (riskPatterns > 0) {
|
|
108
|
+
output += `🟠 RISK PATTERNS (${riskPatterns})\n`;
|
|
109
|
+
output += ' Structural issues that could become vulnerabilities\n\n';
|
|
110
|
+
}
|
|
111
|
+
if (hardening > 0) {
|
|
112
|
+
output += `🟡 HARDENING RECOMMENDATIONS (${hardening})\n`;
|
|
113
|
+
output += ' Best practices for improved security posture\n\n';
|
|
114
|
+
}
|
|
115
|
+
return output;
|
|
116
|
+
}
|
|
117
|
+
// =============================================================================
|
|
118
|
+
// Handler
|
|
119
|
+
// =============================================================================
|
|
120
|
+
async function scanHandler(rawArgs) {
|
|
121
|
+
// Validate arguments
|
|
122
|
+
const parseResult = ScanArgsSchema.safeParse(rawArgs);
|
|
123
|
+
if (!parseResult.success) {
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: `Invalid arguments: ${parseResult.error.message}`,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
isError: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const args = parseResult.data;
|
|
135
|
+
try {
|
|
136
|
+
// Read files from path
|
|
137
|
+
const readResult = readDirectory(args.path);
|
|
138
|
+
if (readResult.files.length === 0) {
|
|
139
|
+
return {
|
|
140
|
+
content: [
|
|
141
|
+
{
|
|
142
|
+
type: 'text',
|
|
143
|
+
text: `No scannable files found in: ${args.path}\n\nSupported file types: .py, .js, .ts, .go, .java, .rb, .yaml, .json, .md`,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Get relative paths for cleaner output
|
|
149
|
+
const files = getRelativePaths(readResult.files, args.path);
|
|
150
|
+
// Call Inkog API
|
|
151
|
+
const client = getClient();
|
|
152
|
+
const response = await client.scan(files, {
|
|
153
|
+
policy: args.policy,
|
|
154
|
+
output: args.output,
|
|
155
|
+
});
|
|
156
|
+
// Format output based on requested format
|
|
157
|
+
if (args.output === 'sarif') {
|
|
158
|
+
// Return raw SARIF for CI/CD integration
|
|
159
|
+
return {
|
|
160
|
+
content: [
|
|
161
|
+
{
|
|
162
|
+
type: 'text',
|
|
163
|
+
text: JSON.stringify(response, null, 2),
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// Build human-readable output
|
|
169
|
+
let output = formatSummary(response.findings, response.riskScore, response.filesScanned, args.policy);
|
|
170
|
+
// Add findings
|
|
171
|
+
if (response.findings.length > 0) {
|
|
172
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
173
|
+
// Group by tier
|
|
174
|
+
const vulnerabilities = response.findings.filter((f) => f.riskTier === 'vulnerability');
|
|
175
|
+
const riskPatterns = response.findings.filter((f) => f.riskTier === 'risk_pattern');
|
|
176
|
+
const hardening = response.findings.filter((f) => f.riskTier === 'hardening');
|
|
177
|
+
if (vulnerabilities.length > 0) {
|
|
178
|
+
output += '🔴 EXPLOITABLE VULNERABILITIES:\n\n';
|
|
179
|
+
for (const finding of vulnerabilities) {
|
|
180
|
+
output += formatFinding(finding, args.output === 'detailed') + '\n\n';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (riskPatterns.length > 0) {
|
|
184
|
+
output += '🟠 RISK PATTERNS:\n\n';
|
|
185
|
+
for (const finding of riskPatterns) {
|
|
186
|
+
output += formatFinding(finding, args.output === 'detailed') + '\n\n';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (hardening.length > 0 && args.policy === 'comprehensive') {
|
|
190
|
+
output += '🟡 HARDENING RECOMMENDATIONS:\n\n';
|
|
191
|
+
for (const finding of hardening) {
|
|
192
|
+
output += formatFinding(finding, args.output === 'detailed') + '\n\n';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Add governance summary if available
|
|
197
|
+
if (response.governance !== undefined) {
|
|
198
|
+
output += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n';
|
|
199
|
+
output += '🏛️ GOVERNANCE STATUS\n\n';
|
|
200
|
+
output += ` Governance Score: ${response.governance.governanceScore}/100\n`;
|
|
201
|
+
output += ` EU AI Act Readiness: ${response.governance.euAiActReadiness}\n`;
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
content: [
|
|
205
|
+
{
|
|
206
|
+
type: 'text',
|
|
207
|
+
text: output,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (error instanceof InkogAuthError) {
|
|
214
|
+
return {
|
|
215
|
+
content: [
|
|
216
|
+
{
|
|
217
|
+
type: 'text',
|
|
218
|
+
text: '🔐 API Key Required\n\nTo use Inkog, you need an API key.\n\n1. Sign up for free at https://app.inkog.io\n2. Set your API key: export INKOG_API_KEY=sk_live_...\n3. Try again!',
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
isError: true,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
if (error instanceof InkogNetworkError) {
|
|
225
|
+
return {
|
|
226
|
+
content: [
|
|
227
|
+
{
|
|
228
|
+
type: 'text',
|
|
229
|
+
text: `Network error: ${error.message}\n\nPlease check your internet connection and try again.`,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
isError: true,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// =============================================================================
|
|
239
|
+
// Tool Definition
|
|
240
|
+
// =============================================================================
|
|
241
|
+
export const scanTool = {
|
|
242
|
+
tool: {
|
|
243
|
+
name: 'inkog_scan',
|
|
244
|
+
description: 'Scan AI agent code for security vulnerabilities including prompt injection, infinite loops, token bombing, SQL injection via LLM, and governance gaps. Supports LangChain, CrewAI, LangGraph, n8n, and other agent frameworks.',
|
|
245
|
+
inputSchema: {
|
|
246
|
+
type: 'object',
|
|
247
|
+
properties: {
|
|
248
|
+
path: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
description: 'File or directory path to scan',
|
|
251
|
+
},
|
|
252
|
+
policy: {
|
|
253
|
+
type: 'string',
|
|
254
|
+
enum: ['low-noise', 'balanced', 'comprehensive', 'governance', 'eu-ai-act'],
|
|
255
|
+
default: 'balanced',
|
|
256
|
+
description: 'Security policy: low-noise (proven vulnerabilities only), balanced (default), comprehensive (all findings), governance (Article 14 focused), eu-ai-act (compliance mode)',
|
|
257
|
+
},
|
|
258
|
+
output: {
|
|
259
|
+
type: 'string',
|
|
260
|
+
enum: ['summary', 'detailed', 'sarif'],
|
|
261
|
+
default: 'summary',
|
|
262
|
+
description: 'Output format: summary (default), detailed (full findings), sarif (for CI/CD)',
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
required: ['path'],
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
handler: scanHandler,
|
|
269
|
+
};
|
|
270
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/tools/scan.ts"],"names":[],"mappings":"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"}
|