@rad-security/mcp-server 0.0.24 → 0.0.25

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/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import cors from 'cors';
4
+ import cors from "cors";
5
5
  import { randomUUID } from "node:crypto";
6
6
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
7
7
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
8
8
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
9
- import { zodToJsonSchema } from 'zod-to-json-schema';
9
+ import { zodToJsonSchema } from "zod-to-json-schema";
10
10
  import { z } from "zod";
11
11
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
12
12
  import express from "express";
@@ -29,6 +29,7 @@ import * as workflows from "./operations/workflows.js";
29
29
  import * as knowledgeBase from "./operations/knowledge-base.js";
30
30
  import * as radql from "./operations/radql.js";
31
31
  import * as cloudCompliance from "./operations/cloud-compliance.js";
32
+ import * as dashboards from "./operations/dashboards.js";
32
33
  import { VERSION } from "./version.js";
33
34
  import { logger } from "./logger.js";
34
35
  // Parse toolkit filters from environment variables
@@ -37,10 +38,14 @@ function parseToolkitFilters() {
37
38
  const excludeEnv = process.env.EXCLUDE_TOOLKITS;
38
39
  const result = {};
39
40
  if (includeEnv) {
40
- result.include = includeEnv.split(',').map(s => s.trim());
41
+ result.include = includeEnv
42
+ .split(",")
43
+ .map((s) => s.trim());
41
44
  }
42
45
  if (excludeEnv) {
43
- result.exclude = excludeEnv.split(',').map(s => s.trim());
46
+ result.exclude = excludeEnv
47
+ .split(",")
48
+ .map((s) => s.trim());
44
49
  }
45
50
  return result;
46
51
  }
@@ -73,343 +78,380 @@ async function newServer() {
73
78
  server.setRequestHandler(ListToolsRequestSchema, async () => {
74
79
  const allTools = [
75
80
  // Container tools
76
- ...(isToolkitEnabled("containers", toolkitFilters) ? [
77
- {
78
- name: "list_containers",
79
- description: "List containers secured by RAD Security with optional filtering by image name, image digest, namespace, cluster_id, or free text search",
80
- inputSchema: zodToJsonSchema(containers.ListContainersSchema),
81
- },
82
- {
83
- name: "get_container_details",
84
- description: "Get detailed information about a container secured by RAD Security",
85
- inputSchema: zodToJsonSchema(containers.GetContainerDetailsSchema),
86
- },
87
- ] : []),
81
+ ...(isToolkitEnabled("containers", toolkitFilters)
82
+ ? [
83
+ {
84
+ name: "list_containers",
85
+ description: "List containers secured by RAD Security with optional filtering by image name, image digest, namespace, cluster_id, or free text search",
86
+ inputSchema: zodToJsonSchema(containers.ListContainersSchema),
87
+ },
88
+ {
89
+ name: "get_container_details",
90
+ description: "Get detailed information about a container secured by RAD Security",
91
+ inputSchema: zodToJsonSchema(containers.GetContainerDetailsSchema),
92
+ },
93
+ ]
94
+ : []),
88
95
  // Cluster tools
89
- ...(isToolkitEnabled("clusters", toolkitFilters) ? [
90
- {
91
- name: "list_clusters",
92
- description: "List Kubernetes clusters managed by RAD Security",
93
- inputSchema: zodToJsonSchema(clusters.ListClustersSchema),
94
- },
95
- {
96
- name: "get_cluster_details",
97
- description: "Get detailed information about a specific Kubernetes cluster managed by RAD Security",
98
- inputSchema: zodToJsonSchema(clusters.GetClusterDetailsSchema),
99
- },
100
- ] : []),
96
+ ...(isToolkitEnabled("clusters", toolkitFilters)
97
+ ? [
98
+ {
99
+ name: "list_clusters",
100
+ description: "List Kubernetes clusters managed by RAD Security",
101
+ inputSchema: zodToJsonSchema(clusters.ListClustersSchema),
102
+ },
103
+ {
104
+ name: "get_cluster_details",
105
+ description: "Get detailed information about a specific Kubernetes cluster managed by RAD Security",
106
+ inputSchema: zodToJsonSchema(clusters.GetClusterDetailsSchema),
107
+ },
108
+ ]
109
+ : []),
101
110
  // Identity tools
102
- ...(isToolkitEnabled("identities", toolkitFilters) ? [
103
- {
104
- name: "list_identities",
105
- description: "Get list of identities for a specific Kubernetes cluster",
106
- inputSchema: zodToJsonSchema(identities.ListIdentitiesSchema),
107
- },
108
- {
109
- name: "get_identity_details",
110
- description: "Get detailed information about a specific identity in a Kubernetes cluster",
111
- inputSchema: zodToJsonSchema(identities.GetIdentityDetailsSchema),
112
- },
113
- ] : []),
111
+ ...(isToolkitEnabled("identities", toolkitFilters)
112
+ ? [
113
+ {
114
+ name: "list_identities",
115
+ description: "Get list of identities for a specific Kubernetes cluster",
116
+ inputSchema: zodToJsonSchema(identities.ListIdentitiesSchema),
117
+ },
118
+ {
119
+ name: "get_identity_details",
120
+ description: "Get detailed information about a specific identity in a Kubernetes cluster",
121
+ inputSchema: zodToJsonSchema(identities.GetIdentityDetailsSchema),
122
+ },
123
+ ]
124
+ : []),
114
125
  // Audit tools
115
- ...(isToolkitEnabled("audit", toolkitFilters) ? [
116
- {
117
- name: "who_shelled_into_pod",
118
- description: "Get k8s audit logs with information about users who shelled into a pod",
119
- inputSchema: zodToJsonSchema(audit.WhoShelledIntoPodSchema),
120
- },
121
- ] : []),
126
+ ...(isToolkitEnabled("audit", toolkitFilters)
127
+ ? [
128
+ {
129
+ name: "who_shelled_into_pod",
130
+ description: "Get k8s audit logs with information about users who shelled into a pod",
131
+ inputSchema: zodToJsonSchema(audit.WhoShelledIntoPodSchema),
132
+ },
133
+ ]
134
+ : []),
122
135
  // Cloud Inventory tools
123
- ...(isToolkitEnabled("cloud_inventory", toolkitFilters) ? [
124
- {
125
- name: "list_cloud_resources",
126
- description: "List cloud resources for a specific provider with optional filtering",
127
- inputSchema: zodToJsonSchema(cloudInventory.ListCloudResourcesSchema),
128
- },
129
- {
130
- name: "get_cloud_resource_details",
131
- description: "Get detailed information about a specific cloud resource",
132
- inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceDetailsSchema),
133
- },
134
- {
135
- name: "get_cloud_resource_facets",
136
- description: "Get available facets for filtering cloud resources from a provider",
137
- inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceFacetsSchema),
138
- },
139
- {
140
- name: "get_cloud_resource_facet_value",
141
- description: "Get values for a specific facet from a cloud provider",
142
- inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceFacetValuesSchema),
143
- },
144
- ] : []),
136
+ ...(isToolkitEnabled("cloud_inventory", toolkitFilters)
137
+ ? [
138
+ {
139
+ name: "list_cloud_resources",
140
+ description: "List cloud resources for a specific provider with optional filtering",
141
+ inputSchema: zodToJsonSchema(cloudInventory.ListCloudResourcesSchema),
142
+ },
143
+ {
144
+ name: "get_cloud_resource_details",
145
+ description: "Get detailed information about a specific cloud resource",
146
+ inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceDetailsSchema),
147
+ },
148
+ {
149
+ name: "get_cloud_resource_facets",
150
+ description: "Get available facets for filtering cloud resources from a provider",
151
+ inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceFacetsSchema),
152
+ },
153
+ {
154
+ name: "get_cloud_resource_facet_value",
155
+ description: "Get values for a specific facet from a cloud provider",
156
+ inputSchema: zodToJsonSchema(cloudInventory.GetCloudResourceFacetValuesSchema),
157
+ },
158
+ ]
159
+ : []),
145
160
  // 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
