@rad-security/mcp-server 0.0.22 → 0.0.24

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 CHANGED
@@ -58,6 +58,7 @@ Available toolkits:
58
58
  - `inbox` - Inbox item operations
59
59
  - `workflows` - Workflow execution operations
60
60
  - `knowledge_base` - Knowledge base search operations
61
+ - `radql` - Query interface for rad data platform
61
62
 
62
63
  Examples:
63
64
 
@@ -228,6 +229,14 @@ docker run \
228
229
  - Get details of a specific CVE
229
230
  - Get latest 30 CVEs
230
231
 
232
+ - RadQL (Advanced Querying)
233
+ - List available data types for querying (containers, findings, kubernetes_resources, etc.)*
234
+ - Get schema/metadata for specific data types*
235
+ - List possible values for filter fields*
236
+ - Execute RadQL queries with filtering, searching, and aggregations*
237
+ - Build queries programmatically from structured conditions*
238
+ - Execute multiple queries in parallel*
239
+
231
240
  `*` - requires authentication and account in Rad Security.
232
241
 
233
242
  ## Development
package/dist/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { logger } from "./logger.js";
1
2
  const USER_AGENT = `rad-security/mcp-server`;
2
3
  export class RadSecurityClient {
3
4
  sessionToken;
@@ -76,7 +77,9 @@ export class RadSecurityClient {
76
77
  }),
77
78
  });
78
79
  if (!response.ok) {
79
- throw new Error(`HTTP error! status: ${response.status}`);
80
+ const error = `HTTP error! status: ${response.status}`;
81
+ logger.error({ auth_method: 'access_key', error }, 'auth_attempt_failed');
82
+ throw new Error(error);
80
83
  }
81
84
  const tokenData = await response.json();
82
85
  // Cache token with 5 min buffer before expiry (assuming 4 hour token validity)
@@ -86,13 +89,18 @@ export class RadSecurityClient {
86
89
  token: tokenData.token,
87
90
  expiry,
88
91
  };
92
+ logger.info({ auth_method: 'access_key' }, 'auth_attempt_succeeded');
89
93
  return this.tokenCache.token;
90
94
  }
91
95
  catch (error) {
96
+ const errorMessage = error instanceof Error ? error.message : String(error);
97
+ logger.error({ auth_method: 'access_key', error: errorMessage }, 'auth_attempt_failed');
92
98
  throw new Error(`Error getting authentication token: ${error}`);
93
99
  }
94
100
  }
95
101
  async makeRequest(endpoint, params = {}, options = {}) {
102
+ const startTime = Date.now();
103
+ const method = options.method || "GET";
96
104
  const headers = {
97
105
  "Content-Type": "application/json",
98
106
  "User-Agent": USER_AGENT,
@@ -113,16 +121,27 @@ export class RadSecurityClient {
113
121
  }
114
122
  });
115
123
  }
116
- const response = await fetch(url, {
117
- method: options.method || "GET",
118
- headers,
119
- body: options.body ? JSON.stringify(options.body) : undefined,
120
- });
121
- const responseBody = await this.parseResponseBody(response);
122
- if (!response.ok) {
123
- throw new Error(`HTTP error! status: ${response.status} error: ${JSON.stringify(responseBody, null, 2)}`);
124
+ logger.debug({ endpoint, method, params }, 'api_request_started');
125
+ try {
126
+ const response = await fetch(url, {
127
+ method,
128
+ headers,
129
+ body: options.body ? JSON.stringify(options.body) : undefined,
130
+ });
131
+ const responseBody = await this.parseResponseBody(response);
132
+ const duration = Date.now() - startTime;
133
+ const logLevel = response.status >= 500 ? 'error' : response.status >= 400 ? 'warn' : 'debug';
134
+ logger[logLevel]({ endpoint, status: response.status, duration_ms: duration }, 'api_response_received');
135
+ if (!response.ok) {
136
+ throw new Error(`HTTP error! status: ${response.status} error: ${JSON.stringify(responseBody, null, 2)}`);
137
+ }
138
+ return responseBody;
139
+ }
140
+ catch (error) {
141
+ const duration = Date.now() - startTime;
142
+ logger.error({ endpoint, duration_ms: duration }, 'api_request_failed');
143
+ throw error;
124
144
  }
125
- return responseBody;
126
145
  }
