| name | lisa-setup-sonar |
| description | Configure the official SonarQube plugin + MCP as Lisa's single Sonar substrate across every supported coding agent. Installs/updates the SonarQube CLI, authenticates (browser login on a dev machine, or SONARQUBE_CLI_TOKEN headless), selects the Test Manager target, runs `sonar integrate <agent>` for each supported agent (Claude, Codex, Cursor, Copilot, Antigravity) and wires the MCP for OpenCode, then writes only non-secret policy to .lisa.config.json. Separate from the CI SonarCloud scan gate, which is unchanged. |
| allowed-tools | ["Bash","Read","Write","Edit","AskUserQuestion","Skill"] |
Set up SonarQube (official plugin + MCP)
This is an explicit exterior setup gate. Run it outside any active Build, QA,
Monitor, or Verify factory — authentication and MCP wiring must be complete before
unattended factories run. It replaces Lisa's former hand-rolled SonarCloud REST
access with the vendor's official token-authed MCP, which is Lisa's single Sonar
substrate on both developer machines and headless cloud routines.
This does not touch the CI static-security job in quality.yml or its
SONAR_TOKEN secret — that enforcement gate is separate and stays as-is.
Supported agents
Wire only Lisa's supported agents: Claude Code, Codex, Cursor, GitHub Copilot,
Antigravity (agy) via sonar integrate <agent>, and OpenCode via its MCP
config. Never wire Kiro or Gemini CLI even though the vendor supports them —
they are not Lisa-supported agents.
1. Install or update the SonarQube CLI
Check sonar on PATH (command -v sonar). If present, update it (sonar self-update, or the package manager that owns it); if absent, install it and ask
for confirmation before running the install:
curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh | bash
A container runtime (Docker/Podman/Nerdctl) must be installed and running — the
MCP runs as a container via sonar run mcp. Probe with docker ps (falling back
to podman ps / nerdctl ps). If none succeed, tell the operator to start it and
note the agent session must restart afterward for the MCP tools to load.
2. Authenticate — token for factories, login for dev machines
The MCP authenticates from environment variables — this is the headless path and
the one factories use. Never write credentials to .lisa.config.json or
.lisa.config.local.json; provide them as environment variables / CI secrets:
SONARQUBE_CLI_TOKEN — required.
SONARQUBE_CLI_ORG — for SonarQube Cloud.
SONARQUBE_CLI_SERVER — for a self-hosted SonarQube Server.
On an interactive developer machine you may instead run sonar auth login
(browser flow; token stored in the OS keychain). Do not use the keychain flow
for headless/cloud-routine environments — provision the env token there instead
(see /lisa:generate-claude-remote-build-script, which now installs the CLI,
pre-pulls the MCP image, and sets SONARQUBE_CLI_TOKEN). Verify with sonar auth status; record the identity label only, never token material.
3. Select the Test Manager target
Use sonar config project (and optional sonar config folder), then sonar config show. Capture the non-secret project/organization identifiers.
4. Integrate per supported agent
Confirm the target scope (single-choice: current project / global), then for each
supported agent detected on PATH run its non-interactive integrate:
sonar integrate claude --non-interactive
sonar integrate codex --non-interactive
sonar integrate cursor --non-interactive
sonar integrate copilot --non-interactive
sonar integrate antigravity --non-interactive
For OpenCode (no vendor integrate path), wire the MCP through OpenCode's own
MCP config so it launches sonar run mcp, authenticated from the same env token.
Skip any agent whose CLI is not installed; never wire Kiro or Gemini.
4a. Patch the generated shims — required, not optional
Each integrate writes a five-line shim that pipes the hook payload to sonar hook <event> and passes the verdict through unchanged. That makes an
unauthenticated CLI refuse every prompt and every file read, with a reason
string that reads exactly like a real finding:
SonarQube secret scanning is inactive: not authenticated. Run 'sonar auth login'.
The operator most likely to hit it is the one who just installed the CLI and has
not logged in — so their very first prompt is rejected, before the session can
say anything useful. Repoint every generated shim at Lisa's wrapper, which keeps
real findings blocking, resolves SONARQUBE_CLI_TOKEN through
lisa-secrets-access when the CLI reports it has none, and degrades the
still-unauthenticated case to a warning:
if ! command -v sonar &> /dev/null; then
exit 0
fi
here="$(cd -- "$(dirname -- "$0")" && pwd)"
exec bash "${here}/<relative-path>/scripts/lisa-hooks/sonar-secrets.sh" <vendor-event>
One wrapper serves every surface — it takes the vendor event name as its only
argument. Known shim locations and their events:
| Agent | Shim | Event |
|---|
| Claude | .claude/hooks/sonar-secrets/build-scripts/prompt-secrets.sh | claude-prompt-submit |
| Claude | .claude/hooks/sonar-secrets/build-scripts/pretool-secrets.sh | claude-pre-tool-use |
| Codex | .codex/hooks/sonar-secrets/build-scripts/prompt-secrets.sh | codex-prompt-submit |
| Copilot | .github/hooks/sonar-secrets/build-scripts/pretool-secrets.sh | copilot-pre-tool-use |
| Antigravity | .agents/sonar/hooks/pretool-secrets.sh | antigravity-pre-tool-use |
Compute the relative path from each shim's own directory rather than assuming a
depth — Antigravity's is three levels up, the rest are four.
Re-running an integrate overwrites the shim with the vendor's original, so
re-apply this patch whenever you re-run step 4, and say so in the summary. Leave
a comment at the top of each patched shim naming the wrapper, so the next reader
does not mistake the delegation for drift.
5. Write non-secret policy config
Merge only non-secret identifiers into committed .lisa.config.json, preserving
every unrelated key (never credentials):
{
"verification": {
"sonar": {
"enabled": true,
"edition": "cloud",
"organization": "<org-key>",
"projectKey": "<project-key>"
}
}
}
Use "edition": "server" with a "serverUrl" for a self-hosted Server.
6. Prove readiness
Run the lisa-sonarcloud-access probe (an mcp__sonarqube__* project search) and
confirm a mcp__sonarqube__* tool answers. Then run lisa doctor and confirm the
Sonar provider check is green. If the MCP tools do not appear, verify the container
runtime is running and restart the agent session.