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.

bash
cd QualityGraph/mcp
npm install
npm run build

That 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.

VariableMeaning
QG_TOKENRequired. An API token, or a session JWT (which expires).
QG_SERVEROptional. Defaults to this installation. Must be a bare origin, not a sub-path.
QG_ORG_IDOptional. Pins a default organization. If unset and you belong to exactly one, that one is used.

3. Point your client at it

Claude Code

bash
claude mcp add qualitygraph -e QG_TOKEN=qg_xxxx -- node /absolute/path/to/QualityGraph/mcp/dist/index.js

Claude Desktop

Add to claude_desktop_config.json:

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:

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 token
  • list_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 bands
  • get_coverage_matrixRepositories × test-type coverage matrix
  • get_org_analyticsAnalytics summary and trends
  • get_org_recommendationsGrouped, actionable QA recommendations
  • get_ci_wasteRedundant, slow and flaky CI spend
  • get_quality_gatesQuality-gate configuration

Repositories

  • list_repositoriesRepositories (search / page / limit)
  • get_repositoryOne repository's full detail
  • get_repository_healthHealth score with weighted breakdown
  • get_repository_coverageCoverage by test type
  • get_repository_trendsTime-series trends

Pull requests

  • list_pull_requestsPRs for an org (status / risk / repo filters)
  • get_high_risk_prsThe highest-risk open PRs
  • get_pull_requestOne PR's detail
  • get_pr_riskRisk score and contributing factors
  • get_pr_test_gapsChanged code lacking test coverage
  • list_flaky_testsFlaky tests across an org, ranked

Test management

  • list_test_casesTest cases (folder / tag / priority / status)
  • list_test_runsTest runs
  • list_journeysUser journeys
  • list_releasesReleases

Troubleshooting

The client shows no tools
Check the path in your config is absolute and that dist/index.js exists — it only appears after npm 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 call list_organizations and 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:

bash
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