dependencyTrack-MCP

MCP-Server fuer OWASP Dependency-Track, in Rust. Read-only Zugriff auf Projekte, Findings und Metriken.

Zwei Frontends, eine gemeinsame Tool-Logik:

Modus Binary Einsatz
stdio dtrack-stdio Lokal: von Claude Desktop via docker run -i gestartet
HTTP dtrack-http Server: StreamableHTTP /mcp, Multi-Client, Bearer-Auth/RBAC, Admin-UI

Status: Stage 3 -- HTTP-Frontend, Bearer-Auth, persistente Config, Admin-UI und RBAC-Enforcement stehen. Tool-Sichtbarkeit pro Client (Stufe 2) und SSO folgen (siehe Roadmap).

Architektur

crates/dtrack-config   Config (TOML laden/speichern, Secret-Masking, Persistenz)
crates/dtrack-perms    RBAC-Policy (Rollen/Clients, Deny-overrides-Allow)
crates/dtrack-core     DT-REST-Client (reqwest+rustls, read-only)
crates/dtrack-tools    rmcp-Server (die Tools) -- transport-unabhaengig, geteilt
crates/dtrack-stdio    Bin: stdio-Frontend
crates/dtrack-http     Bin: HTTP-Frontend (axum + StreamableHTTP + Admin-UI)

Tools

Tool Argument DT-Endpoint
list_projects -- GET /project
project_findings uuid GET /finding/project/{uuid}
project_metrics uuid GET /metrics/project/{uuid}/current

Konfiguration (Umgebungsvariablen)

Var Pflicht Bedeutung
DTRACK_URL ja* Basis-URL der DT-Instanz (ohne /api/v1, wird angehaengt)
DTRACK_API_KEY ja* API-Key eines read-only Teams (VIEW_PORTFOLIO, VIEW_VULNERABILITY)
DTRACK_INSECURE nein 1/true -> TLS-Pruefung aus (Notbehelf bei internem CA-Cert)
DTRACK_CONFIG nein Pfad zu einer TOML-Config; einmal aus env gebootstrappt, danach massgeblich
DTRACK_PERMISSIONS nein (nur HTTP) Pfad zur RBAC-Policy; gesetzt -> RBAC statt flacher Token-Liste
DTRACK_HTTP_TOKENS nein (nur HTTP) kommagetrennte erlaubte Bearer-Tokens; leer = ungeschuetzt
DTRACK_HTTP_ADDR nein (nur HTTP) Bind-Adresse, Default 0.0.0.0:8080
DTRACK_ADMIN_USER nein (nur HTTP) Basic-Auth-User der Admin-UI; leer = UI deaktiviert
DTRACK_ADMIN_PASSWORD nein (nur HTTP) Basic-Auth-Passwort der Admin-UI

* oder ueber DTRACK_CONFIG-Datei.


Schnellstart: lokal testen (Mac/Linux mit Docker)

Beispiele mit docker; podman funktioniert identisch.

Variante A -- aus dem Quellcode bauen (baut nativ fuer deine Architektur)

cp .env.example .env      # DTRACK_URL / DTRACK_API_KEY ausfuellen
docker compose up --build

Variante B -- vorgebautes Release-Image laden

Am Release haengen pro Architektur Tarballs. Passenden waehlen (arm64 = Apple Silicon, amd64 = Intel / "nicht Mac"):

docker load -i dtrack-http-0.1.0-arm64.tar.gz

docker run --rm -p 8080:8080 \
  -e DTRACK_URL=http://host.docker.internal:8081 \
  -e DTRACK_API_KEY=odt_dein_key \
  -e DTRACK_ADMIN_USER=admin -e DTRACK_ADMIN_PASSWORD=geheim \
  dtrack-http:0.1.0-arm64

Pruefen:

  • curl http://localhost:8080/health -> OK
  • http://localhost:8080/admin -> Admin-UI (Basic-Auth)

Der Server bootet auch ohne erreichbare DT -- nur die Tool-Calls brauchen eine echte Instanz. Tipp fuer Persistenz: -v ~/dtrack-data:/data -e DTRACK_CONFIG=/data/config.toml ergaenzen, dann ueberleben Admin-Aenderungen den Neustart.

(optional) Dummy-DependencyTrack zum Testen

docker-compose.yml in einem eigenen Ordner:

services:
  dtrack-apiserver:
    image: dependencytrack/apiserver
    deploy:
      resources:
        limits:
          memory: 4608m
    ports:
      - "8081:8080"          # API -> Host-Port 8081
    volumes:
      - dtrack-data:/data
  dtrack-frontend:
    image: dependencytrack/frontend
    environment:
      - API_BASE_URL=http://localhost:8081
    ports:
      - "8082:8080"          # Web-UI -> Host-Port 8082
