npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

testgraph-mcp

v0.1.21

Published

MCP server: TestGraph test nodes ↔ git/code changes (stdio, Cursor-compatible)

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-mcp

Output: 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: after npm install testgraph-mcp it is under node_modules/testgraph-mcp/dist/cli.cjs inside some project; or clone/build this repo and point at mcp-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 set WORKSPACE_ROOT in env).

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:build from the TestGraph repo whenever you change MCP code, then fully quit and reopen Claude Desktop.
  • Keep testgraph-mcp on Zod 3 (see mcp-server/package.json); Zod 4 breaks tool calls with the official MCP SDK (keyValidator._parse errors).

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. Use http://127.0.0.1:3000 for local dev.
  • WORKSPACE_ROOT: absolute git root for testgraph_git_changed_files / testgraph_impact_from_git. Omit if you pass that path as the last element of args after the package (see options A–D below).
  • TESTGRAPH_AUTH_TOKEN: raw key (tgk_…), or ApiKey tgk_…, or Bearer <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)

  1. From mcp-server/ (this package root), bump version when you release, then publish:

    cd mcp-server
    npm run build
    npm publish --access public

    For a scoped private package (e.g. @yourcompany/testgraph-mcp), use npm publish --access restricted and ensure coworkers are logged in to the registry that hosts it.

  2. Share a single Claude / Cursor snippet. Coworkers merge testgraph into their existing mcpServers and only edit WORKSPACE_ROOT (and TESTGRAPH_URL / TESTGRAPH_AUTH_TOKEN if 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 @latest if you always want newest.

  3. Requirements on each machine: Node 18+, npx on PATH, and network access to the npm registry (and to TESTGRAPH_URL).

  4. Git workspace: WORKSPACE_ROOT must be the git root of the app you run git diff against. Omit the second args entry when using WORKSPACE_ROOT (the server reads it from env).

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:build

Each 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_scenariostestgraph_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 dev in the main project), default http://127.0.0.1:3000, or a deployed URL in TESTGRAPH_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.21testgraph_sync_test_cases supports deleteMissing (API: POST .../test-cases/sync). New tools testgraph_reconcile_test_cases_from_suite (graph → TMS full align) and testgraph_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.json lists README.md in files, adds repository / 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.version aligned for publish (includes prior README refresh: TESTGRAPH_AUTH_TOKEN, full tools list, agent workflow pointer).
  • 0.1.1 — Suite hierarchy (parentSuiteId on 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 800

Tools

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/projectsuserApproved. | | testgraph_update_project | PATCH /api/projects/:iduserApproved. | | testgraph_delete_project | DELETE /api/projects/:iduserApproved. | | testgraph_list_team_members | GET /api/projects/:projectId/team-members. | | testgraph_create_team_member | POST .../team-membersuserApproved. | | testgraph_update_team_member | PATCH .../team-members/:iduserApproved. | | testgraph_delete_team_member | DELETE .../team-members/:iduserApproved. |

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/:iduserApproved. | | testgraph_delete_suite | DELETE /api/suites/:id (fails if child suites exist) — userApproved. | | testgraph_create_nodes | Batch POST .../nodesuserApproved. | | testgraph_delete_nodes | Batch DELETE /api/nodes/:iduserApproved. | | testgraph_create_edges | Batch POST .../edgesuserApproved. | | testgraph_update_edges | Batch PATCH /api/edges/:iduserApproved. | | testgraph_delete_edges | Batch DELETE /api/edges/:iduserApproved. | | testgraph_create_code_mapping | POST .../code-mappingsuserApproved. Also recomputes the node’s codeReference (inspector “Code reference”) from all mappings on that node. | | testgraph_delete_code_mapping | DELETE /api/code-mappings/:iduserApproved. 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/deleteuserApproved. |

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/:iduserApproved. | | testgraph_delete_test_case | DELETE /api/test-cases/:iduserApproved. | | testgraph_sync_test_cases | POST /api/suites/:suiteId/test-cases/syncuserApproved. 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-plansuserApproved. | | testgraph_update_test_plan | PATCH /api/test-plans/:iduserApproved. | | testgraph_delete_test_plan | DELETE /api/test-plans/:iduserApproved. | | 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/runsuserApproved. | | testgraph_update_test_run | PATCH /api/test-runs/:iduserApproved. | | testgraph_update_run_item | PATCH /api/test-run-items/:iduserApproved. | | testgraph_update_step_result | PATCH /api/test-run-step-results/:iduserApproved. |

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 mcp

Builds the workspace package and starts stdio (waits for MCP client).

Claude Desktop: tools list but calls fail (“Tool execution failed”)

  1. Use the bundled CLI with a direct node path (see “Recommended Claude Desktop config” above). npx -y file:… is a common cause of “tools visible but every call fails” (extra process, wrong cwd, or dependency resolution in the npx cache).
  2. Rebuild after any code changenpm run mcp:build, then fully quit and reopen Claude Desktop.
  3. Claude often sends null for optional tool args. This package uses .nullish() so null is accepted.
  4. testgraph_git_changed_files / testgraph_impact_from_git need a repo root — pass it as the second args entry after cli.cjs, or set WORKSPACE_ROOT in env, or pass workspaceRoot on the tool call.
  5. Run testgraph_ping first — it prints argv, cwd, env, and GET /api/mappings. Check Help → Show logs if needed.
  6. TestGraph must be runningcurl your TESTGRAPH_URL/api/mappings.
  7. 401 / 403 on API calls — set TESTGRAPH_AUTH_TOKEN (API key or Bearer JWT) to match your deployment.
  8. 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 testgraph enabled once.