UNPKG

deepsource-mcp-server

Version:
147 lines 6.7 kB
/** * @fileoverview Run handler for the DeepSource MCP server * This module provides MCP tool handlers for fetching a specific DeepSource analysis run. */ import { DeepSourceClient, } from '../deepsource.js'; import { createLogger } from '../utils/logging/logger.js'; // Logger for the run handler const logger = createLogger('RunHandler'); /** * Fetches and returns information about a specific analysis run * @param params - Parameters for fetching the run, including project key and run identifier * @returns A response containing the run data * @throws Error if the DEEPSOURCE_API_KEY environment variable is not set * @public */ export async function handleDeepsourceRun({ projectKey, runIdentifier, isCommitOid = false, }) { const apiKey = process.env.DEEPSOURCE_API_KEY; logger.debug('Checking API key', { exists: Boolean(apiKey), length: apiKey ? apiKey.length : 0, prefix: apiKey ? `${apiKey.substring(0, 5)}...` : 'N/A', }); if (!apiKey) { logger.error('DEEPSOURCE_API_KEY environment variable is not set'); throw new Error('DEEPSOURCE_API_KEY environment variable is not set'); } try { logger.debug('Creating DeepSource client'); const client = new DeepSourceClient(apiKey); logger.info('Fetching run', { projectKey, runIdentifier, identifierType: isCommitOid ? 'commitOid' : 'runUid', }); const run = await client.getRun(runIdentifier); if (!run) { logger.error('Run not found', { projectKey, runIdentifier, identifierType: isCommitOid ? 'commitOid' : 'runUid', }); throw new Error(`Run with ${isCommitOid ? 'commitOid' : 'runUid'} "${runIdentifier}" not found in project "${projectKey}"`); } logger.info('Successfully fetched run', { runUid: run.runUid, commitOid: run.commitOid, branchName: run.branchName, status: run.status, }); return { content: [ { type: 'text', text: JSON.stringify({ run: { id: run.id, runUid: run.runUid, commitOid: run.commitOid, branchName: run.branchName, baseOid: run.baseOid, status: run.status, createdAt: run.createdAt, updatedAt: run.updatedAt, finishedAt: run.finishedAt, summary: { occurrencesIntroduced: run.summary.occurrencesIntroduced, occurrencesResolved: run.summary.occurrencesResolved, occurrencesSuppressed: run.summary.occurrencesSuppressed, occurrenceDistributionByAnalyzer: run.summary.occurrenceDistributionByAnalyzer, occurrenceDistributionByCategory: run.summary.occurrenceDistributionByCategory, }, repository: { name: run.repository.name, id: run.repository.id, }, }, // Provide helpful guidance and related information analysis: { status_info: getStatusInfo(run.status), issue_summary: `This run introduced ${run.summary.occurrencesIntroduced} issues, resolved ${run.summary.occurrencesResolved} issues, and suppressed ${run.summary.occurrencesSuppressed} issues.`, analyzers_used: run.summary.occurrenceDistributionByAnalyzer?.map((a) => a.analyzerShortcode) || [], issue_categories: run.summary.occurrenceDistributionByCategory?.map((c) => c.category) || [], }, related_tools: { issues: 'Use the project_issues tool to get all issues in the project', runs: 'Use the runs tool to list all runs for the project', recent_issues: 'Use the recent_run_issues tool to get issues from the most recent run on a branch', }, }, null, 2), }, ], }; } catch (error) { logger.error('Error in handleDeepsourceRun', { errorType: typeof error, errorName: error instanceof Error ? error.name : 'Unknown', errorMessage: error instanceof Error ? error.message : String(error), errorStack: error instanceof Error ? error.stack : 'No stack available', }); // Return an error object with details const errorMessage = error instanceof Error ? error.message : 'Unknown error'; logger.debug('Returning error response', { errorMessage }); return { isError: true, content: [ { type: 'text', text: JSON.stringify({ error: errorMessage, details: 'Failed to retrieve run', project_key: projectKey, run_identifier: runIdentifier, identifier_type: isCommitOid ? 'commitOid' : 'runUid', }), }, ], }; } } /** * Helper function to get human-readable status information * @param status The run status * @returns Information about the status * @private */ function getStatusInfo(status) { switch (status) { case 'PENDING': return 'The run is currently queued and waiting to be processed.'; case 'SUCCESS': return 'The run completed successfully with all analyzers.'; case 'FAILURE': return 'The run failed due to an error during analysis.'; case 'TIMEOUT': return 'The run exceeded the maximum allowed time and was terminated.'; case 'CANCEL': return 'The run was manually cancelled.'; case 'READY': return 'The run is ready to be processed but not yet started.'; case 'SKIPPED': return 'The run was skipped, possibly due to no code changes detected.'; default: return `Unknown status: ${status}`; } } //# sourceMappingURL=run.js.map