volumes:
  dtrack-data: {}

docker compose up -d (apiserver braucht ~4 GB RAM + ein paar Minuten beim Erststart). Dann http://localhost:8082 (Login admin/admin), unter Administration -> Access Management -> Teams einen API-Key mit VIEW_PORTFOLIO + VIEW_VULNERABILITY erzeugen und ein Projekt anlegen. Aus dem MCP-Container ist die DT unter http://host.docker.internal:8081 erreichbar (nicht localhost).


Mit Claude Desktop verbinden

Wichtig: Der UI-Weg "Add custom connector" (URL eingeben) funktioniert fuer einen lokalen Server nicht -- Claude verbindet sich dabei aus Anthropics Cloud, die deinen localhost nicht erreicht. Fuer lokal geht der Weg ueber die claude_desktop_config.json.

Config-Datei (macOS): ~/Library/Application Support/Claude/claude_desktop_config.json (oder in Desktop: Settings -> Developer -> Edit Config). Den mcpServers-Block neben preferences einfuegen, danach Desktop komplett neu starten (Cmd+Q).

Empfohlen lokal: stdio

stdio hat keinen HTTP-Session-Handshake -> zuverlaessig. Den HTTP-Container braucht man dafuer nicht (nur eine laufende DT).

docker load -i dtrack-stdio-0.1.0-amd64.tar.gz
{
  "mcpServers": {
    "dependency-track": {
      "command": "docker",
      "args": ["run","-i","--rm",
        "-e","DTRACK_URL","-e","DTRACK_API_KEY",
        "dtrack-stdio:0.1.0-amd64"],
      "env": {
        "DTRACK_URL": "http://host.docker.internal:8081",
        "DTRACK_API_KEY": "odt_dein_key"
      }
    }
  }
}

Findet Desktop docker nicht (eingeschraenkter PATH), which docker ausfuehren und den vollen Pfad als command setzen (z.B. /usr/local/bin/docker). Das stdio-Release-Image ist amd64 -> laeuft auf Apple Silicon emuliert (ok zum Testen).

HTTP als echter Remote-Connector

Der HTTP-Modus ist fuer den Betrieb als oeffentlich erreichbarer Remote-MCP gedacht (Custom Connector ueber eine echte URL, z.B. hinter Reverse-Proxy/Tunnel). Der Bridge-Versuch npx mcp-remote http://localhost:8080/mcp fuer lokal scheitert aktuell am rmcp-StreamableHTTP-Handshake (tools/list vor initialized) -- darum lokal stdio nutzen.

Logs bei Problemen: ~/Library/Logs/Claude/mcp*.log.


RBAC (optional, nur HTTP)

Standardmaessig regelt DTRACK_HTTP_TOKENS den Zugang (flache Token-Liste, leer = offen). Fuer feinere Rechte permissions.toml.example nach ./data/permissions.toml kopieren, Tokens/Rollen eintragen und DTRACK_PERMISSIONS=/data/permissions.toml setzen.

Modell: benannte Rollen mit allow/deny ("*" = alle Tools, deny schlaegt allow), Clients ordnen einen Bearer-Token einer Rolle zu. Ein nicht erlaubter tools/call wird mit 403 abgewiesen.

[[roles]]
name  = "metrics-only"
allow = ["list_projects", "project_metrics"]

[[clients]]
name  = "dashboard-bot"
token = "GEHEIM"
role  = "metrics-only"

Admin-UI

Unter /admin (Basic-Auth via DTRACK_ADMIN_USER/_PASSWORD): zeigt URL + maskierten API-Key, erlaubt Aendern (Client wird live neu gebaut) und persistiert bei gesetztem DTRACK_CONFIG. Aktuell bewusst minimal -- Styling und Client-/Rollen-Verwaltung folgen.

Release bauen (Maintainer)

In Gitea einen Release veroeffentlichen (oder Actions -> Release Images -> Run workflow mit Tag). Der Workflow baut via buildx Multi-Arch und haengt an: dtrack-stdio-<tag>-amd64, dtrack-http-<tag>-amd64, dtrack-http-<tag>-arm64 (je .tar.gz). Auth laeuft ueber das automatische gitea.token.

Roadmap

Stage Inhalt Status
0 stdio, read-only, 3 Tools, CI, Container
1 Config-Layer + geteiltes Tool-Crate
2 HTTP-Frontend + Bearer-Auth
3 Admin-UI + Persistenz + RBAC-Enforcement
3.2 Tool-Sichtbarkeit pro Client (tools/list filtern)
4 SSO (Gitea-OIDC)
S
Description
No description provided
Readme 159 KiB
Languages
Rust 98.3%
Dockerfile 1.7%