127
146
  async parseResponseBody(response) {
128
147
  const contentType = response.headers.get("content-type");
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -27,7 +27,10 @@ import * as cves from "./operations/cves.js";
27
27
  import * as inbox from "./operations/inbox.js";
28
28
  import * as workflows from "./operations/workflows.js";
29
29
  import * as knowledgeBase from "./operations/knowledge-base.js";
30
+ import * as radql from "./operations/radql.js";
31
+ import * as cloudCompliance from "./operations/cloud-compliance.js";
30
32
  import { VERSION } from "./version.js";
33
+ import { logger } from "./logger.js";
31
34
  // Parse toolkit filters from environment variables
32
35
  function parseToolkitFilters() {
33
36
  const includeEnv = process.env.INCLUDE_TOOLKITS;
@@ -65,7 +68,6 @@ async function newServer() {
65
68
  prompts: {},
66
69
  resources: {},
67
70
  tools: {},
68
- logging: {},
69
71
  },
70
72
  });
71
73
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -140,6 +142,39 @@ async function newServer() {
140
142
  inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceFacetValuesSchema),
141
143
  },
142
144
  ] : []),
145
+ // Cloud Compliance tools
146
+ ...(isToolkitEnabled("cloud_compliance", toolkitFilters) ? [
147
+ {
148
+ name: "list_compliance_frameworks",
149
+ description: "List all compliance frameworks available for cloud resources (e.g., CIS, SOC2, PCI-DSS)",
150
+ inputSchema: zodToJsonSchema(cloudCompliance.ListComplianceFrameworksSchema),
151
+ },
152
+ {
153
+ name: "list_framework_requirements",
154
+ description: "List all requirements for a specific compliance framework",
155
+ inputSchema: zodToJsonSchema(cloudCompliance.ListFrameworkRequirementsSchema),
156
+ },
157
+ {
158
+ name: "list_requirement_controls",
159
+ description: "List controls associated with a specific requirement within a compliance framework",
160
+ inputSchema: zodToJsonSchema(cloudCompliance.ListRequirementControlsSchema),
161
+ },
162
+ {
163
+ name: "list_compliance_controls",
164
+ description: "List all compliance control summaries for the account",
165
+ inputSchema: zodToJsonSchema(cloudCompliance.ListComplianceControlsSchema),
166
+ },
167
+ {
168
+ name: "get_compliance_control",
169
+ description: "Get detailed information about a specific compliance control",
170
+ inputSchema: zodToJsonSchema(cloudCompliance.GetComplianceControlSchema),
171
+ },
172
+ {
173
+ name: "list_control_resources",
174
+ description: "List cloud resources associated with a specific compliance control",
175
+ inputSchema: zodToJsonSchema(cloudCompliance.ListControlResourcesSchema),
176
+ },
177
+ ] : []),
143
178
  // Image tools
