marcus d76c16d9a7 feat(auth): forward SONARQUBE_TOKEN to upstream as Bearer header
The upstream MCP container requires a SonarQube user token in the
Authorization header. Without one, every call returns 401.

- proxy: read SONARQUBE_TOKEN via sonarqube_token() at session-open
  time; raise TokenMissingError when unset/blank. upstream_session()
  attaches the token as "Authorization: Bearer <token>" via
  streamablehttp_client(headers=...).
- cli: fail fast in serve and check with a clear stderr message and
  exit 1 when the token is missing, before any network attempt. All
  exception text written to stderr passes through _redact() so an
  accidentally-leaked token from a third-party exception is replaced
  with [REDACTED] before display.
- The token is never stored on any object, never logged, and the
  TokenMissingError message contains no token material (it only
  describes how to generate one in SonarQube).
- Tests: header forwarding via mocked streamablehttp_client, missing-
  token exit code, redaction in CLI error paths, whitespace stripping
  on the token. Total: 25 tests.
- Docs: README/CLAUDE updated with the new env-var, Claude Desktop
  config snippet, and the security guarantees. CHANGELOG added.

Bumps version to 0.2.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:42:51 +02:00

mcp-sonarqube-proxy

Stdio-MCP-Server, der einen Upstream-SonarQube-MCP-Server (Streamable HTTP) in Claude Desktop / Claude App einbindet. Der Proxy wird via stdio gespawnt, verbindet sich beim Start mit dem Upstream und reicht alle Tools 1:1 weiter — inklusive inputSchema, outputSchema und annotations, sodass Claude die Tools korrekt aufrufen kann.

Installation

uv tool install git+https://gitea.gecheckt.de/marcus/mcp-sonarqube-proxy.git

SonarQube-Token

Der Upstream-Container verlangt einen SonarQube-User-Token. Token erzeugen in SonarQube unter My Account → Security → Generate Tokens, dann in SONARQUBE_TOKEN setzen. Ohne Token brechen serve und check mit Exit-Code 1 und einer klaren Meldung auf stderr ab. Der Token wird ausschliesslich als Authorization: Bearer <token> an den Upstream weitergereicht und nirgends geloggt; Fehlermeldungen, die den Token versehentlich enthalten, werden vor der Ausgabe maskiert ([REDACTED]).

Verwendung

Verbindung pruefen

SONARQUBE_MCP_URL=http://192.168.0.2:8765/mcp \
SONARQUBE_TOKEN=<your-sonarqube-token> \
  mcp-sonarqube-proxy check

Listet alle Tools auf, die der Upstream bereitstellt. Exit-Code 0 bei Erfolg, 1 wenn der Token fehlt oder der Upstream nicht erreichbar ist.

Claude Desktop / Claude App Konfiguration

In claude_desktop_config.json:

{
  "mcpServers": {
    "sonarqube": {
      "command": "mcp-sonarqube-proxy",
      "args": ["serve"],
      "env": {
        "SONARQUBE_MCP_URL": "http://192.168.0.2:8765/mcp",
        "SONARQUBE_TOKEN": "<your-sonarqube-token>"
      }
    }
  }
}

Auf Windows ist command typischerweise der absolute Pfad zur per uv tool install installierten EXE, z.B. %USERPROFILE%\.local\bin\mcp-sonarqube-proxy.exe.

Umgebungsvariablen

Variable Pflicht Default Beschreibung
SONARQUBE_TOKEN ja SonarQube-User-Token (My Account → Security)
SONARQUBE_MCP_URL nein http://192.168.0.2:8765/mcp Upstream-MCP-Endpoint (Streamable HTTP)

Kommandos

Kommando Beschreibung
mcp-sonarqube-proxy serve Startet den MCP-Server auf stdio.
mcp-sonarqube-proxy check Testet Upstream-Verbindung und listet Tools.
mcp-sonarqube-proxy --version Gibt die Proxy-Version aus.

Funktionsweise

  1. Beim Start liest serve SONARQUBE_TOKEN und oeffnet eine Streamable-HTTP- Session zum Upstream mit Authorization: Bearer <token>. Anschliessend wird initialize() ausgefuehrt. Schlaegt eines davon fehl, beendet sich der Prozess mit Exit-Code 1 und schreibt die Fehlermeldung auf stderr.
  2. Diese Session bleibt fuer die Lebensdauer des Proxies offen.
  3. tools/list-Requests vom Client werden 1:1 an den Upstream weitergeleitet — die Tool-Objekte (mit allen Schemata und Annotations) kommen unveraendert beim Client an.
  4. tools/call-Requests werden ebenfalls weitergeleitet. Das vollstaendige CallToolResult (inklusive isError, structuredContent und allen Content-Bloecken) wird an den Client zurueckgegeben.
  5. stdout ist ausschliesslich fuer JSON-RPC reserviert. Logging und Statusmeldungen gehen auf stderr.

Der Proxy validiert Tool-Argumente bewusst nicht lokal — der Upstream ist die einzige Schema-Autoritaet und uebernimmt die Validierung.

Anforderungen

  • Python >= 3.12
  • mcp >= 1.27, < 2
S
Description
No description provided
Readme 47 KiB
Languages
Python 100%