Skip to main content
Glama
bivex

Scancode License Analysis Tool for MCP

by bivex

mcp_ScancodeMCP_analyze_license_file

Analyze software licenses in files to identify obligations, risks, and compatibility issues using Scancode data for compliance.

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:34-64 (registration)
    Registration of the 'mcp_ScancodeMCP_analyze_license_file' tool using server.registerTool, including schema and inline 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() }] };
      }
    );
  • index.ts:45-63 (handler)
    The handler function for the tool, which processes multiple file paths by calling the helper processFileForLicenseAnalysis and aggregates reports.
    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 defined using Zod validators for the tool parameters: filePaths (array of strings), 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\\').")
    },
  • Core helper function that performs license analysis for a single file: reads snippet, resolves path, finds matching licenses, generates 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 licenseData 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