@smartruns/mcp 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,15 +8,18 @@ function handleError(err) {
8
8
  // Comments in SmartRuns are polymorphic but NOT via Rails-standard commentable_type /
9
9
  // commentable_id, and NOT nested under a parent route. The CommentsController
10
10
  // (app/controllers/comments_controller.rb) drives everything off two flat params,
11
- // `source_type` + `source_id`, validated against Comment::SUPPORTED_SCOPES
12
- // (app/models/comment.rb). The comment body lives on the `text` attribute. Keep this
13
- // enum in sync with Comment::SUPPORTED_SCOPES.
14
- const SOURCE_TYPES = ['test', 'test_plan', 'test_run', 'test_suite', 'spec'];
11
+ // `source_type` + `source_id`, validated server-side against Comment::SUPPORTED_SCOPES
12
+ // (app/models/comment.rb). The comment body lives on the `text` attribute.
13
+ //
14
+ // source_type is intentionally a permissive string, NOT a hardcoded enum: the server is
15
+ // the single source of truth for valid scopes and rejects an unsupported one, so this
16
+ // wrapper never goes stale when a scope is added (e.g. `defect`). Do not re-introduce a
17
+ // client-side enum here — it only duplicates server validation and drifts.
15
18
  const sourceTypeSchema = z
16
- .enum(SOURCE_TYPES)
17
- .describe('Parent entity type the comment belongs to (Comment::SUPPORTED_SCOPES).');
19
+ .string()
20
+ .describe('Parent entity type the comment belongs to — a Comment::SUPPORTED_SCOPES value (currently test, test_plan, test_run, test_suite, spec, defect). Validated server-side; an unsupported scope is rejected by the API.');
18
21
  export function registerCommentTools(server, client) {
19
- server.tool('list_comments', 'List comments on a parent entity (test, test_plan, test_run, test_suite, or spec). Comments are polymorphic: identify the parent with source_type + source_id. Scoped to the current account and project server-side.', {
22
+ server.tool('list_comments', 'List comments on a parent entity (test, test_plan, test_run, test_suite, spec, or defect). Comments are polymorphic: identify the parent with source_type + source_id. Scoped to the current account and project server-side.', {
20
23
  source_type: sourceTypeSchema,
21
24
  source_id: z.number().int().describe('ID of the parent entity the comments belong to'),
22
25
  project_id: z.string().optional().describe('Override the project for this call (WTProject header). Defaults to SMARTRUNS_PROJECT_ID.'),
@@ -29,7 +32,7 @@ export function registerCommentTools(server, client) {
29
32
  return handleError(err);
30
33
  }
31
34
  });
32
- server.tool('create_comment', 'Create a comment on a parent entity (test, test_plan, test_run, test_suite, or spec). The comment body goes in the "text" field. The parent is identified by source_type + source_id. The author is set server-side from the authenticated token.', {
35
+ server.tool('create_comment', 'Create a comment on a parent entity (test, test_plan, test_run, test_suite, spec, or defect). The comment body goes in the "text" field. The parent is identified by source_type + source_id. The author is set server-side from the authenticated token.', {
33
36
  source_type: sourceTypeSchema,
34
37
  source_id: z.number().int().describe('ID of the parent entity to comment on'),
35
38
  text: z.string().describe('The comment body (required)'),
@@ -57,8 +57,8 @@ export function registerDefectTools(server, client) {
57
57
  status: z.object({ id: z.number().int().describe('Status ID') }).describe('Status object with ID (required) — drives the defect state'),
58
58
  extra: z.string().optional().describe('Additional context or notes'),
59
59
  state: z.string().optional().describe('Defect state — usually omitted; the API derives it from the status'),
60
- ticket_id: z.number().int().optional().describe('Associated Jira ticket ID'),
61
- pull_request_id: z.number().int().optional().describe('Associated pull request ID'),
60
+ ticket_id: z.number().int().optional().describe('Associated Jira ticket RECORD id'),
61
+ pull_request_id: z.number().int().optional().describe('Internal PullRequest RECORD id (from search/list), NOT the GitHub PR number'),
62
62
  test_run_id: z.number().int().optional().describe('Associated test run ID'),
63
63
  test_plan_id: z.number().int().optional().describe('Associated test plan ID'),
64
64
  project_id: z.string().optional().describe('Override the project for this call (WTProject header). Defaults to SMARTRUNS_PROJECT_ID.'),
@@ -93,10 +93,12 @@ export function registerDefectTools(server, client) {
93
93
  extra: z.string().optional().describe('Additional context or notes'),
94
94
  state: z.string().optional().describe('Defect state, e.g. "open" or "closed"'),
95
95
  status: z.object({ id: z.number().int().describe('Status ID') }).optional().describe('Status object with ID'),
96
- ticket_id: z.number().int().optional().describe('Associated Jira ticket ID'),
97
- pull_request_id: z.number().int().optional().describe('Associated pull request ID'),
98
- test_run_id: z.number().int().optional().describe('Associated test run ID'),
99
- test_plan_id: z.number().int().optional().describe('Associated test plan ID'),
96
+ // SR-spec-5 (defect 6800): these FK links are nullable so a wrong/cross-account link
97
+ // can be CLEARED by passing null (the API assigns nil). Omit to leave unchanged.
98
+ ticket_id: z.number().int().nullable().optional().describe('Associated Jira ticket RECORD id. Pass null to clear the link.'),
99
+ pull_request_id: z.number().int().nullable().optional().describe('Internal PullRequest RECORD id (from search/list), NOT the GitHub PR number. Pass null to clear the link.'),
100
+ test_run_id: z.number().int().nullable().optional().describe('Associated test run ID. Pass null to clear the link.'),
101
+ test_plan_id: z.number().int().nullable().optional().describe('Associated test plan ID. Pass null to clear the link.'),
100
102
  }, async ({ id, summary, steps, current, expected, extra, state, status, ticket_id, pull_request_id, test_run_id, test_plan_id }) => {
101
103
  try {
102
104
  const body = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartruns/mcp",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "MCP server for the SmartRuns REST API",
5
5
  "type": "module",
6
6
  "bin": {