Skip to main content

MCP Server

tools/mcp-server.mjs is a dependency-free MCP server (JSON-RPC 2.0 over stdio) that exposes the engine to any MCP-capable client. It implements initialize, tools/list, tools/call and ping.

Configuration​

{
"mcpServers": {
"oss-compliance": {
"command": "node",
"args": ["<absolute path>/oss-compliance-analyzer/tools/mcp-server.mjs"]
}
}
}

Use an absolute path — the server is launched by the client as a local subprocess.

Tools​

ToolWhat it does
analyze_sbomParse an SBOM and return components, findings, score and quality
list_findingsAll findings for an analysed SBOM
find_componentsInventory queries (by license, tier, supplier, name)
explain_componentFull component detail including taint sources
diff_sbomsMilestone comparison between two SBOMs
check_license_compatibilityPairwise license compatibility check
evaluate_license_expressionEvaluate an SPDX expression and return the tier
generate_reportCompliance report, NOTICE file or supplier inquiry
release_gatePolicy gate evaluation with pass/fail reasons

Try it from the shell​

printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"analyze_sbom","arguments":{"path":"samples/sample-ivisystem.spdx.json"}}}' \
| node tools/mcp-server.mjs

How it behaves​

Three design points are worth knowing:

  • The cache is keyed on the SBOM path, not on the tool. explain_component and find_components reuse the analysis already performed by analyze_sbom, so an agent can ask follow-up questions without re-parsing. Because analysis is deterministic, caching is safe.
  • The engine decides; the model narrates. Every tool returns data produced by the deterministic engine. Nothing in the protocol lets the agent set a tier, a severity or a score. The agent cannot influence the verdict even if prompted to.
  • Errors are returned, not thrown. An unknown tool or a bad path yields a JSON-RPC response with isError: true and a readable message. The server never crashes the stdio stream, which would kill the agent's session — an important property for a long-lived subprocess.

:::warning Keep the LLM out of the verdict path A non-deterministic component in the verdict path makes the result unauditable. The model may summarise findings, explain why a rule fired and draft correspondence to the supplier — it must never assign a risk tier. This is ADR-014, and it is enforced structurally by what the tools accept, not by a prompt instruction. :::

Why it was built last​

The agent layer was deliberately the final phase. Once the engine is a clean set of pure functions, wrapping it as an agent is mechanical — the value was in getting the deterministic verdict right first, not in the interface.