@vantasdk/vanta-mcp-server
Version:
Model Context Protocol server for Vanta's security compliance platform
110 lines (109 loc) • 5.22 kB
JavaScript
import { baseApiUrl } from "../api.js";
import { z } from "zod";
import { makeAuthenticatedRequest } from "./utils.js";
export async function getTests(args) {
const url = new URL("/v1/tests", baseApiUrl());
if (args.pageSize !== undefined) {
url.searchParams.append("pageSize", args.pageSize.toString());
}
if (args.statusFilter !== undefined) {
url.searchParams.append("statusFilter", args.statusFilter);
}
if (args.integrationFilter !== undefined) {
url.searchParams.append("integrationFilter", args.integrationFilter);
}
if (args.controlFilter !== undefined) {
url.searchParams.append("controlFilter", args.controlFilter);
}
if (args.frameworkFilter !== undefined) {
url.searchParams.append("frameworkFilter", args.frameworkFilter);
}
const response = await makeAuthenticatedRequest(url.toString());
if (!response.ok) {
return {
content: [
{
type: "text",
text: `Url: ${url.toString()}, Error: ${response.statusText}`,
},
],
};
}
return {
content: [
{ type: "text", text: JSON.stringify(await response.json()) },
],
};
}
export async function getTestEntities(args) {
const url = new URL(`/v1/tests/${args.testId}/entities`, baseApiUrl());
if (args.pageSize !== undefined) {
url.searchParams.append("pageSize", args.pageSize.toString());
}
if (args.pageCursor !== undefined) {
url.searchParams.append("pageCursor", args.pageCursor);
}
if (args.entityStatus !== undefined) {
url.searchParams.append("entityStatus", args.entityStatus);
}
const response = await makeAuthenticatedRequest(url.toString());
if (!response.ok) {
return {
content: [
{
type: "text",
text: `Url: ${url.toString()}, Error: ${response.statusText}`,
},
],
};
}
return {
content: [
{ type: "text", text: JSON.stringify(await response.json()) },
],
};
}
const TOOL_DESCRIPTION = `Retrieve Vanta's automated security and compliance tests. Vanta runs 1,200+ automated tests continuously to monitor compliance across your infrastructure. Filter by status (OK, NEEDS_ATTENTION, DEACTIVATED), cloud integration (aws, azure, gcp), or compliance framework (soc2, iso27001, hipaa). Returns test results showing which security controls are passing or failing across your infrastructure. Tests that are NOT_APPLICABLE to your resources are included by default - use statusFilter=NEEDS_ATTENTION to retrieve only actionable failing tests.`;
const TEST_STATUS_FILTER_DESCRIPTION = `Filter tests by their status.
Helpful for retrieving only relevant or actionable results.
Possible values: OK, DEACTIVATED, NEEDS_ATTENTION, IN_PROGRESS, INVALID, NOT_APPLICABLE.`;
const PAGE_SIZE_DESCRIPTION = `Controls the maximum number of tests returned in a single response.
Allowed values: 1–100. Default is 10.`;
const INTEGRATION_FILTER_DESCRIPTION = `Filter by integration. Non-exhaustive examples of possible values include aws, azure, gcp, snyk.`;
const FRAMEWORK_FILTER_DESCRIPTION = `Filter by framework. Non-exhaustive examples: soc2, ccpa, fedramp`;
const CONTROL_FILTER_DESCRIPTION = `Filter by control. Generally will only be known if pulled from the /v1/controls endpoint.`;
export const GetTestsInput = z.object({
pageSize: z.number().describe(PAGE_SIZE_DESCRIPTION).optional(),
statusFilter: z.string().describe(TEST_STATUS_FILTER_DESCRIPTION).optional(),
integrationFilter: z
.string()
.describe(INTEGRATION_FILTER_DESCRIPTION)
.optional(),
frameworkFilter: z.string().describe(FRAMEWORK_FILTER_DESCRIPTION).optional(),
controlFilter: z.string().describe(CONTROL_FILTER_DESCRIPTION).optional(),
});
export const GetTestsTool = {
name: "get_tests",
description: TOOL_DESCRIPTION,
parameters: GetTestsInput,
};
const GetTestEntitiesInput = z.object({
testId: z.string().describe("Lowercase with hyphens"),
pageSize: z
.number()
.describe("Controls the maximum number of tests returned in a single response. Allowed values: 1–100. Default is 10.")
.optional(),
pageCursor: z
.string()
.describe("Used for pagination. Leave blank to start from the first page.")
.optional(),
entityStatus: z
.string()
.describe("Filter by entity status. Possible values: FAILING, DEACTIVATED.")
.optional(),
});
export const GetTestEntitiesTool = {
name: "get_test_entities",
description: `Get the specific failing resources (entities) for a known test ID. Use this when you already know the test name/ID and need to see which specific infrastructure resources are failing that test. For example, if you know "aws-security-groups-open-to-world" test is failing, this returns the actual security group IDs that are failing. Requires a specific testId parameter. Do NOT use this for general test discovery - use get_tests for that.`,
parameters: GetTestEntitiesInput,
};