Legacy Code License Scanner avatar

Legacy Code License Scanner

Under maintenance

Pricing

from $20.00 / 1,000 license report generateds

Go to Apify Store
Legacy Code License Scanner

Legacy Code License Scanner

Under maintenance

Scans a git repository or pasted package.json/requirements.txt for declared and dependency licenses, and reports license-compatibility conflicts (e.g. GPL alongside proprietary code).

Pricing

from $20.00 / 1,000 license report generateds

Rating

0.0

(0)

Developer

Dennis

Dennis

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Scans a git repository — or a pasted package.json / requirements.txt — for declared and dependency licenses, and reports license-compatibility conflicts: which combinations of licenses across the project actually clash (e.g. a GPL-licensed dependency pulled into an otherwise proprietary/closed-source codebase, or two incompatible GPL-family versions).

When should an AI agent use this?

  • "Before I add this npm package as a dependency, does its license conflict with our project?"
  • "Audit this repository for GPL dependencies that shouldn't be in a proprietary codebase."
  • "What license is this GitHub repo actually under, and does it match what the README claims?"
  • "Check this list of Python dependencies (requirements.txt) for license conflicts before we vendor them."
  • "I'm reviewing a legacy/inherited codebase — what licenses does it depend on, and are any of them a legal risk?"
  • "Generate a license-compliance report for this repository as part of an acquisition/audit checklist."

A coding agent that adds dependencies or takes over/refactors a repository needs a deterministic license check before proposing a package or generating an audit report — this is exactly the kind of factual, repeatable verification a tool should perform rather than an LLM "recognizing" license text from training data (with the risk of stale or wrong assumptions).

What this Actor does

  • Accepts a public git repository URL (shallow-cloned, no git binary required) and/or one or more manifest files pasted directly as text (package.json, requirements.txt)
  • Detects the project's own declared license from its LICENSE/COPYING/NOTICE file (text pattern matching against ~15 common OSS license texts) or its package.json "license" field
  • Detects the license of every dependency by querying the public npm registry and PyPI JSON API live (no local install, no node_modules/virtualenv needed)
  • Runs a license-compatibility check — its own compact compatibility matrix — across the project's license and every dependency's license, flagging:
    • A copyleft license (GPL/AGPL) alongside a proprietary/unlicensed project — a real conflict
    • GPL-2.0-only alongside Apache-2.0 — the well-documented one-way incompatibility (patent clause)
    • Two version-locked GPL-family licenses that can't be combined (e.g. GPL-2.0-only + GPL-3.0-only)
    • A weak-copyleft license (LGPL/MPL) alongside proprietary code — flagged as a warning to review, since the actual conflict depends on how the code is combined (dynamic linking vs. static)
    • Any dependency whose license could not be determined — flagged for manual review
  • Returns clean, flat JSON records: one project-summary record, one record per checked dependency, and one record per conflict/warning finding

Input