- ] : []),
161
+ ...(isToolkitEnabled("cloud_compliance", toolkitFilters)
162
+ ? [
163
+ {
164
+ name: "list_compliance_frameworks",
165
+ description: "List all compliance frameworks available for cloud resources (e.g., CIS, SOC2, PCI-DSS)",
166
+ inputSchema: zodToJsonSchema(cloudCompliance.ListComplianceFrameworksSchema),
167
+ },
168
+ {
169
+ name: "list_framework_requirements",
170
+ description: "List all requirements for a specific compliance framework",
171
+ inputSchema: zodToJsonSchema(cloudCompliance.ListFrameworkRequirementsSchema),
172
+ },
173
+ {
174
+ name: "list_requirement_controls",
175
+ description: "List controls associated with a specific requirement within a compliance framework",
176
+ inputSchema: zodToJsonSchema(cloudCompliance.ListRequirementControlsSchema),
177
+ },
178
+ {
179
+ name: "list_compliance_controls",
180
+ description: "List all compliance control summaries for the account",
181
+ inputSchema: zodToJsonSchema(cloudCompliance.ListComplianceControlsSchema),
182
+ },
183
+ {
184
+ name: "get_compliance_control",
185
+ description: "Get detailed information about a specific compliance control",
186
+ inputSchema: zodToJsonSchema(cloudCompliance.GetComplianceControlSchema),
187
+ },
188
+ {
189
+ name: "list_control_resources",
190
+ description: "List cloud resources associated with a specific compliance control",
191
+ inputSchema: zodToJsonSchema(cloudCompliance.ListControlResourcesSchema),
192
+ },
193
+ ]
194
+ : []),
178
195
  // Image tools
179
- ...(isToolkitEnabled("images", toolkitFilters) ? [
180
- {
181
- name: "list_images",
182
- description: "List container images with optional filtering by page, page size, sort, and search query",
183
- inputSchema: zodToJsonSchema(images.ListImagesSchema),
184
- },
185
- {
186
- name: "list_image_vulnerabilities",
187
- description: "List vulnerabilities in a container image with optional filtering by severity",
188
- inputSchema: zodToJsonSchema(images.ListImageVulnerabilitiesSchema),
189
- },
190
- {
191
- name: "get_top_vulnerable_images",
192
- description: "Get the most vulnerable images from your account",
193
- inputSchema: zodToJsonSchema(z.object({})),
194
- },
195
- {
196
- name: "get_image_sbom",
197
- description: "Get the SBOM of a container image",
198
- inputSchema: zodToJsonSchema(images.GetImageSBOMSchema),
199
- },
200
- ] : []),
196
+ ...(isToolkitEnabled("images", toolkitFilters)
197
+ ? [
198
+ {
199
+ name: "list_images",
200
+ description: "List container images with optional filtering by page, page size, sort, and search query",
201
+ inputSchema: zodToJsonSchema(images.ListImagesSchema),
202
+ },
203
+ {
204
+ name: "list_image_vulnerabilities",
205
+ description: "List vulnerabilities in a container image with optional filtering by severity",
206
+ inputSchema: zodToJsonSchema(images.ListImageVulnerabilitiesSchema),
207
+ },
208
+ {
209
+ name: "get_top_vulnerable_images",
210
+ description: "Get the most vulnerable images from your account",
211
+ inputSchema: zodToJsonSchema(z.object({})),
212
+ },
213
+ {
214
+ name: "get_image_sbom",
215
+ description: "Get the SBOM of a container image",
216
+ inputSchema: zodToJsonSchema(images.GetImageSBOMSchema),
217
+ },
218
+ ]
219
+ : []),
201
220
  // Kubernetes Object tools
202
- ...(isToolkitEnabled("kubeobject", toolkitFilters) ? [
203
- {
204
- name: "get_k8s_resource_details",
205
- description: "Get the latest manifest of a Kubernetes resource",
206
- inputSchema: zodToJsonSchema(kubeobject.GetKubernetesResourceDetailsSchema),
207
- },
208
- {
209
- name: "list_k8s_resources",
210
- description: "List Kubernetes resources with optional filtering by namespace, resource types, and cluster",
211
- inputSchema: zodToJsonSchema(kubeobject.ListKubernetesResourcesSchema),
212
- },
213
- ] : []),
221
+ ...(isToolkitEnabled("kubeobject", toolkitFilters)
222
+ ? [
223
+ {
224
+ name: "get_k8s_resource_details",
225
+ description: "Get the latest manifest of a Kubernetes resource",
226
+ inputSchema: zodToJsonSchema(kubeobject.GetKubernetesResourceDetailsSchema),
227
+ },
228
+ {
229
+ name: "list_k8s_resources",
230
+ description: "List Kubernetes resources with optional filtering by namespace, resource types, and cluster",
231
+ inputSchema: zodToJsonSchema(kubeobject.ListKubernetesResourcesSchema),
232
+ },
233
+ ]
234
+ : []),
214
235
  // Manifest Misconfigurations tools
215
- ...(isToolkitEnabled("misconfigs", toolkitFilters) ? [
216
- {
217
- name: "list_k8s_resource_misconfigs",
218
- description: "Get manifest misconfigurations for a Kubernetes resource",
219
- inputSchema: zodToJsonSchema(misconfigs.ListKubernetesResourceMisconfigurationsSchema),
220
- },
221
- {
222
- name: "get_k8s_resource_misconfig",
223
- description: "Get detailed information about a specific Kubernetes resource misconfiguration",
224
- inputSchema: zodToJsonSchema(misconfigs.GetKubernetesResourceMisconfigurationDetailsSchema),
225
- },
226
- {
227
- name: "list_k8s_resource_misconfig_policies",
228
- description: "List available misconfiguration policies used by RAD Security to detect Kubernetes resource misconfigurations",
229
- inputSchema: zodToJsonSchema(misconfigs.ListKubernetesResourceMisconfigurationPoliciesSchema),
230
- },
231
- ] : []),
236
+ ...(isToolkitEnabled("misconfigs", toolkitFilters)
237
+ ? [
238
+ {
239
+ name: "list_k8s_resource_misconfigs",
240
+ description: "Get manifest misconfigurations for a Kubernetes resource",
241
+ inputSchema: zodToJsonSchema(misconfigs.ListKubernetesResourceMisconfigurationsSchema),
242
+ },
243
+ {
244
+ name: "get_k8s_resource_misconfig",
245
+ description: "Get detailed information about a specific Kubernetes resource misconfiguration",
246
+ inputSchema: zodToJsonSchema(misconfigs.GetKubernetesResourceMisconfigurationDetailsSchema),
247
+ },
248
+ {
249
+ name: "list_k8s_resource_misconfig_policies",
250
+ description: "List available misconfiguration policies used by RAD Security to detect Kubernetes resource misconfigurations",
251
+ inputSchema: zodToJsonSchema(misconfigs.ListKubernetesResourceMisconfigurationPoliciesSchema),
252
+ },
253
+ ]
254
+ : []),
232
255
  // Runtime tools
233
- ...(isToolkitEnabled("runtime", toolkitFilters) ? [
234
- {
235
- name: "get_containers_process_trees",
236
- description: "Get process trees for multiple containers",
237
- inputSchema: zodToJsonSchema(runtime.GetContainersProcessTreesSchema),
238
- },
239
- {
240
- name: "get_containers_baselines",
241
- description: "Get runtime baselines for multiple containers",
242
- inputSchema: zodToJsonSchema(runtime.GetContainersBaselinesSchema),
243
- },
244
- {
245
- name: "get_container_llm_analysis",
246
- description: "Get LLM analysis of a container's process tree",
247
- inputSchema: zodToJsonSchema(runtime.GetContainerLLMAnalysisSchema),
248
- },
249
- ] : []),
256
+ ...(isToolkitEnabled("runtime", toolkitFilters)
257
+ ? [
258
+ {
259
+ name: "get_containers_process_trees",
260
+ description: "Get process trees for multiple containers",
261
+ inputSchema: zodToJsonSchema(runtime.GetContainersProcessTreesSchema),
262
+ },
263
+ {
264
+ name: "get_containers_baselines",
265
+ description: "Get runtime baselines for multiple containers",
266
+ inputSchema: zodToJsonSchema(runtime.GetContainersBaselinesSchema),
267
+ },
268
+ {
269
+ name: "get_container_llm_analysis",
270
+ description: "Get LLM analysis of a container's process tree",
271
+ inputSchema: zodToJsonSchema(runtime.GetContainerLLMAnalysisSchema),
272
+ },
273
+ ]
274
+ : []),
250
275
  // Runtime Network tools
