Dependency Security MCP
Provides tools for running OWASP Dependency-Check vulnerability scans against allowed repositories, checking asynchronous scan status, and retrieving normalized reports with dependency and vulnerability findings.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Dependency Security MCPscan /workspace/repos/payment-service for vulnerable dependencies"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Dependency Security MCP
Dependency Security MCP is a small, production-oriented Model Context Protocol server for OWASP Dependency-Check vulnerability scanning. It exposes three narrow tools:
start_dependency_scanget_scan_statusget_scan_report
It does not expose shell execution, arbitrary filesystem access, repository mutation, remediation, package manager commands, or unrestricted OWASP CLI arguments.
Architecture
flowchart TD
LangGraph --> Client[MCP Client]
Client --> Server[Dependency Security MCP]
Server --> ScanService
Server --> ReportService
ScanService --> Scanner[DependencyScanner]
ReportService --> Scanner
Scanner --> OWASP[OWASP Dependency-Check]The MCP layer is intentionally thin. Tool functions validate and serialize request and response data, then call application services. Services depend on repository and scanner abstractions, so a later OSV scanner, dependency resolver, version provider, or remediation service can be added without changing the MCP tool contracts.
Related MCP server: Dependency-Track MCP Server
Requirements
Python 3.12+
OWASP Dependency-Check CLI available as
dependency-checkThe official MCP Python SDK v2
Install Python dependencies:
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"The project uses the current v2 server style:
from mcp.server import MCPServerInstalling OWASP Dependency-Check
Install Dependency-Check from the OWASP project and ensure the dependency-check command is on PATH. You can also point the server at a custom executable:
export OWASP_DEPENDENCY_CHECK_PATH=/opt/dependency-check/bin/dependency-check.shConfiguration
Copy .env.example values into your environment:
export MCP_SERVER_NAME=dependency-security-mcp
export OWASP_DEPENDENCY_CHECK_PATH=dependency-check
export SCAN_OUTPUT_ROOT=/tmp/dependency-security-mcp
export ALLOWED_REPOSITORY_ROOTS=/workspace/repos
export SCAN_TIMEOUT_SECONDS=1800
export LOG_LEVEL=INFOALLOWED_REPOSITORY_ROOTS is a comma-separated allowlist. Requested repositories are resolved with Path.resolve() and must exist, be directories, and live below one configured root.
Running
Run with stdio for local development:
uv run mcp dev src/dependency_security_mcp/server.pyRun with Streamable HTTP for production-style serving:
uv run mcp run src/dependency_security_mcp/server.py --transport streamable-httpOpen the MCP Inspector:
uv run mcp dev src/dependency_security_mcp/server.pyMCP Tools
start_dependency_scan
Starts an OWASP Dependency-Check scan asynchronously and returns immediately after scheduling.
Request:
{
"repository_path": "/workspace/repos/payment-service",
"project_name": "payment-service"
}Response:
{
"scan_id": "4f8b3dfd-e4f7-40ec-b31f-df3d1992c544",
"scanner": "OWASP_DEPENDENCY_CHECK",
"status": "RUNNING",
"project_name": "payment-service",
"started_at": "2026-10-03T07:00:00Z"
}get_scan_status
Request:
{
"scan_id": "4f8b3dfd-e4f7-40ec-b31f-df3d1992c544"
}Response:
{
"scan_id": "4f8b3dfd-e4f7-40ec-b31f-df3d1992c544",
"status": "COMPLETED",
"scanner": "OWASP_DEPENDENCY_CHECK",
"started_at": "2026-10-03T07:00:00Z",
"completed_at": "2026-10-03T07:03:15Z",
"error": null
}get_scan_report
Running response:
{
"scan_id": "4f8b3dfd-e4f7-40ec-b31f-df3d1992c544",
"status": "RUNNING",
"message": "Scan has not completed yet."
}Completed response:
{
"scan_id": "4f8b3dfd-e4f7-40ec-b31f-df3d1992c544",
"scanner": "OWASP_DEPENDENCY_CHECK",
"project_name": "payment-service",
"repository_path": "/workspace/repos/payment-service",
"status": "COMPLETED",
"dependency_count": 147,
"vulnerable_dependency_count": 3,
"vulnerability_count": 5,
"findings": []
}Example Client Flow
from mcp import Client
async with Client("http://localhost:8000/mcp") as client:
start = await client.call_tool(
"start_dependency_scan",
{
"repository_path": "/workspace/repos/payment-service",
"project_name": "payment-service",
},
)
scan_id = start.structured_content["scan_id"]
while True:
status = await client.call_tool("get_scan_status", {"scan_id": scan_id})
if status.structured_content["status"] in {"COMPLETED", "FAILED", "CANCELLED"}:
break
report = await client.call_tool("get_scan_report", {"scan_id": scan_id})
print(report.structured_content)Docker
Build:
docker build -t dependency-security-mcp .Run with a read-only repository mount:
docker run --rm \
-v /repos:/workspace/repos:ro \
-e ALLOWED_REPOSITORY_ROOTS=/workspace/repos \
dependency-security-mcpThe image runs as a non-root user and writes scan output under SCAN_OUTPUT_ROOT.
Security Model
Never executes arbitrary user commands.
Never uses
shell=True.Validates repository paths by resolving them before allowlist checks.
Restricts scans to configured roots.
Server controls output directories.
Enforces scan timeouts and process termination.
Validates scanner exit codes.
Returns structured client-safe errors.
Does not expose environment variables, raw shell access, arbitrary filesystem APIs, or arbitrary OWASP arguments.
The caller decides when and which allowed repository to scan. The MCP server decides whether the path is allowed, which executable and arguments are used, where reports are stored, how long the scan may run, and how reports are normalized.
Tests
Run unit tests:
pytestRun lint:
ruff check .The real OWASP integration test is opt-in:
RUN_OWASP_INTEGRATION_TESTS=true pytest tests/integrationRoadmap
The architecture is ready for additional narrow capabilities later:
Maven, Gradle, and npm dependency resolution
OSV scanning
Dependency version lookup
Suggested dependency fixes
Controlled dependency updates
Build/test verification
Those capabilities are intentionally not implemented in this first version.
Available Tools
3 toolsget_scan_reportB
Get the normalized vulnerability report for a completed scan.
| Name | Required | Description | Default |
|---|---|---|---|
| scan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It notes the scan must be 'completed' but says nothing about error behavior for incomplete scans, required permissions/auth, whether results are cached or paginated, or freshness of the report.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler. The verb and resource lead immediately, and nothing redundant is included.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is unnecessary. But for a retrieval tool with no annotations, the description is thin on preconditions, failure modes, and report scope ('normalized' is left undefined).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and there is one required parameter (scan_id). The description implies the report is keyed to a scan but adds no format, source, or validity detail for scan_id beyond what the schema's name/type already convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and resource ('normalized vulnerability report') scoped to a completed scan. It is distinguishable from get_scan_status (status vs. report) and start_dependency_scan (initiates vs. retrieves), though it does not name those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for a completed scan' implies a precondition (the scan must have finished), which is useful usage context. However, it offers no explicit when-to-use guidance, no alternatives, and no statement of what to do if the scan is still running.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scan_statusC
Get status for a dependency vulnerability scan.
| Name | Required | Description | Default |
|---|---|---|---|
| scan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it discloses almost nothing: not whether status is polled, what states are returned, whether the scan_id must come from start_dependency_scan, or whether the call is cheap/safe to repeat. It only restates the operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no filler and the verb-resource pairing front-loaded. It is efficient, though brevity here shades into under-specification rather than disciplined conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, but the description still omits the essentials for correct invocation: where scan_id comes from, typical polling behavior, and how this differs from the report tool. For a tool with a sibling pair this thin, more context is warranted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single required scan_id parameter, and the description adds only the weak implication that the id identifies a dependency vulnerability scan. It does not explain the id's origin or format, so it fails to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (status for a dependency vulnerability scan), which is meaningfully narrower than the sibling get_scan_report. It does not, however, explicitly distinguish itself from get_scan_report or start_dependency_scan, so an agent must infer the status-vs-report split.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no mention of alternatives, and no indication that this is typically polled after start_dependency_scan. The description offers nothing about when this tool is the right choice versus get_scan_report.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_dependency_scanB
Start an OWASP Dependency-Check scan for an allowed repository path.
| Name | Required | Description | Default |
|---|---|---|---|
| project_name | No | ||
| repository_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full behavioral burden. It mentions starting an OWASP Dependency-Check scan but says nothing about whether the scan is asynchronous, whether the call blocks, what permissions are required, what happens when the path is not allowed, or how the caller should proceed afterward. The output schema covers return values, but operational behavior remains largely undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler. Every part of the sentence earns its place and conveys the core action and target resource efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return-value explanation is not required. Still, for a scan-starting mutation tool with no annotations, the description is too thin: it omits async/polling behavior, permission requirements, and the meaning of the optional project_name parameter. An agent would need to guess important operational details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description should compensate. It mentions the required repository_path and adds that it must be an 'allowed' path, which is some useful context. However, it completely omits the optional project_name parameter, leaving half the parameters undocumented in both the schema and the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: 'Start an OWASP Dependency-Check scan.' This clearly separates it from siblings like get_scan_status and get_scan_report, which handle status and reporting. It is clear enough for selection, though it does not explicitly name or contrast the siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the agent can infer this tool begins a scan for a repository. The phrase 'for an allowed repository path' hints at a precondition, but there is no explicit when-to-use guidance, no mention of alternatives, and no indication of when not to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
get_scan_report - First observed
get_scan_status - First observed
start_dependency_scan
TDQS
Scored across 3 tools
Each tool targets a distinct phase of the scan lifecycle: start a scan, poll its status, and retrieve the completed report. There is no functional overlap, and the descriptions clearly differentiate status polling from report retrieval.
All tool names follow a consistent snake_case verb_noun pattern (start_dependency_scan, get_scan_status, get_scan_report). The shared 'get_scan_' prefix for the two retrieval tools reinforces predictability.
Three tools are well-scoped for a focused dependency scanning service: initiate, monitor, and fetch results. The set contains no redundant or filler tools, and the count sits comfortably in the typical 3-15 range.
The core lifecycle (start → status → report) is fully covered, but there is no way to list existing scans or cancel a running scan. These are minor gaps that agents can work around by retaining scan IDs, but they limit multi-scan management.
Maintenance
Related MCP Connectors
Generate SBOMs, scan vulnerabilities, and analyze dependencies from local projects or Git repos.
Scan packages and lockfiles (npm, PyPI, Go, Maven, Cargo, NuGet) for vulnerabilities and malware.
41Deep security scans of repos you own from your editor: dependency CVEs, SAST, git-history secrets.
Audit GitHub repos for malicious and supply-chain code before you depend on them.
Related MCP Servers
AlicenseNot gradedqualityNot gradedmaintenanceProvides tools for autonomous CVE detection, enrichment, and remediation across managed repositories using GHSA and NVD data. It enables automated triage and pull request creation for dependency fixes based on configurable severity policies.-- AlicenseNot gradedqualityCmaintenanceEnables querying projects, fetching findings, triggering analysis, uploading CycloneDX BOMs, and checking async token status for OWASP Dependency-Track.18 npm1MIT
- AlicenseAqualityBmaintenanceEnables AI assistants to run Offensive360 SAST scans on local codebases, returning security findings with file/line, severity, and fixes, plus scan status tracking.230 npmMIT

@guardbee/mcp-dependencyofficial
AlicenseNot gradedqualityFmaintenanceEnables auditing npm, pip, and other package dependencies for known CVEs via the OSV database, with tools to scan manifests, query individual packages, and integrate into CI/CD workflows.396 npmMIT