FieldTypeDescriptionExample
repoUrlstringPublic git repository to clone (https:///http:// only)"https://github.com/expressjs/express.git"
gitRefstringBranch/tag/commit to check out (default: repo's default branch)"main"
manifestsarray of {filename, content}Manifest contents pasted directly, instead of or alongside repoUrlsee below
checkDependencyLicensesbooleanLook up each dependency's license via npm/PyPI (default true)true
maxDependenciesintegerCap on dependencies checked in one run, 1-500 (default 200)200
assumeProprietaryIfUnlicensedbooleanTreat an undeclared license as proprietary/all-rights-reserved — the real legal default (default true)true

At least one of repoUrl or manifests is required.

{
"manifests": [
{
"filename": "package.json",
"content": "{\"name\":\"my-app\",\"dependencies\":{\"some-gpl-lib\":\"^1.0.0\"}}"
}
]
}

Output

One "project" record per run:

{
"recordType": "project",
"scanId": "b1e6...",
"input": "1 inline manifest(s)",
"projectLicenseSpdxId": "UNLICENSED",
"projectLicenseSource": "manifest-declared",
"projectLicenseConfidence": "low",
"assumedProprietary": true,
"totalDependenciesFound": 2,
"totalDependenciesChecked": 2,
"licensesDetected": ["GPL-3.0-only", "ISC", "UNLICENSED"],
"conflictCount": 1,
"errorCount": 1,
"warningCount": 0,
"highestSeverity": "error",
"error": null
}

One "dependency" record per checked dependency:

{
"recordType": "dependency",
"scanId": "b1e6...",
"name": "some-gpl-lib",
"ecosystem": "npm",
"versionRange": "^1.0.0",
"resolvedVersion": "1.2.0",
"spdxId": "GPL-3.0-only",
"rawLicense": "GPL-3.0-only",
"category": "strong-copyleft",
"source": "npm-registry",
"lookupError": null
}

One "conflict" record per finding:

{
"recordType": "conflict",
"scanId": "b1e6...",
"severity": "error",
"licenseA": "UNLICENSED",
"licenseB": "GPL-3.0-only",
"reason": "GPL-3.0-only is a copyleft license that requires derivative/combined works to be released under a compatible copyleft license. Combining it with UNLICENSED (proprietary/closed-source, or no license declared) is a licensing conflict unless the proprietary code is dual-licensed or the copyleft component is isolated as a genuinely separate program.",
"affected": ["(project)", "some-gpl-lib"]
}

severity is one of error (a real, well-documented conflict), warning (needs manual review — an unknown license, or a weak-copyleft/proprietary combination that depends on how the code is combined), or info (no conflicts found).

Using this Actor as an MCP tool for AI agents

Every public Apify Actor is automatically exposed as a callable "tool" via Apify's MCP server. This Actor is designed for that use case specifically:

  • Flat, typed output — no nested blobs; every field is a string/number/boolean/array of strings, easy for an agent to reason about or filter on (severity === "error")
  • Two independent input modes — an agent that already has manifest text in context (e.g. from a file it just read) can skip the repo clone entirely and pass manifests directly
  • Deterministic, source-cited outputsource on each dependency record says exactly where the license came from (npm-registry, pypi-registry, license-file, package.json-field, manifest-declared), so an agent (or a human reviewing its work) can verify the claim
  • Bounded cost/runtimemaxDependencies and a per-request timeout on every registry call prevent a single run from becoming unexpectedly large or slow

Use cases

  • Pre-merge/pre-dependency-add CI check: does this new package introduce a license conflict?
  • Due-diligence license audit before an acquisition, open-sourcing, or code-sale
  • Legacy/inherited codebase triage: "what are we actually running, license-wise?"
  • Spot-checking a vendored or forked repository's license before redistribution

How license detection works (and its limits)

This Actor deliberately does not wrap a heavyweight tool like the Python-based ScanCode Toolkit — see the architecture note in the project's internal documentation. Instead it combines:

  1. Text-pattern matching against the full text of ~15 common OSS licenses (MIT, Apache-2.0, the BSD/ISC family, the GPL/LGPL/AGPL family with version and "or-later" detection, MPL-2.0, EPL, Unlicense, CC0-1.0) for the project's own LICENSE file — high-confidence when the file is a near-verbatim copy of a standard license text, as the vast majority of open-source projects use.
  2. Live registry metadata (registry.npmjs.org, pypi.org/pypi/<name>/json) for every dependency — the same source npm/pip themselves rely on, no local install needed.
  3. A compact, hand-written compatibility matrix covering the well-documented conflict patterns (copyleft vs. proprietary, GPLv2/Apache-2.0, GPL-family version mismatches) rather than attempting exhaustive SPDX-expression algebra.

This is a pragmatic, fast MVP-grade scanner — not a substitute for a legal opinion. A license the registry has no metadata for, or a custom/modified license text, is reported as unknown rather than guessed. Always have a qualified professional review a genuine compliance-critical finding.

This Actor only clones public repositories you provide a URL for, or scans manifest text you paste directly — it never accesses private repositories, credentials, or personal data. License metadata is technical/legal metadata about software packages, not personal data. The compatibility findings are informational, not legal advice — see "How license detection works" above.

FAQ

Q: Does this replace ScanCode Toolkit / a full SCA (software composition analysis) tool? A: No. It's a fast, dependency-light MVP that covers the two most common manifest ecosystems (npm, pip) and the ~15 most common license texts. For exhaustive, forensic-grade license detection across every ecosystem, a dedicated tool like ScanCode Toolkit or a commercial SCA product (FOSSA, Snyk License Compliance) is more thorough.

Q: What happens if a dependency's license can't be determined? A: It's reported with spdxId: null and a lookupError, and shows up as a standalone warning conflict record — never silently ignored or guessed.

Q: Why does an unlicensed project get flagged as UNLICENSED even though no LICENSE file exists? A: Under copyright law, no declared license means "all rights reserved" by default — the strictest possible position, and a genuine conflict risk if a GPL dependency is combined with it. Set assumeProprietaryIfUnlicensed to false to disable this and leave it unclassified instead.

Q: Can this scan a private repository? A: No — only https:///http:// public repository URLs are accepted (no authentication is performed). For a private repo, paste its manifest contents via manifests instead.

Q: Which ecosystems are supported? A: package.json (npm) and requirements.txt (pip) for this first version. Other ecosystems (Maven pom.xml, Ruby Gemfile, Rust Cargo.toml, Go go.mod) are out of scope for now.

Keywords

license, license-compliance, spdx, gpl, open-source, dependency-audit, sca, software-composition-analysis, compliance, legal-tech, npm, pypi

Changelog

0.1.0

  • Initial release: git-clone or inline-manifest scanning, npm/PyPI dependency license lookup, own text-based license classifier, own compatibility matrix.