251
- ...(isToolkitEnabled("runtime_network", toolkitFilters) ? [
252
- {
253
- name: "list_http_requests",
254
- description: "List HTTP requests insights with optional filtering by method, path, source and destination workloads, and PII detection",
255
- inputSchema: zodToJsonSchema(runtimeNetwork.listHttpRequestsSchema),
256
- },
257
- {
258
- name: "list_network_connections",
259
- description: "List network connections with optional filtering",
260
- inputSchema: zodToJsonSchema(runtimeNetwork.listNetworkConnectionsSchema),
261
- },
262
- {
263
- name: "list_network_connection_srcs",
264
- description: "List network connection sources with optional filtering by source and destination workloads",
265
- inputSchema: zodToJsonSchema(runtimeNetwork.listNetworkConnectionSourcesSchema),
266
- },
267
- ] : []),
276
+ ...(isToolkitEnabled("runtime_network", toolkitFilters)
277
+ ? [
278
+ {
279
+ name: "list_http_requests",
280
+ description: "List HTTP requests insights with optional filtering by method, path, source and destination workloads, and PII detection",
281
+ inputSchema: zodToJsonSchema(runtimeNetwork.listHttpRequestsSchema),
282
+ },
283
+ {
284
+ name: "list_network_connections",
285
+ description: "List network connections with optional filtering",
286
+ inputSchema: zodToJsonSchema(runtimeNetwork.listNetworkConnectionsSchema),
287
+ },
288
+ {
289
+ name: "list_network_connection_srcs",
290
+ description: "List network connection sources with optional filtering by source and destination workloads",
291
+ inputSchema: zodToJsonSchema(runtimeNetwork.listNetworkConnectionSourcesSchema),
292
+ },
293
+ ]
294
+ : []),
268
295
  // Threat Vectors tools
269
- ...(isToolkitEnabled("threats", toolkitFilters) ? [
270
- {
271
- name: "list_threat_vectors",
272
- description: "List threat vectors",
273
- inputSchema: zodToJsonSchema(threats.listThreatVectorsSchema),
274
- },
275
- ] : []),
296
+ ...(isToolkitEnabled("threats", toolkitFilters)
297
+ ? [
298
+ {
299
+ name: "list_threat_vectors",
300
+ description: "List threat vectors",
301
+ inputSchema: zodToJsonSchema(threats.listThreatVectorsSchema),
302
+ },
303
+ ]
304
+ : []),
276
305
  // Findings tools
277
- ...(isToolkitEnabled("findings", toolkitFilters) ? [
278
- {
279
- name: "list_security_findings",
280
- description: "List security findings with optional filtering by types, severities, sources, and status",
281
- inputSchema: zodToJsonSchema(findings.listFindingsSchema),
282
- },
283
- {
284
- name: "update_security_finding_status",
285
- description: "Update the status of a security finding",
286
- inputSchema: zodToJsonSchema(findings.updateFindingStatusSchema),
287
- },
288
- ] : []),
306
+ ...(isToolkitEnabled("findings", toolkitFilters)
307
+ ? [
308
+ {
309
+ name: "list_security_findings",
310
+ description: "List security findings with optional filtering by types, severities, sources, and status",
311
+ inputSchema: zodToJsonSchema(findings.listFindingsSchema),
312
+ },
313
+ {
314
+ name: "update_security_finding_status",
315
+ description: "Update the status of a security finding",
316
+ inputSchema: zodToJsonSchema(findings.updateFindingStatusSchema),
317
+ },
318
+ ]
319
+ : []),
289
320
  // CVE tools
290
- ...(isToolkitEnabled("cves", toolkitFilters) ? [
291
- {
292
- name: "list_cve_vendors",
293
- description: "Get a list of all vendors in the CVE database. Source: cve-search.org",
294
- inputSchema: zodToJsonSchema(z.object({})),
295
- },
296
- {
297
- name: "list_cve_products",
298
- description: "Get a list of all products associated with a vendor in the CVE database. Source: cve-search.org",
299
- inputSchema: zodToJsonSchema(z.object({
300
- vendor: z.string().describe("Vendor name to list products for")
301
- })),
302
- },
303
- {
304
- name: "search_cves",
305
- description: "Search CVEs by vendor and optionally product. Source: cve-search.org",
306
- inputSchema: zodToJsonSchema(cves.searchCvesSchema),
307
- },
308
- {
309
- name: "get_cve",
310
- description: "Get details for a specific CVE ID. Source: cve-search.org",
311
- inputSchema: zodToJsonSchema(cves.getCveSchema),
312
- },
313
- {
314
- name: "get_latest_30_cves",
315
- description: "Get the latest/newest 30 CVEs including CAPEC, CWE and CPE expansions. Source: cve-search.org",
316
- inputSchema: zodToJsonSchema(z.object({})),
317
- },
318
- ] : []),
321
+ ...(isToolkitEnabled("cves", toolkitFilters)
322
+ ? [
323
+ {
324
+ name: "list_cve_vendors",
325
+ description: "Get a list of all vendors in the CVE database. Source: cve-search.org",
326
+ inputSchema: zodToJsonSchema(z.object({})),
327
+ },
328
+ {
329
+ name: "list_cve_products",
330
+ description: "Get a list of all products associated with a vendor in the CVE database. Source: cve-search.org",
331
+ inputSchema: zodToJsonSchema(z.object({
332
+ vendor: z
333
+ .string()
334
+ .describe("Vendor name to list products for"),
335
+ })),
336
+ },
337
+ {
338
+ name: "search_cves",
339
+ description: "Search CVEs by vendor and optionally product. Source: cve-search.org",
340
+ inputSchema: zodToJsonSchema(cves.searchCvesSchema),
341
+ },
342
+ {
343
+ name: "get_cve",
344
+ description: "Get details for a specific CVE ID. Source: cve-search.org",
345
+ inputSchema: zodToJsonSchema(cves.getCveSchema),
346
+ },
347
+ {
348
+ name: "get_latest_30_cves",
349
+ description: "Get the latest/newest 30 CVEs including CAPEC, CWE and CPE expansions. Source: cve-search.org",
350
+ inputSchema: zodToJsonSchema(z.object({})),
351
+ },
352
+ ]
353
+ : []),
319
354
  // Inbox tools
320
- ...(isToolkitEnabled("inbox", toolkitFilters) ? [
321
- {
322
- name: "mark_inbox_item_as_false_positive",
323
- description: "Mark an inbox item as a false positive with a reason",
324
- inputSchema: zodToJsonSchema(inbox.MarkInboxItemAsFalsePositiveSchema),
325
- },
326
- {
327
- name: "list_inbox_items",
328
- description: "List inbox items with optional filtering by any field. Multiple filters can be combined eg. 'search:cve-2024-12345 and severity:high'",
329
- inputSchema: zodToJsonSchema(inbox.ListInboxItemsSchema),
330
- },
331
- {
332
- name: "get_inbox_item_details",
333
- description: "Get detailed information about a specific inbox item",
334
- inputSchema: zodToJsonSchema(inbox.GetInboxItemDetailsSchema),
335
- },
336
- ] : []),
355
+ ...(isToolkitEnabled("inbox", toolkitFilters)
356
+ ? [
357
+ {
358
+ name: "mark_inbox_item_as_false_positive",
359
+ description: "Mark an inbox item as a false positive with a reason",
360
+ inputSchema: zodToJsonSchema(inbox.MarkInboxItemAsFalsePositiveSchema),
361
+ },
362
+ {
363
+ name: "list_inbox_items",
364
+ description: "List inbox items with optional filtering by any field. Multiple filters can be combined eg. 'search:cve-2024-12345 and severity:high'",
365
+ inputSchema: zodToJsonSchema(inbox.ListInboxItemsSchema),
366
+ },
367
+ {
368
+ name: "get_inbox_item_details",
369
+ description: "Get detailed information about a specific inbox item",
370
+ inputSchema: zodToJsonSchema(inbox.GetInboxItemDetailsSchema),
371
+ },
372
+ ]
373
+ : []),
337
374
  // Workflows tools
338
- ...(isToolkitEnabled("workflows", toolkitFilters) ? [
339
- {
340
- name: "list_workflows",
341
- description: "List all workflows",
342
- inputSchema: zodToJsonSchema(workflows.ListWorkflowsSchema),
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
- },
349
- {
350
- name: "list_workflow_runs",
351
- description: "List workflow runs with optional filtering by workflow ID",
352
- inputSchema: zodToJsonSchema(workflows.ListWorkflowRunsSchema),
353
- },
354
- {
355
- name: "get_workflow_run",
356
- description: "Get detailed information about a specific workflow run",
357
- inputSchema: zodToJsonSchema(workflows.GetWorkflowRunSchema),
358
- },
359
- {
360
- name: "run_workflow",
361
- description: "Run a workflow with optional argument overrides",
362
- inputSchema: zodToJsonSchema(workflows.RunWorkflowSchema),
363
- },
364
- {
365
- name: "list_workflow_schedules",
366
- description: "List workflow schedules with optional filtering by workflow ID",
367
- inputSchema: zodToJsonSchema(workflows.ListWorkflowSchedulesSchema),
368
- },
369
- ] : []),
375
+ ...(isToolkitEnabled("workflows", toolkitFilters)
376
+ ? [
377
+ {
378
+ name: "list_workflows",
379
+ description: "List all workflows",
380
+ inputSchema: zodToJsonSchema(workflows.ListWorkflowsSchema),
381
+ },
382
+ {
383
+ name: "get_workflow",
384
+ description: "Get detailed information about a specific workflow by ID. It contains the workflow definition, default arguments, and schema how to run the workflow",
385
+ inputSchema: zodToJsonSchema(workflows.GetWorkflowSchema),
386
+ },
387
+ {
388
+ name: "list_workflow_runs",
389
+ description: "List workflow runs with optional filtering by workflow ID",
390
+ inputSchema: zodToJsonSchema(workflows.ListWorkflowRunsSchema),
391
+ },
392
+ {
393
+ name: "get_workflow_run",
394
+ description: "Get detailed information about a specific workflow run",
395
+ inputSchema: zodToJsonSchema(workflows.GetWorkflowRunSchema),
396
+ },
397
+ {
398
+ name: "run_workflow",
399
+ description: "Run a workflow with optional argument overrides",
400
+ inputSchema: zodToJsonSchema(workflows.RunWorkflowSchema),
401
+ },
402
+ {
403
+ name: "list_workflow_schedules",
404
+ description: "List workflow schedules with optional filtering by workflow ID",
405
+ inputSchema: zodToJsonSchema(workflows.ListWorkflowSchedulesSchema),
406
+ },
407
+ ]
408
+ : []),
370
409
  // Knowledge Base tools
