testgraph-mcp
v0.1.21
Published
MCP server: TestGraph test nodes ↔ git/code changes (stdio, Cursor-compatible)
Maintainers
Readme
testgraph-mcp
MCP server (stdio, Cursor- and Claude Desktop–compatible) that talks to a running TestGraph web app: projects, suites, Gherkin graphs, TMS test cases, plans, runs, code mappings, and git-based trace helpers.
The npm package ships the bundled CLI only (dist/cli.cjs). Optional git workspace root: second argument after cli.cjs in args, or WORKSPACE_ROOT in env.
Set up your project (skill + Cursor rules)
This package provides MCP tools only. In every repository where you configure testgraph-mcp, you should also add the upstream skill and (if you use Cursor) the acceptance rule from the TestGraph repo. They are not bundled in the npm package—copy them from GitHub or from a clone of the monorepo so agents follow the same workflows: suite → feature → scenarios, Gherkin merge patterns, single root + shared Background per feature, code mappings, git impact, and confirmation before mutating tools.
1. Agent skill (any editor / any MCP client)
Vendor-neutral Markdown: use agent skills, IDE rules, project instructions, or paste into a system prompt.
| Resource | Link |
|----------|------|
| Browse | github.com/sosagraviel/TestGraph/blob/main/skill/testgraph.md |
| Raw | raw.githubusercontent.com/sosagraviel/TestGraph/main/skill/testgraph.md |
| Monorepo path | skill/testgraph.md (when this repo is cloned) |
Suggested location in your app repo: e.g. .cursor/skills/testgraph/SKILL.md, docs/agents/testgraph.md, or your team’s knowledge base—whatever your tooling loads.
2. Cursor project rule (Cursor only)
Keeps UI acceptance work aligned with TestGraph MCP: hierarchy under the area suite, child feature suiteId for merges and test cases, and one root + one Background per feature.
| Resource | Link |
|----------|------|
| Browse | github.com/sosagraviel/TestGraph/blob/main/src/.cursor/rules/testgraph-mcp-acceptance.mdc |
| Raw | raw.githubusercontent.com/sosagraviel/TestGraph/main/src/.cursor/rules/testgraph-mcp-acceptance.mdc |
| Monorepo path | src/.cursor/rules/testgraph-mcp-acceptance.mdc (when this repo is cloned) |
Required location in your app repo: .cursor/rules/testgraph-mcp-acceptance.mdc (create .cursor/rules/ if needed). Refresh or restart Cursor after adding the file.
The MCP server also emits shorter in-protocol instructions to the client; the skill and rule are the extended playbook. See Agent-oriented workflows (server instructions) later in this file.
Environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| TESTGRAPH_URL | No | Base URL of the TestGraph app. Default: http://127.0.0.1:3000. No trailing slash required. |
| TESTGRAPH_AUTH_TOKEN | No | Sent as Authorization on every API request when set. Use when the deployment requires login. Accepted forms: raw API key (tgk_…), ApiKey <key>, Bearer <jwt>, or raw JWT string. |
| WORKSPACE_ROOT | No* | Absolute path to the git repository root used by testgraph_git_changed_files and testgraph_impact_from_git. Required unless you pass that path as the last CLI arg after the bundled cli.cjs, or pass workspaceRoot / projectId+paths only on tools that do not need git. |
Many tools also accept an optional per-call testgraphUrl argument; it overrides TESTGRAPH_URL for that request only.
Build (from monorepo root)
npm run mcp:build
# or
npm run build --workspace=testgraph-mcpOutput: mcp-server/dist/cli.cjs — a single bundled file (esbuild) with a shebang. Prefer this for Claude Desktop instead of npx file:…, which often breaks tool execution (spawn/node_modules resolution).
Recommended Claude Desktop config (most reliable)
Where to edit (macOS): ~/Library/Application Support/Claude/claude_desktop_config.json
Merge a testgraph entry into the existing "mcpServers" object (do not remove your other servers unless you are debugging).
Use node on PATH (or an absolute path to node if your MCP host does not inherit your shell PATH—on macOS run which node and paste it as command) and the bundled cli.cjs from a built install (no npx for this pattern):
{
"mcpServers": {
"testgraph": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/testgraph-mcp/dist/cli.cjs",
"/ABSOLUTE/PATH/TO/YOUR_APP_GIT_REPO"
],
"env": {
"TESTGRAPH_URL": "http://127.0.0.1:3000"
}
}
}
}cli.cjs: afternpm install testgraph-mcpit is undernode_modules/testgraph-mcp/dist/cli.cjsinside some project; or clone/build this repo and point atmcp-server/dist/cli.cjs.- Second arg: git root for
testgraph_git_changed_files/testgraph_impact_from_git—typically your product repo; you can use the TestGraph repo while experimenting (or omit this arg and setWORKSPACE_ROOTinenv).
Add authentication when your server is not open anonymously:
"env": {
"TESTGRAPH_URL": "https://your-testgraph.example.com",
"TESTGRAPH_AUTH_TOKEN": "ApiKey tgk_xxxxxxxx"
}- Run
npm run mcp:buildfrom the TestGraph repo whenever you change MCP code, then fully quit and reopen Claude Desktop. - Keep
testgraph-mcpon Zod 3 (seemcp-server/package.json); Zod 4 breaks tool calls with the official MCP SDK (keyValidator._parseerrors).
Cursor / MCP client config
Cursor: configure MCP servers in your user/project MCP settings (UI or JSON, depending on Cursor version)—same command / args / env shape as below. User-level JSON is often ~/.cursor/mcp.json (merge testgraph into the existing "mcpServers" object).
Full example: npx + pinned package + TESTGRAPH_URL, WORKSPACE_ROOT, TESTGRAPH_AUTH_TOKEN
Typical setup when TestGraph runs on a host (local or deployed) and needs auth, and git tools should use a fixed repo root:
{
"mcpServers": {
"testgraph": {
"command": "npx",
"args": ["-y", "[email protected]"],
"env": {
"TESTGRAPH_URL": "https://your-testgraph.example.com",
"WORKSPACE_ROOT": "/ABSOLUTE/PATH/TO/YOUR_APP_GIT_REPO",
"TESTGRAPH_AUTH_TOKEN": "tgk_xxxxxxxx"
}
}
}
}TESTGRAPH_URL: no trailing slash. Usehttp://127.0.0.1:3000for local dev.WORKSPACE_ROOT: absolute git root fortestgraph_git_changed_files/testgraph_impact_from_git. Omit if you pass that path as the last element ofargsafter the package (see options A–D below).TESTGRAPH_AUTH_TOKEN: raw key (tgk_…), orApiKey tgk_…, orBearer <jwt>. Treat it like a password—do not commit it; rotate if it leaks.
A) npx + local package (no npm publish) — like file: install
After npm run mcp:build, point npx at this folder. The last arg is your app repo (git root), same pattern as filesystem’s directory argument:
{
"mcpServers": {
"testgraph": {
"command": "npx",
"args": [
"-y",
"file:/ABSOLUTE/PATH/TO/TestGraph/mcp-server",
"/ABSOLUTE/PATH/TO/YOUR_APP_REPO"
],
"env": {
"TESTGRAPH_URL": "http://127.0.0.1:3000"
}
}
}
}With a workspace root argument you usually do not need WORKSPACE_ROOT in env.
B) node + built entry (filesystem-style, fully explicit)
{
"mcpServers": {
"testgraph": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/TestGraph/mcp-server/dist/cli.cjs",
"/ABSOLUTE/PATH/TO/YOUR_APP_REPO"
],
"env": {
"TESTGRAPH_URL": "http://127.0.0.1:3000"
}
}
}
}C) node + npx binary (explicit npx path when npx is not on the host PATH)
Use the absolute path from which npx on your machine instead of the placeholder.
{
"mcpServers": {
"testgraph": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/npx",
"-y",
"file:/ABSOLUTE/PATH/TO/TestGraph/mcp-server",
"/ABSOLUTE/PATH/TO/YOUR_APP_REPO"
],
"env": {
"TESTGRAPH_URL": "http://127.0.0.1:3000"
}
}
}
}D) After publishing to npm as testgraph-mcp
{
"mcpServers": {
"testgraph": {
"command": "npx",
"args": ["-y", "testgraph-mcp", "/ABSOLUTE/PATH/TO/YOUR_APP_REPO"],
"env": {
"TESTGRAPH_URL": "http://127.0.0.1:3000"
}
}
}
}(Use a scoped name in package.json if testgraph-mcp is taken on the registry.)
For no repo path in args, use WORKSPACE_ROOT in env plus optional TESTGRAPH_AUTH_TOKEN—same shape as the Full example under Cursor / MCP client config (pin testgraph-mcp@… in args if you want a stable version).
Sharing with coworkers (same config for everyone)
Machine-specific absolute paths to node, npx, or cli.cjs do not travel to other machines. Use one of these patterns so the only per-person values are WORKSPACE_ROOT (and maybe TESTGRAPH_URL / TESTGRAPH_AUTH_TOKEN).
Option 1 — Publish testgraph-mcp to npm (best for teams)
From
mcp-server/(this package root), bump version when you release, then publish:cd mcp-server npm run build npm publish --access publicFor a scoped private package (e.g.
@yourcompany/testgraph-mcp), usenpm publish --access restrictedand ensure coworkers are logged in to the registry that hosts it.Share a single Claude / Cursor snippet. Coworkers merge
testgraphinto their existingmcpServersand only editWORKSPACE_ROOT(andTESTGRAPH_URL/TESTGRAPH_AUTH_TOKENif they hit a shared deploy):"testgraph": { "command": "npx", "args": ["-y", "[email protected]"], "env": { "TESTGRAPH_URL": "http://127.0.0.1:3000", "WORKSPACE_ROOT": "/ABSOLUTE/PATH/TO/YOUR_APP_GIT_REPO" } }Pin
@0.1.18(or your published version) so the team upgrades deliberately; use@latestif you always want newest.Requirements on each machine: Node 18+,
npxonPATH, and network access to the npm registry (and toTESTGRAPH_URL).Git workspace:
WORKSPACE_ROOTmust be the git root of the app you rungit diffagainst. Omit the secondargsentry when usingWORKSPACE_ROOT(the server reads it fromenv).
See also: examples/claude-desktop.team.json in this folder for a ready-to-merge template.
Option 2 — No publish: shared clone + file: URL
Everyone clones the same TestGraph repo and builds the MCP once:
git clone <your-repo-url> TestGraph
cd TestGraph && npm install && npm run mcp:buildEach person puts their absolute path to mcp-server in config (only the file: path differs):
"testgraph": {
"command": "npx",
"args": [
"-y",
"file:/ABSOLUTE/PATH/TO/TestGraph/mcp-server",
"/ABSOLUTE/PATH/TO/YOUR_APP_GIT_REPO"
],
"env": {
"TESTGRAPH_URL": "http://127.0.0.1:3000"
}
}Or use WORKSPACE_ROOT in env and drop the last args entry, same as Option 1.
file: can be finicky in some clients; Option 1 is usually smoother.
Option 3 — Internal registry (Verdaccio / GitHub Packages / Artifactory)
Publish testgraph-mcp there instead of npmjs.org. Coworkers add .npmrc (registry URL + auth) once; the MCP JSON stays identical to Option 1, only changing the package name if scoped (e.g. @yourorg/testgraph-mcp).
What stays the same vs per developer
| Same for the whole team | Each person sets |
|---------------------------|------------------|
| command + args (e.g. npx + package name) | WORKSPACE_ROOT → their app repo |
| Package version pin (e.g. @0.1.18) | TESTGRAPH_URL if not everyone uses the same host |
| (optional) | TESTGRAPH_AUTH_TOKEN if the instance requires auth (prefer API keys for long-lived setups) |
Everyone still needs the TestGraph web app reachable at TESTGRAPH_URL (local npm run dev, shared deploy, or tunnel).
Agent-oriented workflows (server instructions)
The MCP server registers long-form instructions delivered in-protocol to the client (so models see them without opening this README). They include: agent operating rules (graph model, ID hygiene, read-before-write, code/sync/impact, gherkinText, anti-patterns), auth, the full tool list, the UI acceptance recipe (area suite → feature suite → Gherkin merge per scenario → testgraph_list_scenarios → testgraph_create_test_case), AI export filters, git trace tools, and scenario-id rules. For an even deeper playbook, use Set up your project (skill + Cursor rules) at the top of this README (same themes, more narrative and examples).
Writes: tools that mutate data require userApproved: true in the tool arguments. Set that only after the human explicitly confirmed the change in chat.
Prerequisites
- TestGraph app running (
npm run devin the main project), default http://127.0.0.1:3000, or a deployed URL inTESTGRAPH_URL. - If the instance uses authentication, set
TESTGRAPH_AUTH_TOKEN(see table above). - DB + mappings (
GET /api/mappings) populated as needed for trace features.
Changelog
- 0.1.21 —
testgraph_sync_test_casessupportsdeleteMissing(API:POST .../test-cases/sync). New toolstestgraph_reconcile_test_cases_from_suite(graph → TMS full align) andtestgraph_reconcile_test_cases_from_git_impact(git diff → trace → reconcile each impacted suite). - 0.1.18 — MCP
instructions: expanded agent playbook (mental model, ID hygiene, read-before-write, code/sync/impact,gherkinText, anti-patterns) + skill raw URL. npm:package.jsonlistsREADME.mdinfiles, addsrepository/homepage/bugs, and fixes Markdown tables so npmjs.com can render the README reliably. - 0.1.17 — README: generic MCP config examples (
/ABSOLUTE/PATH/TO/…placeholders); team template and snippet pins aligned with package. - 0.1.14 — Package version bump; README / team example / MCP
server.versionaligned for publish (includes prior README refresh:TESTGRAPH_AUTH_TOKEN, full tools list, agent workflow pointer). - 0.1.1 — Suite hierarchy (
parentSuiteIdon list/create/update suite); scenarios + Gherkin export/merge APIs;testgraph_list_projects,testgraph_list_test_plans,testgraph_list_test_cases,testgraph_list_scenarios,testgraph_export_gherkin,testgraph_merge_gherkin,testgraph_delete_scenario; suite delete blocked when subsuites exist (API). - 0.1.0 — Initial MCP: mappings, git changed files, affected tests, suite/node/edge CRUD, code mappings, node batch updates.
(The npm package page shows the README from the last published version; run npm publish from mcp-server/ after bumping version to refresh it.)
Pre-publish smoke test (local)
With npm run dev running in the app repo:
# Ping (same probe as testgraph_ping’s fetch)
curl -sS "http://127.0.0.1:3000/api/mappings" | head -c 400
# With auth (example)
# curl -sS -H "Authorization: ApiKey tgk_xxx" "http://127.0.0.1:3000/api/mappings" | head -c 400
# Pick a project id (first project)
PROJECT_ID=$(curl -sS "http://127.0.0.1:3000/api/projects" | node -e "let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{const j=JSON.parse(s);console.log(j.projects?.[0]?.id||'')})")
echo "projectId=$PROJECT_ID"
curl -sS "http://127.0.0.1:3000/api/suites?projectId=${PROJECT_ID}" | head -c 600
# Replace SUITE_ID with a real suite from the JSON above
# curl -sS "http://127.0.0.1:3000/api/suites/SUITE_ID/scenarios" | head -c 800
# curl -sS "http://127.0.0.1:3000/api/suites/SUITE_ID/gherkin" | head -c 800Tools
Summaries match mcp-server/index.ts. userApproved means the tool rejects the call unless userApproved: true (human must have confirmed).
Diagnostics & git
| Tool | Purpose |
|------|--------|
| testgraph_ping | Diagnostics: argv, cwd, env (including whether auth token is set), and GET /api/mappings. |
| testgraph_git_changed_files | git diff --name-only HEAD (staged + unstaged) under workspace root. |
| testgraph_list_code_mappings | GET /api/mappings. |
| testgraph_find_affected_tests | Maps changedFiles to mapped nodes (path match). For full TMS impact use testgraph_tests_for_code_paths or testgraph_impact_from_git. |
| testgraph_tests_for_code_paths | Reverse trace: repo paths → mappings + test cases (POST .../trace/code-to-tests). mode: touch or prefix. |
| testgraph_impact_from_git | Git diff in workspace + code-to-tests trace (touch). |
Projects & team
| Tool | Purpose |
|------|--------|
| testgraph_list_projects | GET /api/projects. |
| testgraph_get_project | GET /api/projects/:projectId. |
| testgraph_create_project | POST /api/projects — userApproved. |
| testgraph_update_project | PATCH /api/projects/:id — userApproved. |
| testgraph_delete_project | DELETE /api/projects/:id — userApproved. |
| testgraph_list_team_members | GET /api/projects/:projectId/team-members. |
| testgraph_create_team_member | POST .../team-members — userApproved. |
| testgraph_update_team_member | PATCH .../team-members/:id — userApproved. |
| testgraph_delete_team_member | DELETE .../team-members/:id — userApproved. |
Suites, nodes, edges, code mappings
| Tool | Purpose |
|------|--------|
| testgraph_list_suites | GET /api/suites (optional projectId, hierarchy via parentSuiteId). |
| testgraph_get_suite | GET /api/suites/:suiteId (nodes, edges, child feature summaries). |
| testgraph_create_suite | POST /api/suites (optional parentSuiteId) — userApproved. |
| testgraph_update_suite | PATCH /api/suites/:id — userApproved. |
| testgraph_delete_suite | DELETE /api/suites/:id (fails if child suites exist) — userApproved. |
| testgraph_create_nodes | Batch POST .../nodes — userApproved. |
| testgraph_delete_nodes | Batch DELETE /api/nodes/:id — userApproved. |
| testgraph_create_edges | Batch POST .../edges — userApproved. |
| testgraph_update_edges | Batch PATCH /api/edges/:id — userApproved. |
| testgraph_delete_edges | Batch DELETE /api/edges/:id — userApproved. |
| testgraph_create_code_mapping | POST .../code-mappings — userApproved. Also recomputes the node’s codeReference (inspector “Code reference”) from all mappings on that node. |
| testgraph_delete_code_mapping | DELETE /api/code-mappings/:id — userApproved. Recomputes or clears codeReference on the node. |
| testgraph_apply_node_updates | Batch PATCH /api/nodes/:id (label, type, position, metadata, scenarioTitle, etc.) — userApproved. |
Scenarios & Gherkin
| Tool | Purpose |
|------|--------|
| testgraph_list_scenarios | GET /api/suites/:suiteId/scenarios (paths, pathNodeIds, scenario id for exports/deletes). |
| testgraph_export_gherkin | GET /api/suites/:suiteId/gherkin (optional scenarioId). |
| testgraph_merge_gherkin | POST .../gherkin/merge (body: gherkinText) — userApproved. |
| testgraph_update_scenario | Delete scenario + merge new Gherkin — userApproved. |
| testgraph_delete_scenario | POST .../scenarios/delete — userApproved. |
Test cases
| Tool | Purpose |
|------|--------|
| testgraph_list_test_cases | GET /api/test-cases (optional suiteId). |
| testgraph_get_test_case | GET /api/test-cases/:id. |
| testgraph_create_test_case | POST /api/test-cases (pathNodeIds from testgraph_list_scenarios) — userApproved. |
| testgraph_update_test_case | PATCH /api/test-cases/:id — userApproved. |
| testgraph_delete_test_case | DELETE /api/test-cases/:id — userApproved. |
| testgraph_sync_test_cases | POST /api/suites/:suiteId/test-cases/sync — userApproved. Optional deleteMissing: remove TMS cases whose path is not in the payload (full replace). |
| testgraph_reconcile_test_cases_from_suite | GET scenarios for suiteId, then sync with deleteMissing so cases match the graph (create/update/delete). — userApproved. |
| testgraph_reconcile_test_cases_from_git_impact | Same git diff + trace as testgraph_impact_from_git, then reconcile each distinct suiteId from the trace. — userApproved, needs WORKSPACE_ROOT. |
Test plans
| Tool | Purpose |
|------|--------|
| testgraph_list_test_plans | GET /api/test-plans (optional projectId). |
| testgraph_get_test_plan | GET /api/test-plans/:planId. |
| testgraph_create_test_plan | POST /api/test-plans — userApproved. |
| testgraph_update_test_plan | PATCH /api/test-plans/:id — userApproved. |
| testgraph_delete_test_plan | DELETE /api/test-plans/:id — userApproved. |
| testgraph_add_plan_items | Add test cases to a plan — userApproved. |
| testgraph_update_plan_item | PATCH plan item (sort order, assignee) — userApproved. |
| testgraph_delete_plan_item | Remove item from plan — userApproved. |
Test runs & execution
| Tool | Purpose |
|------|--------|
| testgraph_list_test_runs | GET /api/test-runs (optional projectId). |
| testgraph_get_test_run | GET /api/test-runs/:runId (items, step results, snapshots). |
| testgraph_create_test_run | POST /api/test-plans/:planId/runs — userApproved. |
| testgraph_update_test_run | PATCH /api/test-runs/:id — userApproved. |
| testgraph_update_run_item | PATCH /api/test-run-items/:id — userApproved. |
| testgraph_update_step_result | PATCH /api/test-run-step-results/:id — userApproved. |
Reports & export
| Tool | Purpose |
|------|--------|
| testgraph_get_project_reports | GET /api/projects/:projectId/reports (aggregated metrics + case list). |
| testgraph_export_test_cases_json | Structured JSON export derived from reports. |
| testgraph_export_test_cases_text | Plain text export grouped by suite. |
| testgraph_export_ai_readable | GET .../reports/ai-export — Markdown + bundle JSON; prefer filtering by suiteIds or testCaseIds so you do not export the whole project by accident. |
Develop from repo root
npm run mcpBuilds the workspace package and starts stdio (waits for MCP client).
Claude Desktop: tools list but calls fail (“Tool execution failed”)
- Use the bundled CLI with a direct
nodepath (see “Recommended Claude Desktop config” above).npx -y file:…is a common cause of “tools visible but every call fails” (extra process, wrongcwd, or dependency resolution in the npx cache). - Rebuild after any code change —
npm run mcp:build, then fully quit and reopen Claude Desktop. - Claude often sends
nullfor optional tool args. This package uses.nullish()sonullis accepted. testgraph_git_changed_files/testgraph_impact_from_gitneed a repo root — pass it as the secondargsentry aftercli.cjs, or setWORKSPACE_ROOTinenv, or passworkspaceRooton the tool call.- Run
testgraph_pingfirst — it printsargv,cwd, env, andGET /api/mappings. Check Help → Show logs if needed. - TestGraph must be running —
curlyourTESTGRAPH_URL/api/mappings. - 401 / 403 on API calls — set
TESTGRAPH_AUTH_TOKEN(API key or Bearer JWT) to match your deployment. - If other MCPs show “Could not attach” (e.g. Playwright, Excel), disable or fix them — a broken server can sometimes make the whole MCP experience flaky; test with only
testgraphenabled once.
