Supply Chain · Transparency
MCP server SBOM security
A Software Bill of Materials (SBOM) is a machine-readable inventory of every package in your MCP server's dependency tree. For buyers evaluating whether to install a community MCP server, an SBOM provides a verifiable record of what they are getting — every package, every version, every license — before they run a single line of code.
What an SBOM contains
A CycloneDX or SPDX SBOM lists every component in your software, including transitive dependencies, with:
- Package name and version
- Package URL (purl) — a standardized identifier linking to the registry entry
- License identifier (SPDX license expression)
- Known vulnerabilities (via VEX — Vulnerability Exploitability eXchange)
- Hash of the installed package (SHA-256 or SHA-512)
- Author / supplier information
This makes it possible for buyers, security teams, and directory reviewers to evaluate your dependency tree without running npm install themselves.
Generating an SBOM for a Node.js MCP server
# CycloneDX format (JSON) — most widely supported
npx @cyclonedx/cyclonedx-npm \
--output-format JSON \
--output-file sbom.json \
--package-lock-only
# SPDX format (for tooling that prefers SPDX)
npx @cyclonedx/cyclonedx-npm \
--output-format XML \
--output-file sbom.xml
# Inspect the SBOM component count
cat sbom.json | node -e "
let d = '';
process.stdin.on('data', c => d += c);
process.stdin.on('end', () => {
const sbom = JSON.parse(d);
console.log('Components:', sbom.components?.length);
const licenses = new Set(sbom.components?.flatMap(c =>
c.licenses?.map(l => l.license?.id || l.expression) || []
));
console.log('Unique licenses:', [...licenses].join(', '));
});
"
Generating an SBOM for a Python MCP server
# Using CycloneDX for Python pip install cyclonedx-bom cyclonedx-py environment --output-format json --output-file sbom.json # Or using Syft (supports both npm and pip) syft dir:. --output cyclonedx-json=sbom.json
Where to commit and publish the SBOM
Commit sbom.json to the root of your repository. Update it on every release by adding a step to your release workflow:
name: Release
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- name: Regenerate SBOM
run: |
npx @cyclonedx/cyclonedx-npm \
--output-format JSON \
--output-file sbom.json
git config user.name "github-actions"
git config user.email "actions@github.com"
git add sbom.json
git diff --staged --quiet || git commit -m "chore: regenerate SBOM for ${{ github.ref_name }}"
- name: Create GitHub Release with SBOM
uses: softprops/action-gh-release@v2
with:
files: sbom.json
How buyers use your SBOM
A security-conscious team lead evaluating your MCP server can load your SBOM into a vulnerability scanner to check for known CVEs without installing anything:
# Check SBOM against the OSV vulnerability database npm install -g @google/osv-scanner osv-scanner --sbom sbom.json # Or using Grype grype sbom:sbom.json
Teams with internal allowlisting policies can also verify that your dependency tree contains no packages on their blocklist before approving the MCP server for internal use.
SBOM diffing between releases
One of the most valuable uses of committed SBOMs is diffing between releases to understand exactly what changed in the dependency tree — not just in your code:
# Compare SBOMs between two releases
git show v1.2.0:sbom.json > sbom-v1.2.0.json
git show v1.3.0:sbom.json > sbom-v1.3.0.json
# Find added or changed packages
node -e "
const old = JSON.parse(require('fs').readFileSync('sbom-v1.2.0.json'));
const new_ = JSON.parse(require('fs').readFileSync('sbom-v1.3.0.json'));
const oldMap = Object.fromEntries(old.components.map(c => [c.name, c.version]));
const newMap = Object.fromEntries(new_.components.map(c => [c.name, c.version]));
for (const [name, ver] of Object.entries(newMap)) {
if (!oldMap[name]) console.log('ADDED:', name, ver);
else if (oldMap[name] !== ver) console.log('CHANGED:', name, oldMap[name], '->', ver);
}
for (const name of Object.keys(oldMap)) {
if (!newMap[name]) console.log('REMOVED:', name);
}
"
Anthropic's Skills Directory now accepts CycloneDX SBOM files as supporting evidence for security review submissions. Providing a current SBOM reduces review turnaround time because reviewers can run automated dependency analysis rather than installing and auditing manually.
SkillAudit findings
sbom.json or sbom.xml file found in repository root — buyers cannot evaluate dependency tree without installing
Run a SkillAudit scan on your MCP server to check SBOM presence, currency, and completeness. SkillAudit also cross-references your SBOM components against the OSV vulnerability database. See also: MCP server supply chain audit and supply chain risk deep-dive.