371
- ...(isToolkitEnabled("knowledge_base", toolkitFilters) ? [
372
- {
373
- name: "search_knowledge_base",
374
- description: "Search your organization's knowledge base to find relevant uploaded documents, procedures, reports, and other content using natural language queries",
375
- inputSchema: zodToJsonSchema(knowledgeBase.SearchKnowledgeBaseSchema),
376
- },
377
- {
378
- name: "list_knowledge_base_collections",
379
- description: "List all collections in your organization's knowledge base. Collections are used to organize and categorize documents",
380
- inputSchema: zodToJsonSchema(knowledgeBase.ListCollectionsSchema),
381
- },
382
- {
383
- name: "list_knowledge_base_documents",
384
- description: "List documents in your organization's knowledge base with optional filtering by collections, file type, or status",
385
- inputSchema: zodToJsonSchema(knowledgeBase.ListDocumentsSchema),
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
- ] : []),
410
+ ...(isToolkitEnabled("knowledge_base", toolkitFilters)
411
+ ? [
412
+ {
413
+ name: "search_knowledge_base",
414
+ description: "Search your organization's knowledge base to find relevant uploaded documents, procedures, reports, and other content using natural language queries",
415
+ inputSchema: zodToJsonSchema(knowledgeBase.SearchKnowledgeBaseSchema),
416
+ },
417
+ {
418
+ name: "list_knowledge_base_collections",
419
+ description: "List all collections in your organization's knowledge base. Collections are used to organize and categorize documents",
420
+ inputSchema: zodToJsonSchema(knowledgeBase.ListCollectionsSchema),
421
+ },
422
+ {
423
+ name: "list_knowledge_base_documents",
424
+ description: "List documents in your organization's knowledge base with optional filtering by collections, file type, or status",
425
+ inputSchema: zodToJsonSchema(knowledgeBase.ListDocumentsSchema),
426
+ },
427
+ {
428
+ name: "query_knowledge_base_document",
429
+ 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",
430
+ inputSchema: zodToJsonSchema(knowledgeBase.StructuredQueryDocumentSchema),
431
+ },
432
+ ]
433
+ : []),
393
434
  // 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).
435
+ ...(isToolkitEnabled("radql", toolkitFilters)
436
+ ? [
437
+ {
438
+ name: "radql_list_data_types",
439
+ 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.",
440
+ inputSchema: zodToJsonSchema(radql.RadQLListDataTypesSchema),
441
+ },
442
+ {
443
+ name: "radql_get_type_metadata",
444
+ 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.",
445
+ inputSchema: zodToJsonSchema(radql.RadQLGetTypeMetadataSchema),
446
+ },
447
+ {
448
+ name: "radql_list_filter_values",
449
+ 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.",
450
+ inputSchema: zodToJsonSchema(radql.RadQLListFilterValuesSchema),
451
+ },
452
+ {
453
+ name: "radql_query",
454
+ description: `Execute RadQL queries for security investigations. Supports: list (filter/search), get_by_id (single item), stats (aggregations).
413
455
 
414
456
  WORKFLOW: radql_list_data_types -> radql_get_type_metadata -> radql_query
415
457
 
@@ -443,19 +485,55 @@ OK to leave unquoted:
443
485
  - Simple wildcards: name:nginx*
444
486
 
445
487
  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
- },
458
- ] : []),
488
+ inputSchema: zodToJsonSchema(radql.RadQLQuerySchema),
489
+ },
490
+ {
491
+ name: "radql_query_builder",
492
+ 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.",
493
+ inputSchema: zodToJsonSchema(radql.RadQLQueryBuilderSchema),
494
+ },
495
+ {
496
+ name: "radql_batch_query",
497
+ 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).",
498
+ inputSchema: zodToJsonSchema(radql.RadQLBatchQuerySchema),
499
+ },
500
+ ]
501
+ : []),
502
+ // Dashboards tools
503
+ ...(isToolkitEnabled("dashboards", toolkitFilters)
504
+ ? [
505
+ {
506
+ name: "list_widget_templates",
507
+ description: "List widget templates with optional filtering by visualization type and category",
508
+ inputSchema: zodToJsonSchema(dashboards.ListWidgetTemplatesSchema),
509
+ },
510
+ {
511
+ name: "get_widget_template",
512
+ description: "Get detailed information about a specific widget template",
513
+ inputSchema: zodToJsonSchema(dashboards.GetWidgetTemplateSchema),
514
+ },
515
+ {
516
+ name: "list_dashboard_templates",
517
+ description: "List dashboard templates with optional filtering by category",
518
+ inputSchema: zodToJsonSchema(dashboards.ListDashboardTemplatesSchema),
519
+ },
520
+ {
521
+ name: "get_dashboard_template",
522
+ description: "Get detailed information about a specific dashboard template",
523
+ inputSchema: zodToJsonSchema(dashboards.GetDashboardTemplateSchema),
524
+ },
525
+ {
526
+ name: "list_dashboards",
527
+ description: "List dashboards for the account",
528
+ inputSchema: zodToJsonSchema(dashboards.ListDashboardsSchema),
529
+ },
530
+ {
531
+ name: "get_dashboard",
532
+ description: "Get detailed information about a specific dashboard",
533
+ inputSchema: zodToJsonSchema(dashboards.GetDashboardSchema),
534
+ },
535
+ ]
536
+ : []),
459
537
  ];
460
538
  return {
461
539
  tools: allTools,
@@ -468,21 +546,25 @@ For complete schema: call radql_get_type_metadata with target data_type`,
468
546
  if (!request.params.arguments) {
469
547
  throw new Error("Arguments are required");
470
548
  }
471
- logger.info({ tool: toolName, arguments: request.params.arguments }, 'tool_invoked');
549
+ logger.info({ tool: toolName, arguments: request.params.arguments }, "tool_invoked");
472
550
  switch (toolName) {
473
551
  // Container tools
474
552
  case "list_containers": {
475
553
  const args = containers.ListContainersSchema.parse(request.params.arguments);
476
554
  const response = await containers.listContainers(client, args.offset, args.limit, args.filters, args.q);
477
555
  return {
478
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
556
+ content: [
557
+ { type: "text", text: JSON.stringify(response, null, 2) },
558
+ ],
479
559
  };
480
560
  }
481
561
  case "get_container_details": {
482
562
  const args = containers.GetContainerDetailsSchema.parse(request.params.arguments);
483
563
  const response = await containers.getContainerDetails(client, args.container_id);
484
564
  return {
485
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
565
+ content: [
566
+ { type: "text", text: JSON.stringify(response, null, 2) },
567
+ ],
486
568
  };
487
569
  }
488
570
  // Cluster tools
@@ -490,14 +572,18 @@ For complete schema: call radql_get_type_metadata with target data_type`,
490
572
  const args = clusters.ListClustersSchema.parse(request.params.arguments);
491
573
  const response = await clusters.listClusters(client, args.page_size, args.page);
492
574
  return {
493
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
575
+ content: [
576
+ { type: "text", text: JSON.stringify(response, null, 2) },
577
+ ],
494
578
  };
495
579
  }
496
580
  case "get_cluster_details": {
497
581
  const args = clusters.GetClusterDetailsSchema.parse(request.params.arguments);
498
582
  const response = await clusters.getClusterDetails(client, args.cluster_id);
499
583
  return {
500
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
584
+ content: [
585
+ { type: "text", text: JSON.stringify(response, null, 2) },
586
+ ],
501
587
  };
502
588
  }
503
589
  // Identity tools
@@ -505,14 +591,18 @@ For complete schema: call radql_get_type_metadata with target data_type`,
505
591
  const args = identities.ListIdentitiesSchema.parse(request.params.arguments);
506
592
  const response = await identities.listIdentities(client, args.identity_types, args.cluster_ids, args.page, args.page_size, args.q);
507
593
  return {
508
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
594
+ content: [
595
+ { type: "text", text: JSON.stringify(response, null, 2) },
596
+ ],
509
597
  };
510
598
  }
511
599
  case "get_identity_details": {
512
600
  const args = identities.GetIdentityDetailsSchema.parse(request.params.arguments);
513
601
  const response = await identities.getIdentityDetails(client, args.identity_id);
514
602
  return {
515
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
603
+ content: [
604
+ { type: "text", text: JSON.stringify(response, null, 2) },
605
+ ],
516
606
  };
517
607
  }
518
608
  // Audit tools
@@ -520,7 +610,9 @@ For complete schema: call radql_get_type_metadata with target data_type`,
520
610
  const args = audit.WhoShelledIntoPodSchema.parse(request.params.arguments);
521
611
  const response = await audit.whoShelledIntoPod(client, args.name, args.namespace, args.cluster_id, args.from_time, args.to_time, args.limit, args.page);
522
612
  return {
523
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
613
+ content: [
614
+ { type: "text", text: JSON.stringify(response, null, 2) },
615
+ ],
524
616
  };
525
617
  }
526
618
  // Cloud Inventory tools
@@ -528,28 +620,36 @@ For complete schema: call radql_get_type_metadata with target data_type`,
528
620
  const args = cloudInventory.ListCloudResourcesSchema.parse(request.params.arguments);
529
621
  const response = await cloudInventory.listCloudResources(client, args.provider, args.filters, args.offset, args.limit, args.q);
530
622
  return {
531
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
623
+ content: [
624
+ { type: "text", text: JSON.stringify(response, null, 2) },
625
+ ],
532
626
  };
533
627
  }
534
628
  case "get_cloud_resource_details": {
535
629
  const args = cloudInventory.GetCloudResourceDetailsSchema.parse(request.params.arguments);
536
630
  const response = await cloudInventory.getCloudResourceDetails(client, args.provider, args.resource_type, args.resource_id);
537
631
  return {
538
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
632
+ content: [
633
+ { type: "text", text: JSON.stringify(response, null, 2) },
634
+ ],
539
635
  };
540
636
  }
541
637
  case "get_cloud_resource_facets": {
542
638
  const args = cloudInventory.GetCloudResourceFacetsSchema.parse(request.params.arguments);
543
639
  const response = await cloudInventory.getCloudResourceFacets(client, args.provider);
544
640
  return {
545
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
641
+ content: [
642
+ { type: "text", text: JSON.stringify(response, null, 2) },
643
+ ],
546
644
  };
547
645
  }
548
646
  case "get_cloud_resource_facet_value": {
549
647
  const args = cloudInventory.GetCloudResourceFacetValuesSchema.parse(request.params.arguments);
550
648
  const response = await cloudInventory.getCloudResourceFacetValues(client, args.provider, args.facet_id);
551
649
  return {
552
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
650
+ content: [
651
+ { type: "text", text: JSON.stringify(response, null, 2) },
652
+ ],
553
653
  };
554
654
  }
555
655
  // Cloud Compliance tools
@@ -557,42 +657,54 @@ For complete schema: call radql_get_type_metadata with target data_type`,
557
657
  const args = cloudCompliance.ListComplianceFrameworksSchema.parse(request.params.arguments);
558
658
  const response = await cloudCompliance.listComplianceFrameworks(client, args.datasource_ids, args.page, args.page_size);
559
659
  return {
560
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
660
+ content: [
661
+ { type: "text", text: JSON.stringify(response, null, 2) },
662
+ ],
561
663
  };
562
664
  }
563
665
  case "list_framework_requirements": {
564
666
  const args = cloudCompliance.ListFrameworkRequirementsSchema.parse(request.params.arguments);
565
667
  const response = await cloudCompliance.listFrameworkRequirements(client, args.framework_name, args.datasource_ids, args.page, args.page_size);
566
668
  return {
567
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
669
+ content: [
670
+ { type: "text", text: JSON.stringify(response, null, 2) },
671
+ ],
568
672
  };
569
673
  }
570
674
  case "list_requirement_controls": {
571
675
  const args = cloudCompliance.ListRequirementControlsSchema.parse(request.params.arguments);
572
676
  const response = await cloudCompliance.listRequirementControls(client, args.framework_name, args.requirement_id, args.datasource_ids, args.page, args.page_size);
573
677
  return {
574
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
678
+ content: [
679
+ { type: "text", text: JSON.stringify(response, null, 2) },
680
+ ],
575
681
  };
576
682
  }
577
683
  case "list_compliance_controls": {
578
684
  const args = cloudCompliance.ListComplianceControlsSchema.parse(request.params.arguments);
579
685
  const response = await cloudCompliance.listComplianceControls(client, args.status, args.providers, args.page, args.page_size);
580
686
  return {
581
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
687
+ content: [
688
+ { type: "text", text: JSON.stringify(response, null, 2) },
689
+ ],
582
690
  };
583
691
  }
584
692
  case "get_compliance_control": {
585
693
  const args = cloudCompliance.GetComplianceControlSchema.parse(request.params.arguments);
586
694
  const response = await cloudCompliance.getComplianceControl(client, args.control_name, args.datasource_ids);
587
695
  return {
588
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
696
+ content: [
697
+ { type: "text", text: JSON.stringify(response, null, 2) },
698
+ ],
589
699
  };
590
700
  }
591
701
  case "list_control_resources": {
592
702
  const args = cloudCompliance.ListControlResourcesSchema.parse(request.params.arguments);
593
703
  const response = await cloudCompliance.listControlResources(client, args.control_name, args.datasource_ids, args.page, args.page_size);
594
704
  return {
595
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
705
+ content: [
706
+ { type: "text", text: JSON.stringify(response, null, 2) },
707
+ ],
596
708
  };
597
709
  }
598
710
  // Image tools
@@ -600,27 +712,35 @@ For complete schema: call radql_get_type_metadata with target data_type`,
600
712
  const args = images.ListImagesSchema.parse(request.params.arguments);
601
713
  const response = await images.listImages(client, args.limit, args.offset, args.sort, args.filters, args.q);
602
714
  return {
603
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
715
+ content: [
716
+ { type: "text", text: JSON.stringify(response, null, 2) },
717
+ ],
604
718
  };
605
719
  }
606
720
  case "list_image_vulnerabilities": {
607
721
  const args = images.ListImageVulnerabilitiesSchema.parse(request.params.arguments);
608
722
  const response = await images.listImageVulnerabilities(client, args.digest, args.severities, args.page, args.page_size);
609
723
  return {
610
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
724
+ content: [
725
+ { type: "text", text: JSON.stringify(response, null, 2) },
726
+ ],
611
727
  };
612
728
  }
613
729
  case "get_top_vulnerable_images": {
614
730
  const response = await images.getTopVulnerableImages(client);
615
731
  return {
616
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
732
+ content: [
733
+ { type: "text", text: JSON.stringify(response, null, 2) },
734
+ ],
617
735
  };
618
736
  }
619
737
  case "get_image_sbom": {
620
738
  const args = images.GetImageSBOMSchema.parse(request.params.arguments);
621
739
  const response = await images.getImageSBOM(client, args.digest);
622
740
  return {
623
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
741
+ content: [
742
+ { type: "text", text: JSON.stringify(response, null, 2) },
743
+ ],
624
744
  };
625
745
  }
626
746
  // Kubernetes Objects tools
@@ -628,14 +748,18 @@ For complete schema: call radql_get_type_metadata with target data_type`,
628
748
  const args = kubeobject.GetKubernetesResourceDetailsSchema.parse(request.params.arguments);
629
749
  const response = await kubeobject.getKubernetesResourceDetails(client, args.cluster_id, args.resource_uid);
630
750
  return {
631
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
751
+ content: [
752
+ { type: "text", text: JSON.stringify(response, null, 2) },
753
+ ],
632
754
  };
633
755
  }
634
756
  case "list_k8s_resources": {
635
757
  const args = kubeobject.ListKubernetesResourcesSchema.parse(request.params.arguments);
636
758
  const response = await kubeobject.listKubernetesResources(client, args.kinds, args.namespace, args.cluster_id, args.page, args.page_size);
637
759
  return {
638
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
760
+ content: [
761
+ { type: "text", text: JSON.stringify(response, null, 2) },
762
+ ],
639
763
  };
640
764
  }
641
765
  // Kubernetes Resource Misconfigurations tools
@@ -643,20 +767,26 @@ For complete schema: call radql_get_type_metadata with target data_type`,
643
767
  const args = misconfigs.ListKubernetesResourceMisconfigurationsSchema.parse(request.params.arguments);
644
768
  const response = await misconfigs.listKubernetesResourceMisconfigurations(client, args.resource_uid);
645
769
  return {
646
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
770
+ content: [
771
+ { type: "text", text: JSON.stringify(response, null, 2) },
772
+ ],
647
773
  };
648
774
  }
649
775
  case "get_k8s_resource_misconfig": {
650
776
  const args = misconfigs.GetKubernetesResourceMisconfigurationDetailsSchema.parse(request.params.arguments);
651
777
  const response = await misconfigs.getKubernetesResourceMisconfigurationDetails(client, args.cluster_id, args.misconfig_id);
652
778
  return {
653
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
779
+ content: [
780
+ { type: "text", text: JSON.stringify(response, null, 2) },
781
+ ],
654
782
  };
655
783
  }
656
784
  case "list_k8s_resource_misconfig_policies": {
657
785
  const response = await misconfigs.listKubernetesResourceMisconfigurationPolicies();
658
786
  return {
659
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
787
+ content: [
788
+ { type: "text", text: JSON.stringify(response, null, 2) },
789
+ ],
660
790
  };
661
791
  }
662
792
  // Runtime tools
@@ -664,21 +794,27 @@ For complete schema: call radql_get_type_metadata with target data_type`,
664
794
  const args = runtime.GetContainersProcessTreesSchema.parse(request.params.arguments);
665
795
  const response = await runtime.getContainersProcessTrees(client, args.container_ids, args.processes_limit);
666
796
  return {
667
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
797
+ content: [
798
+ { type: "text", text: JSON.stringify(response, null, 2) },
799
+ ],
668
800
  };
669
801
  }
670
802
  case "get_containers_baselines": {
671
803
  const args = runtime.GetContainersBaselinesSchema.parse(request.params.arguments);
672
804
  const response = await runtime.getContainersBaselines(client, args.container_ids);
673
805
  return {
674
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
806
+ content: [
807
+ { type: "text", text: JSON.stringify(response, null, 2) },
808
+ ],
675
809
  };
676
810
  }
677
811
  case "get_container_llm_analysis": {
678
812
  const args = runtime.GetContainerLLMAnalysisSchema.parse(request.params.arguments);
679
813
  const response = await runtime.getContainerLLMAnalysis(client, args.container_id);
680
814
  return {
681
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
815
+ content: [
816
+ { type: "text", text: JSON.stringify(response, null, 2) },
817
+ ],
682
818
  };
683
819
  }
684
820
  // Runtime Network tools
@@ -686,21 +822,27 @@ For complete schema: call radql_get_type_metadata with target data_type`,
686
822
  const args = runtimeNetwork.listHttpRequestsSchema.parse(request.params.arguments);
687
823
  const response = await runtimeNetwork.listHttpRequests(client, args);
688
824
  return {
689
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
825
+ content: [
826
+ { type: "text", text: JSON.stringify(response, null, 2) },
827
+ ],
690
828
  };
691
829
  }
