MCP server
Ask Claude, Codex or any other MCP client about your QA data in plain language — “which open PRs are risky?”, “where is coverage worst?”, “what is flaky this week?” The server is a thin, read-only wrapper over the same REST API the dashboard uses.
Read-only by design
Every tool is a GET. Nothing an agent does through this server can change your data. The backend enforces organization membership on each request, so a token only ever sees its own organizations.
1. Build the server
The server ships in the repository and runs locally on your machine. It needs Node.js 18 or newer.
cd QualityGraph/mcp
npm install
npm run buildThat produces dist/index.js. Note its absolute path — the client configuration below needs it.
2. Create a token
Create an API token under Settings → API tokens. Tokens start with qg_ and do not expire. If you have already run qg login, the server reuses those credentials from ~/.qualitygraph/config.json and you can skip this step.
| Variable | Meaning |
|---|---|
| QG_TOKEN | Required. An API token, or a session JWT (which expires). |
| QG_SERVER | Optional. Defaults to this installation. Must be a bare origin, not a sub-path. |
| QG_ORG_ID | Optional. Pins a default organization. If unset and you belong to exactly one, that one is used. |
3. Point your client at it
Claude Code
claude mcp add qualitygraph -e QG_TOKEN=qg_xxxx -- node /absolute/path/to/QualityGraph/mcp/dist/index.jsClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"qualitygraph": {
"command": "node",
"args": ["/absolute/path/to/QualityGraph/mcp/dist/index.js"],
"env": {
"QG_TOKEN": "qg_xxxxxxxxxxxx"
}
}
}
}Codex
Add to ~/.codex/config.toml:
[mcp_servers.qualitygraph]
command = "node"
args = ["/absolute/path/to/QualityGraph/mcp/dist/index.js"]
env = { QG_TOKEN = "qg_xxxxxxxxxxxx" }Cursor and other MCP clients work the same way: run node dist/index.js over stdio with QG_TOKEN in the environment.
Available tools
Twenty-four tools, all returning the API’s JSON response. Org-scoped tools take an optional orgId; omit it to use the resolved default.
Account
whoamiThe authenticated user behind the tokenlist_organizationsOrganizations this token can access, with ids
Organization
get_org_dashboardQA command-center snapshot (repo count, health, KPIs)get_org_healthAggregate org health score and bandsget_coverage_matrixRepositories × test-type coverage matrixget_org_analyticsAnalytics summary and trendsget_org_recommendationsGrouped, actionable QA recommendationsget_ci_wasteRedundant, slow and flaky CI spendget_quality_gatesQuality-gate configuration
Repositories
list_repositoriesRepositories (search / page / limit)get_repositoryOne repository's full detailget_repository_healthHealth score with weighted breakdownget_repository_coverageCoverage by test typeget_repository_trendsTime-series trends
Pull requests
list_pull_requestsPRs for an org (status / risk / repo filters)get_high_risk_prsThe highest-risk open PRsget_pull_requestOne PR's detailget_pr_riskRisk score and contributing factorsget_pr_test_gapsChanged code lacking test coveragelist_flaky_testsFlaky tests across an org, ranked
Test management
list_test_casesTest cases (folder / tag / priority / status)list_test_runsTest runslist_journeysUser journeyslist_releasesReleases
Troubleshooting
- The client shows no tools
- Check the path in your config is absolute and that
dist/index.jsexists — it only appears afternpm run build. - Every call returns 401
- The token is missing, mistyped or a session JWT that has expired. Create a fresh API token under Settings.
- Tools ask for an organization id
- You belong to more than one organization. Set
QG_ORG_ID, or calllist_organizationsand pass the id explicitly.
To check the server without a client, pipe a handshake into it — diagnostics go to stderr, so stdout stays valid protocol:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
| QG_TOKEN=qg_xxxx node dist/index.js