# mcp-sonarqube-launcher

Node.js **stdio launcher** for a **SonarQube MCP server** shipped as a **`.jar`** (runs `java -jar …`). Publish it to npm so teams can run **`npx mcp-sonarqube-launcher`** with env only, or ship the JAR under **`vendor/`** so consumers do not need a separate path.

---

## See also (sibling projects)

| Project | Purpose |
|---------|---------|
| **GitHub Enterprise MCP launcher** | [mcp-github-enterprise-launcher](https://github.com/Wasim-Shaikh25/mcp-github-enterprise-launcher) — same pattern for a **`github-mcp-server`** binary. |
| **Jira MCP** | npm [`jira-mcp-oauth`](https://www.npmjs.com/package/jira-mcp-oauth) — full MCP server for Jira. |
| **Confluence MCP** | npm [`confluence-sso-mcp`](https://www.npmjs.com/package/confluence-sso-mcp) — full MCP server for Confluence. |

---

## Prerequisites

| Requirement | Notes |
|-------------|--------|
| **Node.js 18+** | Runs this launcher. |
| **Java** | **`java`** on `PATH` or **`JAVA_HOME`** set—the launcher does not embed a JRE. |
| **SonarQube MCP JAR** | Built separately. This package spawns **`java -jar`** unless you rely on **`vendor/`**. |
| **`SONARQUBE_URL`**, **`SONARQUBE_TOKEN`**, **`STORAGE_PATH`** | Usually required by the upstream JAR—set in MCP **`env`**. |

---

## Quick start (end users)

### A — JAR bundled in npm (`vendor/`)

After publish includes **`vendor/sonarqube-mcp-server.jar`**:

```json
"sonarqube": {
  "command": "npx",
  "args": ["--yes", "mcp-sonarqube-launcher"],
  "env": {
    "SONARQUBE_URL": "https://sonar.mycompany.com/",
    "SONARQUBE_TOKEN": "<secret>",
    "STORAGE_PATH": "C:\\\\path\\\\to\\\\storage"
  }
}
```

No **`SONARQUBE_MCP_JAR`** when the bundled file is present.

### B — JAR only on disk

```json
"env": {
  "SONARQUBE_MCP_JAR": "C:\\\\tools\\\\sonarqube-mcp-server\\\\build\\\\libs\\\\sonarqube-mcp-server.jar",
  "SONARQUBE_URL": "https://sonar.mycompany.com/",
  "SONARQUBE_TOKEN": "<secret>",
  "STORAGE_PATH": "C:\\\\path\\\\to\\\\storage"
}
```

---

## Maintainer workflow

| Step | Command |
|------|---------|
| Copy JAR into **`vendor/`** | `node scripts/bundle-sonarqube.mjs C:\path\to\sonarqube-mcp-server.jar` |
| Verify | `node scripts/verify-bundle.mjs` (part of **`prepublishOnly`**) |
| Dry pack without JAR | `set SKIP_BUNDLE_CHECK=1` then **`npm pack`** |
| Smoke test | Set **`SONARQUBE_TOKEN`** (and URL/storage as needed), then **`npm run smoke-test`** |
| Publish | `npm publish --access public` |

**Git:** **`vendor/*.jar`** is **gitignored**; **`npm publish`** still includes it if the file exists when you run **`npm pack`** / **`npm publish`**.

---

## Environment

| Variable | Description |
|----------|-------------|
| `SONARQUBE_MCP_JAR` | Overrides bundled **`vendor/sonarqube-mcp-server.jar`**. |
| `JAVA_BIN` | Java executable (defaults to **`java`** or **`JAVA_HOME/bin/java`**). |
| `SONARQUBE_JAVA_OPTS` | Space-separated JVM flags **before** `-jar` (e.g. `-Xmx512m`). |
| `SONARQUBE_URL`, `SONARQUBE_TOKEN`, `STORAGE_PATH` | Passed through to the JVM process (as required by your Sonar MCP build). |

---

## npm scripts

| Script | Purpose |
|--------|---------|
| `npm run bundle` | Runs **`bundle-sonarqube.mjs`** (argv or **`SONARQUBE_MCP_JAR_SRC`**). |
| `npm run smoke-test` | Short-lived spawn test; set **`SONARQUBE_TOKEN`** first. |

---

## Troubleshooting

| Symptom | What to do |
|---------|------------|
| **No JAR found** | Run **`npm run bundle`** or set **`SONARQUBE_MCP_JAR`**. |
| **`java` not found** | Install a JRE/JDK and ensure **`JAVA_HOME`** or **`PATH`** is set. |
| **`prepublishOnly` fails** | Add **`vendor/sonarqube-mcp-server.jar`**, or use **`SKIP_BUNDLE_CHECK=1`** for dry runs only. |
| **`npm ERR! EBUSY` / `rename` … `sonarqube-mcp-server.jar` (Windows)** | Usually the JVM had the **`vendor/`** JAR open while **`npx`** tried to update the cache. **v1.1.1+** copies the bundled JAR to **`%TEMP%`** before `java -jar`, so **`vendor/`** is not locked. Upgrade to **`mcp-sonarqube-launcher@1.1.1`**, or quit Cursor/Java and clear `%LocalAppData%\npm-cache\_npx\…` for this package. |

---

## License

MIT