692
830
  case "list_network_connections": {
693
831
  const args = runtimeNetwork.listNetworkConnectionsSchema.parse(request.params.arguments);
694
832
  const response = await runtimeNetwork.listNetworkConnections(client, args);
695
833
  return {
696
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
834
+ content: [
835
+ { type: "text", text: JSON.stringify(response, null, 2) },
836
+ ],
697
837
  };
698
838
  }
699
839
  case "list_network_connection_srcs": {
700
840
  const args = runtimeNetwork.listNetworkConnectionSourcesSchema.parse(request.params.arguments);
701
841
  const response = await runtimeNetwork.listNetworkConnectionSources(client, args);
702
842
  return {
703
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
843
+ content: [
844
+ { type: "text", text: JSON.stringify(response, null, 2) },
845
+ ],
704
846
  };
705
847
  }
706
848
  // Threat Vectors tools
@@ -708,7 +850,9 @@ For complete schema: call radql_get_type_metadata with target data_type`,
708
850
  const args = threats.listThreatVectorsSchema.parse(request.params.arguments);
709
851
  const response = await threats.listThreatVectors(client, args.clustersIds, args.namespaces, args.resource_uid, args.page, args.page_size);
710
852
  return {
711
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
853
+ content: [
854
+ { type: "text", text: JSON.stringify(response, null, 2) },
855
+ ],
712
856
  };
713
857
  }
714
858
  // Findings tools
@@ -716,50 +860,72 @@ For complete schema: call radql_get_type_metadata with target data_type`,
716
860
  const args = findings.listFindingsSchema.parse(request.params.arguments);
