Skip to main content
Glama

run

Retrieve specific code analysis results from DeepSource using a project key and run identifier or commit hash to access detailed quality metrics and issues.

Instructions

Get a specific analysis run by its runUid or commitOid

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectKeyYesDeepSource project key to identify the project
runIdentifierYesThe run identifier (runUid or commitOid)
isCommitOidNoFlag to indicate whether the runIdentifier is a commitOid (default: false)

Implementation Reference

  • Core handler function that executes the 'run' tool logic: fetches AnalysisRun from repository by runId or commitOid, formats response with run details, summary, analysis info, and returns MCP content.
    return async function handleRun(params: DeepsourceRunParams) { try { const { projectKey, runIdentifier, isCommitOid = false } = params; const projectKeyBranded = asProjectKey(projectKey); deps.logger.info('Fetching run from repository', { projectKey, runIdentifier, identifierType: isCommitOid ? 'commitOid' : 'runUid', }); let domainRun: AnalysisRun | null; if (isCommitOid) { // Search by commit OID const commitOidBranded = asCommitOid(runIdentifier); domainRun = await deps.analysisRunRepository.findByCommit( projectKeyBranded, commitOidBranded ); } else { // Search by run ID (assuming runIdentifier is the runId) const runIdBranded = asRunId(runIdentifier); domainRun = await deps.analysisRunRepository.findByRunId(runIdBranded); } if (!domainRun) { deps.logger.error('Run not found', { projectKey, runIdentifier, identifierType: isCommitOid ? 'commitOid' : 'runUid', }); throw new Error( `Run with ${isCommitOid ? 'commitOid' : 'runUid'} "${runIdentifier}" not found` ); } deps.logger.info('Successfully fetched run', { runId: domainRun.runId, commitOid: domainRun.commitInfo.oid, branchName: domainRun.commitInfo.branch, status: domainRun.status, }); const runData = { run: { id: domainRun.runId, runUid: domainRun.runId, // Domain aggregate uses runId as the unique identifier commitOid: domainRun.commitInfo.oid, branchName: domainRun.commitInfo.branch, baseOid: domainRun.commitInfo.baseOid, status: domainRun.status, createdAt: domainRun.timestamps.createdAt, updatedAt: domainRun.timestamps.startedAt || domainRun.timestamps.createdAt, finishedAt: domainRun.timestamps.finishedAt, summary: { occurrencesIntroduced: domainRun.summary.totalIntroduced.count, occurrencesResolved: domainRun.summary.totalResolved.count, occurrencesSuppressed: domainRun.summary.totalSuppressed.count, occurrenceDistributionByAnalyzer: domainRun.summary.byAnalyzer.map((dist) => ({ analyzerShortcode: dist.analyzerShortcode, introduced: dist.introduced.count, })), occurrenceDistributionByCategory: domainRun.summary.byCategory.map((dist) => ({ category: dist.category, introduced: dist.introduced.count, })), }, repository: { name: 'Repository', // Domain aggregate doesn't store repository name directly id: domainRun.repositoryId, }, }, // Provide helpful guidance and related information analysis: { status_info: getStatusInfo(domainRun.status), issue_summary: `This run introduced ${domainRun.summary.totalIntroduced.count} issues, resolved ${domainRun.summary.totalResolved.count} issues, and suppressed ${domainRun.summary.totalSuppressed.count} issues.`, analyzers_used: domainRun.summary.byAnalyzer?.map((a) => a.analyzerShortcode) || [], issue_categories: domainRun.summary.byCategory?.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', }, }; return { content: [ { type: 'text' as const, text: JSON.stringify(runData), }, ], }; } catch (error) { deps.logger.error('Error in handleRun', { 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', }); const errorMessage = error instanceof Error ? error.message : 'Unknown error'; deps.logger.debug('Returning error response', { errorMessage }); return { isError: true, content: [ { type: 'text' as const, text: JSON.stringify({ error: errorMessage, details: 'Failed to retrieve run', }), }, ], }; } }; }
  • Zod input and output schema definition for the 'run' MCP tool, specifying parameters and response structure.
    export const runToolSchema = { name: 'run', description: 'Get a specific analysis run by its runUid or commitOid', inputSchema: { projectKey: z.string().describe('DeepSource project key to identify the project'), runIdentifier: z.string().describe('The run identifier (runUid or commitOid)'), isCommitOid: z .boolean() .optional() .describe('Flag to indicate whether the runIdentifier is a commitOid (default: false)'), }, outputSchema: { run: z.object({ id: z.string(), runUid: z.string(), commitOid: z.string(), branchName: z.string(), baseOid: z.string(), status: z.string(), createdAt: z.string(), updatedAt: z.string(), finishedAt: z.string().optional(), summary: z.object({ occurrencesIntroduced: z.number(), occurrencesResolved: z.number(), occurrencesSuppressed: z.number(), occurrenceDistributionByAnalyzer: z .array( z.object({ analyzerShortcode: z.string(), introduced: z.number(), }) ) .optional(), occurrenceDistributionByCategory: z .array( z.object({ category: z.string(), introduced: z.number(), }) ) .optional(), }), repository: z.object({ name: z.string(), id: z.string(), }), }), analysis: z.object({ status_info: z.string(), issue_summary: z.string(), analyzers_used: z.array(z.string()), issue_categories: z.array(z.string()), }), }, };
  • TOOL_HANDLERS mapping for 'run' tool: wraps raw params, types them as DeepsourceRunParams, and delegates to handleDeepsourceRun.
    run: async (params: unknown) => { const typedParams = params as Record<string, unknown>; const runParams: DeepsourceRunParams = { projectKey: typedParams.projectKey as string, runIdentifier: typedParams.runIdentifier as string, }; if (typeof typedParams.isCommitOid === 'boolean') { runParams.isCommitOid = typedParams.isCommitOid; } return handleDeepsourceRun(runParams); },
  • Handler entry point that initializes repository dependencies and invokes the core run handler function.
    export async function handleDeepsourceRun(params: DeepsourceRunParams): Promise<ApiResponse> { const baseDeps = createDefaultHandlerDeps({ logger }); const apiKey = baseDeps.getApiKey(); const repositoryFactory = new RepositoryFactory({ apiKey }); const analysisRunRepository = repositoryFactory.createAnalysisRunRepository(); const deps: RunHandlerDeps = { analysisRunRepository, logger, }; const handler = createRunHandlerWithRepo(deps); const result = await handler(params); // If the domain handler returned an error response, throw an error for backward compatibility if (result.isError) { const firstContent = result.content[0]; if (firstContent) { const errorData = JSON.parse(firstContent.text); throw new Error(errorData.error); } else { throw new Error('Unknown run error'); } } return result; }
  • Main registration function that iterates over toolSchemas (including 'run'), pairs with TOOL_HANDLERS['run'], creates ToolDefinition, and registers with MCP ToolRegistry which calls server.registerTool.
    export function registerDeepSourceTools(registry: ToolRegistry): void { 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: ToolDefinition[] = []; // 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), }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sapientpants/deepsource-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server