UNPKG

@turbot/powerpipe-mcp

Version:

Powerpipe MCP server to run benchmarks, detections and controls using AI.

132 lines 6.4 kB
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { logger } from "../services/logger.js"; import { formatCommandError } from "../utils/command.js"; import AjvModule from "ajv"; // Initialize JSON Schema validator const Ajv = AjvModule.default || AjvModule; const ajv = new Ajv(); // Most Frequently Used Operations import { tool as benchmarkListTool } from './powerpipe_benchmark_list.js'; import { tool as benchmarkShowTool } from './powerpipe_benchmark_show.js'; import { tool as benchmarkRunTool } from './powerpipe_benchmark_run.js'; import { tool as controlListTool } from './powerpipe_control_list.js'; import { tool as controlShowTool } from './powerpipe_control_show.js'; import { tool as controlRunTool } from './powerpipe_control_run.js'; // Secondary Operations import { tool as detectionListTool } from './powerpipe_detection_list.js'; import { tool as detectionShowTool } from './powerpipe_detection_show.js'; import { tool as detectionRunTool } from './powerpipe_detection_run.js'; import { tool as queryListTool } from './powerpipe_query_list.js'; import { tool as queryShowTool } from './powerpipe_query_show.js'; // Configuration & Utilities import { tool as modLocationTool } from './powerpipe_mod_location.js'; import { tool as modListTool } from './powerpipe_mod_list.js'; import { tool as variableListTool } from './powerpipe_variable_list.js'; import { tool as variableShowTool } from './powerpipe_variable_show.js'; import { tool as docsHclTool } from './powerpipe_docs_hcl.js'; // Powerpipe import { tool as dashboard_list } from "./powerpipe_dashboard_list.js"; import { tool as dashboard_show } from "./powerpipe_dashboard_show.js"; import { tool as dashboard_run } from "./powerpipe_dashboard_run.js"; // Export all tools for server capabilities export const tools = { // Most Frequently Used Operations powerpipe_benchmark_list: benchmarkListTool, // Primary entry point for users finding benchmarks powerpipe_benchmark_show: benchmarkShowTool, // Detailed benchmark info powerpipe_benchmark_run: benchmarkRunTool, // Running benchmarks - core operation powerpipe_control_list: controlListTool, // Finding available controls powerpipe_control_show: controlShowTool, // Control details powerpipe_control_run: controlRunTool, // Running controls - core operation // Secondary Operations powerpipe_detection_list: detectionListTool, // Less commonly used than benchmarks/controls powerpipe_detection_show: detectionShowTool, powerpipe_detection_run: detectionRunTool, powerpipe_query_list: queryListTool, // More technical/advanced usage powerpipe_query_show: queryShowTool, // Configuration & Utilities powerpipe_mod_location: modLocationTool, // Usually set once and rarely changed powerpipe_mod_list: modListTool, // List available mods powerpipe_variable_list: variableListTool, // Supporting operations powerpipe_variable_show: variableShowTool, // Documentation powerpipe_docs_hcl: docsHclTool, // HCL documentation lookup // Powerpipe powerpipe_dashboard_list: dashboard_list, powerpipe_dashboard_show: dashboard_show, powerpipe_dashboard_run: dashboard_run }; // Initialize tool handlers export function setupTools(server) { // Register tool list handler server.setRequestHandler(ListToolsRequestSchema, async () => { try { return { tools: Object.values(tools), }; } catch (error) { logger.error('Error listing tools:', error); return formatCommandError(error); } }); // Register tool handlers server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { // Validate tool exists const tool = tools[name]; if (!tool) { throw new Error(`Unknown tool: ${name}`); } // Validate tool has handler if (!tool.handler) { throw new Error(`Tool ${name} has no handler defined`); } // Validate arguments against the tool's schema if (tool.inputSchema) { const validate = ajv.compile(tool.inputSchema); if (!validate(args)) { logger.error(`Invalid arguments for tool ${name}:`, validate.errors); // Format validation errors in a user-friendly way const errors = validate.errors || []; const errorMessages = errors.map((err) => { const path = err.instancePath.replace(/^\//, '') || 'input'; switch (err.keyword) { case 'required': return `Missing required field: ${err.params.missingProperty}`; case 'type': return `${path} must be a ${err.params.type}`; case 'enum': return `${path} must be one of: ${err.params.allowedValues?.join(', ')}`; case 'additionalProperties': return `Unexpected field: ${err.params.additionalProperty}`; default: return `${path}: ${err.message}`; } }); return { content: [{ type: "text", text: errorMessages.join('\n') }], isError: true }; } } // Log tool invocation logger.info(`Executing tool: ${name}`, { args }); // Execute tool handler with validated arguments const result = await tool.handler(args || {}); // Log tool completion logger.info(`Tool ${name} completed successfully`); return result; } catch (error) { // Log error logger.error(`Error executing tool ${name}:`, error); // Format and return error return formatCommandError(error); } }); } //# sourceMappingURL=index.js.map