OSS License Auditor - MCP server that audits open-source package licenses against corporate policy — detects viral (GPL, AGPL, SSPL) and unknown licenses before they enter the codebase. Built with Vurb.ts
🔍 OSS License Auditor
MCP server that audits open-source package licenses against corporate policy — detects viral (GPL, AGPL, SSPL) and unknown licenses before they enter the codebase. Built with Vurb.ts.
Why This Exists
A single GPL or AGPL dependency can legally contaminate your entire codebase, forcing you to open-source your proprietary code. Most developers don't check licenses before running npm install.
This MCP server gives any LLM client a deterministic license firewall — call license.audit before adding any dependency. The classification is SPDX-based lookup (no regex, no hallucination), resolved live from the npm registry.
Architecture
Agent reads package.json
↓
Sends dependencies to MCP
↓
MCP fetches license metadata from npm registry (parallel, 8s timeout)
↓
Normalises SPDX → classifies into 5 categories → applies corporate policy
↓
Returns audit report: BLOCKED ❌ / WARNING ⚠️ / ALLOWED ✅
↓
Agent presents verdict with Mermaid distribution chart
Deterministic core — live data: The classification logic is a pure SPDX lookup table (no AI, no drift). The only network call is to the npm registry for license metadata.
License Categories
| Category | Examples | Verdict | |---|---|---| | Permissive | MIT, ISC, Apache-2.0, BSD | ✅ Allowed | | Public Domain | Unlicense, CC0-1.0, WTFPL | ✅ Allowed | | Weak Copyleft | LGPL, MPL-2.0, EPL | ⚠️ Warning — legal review needed | | Strong Copyleft | GPL-2.0, GPL-3.0 | ❌ Blocked — viral, incompatible with proprietary code | | Network Copyleft | AGPL-3.0, SSPL, EUPL | ❌ Blocked — strongest viral, applies over network use | | Unknown | Unrecognised SPDX | ⚠️ Warning — manual review required |
Tools
| Tool | Verb | Description |
|---|---|---|
| license.audit | query | Audit all deps from a package.json against corporate policy |
| license.check | query | Check a single package before npm install |
| license.policy | query | List the full corporate license policy (cached) |
| license.tree | query | Direct + first-level transitive deps with license annotations |
Usage Examples
❌ Example 1 — Detecting a Viral Dependency
User: "Audit the dependencies of my project before we ship."
The LLM reads package.json and calls license.audit:
{
"dependencies": "{\"express\":\"^4.18.0\",\"lodash\":\"^4.17.21\",\"@ffmpeg-installer/ffmpeg\":\"^1.1.0\"}"
}
Result:
total_packages: 3
allowed_count: 2
blocked_count: 1
@ffmpeg-installer/ffmpeg — GPL-2.0-only
❌ BLOCKED: strong copyleft — requires derivative works to be
distributed under the same license. Incompatible with proprietary software.
The Presenter renders a Mermaid pie chart and urgently suggests removing or replacing the blocked package.
✅ Example 2 — Checking Before Installing
User: "Is it safe to add
sequelizeto our project?"
The LLM calls license.check:
{ "package": "sequelize" }
Result:
sequelize@6.x — MIT
✅ ALLOWED: permissive — safe for commercial use.
⚠️ Example 3 — Scanning a Mixed Project
User: "Audit all deps including devDependencies."
{
"dependencies": "{\"react\":\"^18.0.0\",\"axios\":\"^1.6.0\"}",
"dev_dependencies": "{\"vitest\":\"^1.0.0\",\"webpack\":\"^5.0.0\"}"
}
Result:
total_packages: 4
allowed_count: 4 ✅ No issues — all permissive
🔍 Example 4 — Tracing a Transitive License
User: "Show me the full license tree including transitive deps."
The LLM calls license.tree — resolves each direct dep's own dependencies (one level deep) and annotates all with their license verdict.
Deploy
Vinkius Cloud — One Command ⚡
The fastest path to production. vurb deploy publishes your server to Vinkius Cloud's global edge — zero infrastructure, built-in DLP, kill switch, audit logging, and a managed MCP token:
npm install
vurb deploy
No Dockerfile, no CI/CD pipeline, no servers to manage. You get a connection token that works with any MCP client — Cursor, Claude Desktop, Claude Code, Windsurf, Cline, VS Code + Copilot.
# Deploy with a custom name
vurb deploy --name oss-license-auditor
💡 Tip: Install the Vinkius extension to manage your deployed server directly from VS Code, Cursor, or Windsurf — live connections, requests, P95 latency, token management, tool toggling, logs, and deployment history.
Connect Your MCP Client
After deploying, share the managed token with any MCP-compatible client:
Claude Desktop / Cursor / Windsurf
{
"mcpServers": {
"oss-license-auditor": {
"url": "https://edge.vinkius.com/your-token/mcp"
}
}
}
Self-Hosted Alternatives
The same ToolRegistry runs anywhere — no code changes required:
| Platform | Adapter |
|---|---|
| Vercel Edge Functions | @vurb/vercel |
| Cloudflare Workers | @vurb/cloudflare |
| Any Node.js server | Stdio / HTTP+SSE transport |
Full deployment guides: Production Server · Vercel Adapter · Cloudflare Adapter
Running Locally via stdio
If you prefer to run the server locally and connect via stdio — the native MCP transport used by Claude Desktop, Cursor, and Windsurf:
# 1. Install dependencies
npm install
# 2. Build
npm run build
# 3. Test it directly (optional)
node dist/server.js
Then add it to your MCP client config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"oss-license-auditor": {
"command": "node",
"args": ["/absolute/path/to/oss-license-auditor/dist/server.js"]
}
}
}
Or run without cloning via npx (after the package is published):
{
"mcpServers": {
"oss-license-auditor": {
"command": "npx",
"args": ["-y", "@vinkius/oss-license-auditor"]
}
}
}
Note: The classification logic is fully offline — only the npm registry fetch requires network. The SPDX lookup table and policy engine have no external dependencies.
Development
# Install dependencies
npm install
# Development server with HMR
vurb dev
# Type-check
npm run typecheck
# Run tests
npm test
Project Structure
src/
├── data/ ← License policy and SPDX classification
│ ├── types.ts
│ └── license-policy.ts 47 SPDX identifiers + alias normalization + OR/AND expressions
├── engine/ ← npm registry resolution and audit logic
│ ├── npm-registry.ts Batch fetch, 10 concurrent, 8s timeout, graceful fallback
│ └── audit-engine.ts fetch → classify → apply policy → build report
├── models/ M — defineModel()
│ └── index.ts
├── views/ V — definePresenter()
│ └── index.ts
├── agents/ A — Tool definitions
│ └── license/
│ ├── audit.tool.ts
│ ├── check.tool.ts
│ ├── policy.tool.ts
│ └── tree.tool.ts
├── vurb.ts Shared Vurb instance
└── server.ts Bootstrap
Built with Vurb.ts
| Feature | Usage |
|---|---|
| defineModel() | Domain models with guidance labels |
| definePresenter() | Dynamic rules based on blocked count, Mermaid charts, suggestActions |
| f.query() | All tools are read-only — no state mutation |
| .concurrency() | 5 active / 20 queued for audit, 3/10 for tree |
| .egress() | 2MB guard on audit, 4MB on tree |
| .stale() | Real-time — npm registry data must not be cached |
| .cached() | Static policy rules for license.policy |
| f.error() | Self-healing errors with recovery suggestions |
| .instructions() | AI-first guidance: "call BEFORE npm install" |
| agentLimit | Results truncated at 50 with pagination guidance |
| Explicit tool imports | V8-safe bootstrap — no filesystem access at runtime |
Get started with Vurb.ts → · Documentation →
License
Apache 2.0 — See LICENSE for details.