diff --git a/README.md b/README.md index f70c6e5..d4b3cd3 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,12 @@ A [Model Context Protocol](https://modelcontextprotocol.com/) server that provid - Get specific tests that validate each security control - Understand which automated tests monitor compliance for specific controls +### Risk Scenario Management + +- Get all the risk scenarios you are managing in your current risk register. +- Returns details about each risk scenario's status, inherent & residual risk score, treatment plan, and more. +- Filterable by risk category (Access Control, Cryptography, Privacy, and many others). + ### Multi-Region Support - US, EU, and AUS regions with region-specific API endpoints @@ -41,6 +47,7 @@ A [Model Context Protocol](https://modelcontextprotocol.com/) server that provid | `get_framework_controls` | Get detailed security control requirements for a specific compliance framework. Returns the specific controls, their descriptions, implementation guidance, and current compliance status. Essential for understanding what security measures are required for each compliance standard. | | `get_controls` | List all security controls across all frameworks in your Vanta account. Returns control names, descriptions, framework mappings, and current implementation status. Use this to see all available controls or to find a specific control ID for use with other tools. | | `get_control_tests` | Get all automated tests that validate a specific security control. Use this when you know a control ID and want to see which specific tests monitor compliance for that control. Returns test details, current status, and any failing entities for the control's tests. | +| `get_risks` | Get all the risk scenarios you are managing in your current risk register. Returns details about each risk scenario's status, inherent & residual risk score, treatment plan, and more. Filterable by risk category (Access Control, Cryptography, Privacy, and many others). | ## Configuration diff --git a/src/eval/eval.ts b/src/eval/eval.ts index 649ec6b..d3e4c45 100644 --- a/src/eval/eval.ts +++ b/src/eval/eval.ts @@ -9,6 +9,7 @@ import { GetControlsTool, GetControlTestsTool, } from "../operations/controls.js"; +import { GetRisksTool } from "../operations/risks.js"; // Format all tools for OpenAI const tools = [ @@ -60,6 +61,14 @@ const tools = [ parameters: zodToJsonSchema(GetControlTestsTool.parameters), }, }, + { + type: "function" as const, + function: { + name: GetRisksTool.name, + description: GetRisksTool.description, + parameters: zodToJsonSchema(GetRisksTool.parameters), + }, + }, ]; // Test cases with expected tool calls diff --git a/src/index.ts b/src/index.ts index eaaa4d1..e7cba1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,6 +20,7 @@ import { getControls, getControlTests, } from "./operations/controls.js"; +import { getRisks, GetRisksTool } from "./operations/risks.js"; import { initializeToken } from "./auth.js"; const server = new McpServer({ @@ -71,6 +72,13 @@ server.tool( getControlTests, ); +server.tool( + GetRisksTool.name, + GetRisksTool.description, + GetRisksTool.parameters.shape, + getRisks, +); + async function main() { try { await initializeToken(); diff --git a/src/operations/risks.ts b/src/operations/risks.ts new file mode 100644 index 0000000..7266dac --- /dev/null +++ b/src/operations/risks.ts @@ -0,0 +1,61 @@ +import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +import { baseApiUrl } from "../api.js"; +import { Tool } from "../types.js"; +import { z } from "zod"; +import { makeAuthenticatedRequest } from "./utils.js"; + +const GetRisksInput = z.object({ + pageSize: z + .number() + .optional() + .describe( + "Controls the maximum number of risks returned in a single response. Allowed values: 1–100. Default is 10.", + ), + pageCursor: z + .string() + .optional() + .describe("Used for pagination. Leave blank to start from the first page."), + categoryMatchesAny: z + .string() + .optional() + .describe( + "Filter by risk category. Example: Access Control, Cryptography, Privacy, etc.", + ), +}); + +export const GetRisksTool: Tool = { + name: "get_risks", + description: "List all risk scenarios in your Vanta risk register.", + parameters: GetRisksInput, +}; + +export async function getRisks( + args: z.infer, +): Promise { + const url = new URL("/v1/risk-scenarios", baseApiUrl()); + if (args.pageSize !== undefined) { + url.searchParams.append("pageSize", args.pageSize.toString()); + } + if (args.pageCursor !== undefined) { + url.searchParams.append("pageCursor", args.pageCursor); + } + if (args.categoryMatchesAny !== undefined) { + url.searchParams.append("categoryMatchesAny", args.categoryMatchesAny); + } + + const response = await makeAuthenticatedRequest(url.toString()); + + if (!response.ok) { + return { + content: [ + { type: "text" as const, text: `Error: ${response.statusText}` }, + ], + }; + } + + return { + content: [ + { type: "text" as const, text: JSON.stringify(await response.json()) }, + ], + }; +}