717
861
  const response = await findings.listFindings(client, args.limit, args.types, args.severities, args.source_types, args.source_kinds, args.source_names, args.source_namespaces, args.status, args.from_time, args.to_time);
718
862
  return {
719
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
863
+ content: [
864
+ { type: "text", text: JSON.stringify(response, null, 2) },
865
+ ],
720
866
  };
721
867
  }
722
868
  case "update_security_finding_status": {
723
869
  const args = findings.updateFindingStatusSchema.parse(request.params.arguments);
724
870
  await findings.updateFindingGroupStatus(client, args.id, args.status);
725
871
  return {
726
- content: [{ type: "text", text: JSON.stringify({ success: true, message: `Finding ${args.id} status updated to ${args.status}` }, null, 2) }],
872
+ content: [
873
+ {
874
+ type: "text",
875
+ text: JSON.stringify({
876
+ success: true,
877
+ message: `Finding ${args.id} status updated to ${args.status}`,
878
+ }, null, 2),
879
+ },
880
+ ],
727
881
  };
728
882
  }
729
883
  // CVE tools
730
884
  case "list_cve_vendors": {
731
885
  const response = await cves.listCveVendors();
732
886
  return {
733
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
887
+ content: [
888
+ { type: "text", text: JSON.stringify(response, null, 2) },
889
+ ],
734
890
  };
735
891
  }
736
892
  case "list_cve_products": {
737
- const args = z.object({
738
- vendor: z.string()
739
- }).parse(request.params.arguments);
893
+ const args = z
894
+ .object({
895
+ vendor: z.string(),
896
+ })
897
+ .parse(request.params.arguments);
740
898
  const response = await cves.listCveProducts(args.vendor);
741
899
  return {
742
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
900
+ content: [
901
+ { type: "text", text: JSON.stringify(response, null, 2) },
902
+ ],
743
903
  };
744
904
  }
745
905
  case "search_cves": {
746
906
  const args = cves.searchCvesSchema.parse(request.params.arguments);
747
907
  const response = await cves.searchCves(args.vendor, args.product);
748
908
  return {
749
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
909
+ content: [
910
+ { type: "text", text: JSON.stringify(response, null, 2) },
911
+ ],
750
912
  };
751
913
  }
752
914
  case "get_cve": {
753
915
  const args = cves.getCveSchema.parse(request.params.arguments);
754
916
  const response = await cves.getCve(args.cveId);
755
917
  return {
756
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
918
+ content: [
919
+ { type: "text", text: JSON.stringify(response, null, 2) },
920
+ ],
757
921
  };
758
922
  }
759
923
  case "get_latest_30_cves": {
760
924
  const response = await cves.getLatest30Cves();
761
925
  return {
762
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
926
+ content: [
927
+ { type: "text", text: JSON.stringify(response, null, 2) },
928
+ ],
763
929
  };
764
930
  }
765
931
  // Inbox tools
@@ -767,21 +933,27 @@ For complete schema: call radql_get_type_metadata with target data_type`,
767
933
  const args = inbox.MarkInboxItemAsFalsePositiveSchema.parse(request.params.arguments);
768
934
  const response = await inbox.markInboxItemAsFalsePositive(client, args.inbox_item_id, args.value, args.reason);
769
935
  return {
770
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
936
+ content: [
937
+ { type: "text", text: JSON.stringify(response, null, 2) },
938
+ ],
771
939
  };
772
940
  }
773
941
  case "list_inbox_items": {
774
942
  const args = inbox.ListInboxItemsSchema.parse(request.params.arguments);
775
943
  const response = await inbox.listInboxItems(client, args.limit, args.offset, args.filters_query);
776
944
  return {
777
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
945
+ content: [
946
+ { type: "text", text: JSON.stringify(response, null, 2) },
947
+ ],
778
948
  };
779
949
  }
780
950
  case "get_inbox_item_details": {
781
951
  const args = inbox.GetInboxItemDetailsSchema.parse(request.params.arguments);
782
952
  const response = await inbox.getInboxItemDetails(client, args.inbox_item_id);
783
953
  return {
784
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
954
+ content: [
955
+ { type: "text", text: JSON.stringify(response, null, 2) },
956
+ ],
785
957
  };
786
958
  }
787
959
  // Workflows tools
@@ -789,42 +961,54 @@ For complete schema: call radql_get_type_metadata with target data_type`,
789
961
  workflows.ListWorkflowsSchema.parse(request.params.arguments);
