TLDR overview
- The SonarQube plugin for Devin CLI adds dedicated
sonar-*skills so Devin can query quality gates, issues, coverage, duplication, and dependency risks from inside a terminal session. - The plugin fits developers who run Devin CLI against a project that SonarQube already analyzes in CI, and want SonarQube results and standards available without leaving the terminal.
- Running
/sonarqube:sonar-integrateafter installation in Devin CLI enables secrets scanning, the SonarQube MCP Server, and Sonar Vortex (when entitled), so prompts and file reads are checked for credentials and the code Devin writes is guided and verified. - Setup installs the plugin with
devin plugins install, authenticates to SonarQube, and writes a global integration to~/.config/devin/that applies across every project.
The SonarQube plugin for Devin CLI packages SonarQube capabilities as skills that Devin can call from a terminal session. Devin has no built-in view of a project's quality gate, existing issues, or coding standards, and nothing checks its output until CI runs after a pull request. This blueprint covers installing and activating the plugin, running the integration with SonarQube, invoking the skills, scanning for secrets, and, optionally, using the Sonar Vortex context and analysis to guide the agent and verify its output. Examples run against a fork of aws-cli, a large Python codebase analyzed in SonarQube Cloud through CI. The plugin source can be found here.
When to use this
Use this blueprint when you want Devin to work with your SonarQube data and standards directly in the terminal:
- You run Devin CLI in local sessions against a codebase that SonarQube already analyzes.
- You want slash commands for quality gate status, issue lists, coverage gaps, and dependency risks without opening the SonarQube UI.
- You want issues caught in the agent's own loop rather than by a pull request that fails in CI.
What you'll achieve
- The SonarQube plugin installed in Devin CLI, with dedicated
sonar-*skills available as/sonarqube:slash commands. - A global integration in
~/.config/devin/that registers the SonarQube MCP Server (sonar run mcp), secrets hooks, Vortex hooks, and anAGENTS.mdinstruction block. - Working skill calls, a verified secrets block on a file read, and end-of-turn
DEEPanalysis on code the agent writes.
Architecture

The integration splits across two layers.
The plugin layer contributes skills, a sonarqube-reviewer agent, and a rule, and owns no runtime infrastructure. Devin installs it from the SonarSource/sonarqube-agent-plugins repository, where the Devin bundle lives in .devin-plugin/.
The SonarQube CLI layer does the work. sonar integrate devin installs the integration globally into ~/.config/devin/, so the same MCP registration, hooks, and instructions apply to every project you open. sonar auth login holds your session in the OS keychain. sonar run mcp starts the SonarQube MCP Server container, which Devin reaches over stdio. Each hook is a short shell script that calls a sonar hook devin-* command and reuses the same keychain session.
If enabled, Vortex runs on top of this layer. A CI run stores your project's dependencies, compiled artifacts, type information, and build configuration by project key and branch, and Vortex restores that context on demand, so analysis returns results at CI precision without a full scan. Vortex context reaches Devin through the SonarQube CLI (sonar context) rather than as MCP tools, so those tools won't appear in the MCP server's tool list.
Vortex covers the Guide and Verify stages of Sonar's Agent Centric Development Cycle. It guides the agent with project-aware context and constraints, then verifies the agentic loop's output with CI-level precision.
Prerequisites
- Devin CLI installed and authenticated, with plugins permitted by your organization
- SonarQube Cloud on Enterprise, or Team with an annual plan, or SonarQube Server 2026.5 or later on Enterprise or Data Center edition. The Vortex steps also need a Sonar Vortex subscription active for your organization; secrets scanning and the skills work without it
- A container runtime running: Docker, Podman, or nerdctl. The MCP server runs as a container
- (Optional) SonarQube CLI (
sonar). Thesonar-integrateskill installs or updates it, so you can skip this going in. It supports macOS on Apple silicon, Linux, and Windows, and this blueprint was written against version 1.11.0, so later releases may change which files the integration writes - (Optional) A
sonar-project.propertiesfile in the project root. The skills use it to resolve the project key
To follow along exactly, fork aws/aws-cli, import it into SonarQube (Cloud in the case of this guide) with CI-based analysis, and analyze it on a long lived branch. If entitled, Vortex analysis restores the CI analysis context and Vortex context combines SonarQube project data with the local semantic nav.
Step 1 — Install and activate the plugin
In your terminal, install the plugin from the repository:
devin plugins install SonarSource/sonarqube-agent-pluginsConfirm it's installed and inspect the skills it ships:
devin plugins list
devin skills list
Multiple `/sonarqube:` skills are listed. The plugin is loaded at this point, but the SonarQube integration itself isn't configured yet.
Step 2 — Configure the integration
In a Devin session, run the integration skill:
/sonarqube:sonar-integrateThe skill checks that the SonarQube CLI is installed and up to date, checks your authentication status, and then runs the integration. If you aren't signed in, it hands the login back to you because sonar auth login opens a browser. Select your connection (SonarQube Cloud EU or US, or a SonarQube Server URL), enter your organization key for SonarQube Cloud, and complete the browser flow. The token lands in your OS keychain.
The skill then runs sonar integrate devin --non-interactive, which installs every component available to your organization:
- Secrets scanning: Devin prompt and pre-tool hooks that check for credentials, as well as instructions to scan a file for secrets before Devin reads it.
- Sonar Vortex: a post-tool analysis hook, session-start and subagent hooks, and the Vortex instructions.
- SonarQube MCP Server: the MCP configuration for the SonarQube tools.
If your organization has no Vortex subscription, the CLI skips the Vortex components and still installs secrets scanning and the MCP server.

