|
| 1 | +# @testplanit/mcp-server |
| 2 | + |
| 3 | +## 0.1.0 |
| 4 | + |
| 5 | +### Minor Changes |
| 6 | + |
| 7 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Add execution + session read tools (Phase 7): |
| 8 | + - 5 new test-run tools: `testplanit_test_runs_list` (with `statusCounts` inline on every row — D7-06), `testplanit_test_runs_get` (with status rollup), `testplanit_test_runs_cases_list`, `testplanit_test_run_results_list`, `testplanit_test_run_results_get` (with step-level drill-down). |
| 9 | + - 5 new session tools: `testplanit_sessions_list`, `testplanit_sessions_get` (up to 100 sessionResults inline + truncated marker), `testplanit_session_results_list`, `testplanit_session_results_get`, `testplanit_sessions_findings_list` (sessionId / issueId modes). |
| 10 | + - Extend `testplanit_cases_list` with an additive `issueId` filter — enables the killer-app chain `cases_list({issueId}) → test_run_results_list({caseIds})` in two MCP calls (no aggregate helper needed). |
| 11 | + - Total registered tools after Phase 7: 22 (12 from Phase 6 + 10 new). |
| 12 | + - Read-only domain — no write paths added; existing `mode:read` token enforcement (Phase 5) covers all new tools without modification. |
| 13 | + |
| 14 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Initial release: Model Context Protocol server for TestPlanIt. |
| 15 | + - Stdio MCP server invokable via `npx @testplanit/mcp-server`. |
| 16 | + - Authenticates via `TESTPLANIT_API_TOKEN`; supports self-hosted instances via `TESTPLANIT_API_URL`. |
| 17 | + - Token validation on startup with clear error and clean exit on failure. |
| 18 | + - Single `whoami` tool returns the authenticated user and scopes (debug). Production tool catalog lands in Phase 6+. |
| 19 | + - Read-only API token flag (`mode:read` scope tag on the existing `ApiToken.scopes` field) enforced symmetrically across REST and MCP. |
| 20 | + - MCP audit attribution (`metadata.source: "mcp"`) derived from `client:mcp` scope tag — unforgeable by request-time headers. |
| 21 | + |
| 22 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Add new read tools — three new milestones-domain tools and three new `cases_list` filter dimensions: |
| 23 | + - `testplanit_milestones_list` — list milestones scoped to a project, with **pooled `statusCounts` rollup** (merged across linked test runs AND linked sessions in a single response) inline on every row, plus `untested + total` (counts SUM to total). Filters: `isCompleted`, `isStarted`, `milestoneTypeId`, `createdById`, `from`/`to` (createdAt range), `parentId` (`null` = root-only, `number` = direct children of, omitted = all). Each row also carries `directChildrenCount`, `commentCount`, and `totalDescendants` (computed via a single batched recursive CTE per page through a new host endpoint). Cost model: at most 5 backend round trips per page — never per-row. |
| 24 | + - `testplanit_milestones_get` — fetch a single milestone with denormalized header, plain-text `note` and `docs` (ProseMirror), pooled `statusCounts`, and three inlined linked arrays — `linkedTestRuns` (cap **250** — wider than the standard 100 to cover the dominant fan-out), `linkedSessions` (cap 100), `children` (cap 100, 1-level deep with each child carrying `totalDescendants`). Per-array `truncated.<key>: true` overflow stamps. |
| 25 | + - `testplanit_milestone_types_list` — list milestone types assigned to a project via the `MilestoneTypesAssignment` junction. Returns `{items: [{id, name, isDefault}]}` ordered by name; no cursor pagination. |
| 26 | + - `testplanit_cases_list` (extended) — adds `creatorIds: string[]` (array — deliberately wider than `runs_list` / `sessions_list` single-string `createdById`), and `from` / `to` (ISO 8601 createdAt range). Closes the gap _"How many test cases did I write last month?"_. |
| 27 | + |
| 28 | + Total registered tools: **31** (up from 28). All tools are read-only; existing `mode:read` token enforcement covers them without modification. New host endpoint `GET /api/mcp/milestones-descendants` (recursive CTE) is required for the `totalDescendants` denorm — ZenStack RPC has no `$queryRaw` passthrough. |
| 29 | + |
| 30 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Add Phase 8 read tools for the repository + issue surface — six new tools and two extended ones: |
| 31 | + - `testplanit_code_repositories_list` — list the project's code-repository configuration with a derived web URL per provider; the underlying `credentials` column is never selected and the `settings` JSON is stripped to a per-provider public-key allow-list at the mapper boundary. |
| 32 | + - `testplanit_issues_find_by_key` — resolve `(externalKey, externalSystem, projectId)` to an Issue, with multi-match fallback when two integrations of the same provider share an external key in the same project. |
| 33 | + - `testplanit_issues_list` — list issues scoped to a project, filtered by `externalSystem`, `integrationId`, `status`, `externalStatus`. Each row carries `linkedCaseCount` inline (the dominant fan-out — median 6, p95 35 in the dev DB). |
| 34 | + - `testplanit_issues_get` — fetch a single issue with three inlined linked arrays (cases, sessions, test runs) capped at 100 rows each, with per-array `truncated` markers when overflow occurs. |
| 35 | + - `testplanit_issues_list_links` — single dual-mode XOR tool covering all six Issue M:N junctions. Outbound: `{ issueId, target }` over `cases | sessions | sessionResults | testRuns | testRunResults | testRunStepResults`. Inbound: exactly one of `caseId | sessionId | sessionResultId | runId | runResultId | runStepResultId`. |
| 36 | + - `testplanit_repository_case_links_list` — traverse the manual-vs-imported case linkage graph. 3-way XOR over `caseId` (bidirectional via OR clause), `caseAId` (one-way originating), or `caseBId` (one-way destination); optional `linkType` filter (`SAME_TEST_DIFFERENT_SOURCE | DEPENDS_ON`). |
| 37 | + - `testplanit_cases_list` (extended) — adds 7 maintenance filters (`automated`, `source`, `repositoryId`, `hasNeverExecuted`, `staleSinceUpdate`, `updatedAfter`, `updatedBefore`) and 2 row fields (`lastUpdatedAt`, `latestResult`). The `where` literal is now a typed `Prisma.RepositoryCasesWhereInput` so any unknown column or relation accessor trips TS2353 at compile time. |
| 38 | + - `testplanit_cases_get` (extended) — adds inline `codeRepository: { id, name, type, url? } | null` derived from the project's configured code repository. |
| 39 | + |
| 40 | + Total registered tools: 28 (up from 22). All tools are read-only; existing `mode:read` token enforcement covers them without modification. |
| 41 | + |
| 42 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Test-case domain (Phase 6): add 11 production MCP tools. |
| 43 | + - **Cases:** `testplanit_cases_list`, `testplanit_cases_get`, `testplanit_cases_create`, `testplanit_cases_update`, `testplanit_cases_delete`. Cursor pagination, full denormalized detail (folder breadcrumb, custom-fields flat dict, plain-text steps from Tiptap, linked issues + automated tests inline). |
| 44 | + - **Folders:** `testplanit_folders_list` (tree with case counts), `testplanit_folders_get` (breadcrumb + cases summary), `testplanit_folders_create`, `testplanit_folders_update` (rename + reparent), `testplanit_folders_delete` (MCP tool enforces "no cases, no sub-folders" before issuing soft-delete). |
| 45 | + - **Tags + Context:** `testplanit_tags_list` with usage counts (project-scoped when projectId supplied), `testplanit_projects_list` for agent context disambiguation. |
| 46 | + - **Soft-delete invariant:** all delete tools use PATCH update with `isDeleted: true`; never the ZenStack `delete` operation. |
| 47 | + - **Read-only token enforcement:** all write tools inherit Phase 5's `WRITE_HTTP_METHODS` host gate — `mode:read` tokens receive HTTP 403 + `READ_ONLY_TOKEN` and the MCP error mapper surfaces a structured tool error naming the scope. |
| 48 | + |
| 49 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Add write tools for the runs, sessions, and milestones domains (Phase 9): |
| 50 | + - `testplanit_runs_create` — create a test run with optional initial case list |
| 51 | + - `testplanit_runs_update` — update name, state, milestone, tags, and completion status |
| 52 | + - `testplanit_runs_cases_add` — add cases to an existing run |
| 53 | + - `testplanit_test_run_results_create` — submit a pass/fail/blocked result for a run case |
| 54 | + - `testplanit_sessions_create` — create an exploratory test session |
| 55 | + - `testplanit_sessions_update` — update session name, mission, state, milestone, and tags |
| 56 | + - `testplanit_milestones_create` — create a milestone with optional parent nesting |
| 57 | + - `testplanit_milestones_update` — update milestone name, type, note, parent, and completion status |
| 58 | + |
| 59 | +### Patch Changes |
| 60 | + |
| 61 | +- [#289](https://github.com/TestPlanIt/testplanit/pull/289) [`1d711b2`](https://github.com/TestPlanIt/testplanit/commit/1d711b20982bf44f2447be0bf812c86c363e2e79) Thanks [@therealbrad](https://github.com/therealbrad)! - Add Cursor configuration snippet to the README alongside the existing Claude Desktop snippet so npm visitors can wire either MCP-aware client without bouncing to the Docusaurus site. Documentation-only change — no behavior change to the published binary. |
0 commit comments