790
962
  const response = await workflows.listWorkflows(client);
791
963
  return {
792
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
964
+ content: [
965
+ { type: "text", text: JSON.stringify(response, null, 2) },
966
+ ],
793
967
  };
794
968
  }
795
969
  case "get_workflow": {
796
970
  const args = workflows.GetWorkflowSchema.parse(request.params.arguments);
797
971
  const response = await workflows.getWorkflow(client, args.workflow_id);
798
972
  return {
799
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
973
+ content: [
974
+ { type: "text", text: JSON.stringify(response, null, 2) },
975
+ ],
800
976
  };
801
977
  }
802
978
  case "list_workflow_runs": {
803
979
  const args = workflows.ListWorkflowRunsSchema.parse(request.params.arguments);
804
980
  const response = await workflows.listWorkflowRuns(client, args.workflow_id);
805
981
  return {
806
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
982
+ content: [
983
+ { type: "text", text: JSON.stringify(response, null, 2) },
984
+ ],
807
985
  };
808
986
  }
809
987
  case "get_workflow_run": {
810
988
  const args = workflows.GetWorkflowRunSchema.parse(request.params.arguments);
811
989
  const response = await workflows.getWorkflowRun(client, args.workflow_id, args.run_id);
812
990
  return {
813
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
991
+ content: [
992
+ { type: "text", text: JSON.stringify(response, null, 2) },
993
+ ],
814
994
  };
815
995
  }
816
996
  case "run_workflow": {
817
997
  const args = workflows.RunWorkflowSchema.parse(request.params.arguments);
818
998
  const response = await workflows.runWorkflow(client, args.workflow_id, args.async, args.args);
819
999
  return {
820
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1000
+ content: [
1001
+ { type: "text", text: JSON.stringify(response, null, 2) },
1002
+ ],
821
1003
  };
822
1004
  }
823
1005
  case "list_workflow_schedules": {
824
1006
  const args = workflows.ListWorkflowSchedulesSchema.parse(request.params.arguments);
825
1007
  const response = await workflows.listWorkflowSchedules(client, args.workflow_id);
826
1008
  return {
827
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1009
+ content: [
1010
+ { type: "text", text: JSON.stringify(response, null, 2) },
1011
+ ],
828
1012
  };
829
1013
  }
830
1014
  // Knowledge Base tools
@@ -832,82 +1016,157 @@ For complete schema: call radql_get_type_metadata with target data_type`,
832
1016
  const args = knowledgeBase.SearchKnowledgeBaseSchema.parse(request.params.arguments);
833
1017
  const response = await knowledgeBase.searchKnowledgeBase(client, args.query, args.top_k, args.min_score, args.thread_id, args.collections, args.document_ids);
834
1018
  return {
835
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1019
+ content: [
1020
+ { type: "text", text: JSON.stringify(response, null, 2) },
1021
+ ],
836
1022
  };
837
1023
  }
838
1024
  case "list_knowledge_base_collections": {
839
1025
  const args = knowledgeBase.ListCollectionsSchema.parse(request.params.arguments);
840
1026
  const response = await knowledgeBase.listCollections(client, args.limit, args.offset);
841
1027
  return {
842
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1028
+ content: [
1029
+ { type: "text", text: JSON.stringify(response, null, 2) },
1030
+ ],
843
1031
  };
844
1032
  }
845
1033
  case "list_knowledge_base_documents": {
846
1034
  const args = knowledgeBase.ListDocumentsSchema.parse(request.params.arguments);
847
1035
  const response = await knowledgeBase.listDocuments(client, args.limit, args.offset, args.filters);
848
1036
  return {
849
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1037
+ content: [
1038
+ { type: "text", text: JSON.stringify(response, null, 2) },
1039
+ ],
850
1040
  };
851
1041
  }
852
1042
  case "query_knowledge_base_document": {
853
1043
  const args = knowledgeBase.StructuredQueryDocumentSchema.parse(request.params.arguments);
854
1044
  const response = await knowledgeBase.structuredQueryDocument(client, args.document_id, args.query);
855
1045
  return {
856
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1046
+ content: [
1047
+ { type: "text", text: JSON.stringify(response, null, 2) },
1048
+ ],
857
1049
  };
858
1050
  }
859
1051
  // RadQL tools
860
1052
  case "radql_list_data_types": {
861
1053
  const response = await radql.executeListDataTypes(client);
862
1054
  return {
863
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1055
+ content: [
1056
+ { type: "text", text: JSON.stringify(response, null, 2) },
1057
+ ],
864
1058
  };
865
1059
  }
866
1060
  case "radql_get_type_metadata": {
867
1061
  const args = radql.RadQLGetTypeMetadataSchema.parse(request.params.arguments);
868
1062
  const response = await radql.executeGetTypeMetadata(client, args);
869
1063
  return {
870
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1064
+ content: [
1065
+ { type: "text", text: JSON.stringify(response, null, 2) },
1066
+ ],
871
1067
  };
872
1068
  }
873
1069
  case "radql_list_filter_values": {
874
1070
  const args = radql.RadQLListFilterValuesSchema.parse(request.params.arguments);
875
1071
  const response = await radql.executeListFilterValues(client, args);
876
1072
  return {
877
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1073
+ content: [
1074
+ { type: "text", text: JSON.stringify(response, null, 2) },
1075
+ ],
878
1076
  };
879
1077
  }
880
1078
  case "radql_query": {
881
1079
  const args = radql.RadQLQuerySchema.parse(request.params.arguments);
882
1080
  const response = await radql.executeRadQLQuery(client, args);
883
1081
  return {
884
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1082
+ content: [
1083
+ { type: "text", text: JSON.stringify(response, null, 2) },
1084
+ ],
885
1085
  };
886
1086
  }
887
1087
  case "radql_query_builder": {
888
1088
  const args = radql.RadQLQueryBuilderSchema.parse(request.params.arguments);
889
1089
  const response = radql.buildRadQLQuery(args);
890
1090
  return {
891
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1091
+ content: [
1092
+ { type: "text", text: JSON.stringify(response, null, 2) },
1093
+ ],
892
1094
  };
893
1095
  }
894
1096
  case "radql_batch_query": {
895
1097
  const args = radql.RadQLBatchQuerySchema.parse(request.params.arguments);
896
1098
  const response = await radql.executeBatchQueries(client, args);
897
1099
  return {
898
- content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
1100
+ content: [
1101
+ { type: "text", text: JSON.stringify(response, null, 2) },
1102
+ ],
1103
+ };
1104
+ }
1105
+ // Dashboards tools
1106
+ case "list_widget_templates": {
1107
+ const args = dashboards.ListWidgetTemplatesSchema.parse(request.params.arguments);
1108
+ const response = await dashboards.listWidgetTemplates(client, args.limit, args.offset, args.visualization_type, args.category);
1109
+ return {
1110
+ content: [
1111
+ { type: "text", text: JSON.stringify(response, null, 2) },
1112
+ ],
1113
+ };
1114
+ }
1115
+ case "get_widget_template": {
1116
+ const args = dashboards.GetWidgetTemplateSchema.parse(request.params.arguments);
1117
+ const response = await dashboards.getWidgetTemplate(client, args.widget_template_id);
1118
+ return {
1119
+ content: [
1120
+ { type: "text", text: JSON.stringify(response, null, 2) },
1121
+ ],
1122
+ };
1123
+ }
1124
+ case "list_dashboard_templates": {
1125
+ const args = dashboards.ListDashboardTemplatesSchema.parse(request.params.arguments);
1126
+ const response = await dashboards.listDashboardTemplates(client, args.limit, args.offset, args.category);
1127
+ return {
1128
+ content: [
1129
+ { type: "text", text: JSON.stringify(response, null, 2) },
1130
+ ],
1131
+ };
1132
+ }
1133
+ case "get_dashboard_template": {
1134
+ const args = dashboards.GetDashboardTemplateSchema.parse(request.params.arguments);
1135
+ const response = await dashboards.getDashboardTemplate(client, args.dashboard_template_id);
1136
+ return {
1137
+ content: [
1138
+ { type: "text", text: JSON.stringify(response, null, 2) },
1139
+ ],
1140
+ };
1141
+ }
1142
+ case "list_dashboards": {
1143
+ const args = dashboards.ListDashboardsSchema.parse(request.params.arguments);
1144
+ const response = await dashboards.listDashboards(client, args.limit, args.offset);
1145
+ return {
1146
+ content: [
1147
+ { type: "text", text: JSON.stringify(response, null, 2) },
1148
+ ],
1149
+ };
1150
+ }
1151
+ case "get_dashboard": {
1152
+ const args = dashboards.GetDashboardSchema.parse(request.params.arguments);
1153
+ const response = await dashboards.getDashboard(client, args.dashboard_id);
1154
+ return {
1155
+ content: [
1156
+ { type: "text", text: JSON.stringify(response, null, 2) },
1157
+ ],
899
1158
  };
900
1159
  }
901
1160
  default:
902
1161
  throw new Error(`Unknown tool: ${toolName}`);
903
1162
  }
904
1163
  const duration = Date.now() - startTime;
905
- logger.info({ tool: toolName, duration_ms: duration }, 'tool_execution_completed');
1164
+ logger.info({ tool: toolName, duration_ms: duration }, "tool_execution_completed");
906
1165
  }
907
1166
  catch (error) {
908
1167
  const duration = Date.now() - startTime;
909
1168
  const errorMessage = error instanceof Error ? error.message : String(error);
910
- logger.error({ tool: toolName, error: errorMessage, duration_ms: duration }, 'tool_execution_failed');
1169
+ logger.error({ tool: toolName, error: errorMessage, duration_ms: duration }, "tool_execution_failed");
911
1170
  return {
912
1171
  content: [
913
1172
  {
@@ -924,39 +1183,39 @@ For complete schema: call radql_get_type_metadata with target data_type`,
924
1183
  }
