UNPKG

@turbot/guardrails-mcp

Version:

MCP server for interacting with Turbot Guardrails.

124 lines (123 loc) 6.62 kB
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { logger } from "../services/pinoLogger.js"; import { errorResponse } from "../utils/responseFormatter.mjs"; import AjvModule from "ajv"; // Initialize JSON Schema validator const Ajv = AjvModule.default || AjvModule; const ajv = new Ajv(); // Import tools import { tool as queryTool } from "./guardrails_query.js"; import { tool as listResourceTypesTool } from "./guardrails_resource_type_list.js"; import { tool as listControlTypesTool } from "./guardrails_control_type_list.js"; import { tool as listPolicyTypesTool } from "./guardrails_policy_type_list.js"; import { tool as listResourcesTool } from "./guardrails_resource_list.js"; import { tool as runControlTool } from "./guardrails_control_run.js"; import { tool as queryRunnableTool } from "./guardrails_query_runnable.js"; import { tool as queryRunnableIntrospectionTool } from "./guardrails_query_runnable_introspection.js"; import { tool as processTemplateTool } from "./guardrails_process_template.js"; import { tool as guardrailsControlTypeShowTool } from "./guardrails_control_type_show.js"; import { tool as guardrailsPolicyTypeShowTool } from "./guardrails_policy_type_show.js"; import { tool as guardrailsResourceTypeShowTool } from "./guardrails_resource_type_show.js"; import { tool as guardrailsResourceShowTool } from "./guardrails_resource_show.js"; import { tool as guardrailsControlListTool } from "./guardrails_control_list.js"; import { tool as guardrailsControlShowTool } from "./guardrails_control_show.js"; import { tool as guardrailsPolicySettingListTool } from './guardrails_policy_setting_list.js'; import { tool as guardrailsPolicySettingShowTool } from './guardrails_policy_setting_show.js'; // Export all tools for server capabilities export const tools = { // Core Guardrails Operations guardrails_query: queryTool, // Execute GraphQL queries // Resource Operations guardrails_resource_list: listResourcesTool, // List resources guardrails_resource_show: guardrailsResourceShowTool, // Show resource details // Resource Type Operations guardrails_resource_type_list: listResourceTypesTool, // List resource types guardrails_resource_type_show: guardrailsResourceTypeShowTool, // Show resource type details // Control Type Operations guardrails_control_type_list: listControlTypesTool, // List control types guardrails_control_type_show: guardrailsControlTypeShowTool, // Show control type details // Policy Type Operations guardrails_policy_type_list: listPolicyTypesTool, // List policy types guardrails_policy_type_show: guardrailsPolicyTypeShowTool, // Show policy type details // Control Operations guardrails_control_list: guardrailsControlListTool, // List controls guardrails_control_show: guardrailsControlShowTool, // Show control details guardrails_control_run: runControlTool, // Run controls // Policy Setting Operations guardrails_policy_setting_list: guardrailsPolicySettingListTool, // List policy settings guardrails_policy_setting_show: guardrailsPolicySettingShowTool, // Show policy setting details // Query and Template Operations guardrails_query_runnable: queryRunnableTool, // Query runnable types guardrails_query_runnable_introspection: queryRunnableIntrospectionTool, // Introspect runnable types guardrails_process_template: processTemplateTool, // Process templates }; // 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 errorResponse(error instanceof Error ? error.message : String(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) { logger.error(`Unknown tool: ${name}`); return errorResponse(`Unknown tool: ${name}`); } // Validate tool has handler if (!tool.handler) { logger.error(`Tool ${name} has no handler defined`); return errorResponse(`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 errorResponse(errorMessages.join('\n')); } } // 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`); return result; } catch (error) { // Log error logger.error(`Error executing tool ${name}:`, error); // Format and return error return errorResponse(error instanceof Error ? error.message : String(error)); } }); }