Skip to main content
Glama
bivex

Scancode License Analysis Tool for MCP

by bivex

mcp_ScancodeMCP_analyze_license_file

Analyzes software licenses in files to identify obligations, risks, and compatibility issues, ensuring compliance and legal clarity through clause-by-clause evaluation.

Instructions

Clause-by-clause legal analysis of all licenses detected in a file, including obligations, risks, and compatibility.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathsYesAn array of file paths to analyze. Can be a single file path for individual analysis.
linesToReadNoNumber of lines to read from each file (default: 100).
scannedDataBasePathNoThe base absolute path for resolving relative license paths (default: 'C:\Users\Admin\Desktop\LICENSE_MANAGER\').

Implementation Reference

  • index.ts:45-62 (handler)
    The core handler function for the 'mcp_ScancodeMCP_analyze_license_file' tool. It validates inputs, processes multiple file paths by calling helper functions, and returns a markdown report.
    async ({ filePaths, linesToRead, scannedDataBasePath }) => { if (!licenseData?.problematic_licenses) { return { content: [{ type: "text", text: "License data not loaded or no problematic licenses found." }] }; } const effectiveLinesToRead = linesToRead ?? 100; const effectiveScannedDataBasePath = scannedDataBasePath ?? "C:\\Users\\Admin\\Desktop\\LICENSE_MANAGER\\"; if (!filePaths?.length) { return { content: [{ type: "text", text: "Please provide 'filePaths' to analyze." }] }; } let overallReport = ''; for (const currentFilePath of filePaths) { overallReport += await processFileForLicenseAnalysis(currentFilePath, effectiveLinesToRead, effectiveScannedDataBasePath); } return { content: [{ type: "text", text: overallReport.trim() }] };
  • Input schema definition using Zod for validating the tool's parameters: filePaths (array), linesToRead (optional number), scannedDataBasePath (optional string).
    inputSchema: { filePaths: z.array(z.string()).describe("An array of file paths to analyze. Can be a single file path for individual analysis."), linesToRead: z.number().int().min(1).optional().describe("Number of lines to read from each file (default: 100)."), scannedDataBasePath: z.string().optional().describe("The base absolute path for resolving relative license paths (default: 'C:\\Users\\Admin\\Desktop\\LICENSE_MANAGER\\').") },
  • index.ts:34-64 (registration)
    Registration of the tool using McpServer.registerTool, specifying the tool name, metadata (title, description, inputSchema), and the handler function.
    server.registerTool( "mcp_ScancodeMCP_analyze_license_file", { title: "Analyze License File (Legal Breakdown)", description: "Clause-by-clause legal analysis of all licenses detected in a file, including obligations, risks, and compatibility.", inputSchema: { filePaths: z.array(z.string()).describe("An array of file paths to analyze. Can be a single file path for individual analysis."), linesToRead: z.number().int().min(1).optional().describe("Number of lines to read from each file (default: 100)."), scannedDataBasePath: z.string().optional().describe("The base absolute path for resolving relative license paths (default: 'C:\\Users\\Admin\\Desktop\\LICENSE_MANAGER\\').") }, }, async ({ filePaths, linesToRead, scannedDataBasePath }) => { if (!licenseData?.problematic_licenses) { return { content: [{ type: "text", text: "License data not loaded or no problematic licenses found." }] }; } const effectiveLinesToRead = linesToRead ?? 100; const effectiveScannedDataBasePath = scannedDataBasePath ?? "C:\\Users\\Admin\\Desktop\\LICENSE_MANAGER\\"; if (!filePaths?.length) { return { content: [{ type: "text", text: "Please provide 'filePaths' to analyze." }] }; } let overallReport = ''; for (const currentFilePath of filePaths) { overallReport += await processFileForLicenseAnalysis(currentFilePath, effectiveLinesToRead, effectiveScannedDataBasePath); } return { content: [{ type: "text", text: overallReport.trim() }] }; } );
  • Helper function that performs the detailed analysis for a single file: reads file snippet, normalizes path, finds matching licenses in the data, and compiles legal report using legalSummaryForLicense.
    async function processFileForLicenseAnalysis(currentFilePath: string, effectiveLinesToRead: number, effectiveScannedDataBasePath: string): Promise<string> { const fileContentSnippet = await readFirstNLines(currentFilePath, effectiveLinesToRead); let report = `\n--- File Content Snippet for ${currentFilePath} ---\n${fileContentSnippet}\n`; let pathForLookup = currentFilePath; if (path.isAbsolute(currentFilePath)) { pathForLookup = path.relative(effectiveScannedDataBasePath, currentFilePath); } pathForLookup = pathForLookup.replace(/\\/g, '/'); const found: { name: string, score: number }[] = findLicensesForFile(pathForLookup); if (found.length === 0) { report += `No problematic licenses found for file: ${currentFilePath}\n\n`; } else { let licReport = `Legal Analysis for ${currentFilePath}:\n`; for (const lic of found) { licReport += `\n---\nLicense: ${lic.name}\nScore: ${lic.score}\n`; licReport += await legalSummaryForLicense(lic.name); } report += `${licReport}\n\n`; } return report; }
  • Helper function that searches the loaded license data for problematic licenses matching the given file path.
    function findLicensesForFile(pathForLookup: string): { name: string, score: number }[] { const found: { name: string, score: number }[] = []; for (const category in licenseData?.problematic_licenses ?? {}) { for (const item of licenseData?.problematic_licenses?.[category] ?? []) { if (item.file?.toLowerCase() === pathForLookup?.toLowerCase()) { found.push({ name: item.name, score: item.score }); } } } return found; }

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/bivex/scancodeMCP'

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