{"_id":"@aksorn/sonarqube-mcp","_rev":"5-d6b078bd680ab39d7e1169ed9cf9d3ce","name":"@aksorn/sonarqube-mcp","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@aksorn/sonarqube-mcp","version":"0.1.0","keywords":["mcp","sonarqube","cursor","code-quality"],"_id":"@aksorn/sonarqube-mcp@0.1.0","maintainers":[{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"}],"bin":{"sonarqube-mcp":"dist/index.js"},"dist":{"shasum":"d8c3b815488e70e391e6b0a74c7a0dde89639a1b","tarball":"https://registry.npmjs.org/@aksorn/sonarqube-mcp/-/sonarqube-mcp-0.1.0.tgz","fileCount":22,"integrity":"sha512-G1YfaJm3u0gTbzbfMqMzm5WG1XStFzK/5fVzVanCnW4MSbdJZL1Ls/1FEUfpiTDVC9eWcqBDD2+hlz1oAVlJHA==","signatures":[{"sig":"MEUCIHeXLbyagz3w1ioFby1vZgXcLNz1nYhNV470/Ky4KCTvAiEAjk/KDe56IgN6u5pimRkk4Wx8xhswsG1FcOpLqYwEA/0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":117729},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"7a68b17b65b8eb7eb09f06746462dc13e9fa18d8","scripts":{"dev":"tsx src/index.ts","build":"tsc","start":"node dist/index.js","dev:http":"tsx src/http.ts","typecheck":"tsc --noEmit","start:http":"node dist/http.js"},"_npmUser":{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"},"_npmVersion":"10.9.3","description":"MCP server that exposes SonarQube scan and code-quality tools to Cursor","directories":{},"_nodeVersion":"22.20.0","dependencies":{"zod":"^3.24.4","archiver":"^7.0.1","sonarqube-scanner":"^4.3.6","@modelcontextprotocol/sdk":"^1.12.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","typescript":"^5.8.2","@types/node":"^22.14.0","@types/archiver":"^6.0.3"},"_npmOperationalInternal":{"tmp":"tmp/sonarqube-mcp_0.1.0_1779186708165_0.47683189356135736","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aksorn/sonarqube-mcp","version":"0.2.0","keywords":["mcp","sonarqube","cursor","code-quality"],"_id":"@aksorn/sonarqube-mcp@0.2.0","maintainers":[{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"}],"bin":{"sonarqube-mcp":"dist/index.js"},"dist":{"shasum":"5ab43a8e98d64bfa0b4c981d56e396ecee1d3eba","tarball":"https://registry.npmjs.org/@aksorn/sonarqube-mcp/-/sonarqube-mcp-0.2.0.tgz","fileCount":22,"integrity":"sha512-Afbqhionxs5fCGvdD+7MdMlL9o8UuZzEdlyw4bHx3WH+e6U0XA6dlTVVyAY471sJaeGocSwzEwQ7T/vncnJFSw==","signatures":[{"sig":"MEYCIQD7ypEgjfoRAthLXFiZpSCQCb8n4uDntgsr5Yn/mjt/DwIhALngn6EhFXC08bND0bBJETJVGXS+uAKuOXK6uLN2vmLV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120007},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"29a02369593ff95ce217677c2ededa869e949df2","scripts":{"dev":"tsx src/index.ts","build":"tsc","start":"node dist/index.js","dev:http":"tsx src/http.ts","typecheck":"tsc --noEmit","start:http":"node dist/http.js"},"_npmUser":{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"},"_npmVersion":"10.9.3","description":"MCP server that exposes SonarQube scan and code-quality tools to Cursor","directories":{},"_nodeVersion":"22.20.0","dependencies":{"zod":"^3.24.4","archiver":"^7.0.1","sonarqube-scanner":"^4.3.6","@modelcontextprotocol/sdk":"^1.12.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","typescript":"^5.8.2","@types/node":"^22.14.0","@types/archiver":"^6.0.3"},"_npmOperationalInternal":{"tmp":"tmp/sonarqube-mcp_0.2.0_1779250420836_0.3276149577443108","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aksorn/sonarqube-mcp","version":"0.2.1","keywords":["mcp","sonarqube","cursor","code-quality"],"_id":"@aksorn/sonarqube-mcp@0.2.1","maintainers":[{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"}],"bin":{"sonarqube-mcp":"dist/index.js"},"dist":{"shasum":"74d90f220297e63d13a477d83d9f147dd3895beb","tarball":"https://registry.npmjs.org/@aksorn/sonarqube-mcp/-/sonarqube-mcp-0.2.1.tgz","fileCount":22,"integrity":"sha512-j4KJrirlsmoMnSmP+P8GjxEL/cZZoBWeASaGekV4aNXgcimDKIzjrv+moGpypzoI6LJXXELcDbmHsao+fjGqMg==","signatures":[{"sig":"MEUCIQDo+2gw5LXhCIvChIfKAiIMsk9lcqswZFdOvp9MnVvBawIgHc5pG0hRIWyiRV8r70dQuTms+wwGocP3YjaX9XyQ9s8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120282},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"b49f493c44ada6cf263f75a49bbc34f5e3b47075","scripts":{"dev":"tsx src/index.ts","build":"tsc","start":"node dist/index.js","dev:http":"tsx src/http.ts","typecheck":"tsc --noEmit","start:http":"node dist/http.js"},"_npmUser":{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"},"_npmVersion":"10.9.3","description":"MCP server that exposes SonarQube scan and code-quality tools to Cursor","directories":{},"_nodeVersion":"22.20.0","dependencies":{"zod":"^3.24.4","archiver":"^7.0.1","sonarqube-scanner":"^4.3.6","@modelcontextprotocol/sdk":"^1.12.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","typescript":"^5.8.2","@types/node":"^22.14.0","@types/archiver":"^6.0.3"},"_npmOperationalInternal":{"tmp":"tmp/sonarqube-mcp_0.2.1_1779766215307_0.873458461673744","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@aksorn/sonarqube-mcp","version":"0.2.2","keywords":["mcp","sonarqube","cursor","code-quality"],"_id":"@aksorn/sonarqube-mcp@0.2.2","maintainers":[{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"}],"bin":{"sonarqube-mcp":"dist/index.js"},"dist":{"shasum":"02f6fdda659044dbf0589cf7bd2ddb79ecd678f1","tarball":"https://registry.npmjs.org/@aksorn/sonarqube-mcp/-/sonarqube-mcp-0.2.2.tgz","fileCount":22,"integrity":"sha512-tlbtv4qSndePtzy7CNYjI2GlOQd6PpFR1g+Eh/Xrlkakhs8NB6AHFB9/+tFWtLJuEXYvEQBhTRiAEnLgAkgNQA==","signatures":[{"sig":"MEQCIG/BE5t8j/zTM4q1kRj4P5bqw2eXi1a7CklCP1EQVo1YAiBNtFcQx63PrqxA6B3CSiAiB8+WWasPUzWt0ghsDXtr+A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120324},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"8307a271588537e5410e3a81f25a788dd6d1cb7f","scripts":{"dev":"tsx src/index.ts","build":"tsc","start":"node dist/index.js","dev:http":"tsx src/http.ts","typecheck":"tsc --noEmit","start:http":"node dist/http.js"},"_npmUser":{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"},"_npmVersion":"10.9.3","description":"MCP server that exposes SonarQube scan and code-quality tools to Cursor","directories":{},"_nodeVersion":"22.20.0","dependencies":{"zod":"^3.24.4","archiver":"^7.0.1","sonarqube-scanner":"^4.3.6","@modelcontextprotocol/sdk":"^1.12.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.4","typescript":"^5.8.2","@types/node":"^22.14.0","@types/archiver":"^6.0.3"},"_npmOperationalInternal":{"tmp":"tmp/sonarqube-mcp_0.2.2_1779766654106_0.10500186806605116","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aksorn/sonarqube-mcp","version":"0.3.0","description":"MCP server that exposes SonarQube scan, code-quality, minify, and image-compression tools to Cursor","type":"module","main":"dist/index.js","bin":{"sonarqube-mcp":"dist/index.js"},"keywords":["mcp","sonarqube","cursor","code-quality","minify","image-compression"],"scripts":{"build":"tsc","start":"node dist/index.js","start:http":"node dist/http.js","dev":"tsx src/index.ts","dev:http":"tsx src/http.ts","typecheck":"tsc --noEmit"},"dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","archiver":"^7.0.1","esbuild":"^0.25.9","html-minifier-terser":"^7.2.0","sharp":"^0.34.2","sonarqube-scanner":"^4.3.6","zod":"^3.24.4"},"devDependencies":{"@types/archiver":"^6.0.3","@types/html-minifier-terser":"^7.0.2","@types/node":"^22.14.0","tsx":"^4.19.4","typescript":"^5.8.2"},"engines":{"node":">=18"},"_id":"@aksorn/sonarqube-mcp@0.3.0","gitHead":"16e780f0fc880b3645ef442ebe7f755b0d74cf78","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-Orwx44coWWl0F9bUCTQ/6GCHf/7DWfnPdzVchL8xY7IvkMa5MNpi9lleLoeuOhIJhkxrSDRifFe/A098qLxDpA==","shasum":"38d78a55a868c7df4db0fc9425e19352eb84f045","tarball":"https://registry.npmjs.org/@aksorn/sonarqube-mcp/-/sonarqube-mcp-0.3.0.tgz","fileCount":23,"unpackedSize":135855,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDxVRSLmRSzMOMUwA0oeisRXjLEygsHctdbX89vCG97twIgfMXB8mPd/x3YjVHp5Bv/aCf8PloWBHtWbBbAIImm6kc="}]},"_npmUser":{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"},"directories":{},"maintainers":[{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sonarqube-mcp_0.3.0_1786677853583_0.3312860226578107"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-19T10:31:48.078Z","modified":"2026-08-14T03:24:13.923Z","0.1.0":"2026-05-19T10:31:48.304Z","0.2.0":"2026-05-20T04:13:40.979Z","0.2.1":"2026-05-26T03:30:15.494Z","0.2.2":"2026-05-26T03:37:34.257Z","0.3.0":"2026-08-14T03:24:13.735Z"},"keywords":["mcp","sonarqube","cursor","code-quality","minify","image-compression"],"description":"MCP server that exposes SonarQube scan, code-quality, minify, and image-compression tools to Cursor","maintainers":[{"name":"natheetarnp-aksorn","email":"natheetarn.pan@aksorn.com"}],"readme":"# SonarQube MCP Server\n\nAn MCP (Model Context Protocol) server that lets Cursor's AI agent check code quality and security using SonarQube across many apps.\n\n**Target workflow:** a non-technical user says \"check my code\" in Cursor, the agent resolves the correct SonarQube project, reads issues, fixes code, runs another scan, confirms the updated result, then minifies the project into `dist/`.\n\nTool descriptions embed an explicit **resolve project → fetch → explain → fix → rescan → verify → minify** workflow. For consistent agent behavior across projects, distribute the skill folders at [distribution-skill/sonarqube-mcp-workflow](/Users/natheetarn.pan/Documents/GitHub/sonarqube-mcp-local-server/distribution-skill/sonarqube-mcp-workflow) and [distribution-skill/minify-project](/Users/natheetarn.pan/Documents/GitHub/sonarqube-mcp-local-server/distribution-skill/minify-project).\n\nFor app-team setup instructions, see [USER_SETUP.md](/Users/natheetarn.pan/Documents/GitHub/sonarqube-mcp-local-server/USER_SETUP.md).\n\n---\n\n## What it does\n\nTwo groups of tools are exposed to the AI:\n\n### SonarQube tools (always available)\n| Tool | What the AI uses it for |\n|------|------------------------|\n| `find_projects` | Search SonarQube projects by app name or project key |\n| `ensure_project` | Resolve or create the SonarQube project for a new app |\n| `run_scan` | Run a SonarQube scan directly from the MCP server and wait for completion |\n| `check_code` | Get quality gate status + all issues in one call — the main \"check my code\" tool |\n| `minify_project` | Minify JS, CSS, and HTML and compress images into `dist/` after the SonarQube loop. Do not minify before scanning. |\n| `get_issues` | Drill into specific files, rules, or severity levels |\n| `get_quality_gate` | See which quality gate conditions are failing and why |\n| `get_rule_details` | Understand a specific rule and how to fix it |\n\n### Content Gate tools (enabled when `CONTENT_GATE_URL` is set)\n| Tool | What the AI uses it for |\n|------|------------------------|\n| `submit_scan` | ZIP a directory, upload it, and enqueue a governance scan |\n| `get_scan_status` | Poll job status until completion |\n| `get_scan_result` | Get the final pass/fail verdict and all findings |\n| `list_recent_scans` | See recent scan history for a project |\n\n---\n\n## Two deployment modes\n\n| Mode | Best for | Setup effort |\n|------|----------|-------------|\n| **Shared HTTP server** | Teams — one instance, everyone connects | Admin sets it up once on an internal server |\n| **Local stdio** | Individual developers or offline use | Each person installs and configures locally |\n\n### Docker / Dokploy\n\nFor **Dokploy** (or any container host), use the included `Dockerfile`. The image runs **`node dist/http.js`** and listens on **`3333`** by default.\n\nStep-by-step: see **[DOKPLOY.md](./DOKPLOY.md)**.\n\n---\n\n## Prerequisites\n\n- **Node.js 18+**\n- Access to the internal SonarQube instance (`https://idg-sonarqube.aksorn.com`) — requires company VPN/network\n- A SonarQube user token (see setup below)\n\n---\n\n## Shared HTTP server setup (recommended for teams)\n\nRun once on any machine on your internal network. Teammates just add a URL to Cursor — no installation required on their end.\n\n### 1. Run the server (admin only)\n\n```bash\n# On the shared machine:\ncd sonarqube-mcp-server\nnpm install && npm run build\n\n# Set env vars and start\nSONAR_HOST_URL=https://idg-sonarqube.aksorn.com \\\nSONAR_TOKEN=<service-account-token> \\\nSONAR_PROJECT_KEY_PREFIX=vibe \\\nSONAR_AUTO_CREATE_PROJECTS=true \\\nMCP_HTTP_PORT=3333 \\\nnpm run start:http\n```\n\nOptional settings:\n```bash\nMCP_HTTP_PORT=3333       # port to listen on (default: 3333)\nMCP_HTTP_HOST=0.0.0.0    # bind address (default: 0.0.0.0)\nMCP_API_KEY=secret123    # optional — require this key from all clients\nSONAR_PROJECT_KEY_FIXED=vibe:some-existing-app   # fallback for single-app setups\nSONAR_PROJECT_KEY_PREFIX=vibe                    # prefix for derived keys like vibe:my-app\nSONAR_AUTO_CREATE_PROJECTS=true                  # allow onboarding of new apps\nSONAR_SCANNER_CLI_PATH=sonar-scanner             # scanner binary for run_scan\nCONTENT_GATE_URL=http://localhost:3000   # enables Content Gate tools\n```\n\n> **Use a SonarQube service account token**, not a personal token — so it doesn't expire when someone leaves.\n> The Docker image includes SonarScanner CLI for the built-in `run_scan` tool.\n> The server auto-loads a local `.env` file from its working directory too, so Docker deployments can use `--env-file .env` or mount `/app/.env`.\n\n### 2. Keep it running (use PM2 or systemd)\n\n```bash\nnpm install -g pm2\npm2 start npm --name sonarqube-mcp -- run start:http\npm2 save && pm2 startup\n```\n\n### 3. What teammates add to Cursor\n\nEach teammate adds **one URL** to their `.cursor/mcp.json` — nothing to install:\n\n```json\n{\n  \"mcpServers\": {\n    \"sonarqube\": {\n      \"url\": \"http://YOUR_SERVER_IP:3333/mcp\"\n    }\n  }\n}\n```\n\nIf `MCP_API_KEY` is set on the server:\n```json\n{\n  \"mcpServers\": {\n    \"sonarqube\": {\n      \"url\": \"http://YOUR_SERVER_IP:3333/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer secret123\"\n      }\n    }\n  }\n}\n```\n\nThen `Cmd+Shift+P` → **MCP: Restart All Servers** — done.\n\n---\n\n## Local stdio setup (individual / offline)\n\n```bash\n# From the sonarqube-mcp-local-server repo root:\ncd sonarqube-mcp-server\nnpm install\nnpm run build\n```\n\n### 2. Get a SonarQube token\n\n1. Open `https://idg-sonarqube.aksorn.com` (must be on company network/VPN)\n2. Click your avatar → **My Account** → **Security**\n3. Under **Generate Tokens**, enter a name (e.g. `cursor-mcp`) and click **Generate**\n4. Copy the token — you won't see it again\n\n### 3. Configure Cursor\n\nCreate or edit `.cursor/mcp.json` in your project root:\n\n```json\n{\n  \"mcpServers\": {\n    \"sonarqube-local\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/sonarqube-mcp-server/dist/index.js\"],\n      \"env\": {\n        \"SONAR_HOST_URL\": \"https://idg-sonarqube.aksorn.com\",\n        \"SONAR_TOKEN\": \"YOUR_TOKEN_HERE\",\n        \"SONAR_PROJECT_KEY_PREFIX\": \"vibe\",\n        \"SONAR_AUTO_CREATE_PROJECTS\": \"true\",\n        \"SONAR_MAX_ISSUES\": \"50\"\n      }\n    }\n  }\n}\n```\n\n> Replace `/absolute/path/to/sonarqube-mcp-server` with the real path on your machine.\n> On macOS this is typically `/Users/YOUR_NAME/Documents/GitHub/sonarqube-mcp-local-server/sonarqube-mcp-server`\n\n### 4. Activate in Cursor\n\n`Cmd+Shift+P` → **MCP: Restart All Servers**\n\nYou should see `sonarqube-local` with SonarQube project, scan, and issue tools in Cursor Settings → MCP.\n\n> `run_scan` requires SonarScanner CLI in local stdio mode. If `sonar-scanner` is not installed, the tool falls back to Docker when Docker is available. The read-only SonarQube tools still work without either scanner.\n\n---\n\n## Usage\n\n### Check code quality\n\nJust say it naturally in Cursor chat:\n\n> \"Check my code\"\n> \"Are there any security issues?\"\n> \"What's failing the quality gate?\"\n\nFor multi-app use, the AI should:\n\n1. call `find_projects` if the correct project is not obvious\n2. call `ensure_project` if the app has no SonarQube project yet\n3. call `run_scan` to upload a fresh analysis\n4. call `check_code` to get the current issues\n5. fix issues in the repo\n6. call `run_scan` again\n7. call `check_code` again to confirm the result\n\nThe AI should prioritize BLOCKER and CRITICAL issues first, then MAJOR, then MINOR.\n\n### Submit for governance review\n\n> \"Submit my code for content gate review\"\n> \"Run the content gate scan on the src/ directory\"\n\nThe AI will ZIP your code, submit it, wait for the scan, and report the verdict.\n\n---\n\n## Optional: Content Gate adapter\n\nTo enable the governance tools, add to your `mcp.json` env:\n\n```json\n\"CONTENT_GATE_URL\": \"http://localhost:3000\",\n\"CONTENT_GATE_TOKEN\": \"your-content-gate-token\"\n```\n\nThis requires a reachable Content Gate service.\n\n---\n\n## Testing without VPN (mock mode)\n\nTo test the full AI → MCP → fix workflow without needing VPN access, add to your `mcp.json` env:\n\n```json\n\"SONAR_MOCK\": \"true\"\n```\n\nThis returns realistic fake issues so you can validate the Cursor integration works before connecting to the real SonarQube instance. Remove this line when on the company network.\n\n---\n\n## Environment variables reference\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `SONAR_HOST_URL` | yes | — | SonarQube URL. Fallback: `SONARQUBE_URL` |\n| `SONAR_TOKEN` | yes | — | SonarQube user token. Fallback: `SONARQUBE_TOKEN` |\n| `SONAR_PROJECT_KEY_FIXED` | no | derived from repo name or prefix | Fallback project key for single-app setups |\n| `SONAR_PROJECT_KEY_PREFIX` | no | `vibe` | Prefix used when deriving per-app project keys |\n| `SONAR_AUTO_CREATE_PROJECTS` | no | `false` | If `true`, `ensure_project` and `check_code` may create missing SonarQube projects |\n| `SONAR_QUALITY_GATE_NAME` | no | SonarQube default gate | If set, projects created by this MCP are automatically assigned to this quality gate |\n| `SONAR_ORGANIZATION` | no | — | SonarCloud org slug (not needed for self-hosted) |\n| `SONAR_MAX_ISSUES` | no | `50` | Max issues returned per tool call |\n| `SONAR_SCANNER_CLI_PATH` | no | `sonar-scanner` | Scanner binary used by `run_scan` |\n| `SONAR_SCANNER_DOCKER_IMAGE` | no | `sonarsource/sonar-scanner-cli` | Legacy Docker fallback image if `sonar-scanner` is not installed |\n| `SONAR_SCANNER_WAIT_TIMEOUT_MS` | no | `180000` | Max time `run_scan` waits for SonarQube compute task completion |\n| `SONAR_SCANNER_POLL_INTERVAL_MS` | no | `3000` | Poll interval while waiting for SonarQube compute task completion |\n| `SONAR_MOCK` | no | — | Set to `true` to return fake issues (for testing) |\n| `CONTENT_GATE_URL` | no | — | Enables Content Gate tools when set (e.g. `http://localhost:3000`) |\n| `CONTENT_GATE_TOKEN` | no | — | Auth token for the Content Gate service |\n| `MCP_HTTP_PORT` | no | `3333` | Port for HTTP server mode (`npm run start:http`) |\n| `MCP_HTTP_HOST` | no | `0.0.0.0` | Bind address for HTTP server mode |\n| `MCP_API_KEY` | no | — | If set, all HTTP clients must pass this as a Bearer token |\n\n---\n\n## Development\n\n```bash\n# Run without building (uses tsx)\nnpm run dev\n\n# Type-check only\nnpm run typecheck\n\n# Build to dist/\nnpm run build\n```\n\n---\n\n## Troubleshooting\n\n**\"sonarqube-local\" doesn't appear in Cursor**\n- Check the `args` path in `mcp.json` is absolute and correct\n- Run `npm run build` and confirm `dist/index.js` exists\n\n**Tools return \"Cannot reach SonarQube\"**\n- You must be on company VPN or internal network\n- Verify with: `curl -u \"YOUR_TOKEN:\" https://idg-sonarqube.aksorn.com/api/system/status`\n\n**`run_scan` fails**\n- Ensure SonarScanner CLI is installed on the MCP host:\n  `sonar-scanner --version`\n- If you rely on the Docker fallback locally, ensure Docker is installed and running\n- Check that the SonarQube project exists or use `ensure_project` first\n\n**`check my code` uses the wrong app**\n- Search first with `find_projects`\n- Pass the returned `projectKey` into `check_code`\n- For new apps, call `ensure_project` before the first scan\n\n**Tools return \"AUTH_FAILED\"**\n- Your token has expired or was deleted — generate a new one (step 2 above)\n\n**`submit_scan` fails with \"DIRECTORY_NOT_FOUND\"**\n- Pass an absolute path to `directory`, or ensure `cwd` is your project root\n\n**`minify_project` writes nothing useful**\n- The tool minifies `.js`, `.css`, and `.html` files and compresses JPEG, PNG, WebP, AVIF, and TIFF images\n- GIF and SVG are copied unchanged; `node_modules`, `.git`, and existing `dist/` folders are skipped\n- Run it after `check_code`, never before `run_scan`\n\n**Content Gate tools not appearing**\n- `CONTENT_GATE_URL` must be set in `mcp.json` for these tools to register\n- the Content Gate service must be running at that URL\n","readmeFilename":"README.md"}