144
179
  ...(isToolkitEnabled("images", toolkitFilters) ? [
145
180
  {
@@ -306,6 +341,11 @@ async function newServer() {
306
341
  description: "List all workflows",
307
342
  inputSchema: zodToJsonSchema(workflows.ListWorkflowsSchema),
308
343
  },
344
+ {
345
+ name: "get_workflow",
346
+ description: "Get detailed information about a specific workflow by ID. It contains the workflow definition, default arguments, and schema how to run the workflow",
347
+ inputSchema: zodToJsonSchema(workflows.GetWorkflowSchema),
348
+ },
309
349
  {
310
350
  name: "list_workflow_runs",
311
351
  description: "List workflow runs with optional filtering by workflow ID",
@@ -318,7 +358,7 @@ async function newServer() {
318
358
  },
319
359
  {
320
360
  name: "run_workflow",
321
- description: "Run a workflow",
361
+ description: "Run a workflow with optional argument overrides",
322
362
  inputSchema: zodToJsonSchema(workflows.RunWorkflowSchema),
323
363
  },
324
364
  {
@@ -344,6 +384,77 @@ async function newServer() {
344
384
  description: "List documents in your organization's knowledge base with optional filtering by collections, file type, or status",
345
385
  inputSchema: zodToJsonSchema(knowledgeBase.ListDocumentsSchema),
346
386
  },
387
+ {
388
+ name: "query_knowledge_base_document",
389
+ description: "Query a CSV document from the knowledge base using natural language. IMPORTANT: This tool ONLY works with CSV documents. Use list_knowledge_base_documents with filters='file_type:csv' to find CSV document IDs (search_knowledge_base results also contain document IDs). Results are returned as a markdown table",
390
+ inputSchema: zodToJsonSchema(knowledgeBase.StructuredQueryDocumentSchema),
391
+ },
392
+ ] : []),
393
+ // RadQL tools
394
+ ...(isToolkitEnabled("radql", toolkitFilters) ? [
395
+ {
396
+ name: "radql_list_data_types",
397
+ description: "List all available RadQL data types (discovery). ALWAYS call this FIRST before using other RadQL tools to discover what data is available to query. Returns data types like 'containers', 'kubernetes_resources', 'inbox_items', 'vulnerabilities', etc. with descriptions.",
398
+ inputSchema: zodToJsonSchema(radql.RadQLListDataTypesSchema),
399
+ },
400
+ {
401
+ name: "radql_get_type_metadata",
402
+ description: "Get schema/metadata for a specific RadQL data type. Shows available fields, data types, which fields can be filtered/searched, and provides query examples. Call this AFTER radql_list_data_types to understand how to query a specific data type.",
403
+ inputSchema: zodToJsonSchema(radql.RadQLGetTypeMetadataSchema),
404
+ },
405
+ {
406
+ name: "radql_list_filter_values",
407
+ description: "List possible values for a filter field (e.g., namespace list, cluster list, severity values). Useful for building dynamic filters when you need to know available enum-like values. Call this when constructing filters that need specific values.",
408
+ inputSchema: zodToJsonSchema(radql.RadQLListFilterValuesSchema),
409
+ },
410
+ {
411
+ name: "radql_query",
412
+ description: `Execute RadQL queries for security investigations. Supports: list (filter/search), get_by_id (single item), stats (aggregations).
413
+
414
+ WORKFLOW: radql_list_data_types -> radql_get_type_metadata -> radql_query
415
+
416
+ COMMON FIELDS BY DATA TYPE:
417
+ containers: name, image_name, image_repo, owner_kind, cluster_id, created_at
418
+ Example: image_name:*nginx* AND owner_kind:Pod
419
+
420
+ finding_groups: type, source_kind, source_name, rule_title, severity, event_timestamp
421
+ Types: k8s_misconfiguration, k8s_audit_logs_anomaly, threat_vector
422
+ Example: type:k8s_misconfiguration AND severity:critical
423
+
424
+ inbox_items: severity (High|Medium|Low), type, title, archived, false_positive, created_at
425
+ Example: severity:High AND archived:false
426
+
427
+ kubernetes_resources: kind, name, namespace, cluster_id, owner_kind, created_at
428
+ Example: kind:Deployment AND namespace:production
429
+
430
+ CRITICAL QUOTING RULES:
431
+ MUST quote when value contains:
432
+ - Dates/timestamps: created_at>"2024-01-01" (NOT created_at>2024-01-01)
433
+ - Hyphens: cluster_id:"abc-123-def", name:"kube-system"
434
+ - UUIDs: id:"550e8400-e29b-41d4-a716-446655440000"
435
+ - Spaces: title:"my alert"
436
+ - Special chars: :, =, <, >, !, (, )
437
+ - Wildcards with hyphens: name:"kube-*"
438
+
439
+ OK to leave unquoted:
440
+ - Simple strings: status:active, kind:Pod
441
+ - Numbers: count:123
442
+ - Booleans: archived:true
443
+ - Simple wildcards: name:nginx*
444
+
445
+ For complete schema: call radql_get_type_metadata with target data_type`,
446
+ inputSchema: zodToJsonSchema(radql.RadQLQuerySchema),
447
+ },
448
+ {
449
+ name: "radql_query_builder",
450
+ description: "Helper tool to build RadQL queries programmatically from structured conditions. Useful when you need to construct complex filter or stats queries from structured inputs.",
451
+ inputSchema: zodToJsonSchema(radql.RadQLQueryBuilderSchema),
452
+ },
453
+ {
454
+ name: "radql_batch_query",
455
+ description: "Execute multiple RadQL queries in parallel for efficiency. Useful for fetching related data from different data types simultaneously (e.g., container details + vulnerabilities + network connections).",
456
+ inputSchema: zodToJsonSchema(radql.RadQLBatchQuerySchema),
457
+ },
347
458
  ] : []),
348
459
  ];
349
460
  return {
@@ -351,11 +462,13 @@ async function newServer() {
351
462
  };
352
463
  });
353
464
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
465
+ const startTime = Date.now();
466
+ const toolName = request.params.name;
354
467
  try {
355
468
  if (!request.params.arguments) {
356
469
  throw new Error("Arguments are required");
357
470
  }
358
- const toolName = request.params.name;
471
+ logger.info({ tool: toolName, arguments: request.params.arguments }, 'tool_invoked');
359
472
  switch (toolName) {
360
473
  // Container tools
361
474
  case "list_containers": {
@@ -439,6 +552,49 @@ async function newServer() {
439
552
  content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
440
553
  };
441
554
  }
555
+ // Cloud Compliance tools
556
+ case "list_compliance_frameworks": {
557
+ const args = cloudCompliance.ListComplianceFrameworksSchema.parse(request.params.arguments);
558
+ const response = await cloudCompliance.listComplianceFrameworks(client, args.datasource_ids, args.page, args.page_size);
559
+ return {
560
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
561
+ };
562
+ }
563
+ case "list_framework_requirements": {
564
+ const args = cloudCompliance.ListFrameworkRequirementsSchema.parse(request.params.arguments);
565
+ const response = await cloudCompliance.listFrameworkRequirements(client, args.framework_name, args.datasource_ids, args.page, args.page_size);
566
+ return {
567
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
568
+ };
569
+ }
570
+ case "list_requirement_controls": {
571
+ const args = cloudCompliance.ListRequirementControlsSchema.parse(request.params.arguments);
572
+ const response = await cloudCompliance.listRequirementControls(client, args.framework_name, args.requirement_id, args.datasource_ids, args.page, args.page_size);
573
+ return {
574
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
575
+ };
576
+ }
577
+ case "list_compliance_controls": {
578
+ const args = cloudCompliance.ListComplianceControlsSchema.parse(request.params.arguments);
579
+ const response = await cloudCompliance.listComplianceControls(client, args.status, args.providers, args.page, args.page_size);
580
+ return {
581
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
582
+ };
583
+ }
584
+ case "get_compliance_control": {
585
+ const args = cloudCompliance.GetComplianceControlSchema.parse(request.params.arguments);
586
+ const response = await cloudCompliance.getComplianceControl(client, args.control_name, args.datasource_ids);
587
+ return {
588
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
589
+ };
590
+ }
591
+ case "list_control_resources": {
592
+ const args = cloudCompliance.ListControlResourcesSchema.parse(request.params.arguments);
593
+ const response = await cloudCompliance.listControlResources(client, args.control_name, args.datasource_ids, args.page, args.page_size);
594
+ return {
595
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
596
+ };
597
+ }
442
598
  // Image tools
443
599
  case "list_images": {
444
600
  const args = images.ListImagesSchema.parse(request.params.arguments);
@@ -636,6 +792,13 @@ async function newServer() {
636
792
  content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
637
793
  };
638
794
  }
795
+ case "get_workflow": {
796
+ const args = workflows.GetWorkflowSchema.parse(request.params.arguments);
797
+ const response = await workflows.getWorkflow(client, args.workflow_id);
798
+ return {
799
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
800
+ };
801
+ }
639
802
  case "list_workflow_runs": {
640
803
  const args = workflows.ListWorkflowRunsSchema.parse(request.params.arguments);
641
804
  const response = await workflows.listWorkflowRuns(client, args.workflow_id);
@@ -652,7 +815,7 @@ async function newServer() {
652
815
  }
653
816
  case "run_workflow": {
654
817
  const args = workflows.RunWorkflowSchema.parse(request.params.arguments);
655
- const response = await workflows.runWorkflow(client, args.workflow_id, args.async);
818
+ const response = await workflows.runWorkflow(client, args.workflow_id, args.async, args.args);
656
819
  return {
657
820
  content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
658
821
  };
@@ -686,18 +849,71 @@ async function newServer() {
686
849
  content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
687
850
  };
688
851
  }
852
+ case "query_knowledge_base_document": {
853
+ const args = knowledgeBase.StructuredQueryDocumentSchema.parse(request.params.arguments);
854
+ const response = await knowledgeBase.structuredQueryDocument(client, args.document_id, args.query);
855
+ return {
856
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
857
+ };
858
+ }
859
+ // RadQL tools
860
+ case "radql_list_data_types": {
861
+ const response = await radql.executeListDataTypes(client);
862
+ return {
863
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
864
+ };
865
+ }
866
+ case "radql_get_type_metadata": {
867
+ const args = radql.RadQLGetTypeMetadataSchema.parse(request.params.arguments);
868
+ const response = await radql.executeGetTypeMetadata(client, args);
869
+ return {
870
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
871
+ };
872
+ }
873
+ case "radql_list_filter_values": {
874
+ const args = radql.RadQLListFilterValuesSchema.parse(request.params.arguments);
875
+ const response = await radql.executeListFilterValues(client, args);
876
+ return {
877
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
878
+ };
879
+ }
880
+ case "radql_query": {
881
+ const args = radql.RadQLQuerySchema.parse(request.params.arguments);
882
+ const response = await radql.executeRadQLQuery(client, args);
883
+ return {
884
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
885
+ };
886
+ }
887
+ case "radql_query_builder": {
888
+ const args = radql.RadQLQueryBuilderSchema.parse(request.params.arguments);
889
+ const response = radql.buildRadQLQuery(args);
890
+ return {
891
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
892
+ };
893
+ }
894
+ case "radql_batch_query": {
895
+ const args = radql.RadQLBatchQuerySchema.parse(request.params.arguments);
896
+ const response = await radql.executeBatchQueries(client, args);
897
+ return {
898
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
899
+ };
900
+ }
689
901
  default:
690
902
  throw new Error(`Unknown tool: ${toolName}`);
691
903
  }
904
+ const duration = Date.now() - startTime;
905
+ logger.info({ tool: toolName, duration_ms: duration }, 'tool_execution_completed');
692
906
  }
693
907
  catch (error) {
694
- console.error("Error calling tool:", error);
908
+ const duration = Date.now() - startTime;
909
+ const errorMessage = error instanceof Error ? error.message : String(error);
910
+ logger.error({ tool: toolName, error: errorMessage, duration_ms: duration }, 'tool_execution_failed');
695
911
  return {
696
912
  content: [
697
913
  {
698
914
  type: "text",
699
915
  text: JSON.stringify({
700
- error: error instanceof Error ? error.message : String(error),
916
+ error: errorMessage,
701
917
  }),
702
918
  },
703
919
  ],
@@ -712,25 +928,28 @@ async function main() {
712
928
  if (!['stdio', 'sse', 'streamable'].includes(transportType)) {
713
929
  throw new Error("Transport type must be either 'stdio', 'sse' or 'streamable'");
714
930
  }
715
- console.error(`RAD Security MCP server version: ${VERSION}`);
716
- console.error(`Node version: ${process.version}`);
931
+ // Log server startup
932
+ logger.info({
933
+ version: VERSION,
934
+ transport: transportType,
935
+ node_version: process.version
936
+ }, 'server_starting');
717
937
  // Log toolkit filters if set
718
938
  const filters = parseToolkitFilters();
719
939
  if (filters.include && filters.include.length > 0) {
720
- console.error(`Toolkit filter: INCLUDE ONLY [${filters.include.join(', ')}]`);
940
+ logger.info({ mode: "include", toolkits: filters.include }, 'toolkit_filter_configured');
721
941
  }
722
942
  else if (filters.exclude && filters.exclude.length > 0) {
723
- console.error(`Toolkit filter: EXCLUDE [${filters.exclude.join(', ')}]`);
943
+ logger.info({ mode: "exclude", toolkits: filters.exclude }, 'toolkit_filter_configured');
724
944
  }
725
945
  else {
726
- console.error(`Toolkit filter: ALL toolkits enabled`);
946
+ logger.info('toolkit_all_enabled');
727
947
  }
728
- console.error(`Starting MCP server with transport type: ${transportType}...`);
729
948
  if (transportType === 'stdio') {
730
949
  const transport = new StdioServerTransport();
731
950
  const server = await newServer();
732
951
  await server.connect(transport);
733
- console.error(`RAD Security MCP server started.`);
952
+ logger.info({ transport: 'stdio' }, 'server_ready');
734
953
  }
735
954
  else if (transportType === 'sse') {
736
955
  const app = express();
@@ -756,7 +975,7 @@ async function main() {
756
975
  });
757
976
  const port = process.env.PORT || 3000;
758
977
  app.listen(port, () => {
759
- console.error(`RAD Security MCP Server started on http://localhost:${port}/sse`);
978
+ logger.info({ transport: 'sse', url: `http://localhost:${port}/sse` }, 'server_ready');
760
979
  });
761
980
  }
762
981
  else if (transportType === 'streamable') {
@@ -828,18 +1047,19 @@ async function main() {
828
1047
  app.delete('/mcp', handleSessionRequest);
829
1048
  const port = process.env.PORT || 3000;
830
1049
  app.listen(port, () => {
831
- console.error(`MCP Stateless Streamable HTTP Server listening on port ${port}`);
1050
+ logger.info({ transport: 'streamable', url: `http://localhost:${port}/mcp` }, 'server_ready');
832
1051
  });
833
1052
  }
834
- console.error(`RAD Security MCP server started.`);
835
1053
  }
836
1054
  catch (error) {
837
- console.error("Error starting server:", error);
1055
+ const errorMessage = error instanceof Error ? error.message : String(error);
1056
+ logger.fatal({ error: errorMessage }, 'server_startup_failed');
838
1057
  process.exit(1);
839
1058
  }
840
1059
  }
841
1060
  main().catch((error) => {
842
- console.error("Unhandled error:", error);
1061
+ const errorMessage = error instanceof Error ? error.message : String(error);
1062
+ logger.fatal({ error: errorMessage }, 'server_error_unhandled');
843
1063
  process.exit(1);
844
1064
  });
845
1065
  //# sourceMappingURL=index.js.map