Step 3 — Review what the integration configured
The integration writes to ~/.config/devin/ in your user home. Nothing is written to your project, so there's no per-project config to commit or maintain.
~/.config/devin/mcp_config.json registers the MCP server for every project:
{
"mcpServers": {
"sonarqube": {
"command": "sonar",
"args": ["run", "mcp"]
}
}
} The server starts through the CLI rather than a raw docker run, which is how the CLI detects your container runtime and hands off the keychain session. The registration is global, so it carries no project key.
~/.config/devin/config.json holds the hook registrations. This entry runs the secrets check before every file read:
{
"hooks": {
"PreToolUse": [
{
"matcher": "^read$",
"hooks": [
{
"type": "command",
"command": "'<home>/.config/devin/hooks/sonar-secrets/build-scripts/pretool-secrets.sh'",
"timeout": 60
}
]
}
]
}
} Five hooks are registered in total:
The scripts live in ~/.config/devin/hooks/, grouped into sonar-secrets/, sonar-vortex/, and sonar-sqaa/. On macOS and Linux, each one is a short wrapper that exits quietly if sonar isn't on your PATH (on Windows, the config directory is %APPDATA%\devin and the scripts differ):
#!/bin/bash
if ! command -v sonar &> /dev/null; then
exit 0
fi
sonar hook devin-pre-tool-use~/.config/devin/AGENTS.md carries two managed instruction blocks, delimited by marker comments. The devin-secrets-on-read block tells Devin to run sonar analyze secrets <file> before reading any file and to stop if the scan reports a secret. The sonarqube-agentic-analysis-protocol block tells Devin to run one analysis at the end of any turn that changed files:
sonar analyze agentic --depth DEEP --file <path/to/file1> --file <path/to/file2>The command needs no --project or --branch flag because both are detected from the working directory. The CLI preserves any other content in AGENTS.md and refreshes only its own blocks when you re-run the integration.
The SonarQube CLI also keeps its analyzer binaries in ~/.sonar/sonarqube-cli/bin/ and its integration state in ~/.sonar/sonarqube-cli/state.json.
Step 4 — Invoke the plugin skills
Open the aws-cli clone in a new Devin session. Hooks and MCP settings are read at startup. In the new session, confirm the MCP server is connected:

Then invoke skills through plain language prompting, or directly by using the dedicated slash commands:
/sonarqube:sonar-list-projects
/sonarqube:sonar-list-issues
When you don't pass a project key, running sonar link <projectKey> once in the repo root creates .sonar-config.json, and the skills pick the key up from it. It's the native Sonar CLI way to define your project key. Alternatively, the skills resolve one from sonar-project.properties in the project root or from the MCP integration default. The other skills work the same way, though /sonarqube:sonar-dependency-risks also requires SonarQube Advanced Security.
Step 5 — Scan for secrets
Create a file that contains a fake credential. Use random, plausible values: the scanner applies an entropy check and skips obvious placeholders such as EXAMPLE_TOKEN. Don't use a real key.
cat > creds-demo.txt << 'EOF'
AWS_ACCESS_KEY_ID=AKIAJ7QK4XPN2MWD5RTA
AWS_SECRET_ACCESS_KEY=w3Jq9ZxT5vLm2KdR8nYp0BhFc4UaGsE7oIt1VeNx
EOFIn a fresh Devin session, ask Devin to read it:
Read the file creds-demo.txt and summarize what it contains.Devin doesn't read the file. The secrets check stops the read, either the PreToolUse hook on read or the AGENTS.md instruction to scan a file before reading it, and Devin reports that the file appears to contain a secret.

