@nohacklabs/mcp-server 1.0.3

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 ADDED
@@ -0,0 +1,165 @@
1
+ # NoHack Security MCP Server
2
+
3
+ An MCP (Model Context Protocol) server for querying security scan data from the NoHack platform. Analyze vulnerabilities, secrets, scans, and repository configurations directly from AI assistants like Claude, Cursor, or any MCP-compatible client.
4
+
5
+ ## Features
6
+
7
+ - Query security scan results across repositories
8
+ - Analyze vulnerabilities by severity, type, and status
9
+ - Track detected secrets with filtering by detector type
10
+ - Aggregate and trend analysis with grouping support
11
+ - Filter by organization, repository, date ranges, and custom criteria
12
+
13
+ ## Tools
14
+
15
+ ### Listing Tools
16
+
17
+ | Tool | Description |
18
+ |------|-------------|
19
+ | `list_scans` | List security scans with filters |
20
+ | `list_vulnerabilities` | List vulnerabilities by severity, status, scan |
21
+ | `list_repositories` | List configured repositories |
22
+ | `list_secrets` | List detected secrets with detector type filtering |
23
+ | `get_recent_scans` | Get scans from last N days |
24
+ | `get_recent_vulnerabilities` | Get vulnerabilities from last N days |
25
+ | `search_vulnerabilities` | Text search across vulnerabilities |
26
+
27
+ ### Advanced Query Tool
28
+
29
+ | Tool | Description |
30
+ |------|-------------|
31
+ | `query_collection` | Complex queries with aggregations and grouping |
32
+
33
+ ### Detail Tools
34
+
35
+ | Tool | Description |
36
+ |------|-------------|
37
+ | `get_scan_details` | Full scan details with vulnerabilities and secrets |
38
+ | `get_vulnerability_details` | Full vulnerability with code context and recommendations |
39
+ | `get_repo_config_details` | Repository configuration details |
40
+ | `get_organization` | Organization details |
41
+
42
+ ## Collections
43
+
44
+ - `scans` - Security scan records
45
+ - `vulnerabilities` - Detected vulnerabilities
46
+ - `secrets` - Detected secrets (filter by `detector_name`: Github, AWS, PrivateKey, OpenAI, etc.)
47
+ - `github_repo_config` - Repository configurations
48
+ - `organisations` - Organization data
49
+
50
+ ## Usage Examples
51
+
52
+ ### List Critical Vulnerabilities
53
+ ```json
54
+ {
55
+ "orgId": "your-org-id",
56
+ "severity": "Critical",
57
+ "limit": 50
58
+ }
59
+ ```
60
+
61
+ ### List GitHub Secrets
62
+ ```json
63
+ {
64
+ "orgId": "your-org-id",
65
+ "detectorName": "Github",
66
+ "limit": 50
67
+ }
68
+ ```
69
+
70
+ ### Count Vulnerabilities by Severity
71
+ ```json
72
+ {
73
+ "collection": "vulnerabilities",
74
+ "aggregate": { "count": "*" },
75
+ "groupBy": ["severity"],
76
+ "limit": -1
77
+ }
78
+ ```
79
+
80
+ ### Search for SQL Injection
81
+ ```json
82
+ {
83
+ "orgId": "your-org-id",
84
+ "query": "SQL injection",
85
+ "limit": 50
86
+ }
87
+ ```
88
+
89
+ ## Configuration
90
+
91
+ The server requires environment variables:
92
+
93
+ | Variable | Description |
94
+ |----------|-------------|
95
+ | `NOHACK_API_URL` | NoHack API endpoint |
96
+ | `NOHACK_API_TOKEN` | Your API access token |
97
+
98
+ ## Integration
99
+
100
+ ### Claude Desktop
101
+
102
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
103
+
104
+ ```json
105
+ {
106
+ "mcpServers": {
107
+ "nohack-security": {
108
+ "command": "npx",
109
+ "args": ["@nohacklabs/mcp-server"],
110
+ "env": {
111
+ "NOHACK_API_URL": "https://your-nohack-instance.com",
112
+ "NOHACK_API_TOKEN": "your-api-token"
113
+ }
114
+ }
115
+ }
116
+ }
117
+ ```
118
+
119
+ ### Cursor
120
+
121
+ Add to your Cursor MCP settings:
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "nohack-security": {
127
+ "command": "npx",
128
+ "args": ["@nohacklabs/mcp-server"],
129
+ "env": {
130
+ "NOHACK_API_URL": "https://your-nohack-instance.com",
131
+ "NOHACK_API_TOKEN": "your-api-token"
132
+ }
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## Filter Operators
139
+
140
+ | Operator | Description |
141
+ |----------|-------------|
142
+ | `_eq` | Equals |
143
+ | `_neq` | Not equals |
144
+ | `_in` | In array |
145
+ | `_gt`, `_gte`, `_lt`, `_lte` | Comparisons |
146
+ | `_contains`, `_icontains` | Text search |
147
+ | `_null`, `_nnull` | Null checks |
148
+ | `_and`, `_or` | Logical operators |
149
+
150
+ ## Dynamic Dates
151
+
152
+ | Expression | Meaning |
153
+ |------------|---------|
154
+ | `$NOW(-7 days)` | 7 days ago |
155
+ | `$NOW(-1 month)` | 1 month ago |
156
+ | `$NOW(-1 year)` | 1 year ago |
157
+
158
+ ## License
159
+
160
+ MIT
161
+
162
+ ## Links
163
+
164
+ - [NoHack Labs](https://nohacklabs.com)
165
+ - [Documentation](https://docs.nohacklabs.com)
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,724 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ // ============================================================================
6
+ // API CLIENT
7
+ // ============================================================================
8
+ class ApiClient {
9
+ apiUrl;
10
+ token;
11
+ constructor(apiUrl, token) {
12
+ this.apiUrl = apiUrl;
13
+ this.token = token;
14
+ }
15
+ async fetch(endpoint, options) {
16
+ const url = `${this.apiUrl}${endpoint}`;
17
+ const response = await fetch(url, {
18
+ ...options,
19
+ headers: {
20
+ Authorization: `Bearer ${this.token}`,
21
+ "Content-Type": "application/json",
22
+ ...options?.headers,
23
+ },
24
+ });
25
+ if (!response.ok) {
26
+ const errorText = await response.text();
27
+ throw new Error(`API Error: ${response.status} ${response.statusText} - ${errorText}`);
28
+ }
29
+ return response.json();
30
+ }
31
+ // ---------------------------------------------------------------------------
32
+ // Schema Discovery (via generic collections API metadata)
33
+ // ---------------------------------------------------------------------------
34
+ async getCollectionSchema(collection) {
35
+ // Use the generic collections API with meta parameter to get schema info
36
+ const params = new URLSearchParams();
37
+ params.set("limit", "1");
38
+ params.set("meta", "*");
39
+ const result = await this.fetch(`/api/collections/${collection}?${params.toString()}`);
40
+ // Return basic schema information from metadata
41
+ return {
42
+ collection,
43
+ message: "Schema discovery via BFF API. Use query_collection with specific fields.",
44
+ availableFields: "Use the generic query API to discover available fields by querying with limit=1",
45
+ sampleQuery: `{ collection: "${collection}", fields: ["*"], limit: 1 }`
46
+ };
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // Generic Query (via BFF API)
50
+ // ---------------------------------------------------------------------------
51
+ async queryCollection(options) {
52
+ const { collection, filter, aggregate, groupBy, sort, limit, offset, fields, deep, orgId, } = options;
53
+ const params = new URLSearchParams();
54
+ // Add orgId if provided
55
+ if (orgId) {
56
+ params.set("orgId", orgId);
57
+ }
58
+ // Add filter
59
+ if (filter) {
60
+ params.set("filter", JSON.stringify(filter));
61
+ }
62
+ // Add aggregation
63
+ if (aggregate) {
64
+ if (aggregate.count) {
65
+ if (Array.isArray(aggregate.count)) {
66
+ aggregate.count.forEach((field) => params.append("aggregate[count][]", field));
67
+ }
68
+ else {
69
+ params.set("aggregate[count]", aggregate.count);
70
+ }
71
+ }
72
+ if (aggregate.avg) {
73
+ aggregate.avg.forEach((field) => params.append("aggregate[avg][]", field));
74
+ }
75
+ if (aggregate.sum) {
76
+ aggregate.sum.forEach((field) => params.append("aggregate[sum][]", field));
77
+ }
78
+ if (aggregate.min) {
79
+ aggregate.min.forEach((field) => params.append("aggregate[min][]", field));
80
+ }
81
+ if (aggregate.max) {
82
+ aggregate.max.forEach((field) => params.append("aggregate[max][]", field));
83
+ }
84
+ if (aggregate.countDistinct) {
85
+ aggregate.countDistinct.forEach((field) => params.append("aggregate[countDistinct][]", field));
86
+ }
87
+ }
88
+ // Add groupBy
89
+ if (groupBy && groupBy.length > 0) {
90
+ groupBy.forEach((field) => params.append("groupBy[]", field));
91
+ }
92
+ // Add sort
93
+ if (sort && sort.length > 0) {
94
+ sort.forEach((field) => params.append("sort[]", field));
95
+ }
96
+ // Add limit
97
+ if (limit !== undefined) {
98
+ params.set("limit", limit.toString());
99
+ }
100
+ // Add offset (for pagination)
101
+ if (offset !== undefined) {
102
+ params.set("offset", offset.toString());
103
+ }
104
+ // Add fields (supports dot notation for relations)
105
+ if (fields && fields.length > 0) {
106
+ fields.forEach((field) => params.append("fields[]", field));
107
+ }
108
+ // Add deep query parameters for nested relations
109
+ if (deep) {
110
+ Object.entries(deep).forEach(([key, value]) => {
111
+ if (typeof value === "object") {
112
+ Object.entries(value).forEach(([deepKey, deepValue]) => {
113
+ params.set(`deep[${key}][${deepKey}]`, String(deepValue));
114
+ });
115
+ }
116
+ });
117
+ }
118
+ // Add meta for total count
119
+ params.set("meta", "total_count,filter_count");
120
+ const result = await this.fetch(`/api/collections/${collection}?${params.toString()}`);
121
+ return {
122
+ data: result.data || [],
123
+ meta: result.meta || { total_count: 0, filter_count: 0 },
124
+ count: result.data?.length || 0,
125
+ };
126
+ }
127
+ // ---------------------------------------------------------------------------
128
+ // Convenience Methods (via BFF API)
129
+ // ---------------------------------------------------------------------------
130
+ // --- List Methods ---
131
+ async listScans(options) {
132
+ const params = new URLSearchParams();
133
+ params.set("orgId", options.orgId);
134
+ params.set("limit", (options.limit || 20).toString());
135
+ params.set("page", (options.page || 1).toString());
136
+ params.set("sort[]", "-date_created");
137
+ if (options.scanType) {
138
+ params.set("filter", JSON.stringify({ scan_type: { _eq: options.scanType } }));
139
+ }
140
+ if (options.status) {
141
+ params.set("filter", JSON.stringify({ status: { _eq: options.status } }));
142
+ }
143
+ const result = await this.fetch(`/api/scans?${params.toString()}`);
144
+ return result;
145
+ }
146
+ async listVulnerabilities(options) {
147
+ const params = new URLSearchParams();
148
+ params.set("orgId", options.orgId);
149
+ params.set("limit", (options.limit || 50).toString());
150
+ params.set("page", (options.page || 1).toString());
151
+ const filters = [];
152
+ if (options.severity) {
153
+ filters.push({ severity: { _eq: options.severity } });
154
+ }
155
+ if (options.status) {
156
+ filters.push({ vuln_status: { _eq: options.status } });
157
+ }
158
+ if (options.scanId) {
159
+ filters.push({ scan: { _eq: options.scanId } });
160
+ }
161
+ if (filters.length > 0) {
162
+ params.set("filter", JSON.stringify(filters.length === 1 ? filters[0] : { _and: filters }));
163
+ }
164
+ const result = await this.fetch(`/api/vulnerabilities?${params.toString()}`);
165
+ return result;
166
+ }
167
+ async listRepositories(options) {
168
+ const params = new URLSearchParams();
169
+ params.set("orgId", options.orgId);
170
+ params.set("limit", (options.limit || 20).toString());
171
+ params.set("page", (options.page || 1).toString());
172
+ const result = await this.fetch(`/api/repos?${params.toString()}`);
173
+ return result;
174
+ }
175
+ async listSecrets(options) {
176
+ const params = new URLSearchParams();
177
+ params.set("orgId", options.orgId);
178
+ params.set("limit", (options.limit || 50).toString());
179
+ params.set("page", (options.page || 1).toString());
180
+ // Simple query params (preferred)
181
+ if (options.scanId) {
182
+ params.set("scanId", options.scanId);
183
+ }
184
+ if (options.detectorName) {
185
+ params.set("detectorName", options.detectorName);
186
+ }
187
+ if (options.secretStatus) {
188
+ params.set("secretStatus", options.secretStatus);
189
+ }
190
+ if (options.verified) {
191
+ params.set("verified", options.verified);
192
+ }
193
+ const result = await this.fetch(`/api/secrets?${params.toString()}`);
194
+ return result;
195
+ }
196
+ async getRecentScans(options) {
197
+ const days = options.days || 7;
198
+ const params = new URLSearchParams();
199
+ params.set("orgId", options.orgId);
200
+ params.set("limit", (options.limit || 20).toString());
201
+ params.set("filter", JSON.stringify({
202
+ date_created: { _gte: `$NOW(-${days} days)` }
203
+ }));
204
+ params.set("sort[]", "-date_created");
205
+ const result = await this.fetch(`/api/scans?${params.toString()}`);
206
+ return result;
207
+ }
208
+ async getRecentVulnerabilities(options) {
209
+ const days = options.days || 7;
210
+ const params = new URLSearchParams();
211
+ params.set("orgId", options.orgId);
212
+ params.set("limit", (options.limit || 50).toString());
213
+ const filters = [
214
+ { date_created: { _gte: `$NOW(-${days} days)` } }
215
+ ];
216
+ if (options.severity) {
217
+ filters.push({ severity: { _eq: options.severity } });
218
+ }
219
+ params.set("filter", JSON.stringify({ _and: filters }));
220
+ params.set("sort[]", "-date_created");
221
+ const result = await this.fetch(`/api/vulnerabilities?${params.toString()}`);
222
+ return result;
223
+ }
224
+ async searchVulnerabilities(options) {
225
+ const params = new URLSearchParams();
226
+ params.set("orgId", options.orgId);
227
+ params.set("limit", (options.limit || 50).toString());
228
+ params.set("filter", JSON.stringify({
229
+ _or: [
230
+ { type: { _icontains: options.query } },
231
+ { file: { _icontains: options.query } },
232
+ { description: { _icontains: options.query } }
233
+ ]
234
+ }));
235
+ const result = await this.fetch(`/api/vulnerabilities?${params.toString()}`);
236
+ return result;
237
+ }
238
+ // --- Detail Methods ---
239
+ async getScanById(scanId) {
240
+ const result = await this.fetch(`/api/scans/${scanId}`);
241
+ return result.data;
242
+ }
243
+ async getVulnerabilityById(vulnId) {
244
+ const result = await this.fetch(`/api/vulnerabilities/${vulnId}`);
245
+ return result.data;
246
+ }
247
+ async getRepoConfigById(repoId) {
248
+ const result = await this.fetch(`/api/repos/${repoId}`);
249
+ return result.data;
250
+ }
251
+ async getOrganization(orgId) {
252
+ const result = await this.fetch(`/api/orgs/${orgId}`);
253
+ return result.data;
254
+ }
255
+ }
256
+ // ============================================================================
257
+ // MCP SERVER
258
+ // ============================================================================
259
+ const server = new McpServer({
260
+ name: "nohack-security-api",
261
+ version: "1.0.0",
262
+ description: "MCP server for NoHack security scanning API - query vulnerabilities, secrets, scans, and repo configs",
263
+ });
264
+ // Get API configuration from environment
265
+ function getClient() {
266
+ // Default to local dev server, but allow override
267
+ const apiUrl = process.env.NOHACK_API_URL || "http://localhost:5173";
268
+ const apiToken = process.env.NOHACK_API_TOKEN;
269
+ if (!apiToken) {
270
+ throw new Error("NOHACK_API_TOKEN environment variable is required (your access token from localStorage)");
271
+ }
272
+ return new ApiClient(apiUrl, apiToken);
273
+ }
274
+ // ============================================================================
275
+ // TOOL DEFINITIONS
276
+ // ============================================================================
277
+ // Define collections enum for reuse
278
+ const collectionsEnum = z.enum([
279
+ "scans",
280
+ "vulnerabilities",
281
+ "secrets",
282
+ "github_repo_config",
283
+ "organisations",
284
+ ]);
285
+ // ============================================================================
286
+ // LISTING TOOLS - Simple queries for common operations
287
+ // ============================================================================
288
+ server.registerTool("list_scans", {
289
+ description: `List security scans with optional filtering.
290
+ Use this for simple scan listings. For aggregations/grouping, use query_collection.
291
+
292
+ Returns paginated results with scan details.`,
293
+ inputSchema: z.object({
294
+ orgId: z.string().describe("Organization ID (required)"),
295
+ limit: z.number().optional().describe("Number of results (default: 20)"),
296
+ page: z.number().optional().describe("Page number (default: 1)"),
297
+ scanType: z.string().optional().describe("Filter by scan type: 'sast', 'dast', 'full'"),
298
+ status: z.string().optional().describe("Filter by status: 'published', 'draft', etc."),
299
+ }),
300
+ }, async ({ orgId, limit, page, scanType, status }) => {
301
+ try {
302
+ const client = getClient();
303
+ const result = await client.listScans({ orgId, limit, page, scanType, status });
304
+ return {
305
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
306
+ };
307
+ }
308
+ catch (error) {
309
+ return {
310
+ content: [{ type: "text", text: `Error: ${error.message}` }],
311
+ isError: true,
312
+ };
313
+ }
314
+ });
315
+ server.registerTool("list_vulnerabilities", {
316
+ description: `List vulnerabilities with optional filtering.
317
+ Use this for simple vulnerability listings. For aggregations/grouping, use query_collection.
318
+
319
+ Returns paginated results with vulnerability details.`,
320
+ inputSchema: z.object({
321
+ orgId: z.string().describe("Organization ID (required)"),
322
+ limit: z.number().optional().describe("Number of results (default: 50)"),
323
+ page: z.number().optional().describe("Page number (default: 1)"),
324
+ severity: z.string().optional().describe("Filter by severity: 'Critical', 'High', 'Medium', 'Low'"),
325
+ status: z.string().optional().describe("Filter by status: 'Open', 'Fixed', 'Accepted', etc."),
326
+ scanId: z.string().optional().describe("Filter by specific scan ID"),
327
+ }),
328
+ }, async ({ orgId, limit, page, severity, status, scanId }) => {
329
+ try {
330
+ const client = getClient();
331
+ const result = await client.listVulnerabilities({ orgId, limit, page, severity, status, scanId });
332
+ return {
333
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
334
+ };
335
+ }
336
+ catch (error) {
337
+ return {
338
+ content: [{ type: "text", text: `Error: ${error.message}` }],
339
+ isError: true,
340
+ };
341
+ }
342
+ });
343
+ server.registerTool("list_repositories", {
344
+ description: `List configured repositories.
345
+ Use this for simple repository listings.
346
+
347
+ Returns paginated results with repository details.`,
348
+ inputSchema: z.object({
349
+ orgId: z.string().describe("Organization ID (required)"),
350
+ limit: z.number().optional().describe("Number of results (default: 20)"),
351
+ page: z.number().optional().describe("Page number (default: 1)"),
352
+ }),
353
+ }, async ({ orgId, limit, page }) => {
354
+ try {
355
+ const client = getClient();
356
+ const result = await client.listRepositories({ orgId, limit, page });
357
+ return {
358
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
359
+ };
360
+ }
361
+ catch (error) {
362
+ return {
363
+ content: [{ type: "text", text: `Error: ${error.message}` }],
364
+ isError: true,
365
+ };
366
+ }
367
+ });
368
+ server.registerTool("list_secrets", {
369
+ description: `List detected secrets with optional filtering.
370
+ Use this for simple secret listings.
371
+
372
+ KEY FIELDS:
373
+ - detector_name: Type of secret (e.g., 'Github', 'AWS', 'PrivateKey', 'OpenAI', 'Stripe', 'MongoDB', 'JDBC')
374
+ - detector_type: Numeric ID for the detector
375
+ - secret_status: 'open', 'false_positive', 'duplicate'
376
+ - verified: Whether the secret was verified as valid
377
+
378
+ Common detector_name values: Github, GitHubOauth2, PrivateKey, AWS, OpenAI, Stripe, MongoDB, JDBC, Postgres, SQLServer, URI, NpmToken, Gitlab, Slack, SendGrid, Anthropic, HuggingFace
379
+
380
+ Returns paginated results with secret details.`,
381
+ inputSchema: z.object({
382
+ orgId: z.string().describe("Organization ID (required)"),
383
+ limit: z.number().optional().describe("Number of results (default: 50)"),
384
+ page: z.number().optional().describe("Page number (default: 1)"),
385
+ scanId: z.string().optional().describe("Filter by specific scan ID"),
386
+ detectorName: z.string().optional().describe("Filter by detector/secret type (e.g., 'Github', 'AWS', 'PrivateKey', 'OpenAI')"),
387
+ secretStatus: z.string().optional().describe("Filter by status: 'open', 'false_positive', 'duplicate'"),
388
+ verified: z.string().optional().describe("Filter by verified status: 'true' or 'false'"),
389
+ }),
390
+ }, async ({ orgId, limit, page, scanId, detectorName, secretStatus, verified }) => {
391
+ try {
392
+ const client = getClient();
393
+ const result = await client.listSecrets({ orgId, limit, page, scanId, detectorName, secretStatus, verified });
394
+ return {
395
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
396
+ };
397
+ }
398
+ catch (error) {
399
+ return {
400
+ content: [{ type: "text", text: `Error: ${error.message}` }],
401
+ isError: true,
402
+ };
403
+ }
404
+ });
405
+ server.registerTool("get_recent_scans", {
406
+ description: `Get scans from the last N days.
407
+ Useful for recent activity monitoring.
408
+
409
+ Returns scans sorted by most recent first.`,
410
+ inputSchema: z.object({
411
+ orgId: z.string().describe("Organization ID (required)"),
412
+ days: z.number().optional().describe("Number of days to look back (default: 7)"),
413
+ limit: z.number().optional().describe("Number of results (default: 20)"),
414
+ }),
415
+ }, async ({ orgId, days, limit }) => {
416
+ try {
417
+ const client = getClient();
418
+ const result = await client.getRecentScans({ orgId, days, limit });
419
+ return {
420
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
421
+ };
422
+ }
423
+ catch (error) {
424
+ return {
425
+ content: [{ type: "text", text: `Error: ${error.message}` }],
426
+ isError: true,
427
+ };
428
+ }
429
+ });
430
+ server.registerTool("get_recent_vulnerabilities", {
431
+ description: `Get vulnerabilities discovered in the last N days.
432
+ Useful for recent findings and trend monitoring.
433
+
434
+ Returns vulnerabilities sorted by most recent first.`,
435
+ inputSchema: z.object({
436
+ orgId: z.string().describe("Organization ID (required)"),
437
+ days: z.number().optional().describe("Number of days to look back (default: 7)"),
438
+ limit: z.number().optional().describe("Number of results (default: 50)"),
439
+ severity: z.string().optional().describe("Filter by severity: 'Critical', 'High', 'Medium', 'Low'"),
440
+ }),
441
+ }, async ({ orgId, days, limit, severity }) => {
442
+ try {
443
+ const client = getClient();
444
+ const result = await client.getRecentVulnerabilities({ orgId, days, limit, severity });
445
+ return {
446
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
447
+ };
448
+ }
449
+ catch (error) {
450
+ return {
451
+ content: [{ type: "text", text: `Error: ${error.message}` }],
452
+ isError: true,
453
+ };
454
+ }
455
+ });
456
+ server.registerTool("search_vulnerabilities", {
457
+ description: `Search vulnerabilities by text query.
458
+ Searches in: type, file path, and description.
459
+
460
+ Returns matching vulnerabilities.`,
461
+ inputSchema: z.object({
462
+ orgId: z.string().describe("Organization ID (required)"),
463
+ query: z.string().describe("Search query (e.g., 'SQL injection', 'auth.js', 'XSS')"),
464
+ limit: z.number().optional().describe("Number of results (default: 50)"),
465
+ }),
466
+ }, async ({ orgId, query, limit }) => {
467
+ try {
468
+ const client = getClient();
469
+ const result = await client.searchVulnerabilities({ orgId, query, limit });
470
+ return {
471
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
472
+ };
473
+ }
474
+ catch (error) {
475
+ return {
476
+ content: [{ type: "text", text: `Error: ${error.message}` }],
477
+ isError: true,
478
+ };
479
+ }
480
+ });
481
+ // ============================================================================
482
+ // ADVANCED QUERY TOOL - For aggregations, grouping, and complex queries
483
+ // ============================================================================
484
+ server.registerTool("query_collection", {
485
+ description: `ADVANCED QUERY TOOL - For aggregations, grouping, and complex filtering.
486
+
487
+ ⚠️ USE THIS ONLY FOR:
488
+ - AGGREGATIONS: Count, sum, avg, min, max
489
+ - GROUPING: Group by severity, status, repo, etc.
490
+ - COMPLEX FILTERS: Multiple conditions, nested relations, custom logic
491
+ - TREND ANALYSIS: Time-series data with groupBy
492
+
493
+ ❌ DON'T USE FOR:
494
+ - Simple listings → Use list_scans, list_vulnerabilities, etc.
495
+ - Recent items → Use get_recent_scans, get_recent_vulnerabilities
496
+ - Text search → Use search_vulnerabilities
497
+
498
+ WHEN TO USE:
499
+ - "Count vulnerabilities by severity" ✅
500
+ - "Show vulnerability trend by month" ✅
501
+ - "Average scan duration by repo" ✅
502
+ - "List scans" ❌ (use list_scans instead)
503
+
504
+ AVAILABLE COLLECTIONS:
505
+ - 'scans': Security scan data (fields: id, scan_status, scan_type, date_created, repo_config, etc.)
506
+ - 'vulnerabilities': Vulnerability findings (fields: id, type, severity, vuln_status, file, line, etc.)
507
+ - 'secrets': Exposed secrets (fields: id, detector_name, detector_type, secret_status, verified, etc.)
508
+ NOTE: Use 'detector_name' for secret type (e.g., 'Github', 'AWS', 'PrivateKey'), NOT 'type'
509
+ - 'github_repo_config': Repository configurations (fields: id, name, full_name, url, type, branch, etc.)
510
+ - 'organisations': Organization data (fields: id, name, quota, plan, etc.)
511
+
512
+ CRITICAL RULES:
513
+ 1. ALWAYS specify fields (collections have 40+ fields!)
514
+ 2. Use limit: -1 ONLY for aggregations (to count ALL records)
515
+ 3. Use limit: 10-100 for data queries
516
+ 4. Use orgId to filter by organization
517
+
518
+ FILTER OPERATORS:
519
+ - Equality: _eq, _neq, _in, _nin
520
+ - Comparison: _gt, _gte, _lt, _lte
521
+ - Text: _contains, _icontains, _starts_with, _ends_with
522
+ - Null: _null, _nnull, _empty, _nempty
523
+ - Logical: _and, _or
524
+ - Relations: _some, _none
525
+
526
+ DYNAMIC DATES (use in filters):
527
+ - Last 7 days: { "date_created": { "_gte": "$NOW(-7 days)" } }
528
+ - Last month: { "date_created": { "_gte": "$NOW(-1 month)" } }
529
+
530
+ AGGREGATIONS:
531
+ - count: Count records (use "*" or specific field)
532
+ - avg, sum, min, max: Numeric operations
533
+ - groupBy: Group results (e.g., ["severity", "vuln_status"])
534
+
535
+ EXAMPLES:
536
+ // List critical vulnerabilities
537
+ { collection: "vulnerabilities", filter: { severity: { _eq: "Critical" } }, fields: ["id", "type", "file"], limit: 50 }
538
+
539
+ // Count vulnerabilities by severity
540
+ { collection: "vulnerabilities", aggregate: { count: "*" }, groupBy: ["severity"], limit: -1 }
541
+
542
+ // Count secrets by detector type
543
+ { collection: "secrets", aggregate: { count: "*" }, groupBy: ["detector_name"], limit: -1 }
544
+
545
+ // List AWS secrets
546
+ { collection: "secrets", filter: { detector_name: { _eq: "AWS" } }, fields: ["id", "detector_name", "secret_status", "verified"], limit: 50 }
547
+
548
+ // Recent scans for a repo
549
+ { collection: "scans", filter: { repo_config: { name: { _eq: "my-repo" } } }, fields: ["id", "scan_type", "date_created"], limit: 10 }`,
550
+ inputSchema: z.object({
551
+ collection: collectionsEnum.describe("The collection to query"),
552
+ filter: z
553
+ .record(z.any())
554
+ .optional()
555
+ .describe('Filter object. Supports nested relations. Example: {"severity": {"_eq": "Critical"}, "scan": {"scan_type": {"_eq": "sast"}}}'),
556
+ aggregate: z
557
+ .object({
558
+ count: z.union([z.string(), z.array(z.string())]).optional(),
559
+ avg: z.array(z.string()).optional(),
560
+ sum: z.array(z.string()).optional(),
561
+ min: z.array(z.string()).optional(),
562
+ max: z.array(z.string()).optional(),
563
+ countDistinct: z.array(z.string()).optional(),
564
+ })
565
+ .optional()
566
+ .describe("Aggregation functions"),
567
+ groupBy: z
568
+ .array(z.string())
569
+ .optional()
570
+ .describe('Fields to group by (e.g., ["severity", "vuln_status"])'),
571
+ sort: z
572
+ .array(z.string())
573
+ .optional()
574
+ .describe('Sort fields (prefix with - for descending, e.g., ["-date_created"])'),
575
+ limit: z
576
+ .number()
577
+ .optional()
578
+ .describe("Max results. Use -1 for aggregations to count ALL records, 10-100 for data queries"),
579
+ offset: z.number().optional().describe("Records to skip (for pagination)"),
580
+ fields: z
581
+ .array(z.string())
582
+ .optional()
583
+ .describe('Fields to return. Use dot notation for relations: ["id", "scan.repo_config.name"]'),
584
+ deep: z
585
+ .record(z.any())
586
+ .optional()
587
+ .describe("Deep query parameters for nested relations"),
588
+ orgId: z
589
+ .string()
590
+ .optional()
591
+ .describe("Organization ID to filter by (auto-applied to queries)"),
592
+ }),
593
+ }, async ({ collection, filter, aggregate, groupBy, sort, limit, offset, fields, deep, orgId, }) => {
594
+ try {
595
+ const client = getClient();
596
+ const result = await client.queryCollection({
597
+ collection,
598
+ filter,
599
+ aggregate,
600
+ groupBy,
601
+ sort,
602
+ limit,
603
+ offset,
604
+ fields,
605
+ deep,
606
+ orgId,
607
+ });
608
+ return {
609
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
610
+ };
611
+ }
612
+ catch (error) {
613
+ return {
614
+ content: [{ type: "text", text: `Error: ${error.message}` }],
615
+ isError: true,
616
+ };
617
+ }
618
+ });
619
+ // ============================================================================
620
+ // DETAIL TOOLS - Get full records by ID
621
+ // ============================================================================
622
+ server.registerTool("get_scan_details", {
623
+ description: `Get complete details for a specific scan by ID.
624
+ Returns the full scan record with all vulnerabilities, secrets, and related data.
625
+
626
+ Use this when you have a scan ID and need all its details.`,
627
+ inputSchema: z.object({
628
+ scanId: z.string().describe("The scan ID"),
629
+ }),
630
+ }, async ({ scanId }) => {
631
+ try {
632
+ const client = getClient();
633
+ const result = await client.getScanById(scanId);
634
+ return {
635
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
636
+ };
637
+ }
638
+ catch (error) {
639
+ return {
640
+ content: [{ type: "text", text: `Error: ${error.message}` }],
641
+ isError: true,
642
+ };
643
+ }
644
+ });
645
+ server.registerTool("get_vulnerability_details", {
646
+ description: `Get complete details for a specific vulnerability by ID.
647
+ Returns the full vulnerability record with code context, data flow, and recommendations.
648
+
649
+ Use this when you have a vulnerability ID and need all its details.`,
650
+ inputSchema: z.object({
651
+ vulnerabilityId: z.string().describe("The vulnerability ID"),
652
+ }),
653
+ }, async ({ vulnerabilityId }) => {
654
+ try {
655
+ const client = getClient();
656
+ const result = await client.getVulnerabilityById(vulnerabilityId);
657
+ return {
658
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
659
+ };
660
+ }
661
+ catch (error) {
662
+ return {
663
+ content: [{ type: "text", text: `Error: ${error.message}` }],
664
+ isError: true,
665
+ };
666
+ }
667
+ });
668
+ server.registerTool("get_repo_config_details", {
669
+ description: `Get complete details for a specific repository by ID.
670
+ Returns the full repository record with related scans, vulnerabilities, and secrets.
671
+
672
+ Use this when you have a repository ID and need all its details.`,
673
+ inputSchema: z.object({
674
+ repoId: z.string().describe("The repository configuration ID"),
675
+ }),
676
+ }, async ({ repoId }) => {
677
+ try {
678
+ const client = getClient();
679
+ const result = await client.getRepoConfigById(repoId);
680
+ return {
681
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
682
+ };
683
+ }
684
+ catch (error) {
685
+ return {
686
+ content: [{ type: "text", text: `Error: ${error.message}` }],
687
+ isError: true,
688
+ };
689
+ }
690
+ });
691
+ server.registerTool("get_organization", {
692
+ description: `Get organization details by ID.
693
+ Returns organization name, quota, and plan information.`,
694
+ inputSchema: z.object({
695
+ orgId: z.string().describe("The organization ID"),
696
+ }),
697
+ }, async ({ orgId }) => {
698
+ try {
699
+ const client = getClient();
700
+ const result = await client.getOrganization(orgId);
701
+ return {
702
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
703
+ };
704
+ }
705
+ catch (error) {
706
+ return {
707
+ content: [{ type: "text", text: `Error: ${error.message}` }],
708
+ isError: true,
709
+ };
710
+ }
711
+ });
712
+ // ============================================================================
713
+ // SERVER STARTUP
714
+ // ============================================================================
715
+ async function main() {
716
+ const transport = new StdioServerTransport();
717
+ await server.connect(transport);
718
+ console.error("NoHack Security MCP Server running on stdio");
719
+ }
720
+ main().catch((error) => {
721
+ console.error("Fatal error:", error);
722
+ process.exit(1);
723
+ });
724
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@nohacklabs/mcp-server",
3
+ "version": "1.0.3",
4
+ "description": "MCP server for NoHack security scanning API - query vulnerabilities, secrets, scans, and repo configs",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "nohack-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "start": "node dist/index.js",
17
+ "dev": "tsc --watch",
18
+ "prepublishOnly": "npm run build",
19
+ "inspector": "npx @anthropic-ai/mcp-inspector node dist/index.js"
20
+ },
21
+ "dependencies": {
22
+ "@modelcontextprotocol/sdk": "^1.11.0",
23
+ "zod": "^3.25.76"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^22.15.0",
27
+ "typescript": "^5.7.3"
28
+ },
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "keywords": [
33
+ "mcp",
34
+ "model-context-protocol",
35
+ "security",
36
+ "vulnerability",
37
+ "sast",
38
+ "scanning",
39
+ "nohack",
40
+ "ai",
41
+ "cursor",
42
+ "claude"
43
+ ],
44
+ "author": "NoHack Labs",
45
+ "license": "MIT",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/nohacklabs/mcp-server.git"
49
+ },
50
+ "homepage": "https://nohacklabs.com",
51
+ "publishConfig": {
52
+ "access": "public"
53
+ }
54
+ }