925
1184
  async function main() {
926
1185
  try {
927
- const transportType = process.env.TRANSPORT_TYPE || 'stdio';
928
- if (!['stdio', 'sse', 'streamable'].includes(transportType)) {
1186
+ const transportType = process.env.TRANSPORT_TYPE || "stdio";
1187
+ if (!["stdio", "sse", "streamable"].includes(transportType)) {
929
1188
  throw new Error("Transport type must be either 'stdio', 'sse' or 'streamable'");
930
1189
  }
931
1190
  // Log server startup
932
1191
  logger.info({
933
1192
  version: VERSION,
934
1193
  transport: transportType,
935
- node_version: process.version
936
- }, 'server_starting');
1194
+ node_version: process.version,
1195
+ }, "server_starting");
937
1196
  // Log toolkit filters if set
938
1197
  const filters = parseToolkitFilters();
939
1198
  if (filters.include && filters.include.length > 0) {
940
- logger.info({ mode: "include", toolkits: filters.include }, 'toolkit_filter_configured');
1199
+ logger.info({ mode: "include", toolkits: filters.include }, "toolkit_filter_configured");
941
1200
  }
942
1201
  else if (filters.exclude && filters.exclude.length > 0) {
943
- logger.info({ mode: "exclude", toolkits: filters.exclude }, 'toolkit_filter_configured');
1202
+ logger.info({ mode: "exclude", toolkits: filters.exclude }, "toolkit_filter_configured");
944
1203
  }
945
1204
  else {
946
- logger.info('toolkit_all_enabled');
1205
+ logger.info("toolkit_all_enabled");
947
1206
  }
948
- if (transportType === 'stdio') {
1207
+ if (transportType === "stdio") {
949
1208
  const transport = new StdioServerTransport();
950
1209
  const server = await newServer();
951
1210
  await server.connect(transport);
952
- logger.info({ transport: 'stdio' }, 'server_ready');
1211
+ logger.info({ transport: "stdio" }, "server_ready");
953
1212
  }
954
- else if (transportType === 'sse') {
1213
+ else if (transportType === "sse") {
955
1214
  const app = express();
956
1215
  app.use(cors({
957
- origin: '*',
958
- methods: ['GET', 'POST', 'OPTIONS', 'HEAD'],
959
- allowedHeaders: ['Content-Type'],
1216
+ origin: "*",
1217
+ methods: ["GET", "POST", "OPTIONS", "HEAD"],
1218
+ allowedHeaders: ["Content-Type"],
960
1219
  }));
961
1220
  const server = await newServer();
962
1221
  let transport;
@@ -975,23 +1234,23 @@ async function main() {
975
1234
  });
976
1235
  const port = process.env.PORT || 3000;
977
1236
  app.listen(port, () => {
978
- logger.info({ transport: 'sse', url: `http://localhost:${port}/sse` }, 'server_ready');
1237
+ logger.info({ transport: "sse", url: `http://localhost:${port}/sse` }, "server_ready");
979
1238
  });
980
1239
  }
981
- else if (transportType === 'streamable') {
1240
+ else if (transportType === "streamable") {
982
1241
  const app = express();
983
1242
  app.use(express.json());
984
1243
  app.use(cors({
985
- origin: '*',
986
- methods: ['GET', 'POST', 'OPTIONS', 'HEAD'],
987
- allowedHeaders: ['Content-Type'],
1244
+ origin: "*",
1245
+ methods: ["GET", "POST", "OPTIONS", "HEAD"],
1246
+ allowedHeaders: ["Content-Type"],
988
1247
  }));
989
1248
  // Map to store transports by session ID
990
1249
  const transports = {};
991
1250
  // Handle POST requests for client-to-server communication
992
- app.post('/mcp', async (req, res) => {
1251
+ app.post("/mcp", async (req, res) => {
993
1252
  // Check for existing session ID
994
- const sessionId = req.headers['mcp-session-id'];
1253
+ const sessionId = req.headers["mcp-session-id"];
995
1254
  let transport;
996
1255
  if (sessionId && transports[sessionId]) {
997
1256
  // Reuse existing transport
@@ -1004,7 +1263,7 @@ async function main() {
1004
1263
  onsessioninitialized: (sessionId) => {
1005
1264
  // Store the transport by session ID
1006
1265
  transports[sessionId] = transport;
1007
- }
1266
+ },
1008
1267
  });
1009
1268
  // Clean up transport when closed
1010
1269
  transport.onclose = () => {
@@ -1019,10 +1278,10 @@ async function main() {
1019
1278
  else {
1020
1279
  // Invalid request
1021
1280
  res.status(400).json({
1022
- jsonrpc: '2.0',
1281
+ jsonrpc: "2.0",
1023
1282
  error: {
1024
1283
  code: -32000,
1025
- message: 'Bad Request: No valid session ID provided',
1284
+ message: "Bad Request: No valid session ID provided",
1026
1285
  },
1027
1286
  id: null,
1028
1287
  });
@@ -1033,33 +1292,33 @@ async function main() {
1033
1292
  });
1034
1293
  // Reusable handler for GET and DELETE requests
1035
1294
  const handleSessionRequest = async (req, res) => {
1036
- const sessionId = req.headers['mcp-session-id'];
1295
+ const sessionId = req.headers["mcp-session-id"];
1037
1296
  if (!sessionId || !transports[sessionId]) {
1038
- res.status(400).send('Invalid or missing session ID');
1297
+ res.status(400).send("Invalid or missing session ID");
1039
1298
  return;
1040
1299
  }
1041
1300
  const transport = transports[sessionId];
1042
1301
  await transport.handleRequest(req, res);
1043
1302
  };
1044
1303
  // Handle GET requests for server-to-client notifications via SSE
1045
- app.get('/mcp', handleSessionRequest);
1304
+ app.get("/mcp", handleSessionRequest);
1046
1305
  // Handle DELETE requests for session termination
1047
- app.delete('/mcp', handleSessionRequest);
1306
+ app.delete("/mcp", handleSessionRequest);
1048
1307
  const port = process.env.PORT || 3000;
1049
1308
  app.listen(port, () => {
1050
- logger.info({ transport: 'streamable', url: `http://localhost:${port}/mcp` }, 'server_ready');
1309
+ logger.info({ transport: "streamable", url: `http://localhost:${port}/mcp` }, "server_ready");
1051
1310
  });
1052
1311
  }
1053
1312
  }
1054
1313
  catch (error) {
1055
1314
  const errorMessage = error instanceof Error ? error.message : String(error);
1056
- logger.fatal({ error: errorMessage }, 'server_startup_failed');
1315
+ logger.fatal({ error: errorMessage }, "server_startup_failed");
1057
1316
  process.exit(1);
1058
1317
  }
1059
1318
  }
1060
1319
  main().catch((error) => {
1061
1320
  const errorMessage = error instanceof Error ? error.message : String(error);
1062
- logger.fatal({ error: errorMessage }, 'server_error_unhandled');
1321
+ logger.fatal({ error: errorMessage }, "server_error_unhandled");
1063
1322
  process.exit(1);
1064
1323
  });
1065
1324
  //# sourceMappingURL=index.js.map