The UserPromptSubmit hook covers the other path. A prompt that contains the fake key is blocked when you submit it.
Remove the demo file:
rm creds-demo.txtStep 6 (optional) — Guide the agent with project-aware context and constraints
Vortex injects project context when a session starts, and Devin can query it on demand. Ask for the guidelines that apply to the project:
what are the coding guidelines for this project?Devin retrieves guidelines with sonar context guidelines get and answers with rules specific to the codebase, drawn from the project's issue history and narrowed to the task and languages involved, rather than a generic style list.

Then ask for the project structure:
show me the top-level architecture of this projectThe answer comes from Vortex's architecture context for the analyzed project, and it describes the module layout and the main execution path through the aws-cli package.

Step 7 (optional) — Verify the agentic loop
Ask Devin to write new code, and watch how the integration shapes the turn:
Add s3_helper.py at the project root with an upload_with_retry(
bucket, key, file_path, max_retries=3
) function.
Implement a small boto3-based S3 upload helper using the standard upload_file
transfer API. Retry transient upload failures with exponential backoff, log each
attempt, and raise a clear error after all retries fail. Keep the public function
signature as specified. Include a TODO for adding metric emission later.Devin starts with a three-item plan: retrieve project guidance and scan the workspace files it needs for secrets before reading them, implement the helper, then run focused tests and a Vortex DEEP analysis. It fetches the project's Python guidelines with sonar context guidelines get --languages python, scans files for secrets before it reads them, writes s3_helper.py and tests/unit/test_s3_helper.py, and runs the tests.


