UNPKG

deepsource-mcp-server

Version:
351 lines 12.8 kB
/** * @fileoverview Tool registration module for DeepSource MCP tools * * This module handles the registration of all DeepSource tools with the * MCP server. It centralizes tool registration logic and provides a * clean interface for registering tools. * * @packageDocumentation */ import { toolSchemas } from './tool-definitions.js'; import { handleProjects, handleDeepsourceQualityMetrics, handleDeepsourceUpdateMetricThreshold, handleDeepsourceUpdateMetricSetting, handleDeepsourceComplianceReport, handleDeepsourceProjectIssues, handleDeepsourceProjectRuns, handleDeepsourceRun, handleDeepsourceRecentRunIssues, handleDeepsourceDependencyVulnerabilities, } from '../handlers/index.js'; import { createLogger } from '../utils/logging/logger.js'; const logger = createLogger('ToolRegistration'); /** * Handler mapping for tool schemas */ const TOOL_HANDLERS = { projects: async (params) => { logger.info('=== PROJECTS HANDLER START ==='); logger.info('Projects handler called with params:', { params, type: typeof params }); try { // Params currently unused but may be used for future filtering const result = await handleProjects(); logger.info('=== PROJECTS HANDLER SUCCESS ===', { result }); return result; } catch (error) { logger.error('=== PROJECTS HANDLER ERROR ===', { error, message: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, }); throw error; } }, quality_metrics: async (params) => { const typedParams = params; const metricsParams = { projectKey: typedParams.projectKey, }; const shortcodeIn = typedParams.shortcodeIn; if (shortcodeIn) { metricsParams.shortcodeIn = shortcodeIn; } return handleDeepsourceQualityMetrics(metricsParams); }, update_metric_threshold: async (params) => { const typedParams = params; const thresholdParams = { projectKey: typedParams.projectKey, repositoryId: typedParams.repositoryId, metricShortcode: typedParams.metricShortcode, metricKey: typedParams.metricKey, }; const thresholdValue = typedParams.thresholdValue; if (thresholdValue !== undefined) { thresholdParams.thresholdValue = thresholdValue; } return handleDeepsourceUpdateMetricThreshold(thresholdParams); }, update_metric_setting: async (params) => { const typedParams = params; return handleDeepsourceUpdateMetricSetting({ projectKey: typedParams.projectKey, repositoryId: typedParams.repositoryId, metricShortcode: typedParams.metricShortcode, isReported: typedParams.isReported, isThresholdEnforced: typedParams.isThresholdEnforced, }); }, compliance_report: async (params) => { const typedParams = params; return handleDeepsourceComplianceReport({ projectKey: typedParams.projectKey, reportType: typedParams.reportType, }); }, project_issues: async (params) => { const typedParams = params; const issuesParams = { projectKey: typedParams.projectKey, }; if (typeof typedParams.path === 'string') { issuesParams.path = typedParams.path; } if (Array.isArray(typedParams.analyzerIn)) { issuesParams.analyzerIn = typedParams.analyzerIn; } if (Array.isArray(typedParams.tags)) { issuesParams.tags = typedParams.tags; } if (typeof typedParams.first === 'number') { issuesParams.first = typedParams.first; } if (typeof typedParams.last === 'number') { issuesParams.last = typedParams.last; } if (typeof typedParams.after === 'string') { issuesParams.after = typedParams.after; } if (typeof typedParams.before === 'string') { issuesParams.before = typedParams.before; } return handleDeepsourceProjectIssues(issuesParams); }, runs: async (params) => { const typedParams = params; const runsParams = { projectKey: typedParams.projectKey, analyzerIn: typedParams.analyzerIn, }; if (typeof typedParams.first === 'number') { runsParams.first = typedParams.first; } if (typeof typedParams.last === 'number') { runsParams.last = typedParams.last; } if (typeof typedParams.after === 'string') { runsParams.after = typedParams.after; } if (typeof typedParams.before === 'string') { runsParams.before = typedParams.before; } return handleDeepsourceProjectRuns(runsParams); }, run: async (params) => { const typedParams = params; const runParams = { projectKey: typedParams.projectKey, runIdentifier: typedParams.runIdentifier, }; if (typeof typedParams.isCommitOid === 'boolean') { runParams.isCommitOid = typedParams.isCommitOid; } return handleDeepsourceRun(runParams); }, recent_run_issues: async (params) => { const typedParams = params; const recentRunParams = { projectKey: typedParams.projectKey, branchName: typedParams.branchName, }; if (typeof typedParams.first === 'number') { recentRunParams.first = typedParams.first; } if (typeof typedParams.last === 'number') { recentRunParams.last = typedParams.last; } if (typeof typedParams.after === 'string') { recentRunParams.after = typedParams.after; } if (typeof typedParams.before === 'string') { recentRunParams.before = typedParams.before; } return handleDeepsourceRecentRunIssues(recentRunParams); }, dependency_vulnerabilities: async (params) => { const typedParams = params; const vulnParams = { projectKey: typedParams.projectKey, }; if (typeof typedParams.first === 'number') { vulnParams.first = typedParams.first; } if (typeof typedParams.last === 'number') { vulnParams.last = typedParams.last; } if (typeof typedParams.after === 'string') { vulnParams.after = typedParams.after; } if (typeof typedParams.before === 'string') { vulnParams.before = typedParams.before; } return handleDeepsourceDependencyVulnerabilities(vulnParams); }, }; /** * Creates a tool definition from a schema and handler * * @param schema - The tool schema * @param handler - The tool handler function * @returns The tool definition */ function createToolDefinition(schema, handler) { logger.debug(`Creating tool definition for ${schema.name}`, { hasInputSchema: Boolean(schema.inputSchema), inputSchemaType: typeof schema.inputSchema, inputSchema: schema.inputSchema, }); return { name: schema.name, description: schema.description, inputSchema: schema.inputSchema, outputSchema: schema.outputSchema, handler, }; } /** * Registers all DeepSource tools with the tool registry * * @param registry - The tool registry to register tools with */ export function registerDeepSourceTools(registry) { logger.info('=== REGISTER DEEPSOURCE TOOLS START ==='); logger.info('Registering DeepSource tools', { toolSchemasType: typeof toolSchemas, toolSchemasIsArray: Array.isArray(toolSchemas), toolSchemasLength: Array.isArray(toolSchemas) ? toolSchemas.length : 'not an array', toolSchemaNames: Array.isArray(toolSchemas) ? toolSchemas.map((s) => s.name) : 'not an array', }); const toolDefinitions = []; // Create tool definitions from schemas and handlers for (const schema of toolSchemas) { logger.debug(`Processing schema: ${schema.name}`); const handler = TOOL_HANDLERS[schema.name]; if (!handler) { logger.warn(`No handler found for tool: ${schema.name}`); continue; } logger.debug(`Creating tool definition for: ${schema.name}`); const toolDef = createToolDefinition(schema, handler); toolDefinitions.push(toolDef); logger.debug(`Successfully created tool definition for: ${schema.name}`); } logger.info(`Prepared ${toolDefinitions.length} tool definitions for registration`); // Register all tools registry.registerTools(toolDefinitions); logger.info('=== REGISTER DEEPSOURCE TOOLS COMPLETE ===', { registeredCount: toolDefinitions.length, registeredTools: toolDefinitions.map((t) => t.name), }); } /** * Tool categories for organization */ export var ToolCategory; (function (ToolCategory) { ToolCategory["PROJECT_MANAGEMENT"] = "project_management"; ToolCategory["CODE_QUALITY"] = "code_quality"; ToolCategory["SECURITY"] = "security"; ToolCategory["ANALYSIS"] = "analysis"; ToolCategory["DEPENDENCIES"] = "dependencies"; })(ToolCategory || (ToolCategory = {})); /** * Metadata for all DeepSource tools */ export const TOOL_METADATA = { projects: { category: ToolCategory.PROJECT_MANAGEMENT, tags: ['projects', 'list', 'discovery'], requiresAuth: true, supportsFiltering: false, supportsPagination: false, }, quality_metrics: { category: ToolCategory.CODE_QUALITY, tags: ['metrics', 'quality', 'code', 'statistics'], requiresAuth: true, supportsFiltering: true, supportsPagination: false, }, update_metric_threshold: { category: ToolCategory.CODE_QUALITY, tags: ['metrics', 'quality', 'threshold', 'update', 'mutation'], requiresAuth: true, supportsFiltering: false, supportsPagination: false, }, update_metric_setting: { category: ToolCategory.CODE_QUALITY, tags: ['metrics', 'quality', 'settings', 'update', 'mutation'], requiresAuth: true, supportsFiltering: false, supportsPagination: false, }, compliance_report: { category: ToolCategory.SECURITY, tags: ['compliance', 'security', 'report', 'owasp', 'sans'], requiresAuth: true, supportsFiltering: false, supportsPagination: false, }, project_issues: { category: ToolCategory.CODE_QUALITY, tags: ['issues', 'problems', 'code', 'quality', 'list'], requiresAuth: true, supportsFiltering: true, supportsPagination: true, }, runs: { category: ToolCategory.ANALYSIS, tags: ['runs', 'analysis', 'history', 'list'], requiresAuth: true, supportsFiltering: true, supportsPagination: true, }, run: { category: ToolCategory.ANALYSIS, tags: ['run', 'analysis', 'details', 'single'], requiresAuth: true, supportsFiltering: false, supportsPagination: false, }, recent_run_issues: { category: ToolCategory.ANALYSIS, tags: ['issues', 'run', 'recent', 'branch', 'analysis'], requiresAuth: true, supportsFiltering: false, supportsPagination: true, }, dependency_vulnerabilities: { category: ToolCategory.DEPENDENCIES, tags: ['dependencies', 'vulnerabilities', 'security', 'cve', 'list'], requiresAuth: true, supportsFiltering: false, supportsPagination: true, }, }; /** * Gets tools by category * * @param category - The tool category * @returns Array of tool names in the category */ export function getToolsByCategory(category) { return Object.entries(TOOL_METADATA) .filter(([, metadata]) => metadata.category === category) .map(([name]) => name); } /** * Gets tools by tag * * @param tag - The tag to filter by * @returns Array of tool names with the tag */ export function getToolsByTag(tag) { return Object.entries(TOOL_METADATA) .filter(([, metadata]) => metadata.tags.includes(tag)) .map(([name]) => name); } /** * Gets paginated tools * * @returns Array of tool names that support pagination */ export function getPaginatedTools() { return Object.entries(TOOL_METADATA) .filter(([, metadata]) => metadata.supportsPagination) .map(([name]) => name); } //# sourceMappingURL=tool-registration.js.map