Not every red mark in the trace is a Sonar failure. ruff isn't installed in the project environment, so that line fails and Devin moves on. The sonar analyze agentic lines exit with code 51, which means the analysis completed and found issues.
The first DEEP run reports one finding, python:S7608. The rule raises when an S3 operation runs without verifying bucket ownership. Without ExpectedBucketOwner, a naming collision or a dynamically constructed bucket name can send the upload to a bucket in a different AWS account. For upload_file, the issue message asks you to add ExpectedBucketOwner to the ExtraArgs parameter. The tests pass and the code reads correctly, but the upload call has no ownership check, and CI analysis would report the same rule after the pull request.
As the AGENTS.md protocol directs, Devin fixes findings on the lines it touched. It confirms that boto3 accepts ExpectedBucketOwner as an upload argument by checking S3Transfer.ALLOWED_UPLOAD_ARGS, then patches s3_helper.py (+6 -1) and the test file (+6 -2). Your prompt told Devin to keep the public signature, so the fix doesn't add a parameter. The helper reads the owner from the AWS_EXPECTED_BUCKET_OWNER environment variable and passes it when it's set.
Devin then rescans the changed files for secrets, re-runs the four unit tests, and runs the DEEP analysis again. S7608 is gone. One finding remains, the TODO that the prompt asked for, which is why the run still exits with code 51. Devin keeps the TODO on purpose and says so in its summary.
Analysis runs once, at the end of the turn, over every file the turn changed. It uses DEEP depth even for a single file so it includes cross-file findings. Vortex supplies the catch and the verify, and Devin does the fix.
Step 8 (optional) — Run multi-file DEEP analysis
Single-file analysis won't catch issues that only appear across boundaries. Pass repeated --file flags to widen the scope:
sonar analyze agentic --file awscli/clidriver.py --file s3_helper.py --file awscli/customizations/s3/subcommands.py! awscli/clidriver.py · 1 issue
[1] line 289 Complete the task associated to this "TODO" comment. python:S1135
! s3_helper.py · 1 issue
[1] line 27 Complete the task associated to this "TODO" comment. python:S1135
! awscli/customizations/s3/subcommands.py · 10 issues
[1] line 903 Define a constant instead of duplicating this literal "%s\nError: Invalid argument type" 3 times. python:S1192
[2] line 555 Define a constant instead of duplicating this literal 's3://' 8 times. python:S1192
[3] line 771 Define a constant instead of duplicating this literal "<S3Uri>" 4 times. python:S1192
[4] line 429 Using HTTP protocol is insecure. Use HTTPS instead. python:S5332
[5] line 925 Complete the task associated to this "TODO" comment. python:S1135
[6] line 1096 Refactor this function to reduce its Cognitive Complexity from 24 to the 15 allowed. python:S3776
[7] line 1248 Either merge this branch with the identical one on line "1230" or change one of the implementations. python:S1871
[8] line 1474 Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed. python:S3776
[9] line 1510 Use the opposite operator ("!=") instead. python:S1940
[10] line 1594 Replace the unused local variable "bucket" with "_". python:S1481
3 files analyzed · 3 with issues · 12 issues found · DEEP analysisThe s3_helper.py finding is the intentional TODO from Step 7. The subcommands.py findings are pre-existing issues in the upstream codebase, which the protocol tells the agent to leave alone unless you ask.
These flags and defaults govern this command:
- Two or more
--fileflags activateDEEPautomatically. You don't need to pass--depth. --depthacceptsSTANDARD, the single-file default, andDEEP.--projectand--branchare inferred from your project configuration when you run inside the project directory.- Large change sets trigger a confirmation prompt; pass
--forceto skip it. - The command exits with code 51 when it reports issues and 0 when the change set is clean.
Verify the setup
Run these in order to confirm every layer is live:
sonar auth status # authentication and connectivity
sonar system status # MCP status and, with Vortex, subscription and usage
sonar --version # 1.11.0 or later
docker ps --filter "ancestor=sonarsource/sonarqube-mcp"Then, in a fresh Devin session, confirm each layer:
- Plugin and MCP. The
/sonarqube:skills appear indevin skills list,/mcpshowssonarqube - Connected(devin mcp listalso lists it), and/sonarqube:sonar-list-projectsreturns your project. - Secrets detection. The agent refused to read
creds-demo.txtin Step 5. - (Optional) context is injecting. Ask an architecture question rather than a coding task. A module graph means context arrived. A generic answer, or one derived only from files the agent just read, means it didn't.
- (Optional) analysis runs. After a real edit, the agent runs a
DEEPpass before its final reply. The instructions direct this rather than a hook enforcing it, so you're confirming the agent followed them.
Your user home should now carry these artifacts, and your project directory should carry none of them:
What to know
- Skills that query SonarQube data depend on prior CI analysis. Vortex context and analysis restore stored CI analysis context, and for Java projects analyzed through Automatic Analysis only basic results come back.
- Vortex analysis spans 25 programming languages including Python. Taint analysis is limited to Java, JavaScript, TypeScript, C#, and VB.NET, and semantic navigation to Java, C#, JavaScript, TypeScript, Python, and Rust.
- Secrets checks run on prompts and on Devin's
readtool, with theAGENTS.mdinstruction as a second layer. Other tools, such as a shell command that prints a file, aren't scanned by the hooks. The hook wrappers exit quietly ifsonarisn't on thePATHDevin uses, and a scan error lets the action through, so treat the checks as a safeguard rather than a guarantee. - Restart Devin after you integrate. If MCP shows as failed or not started, check that your container runtime is running, then restart. Re-running
sonar integrate devinrefreshes the managed blocks and fixes drift, and running it interactively and choosing Customize removes the integration.sonar system statusis the fastest check on whether the Vortex subscription is active. - Per-edit hooks run
STANDARDanalysis and never block. The end-of-turnDEEPcheck comes from theAGENTS.mdinstructions, not from a hook, andsonar analyzeexits with code 51 when it finds issues.
Next steps
Related Sonar guides:
- Set up the SonarQube plugin for GitHub Copilot in VS Code
- Set up the SonarQube plugin for GitHub Copilot CLI
- Set up the SonarQube plugin for Claude Code
- Set up the SonarQube plugin for Codex
- Set up the SonarQube plugin for Antigravity
- Introducing Sonar Vortex
- The Future is AC/DC: the Agent Centric Development Cycle
Documentation:
