@aaronsb/jira-cloud-mcp 0.2.7 → 0.3.1

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.
@@ -0,0 +1,481 @@
1
+ /**
2
+ * Tool documentation generators.
3
+ * Each function returns a structured documentation object for an MCP tool resource.
4
+ */
5
+ export function formatToolName(toolName) {
6
+ return toolName
7
+ .split('_')
8
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
9
+ .join(' ');
10
+ }
11
+ const documentationGenerators = {
12
+ manage_jira_issue: generateIssueToolDocumentation,
13
+ manage_jira_board: generateBoardToolDocumentation,
14
+ manage_jira_sprint: generateSprintToolDocumentation,
15
+ manage_jira_filter: generateFilterToolDocumentation,
16
+ manage_jira_project: generateProjectToolDocumentation,
17
+ queue_jira_operations: generateQueueToolDocumentation,
18
+ };
19
+ export function generateToolDocumentation(toolName, schema) {
20
+ const generator = documentationGenerators[toolName];
21
+ if (generator) {
22
+ return generator(schema);
23
+ }
24
+ return generateGenericToolDocumentation(toolName, schema);
25
+ }
26
+ function generateIssueToolDocumentation(schema) {
27
+ return {
28
+ name: "Issue Management",
29
+ description: schema.description,
30
+ operations: {
31
+ get: {
32
+ description: "Retrieves issue details",
33
+ required_parameters: ["issueKey"],
34
+ optional_parameters: ["expand"],
35
+ expand_options: ["comments", "transitions", "attachments", "related_issues", "history"],
36
+ examples: [
37
+ {
38
+ description: "Get basic issue details",
39
+ code: { operation: "get", issueKey: "PROJ-123" }
40
+ },
41
+ {
42
+ description: "Get issue with comments and attachments",
43
+ code: { operation: "get", issueKey: "PROJ-123", expand: ["comments", "attachments"] }
44
+ }
45
+ ]
46
+ },
47
+ create: {
48
+ description: "Creates a new issue",
49
+ required_parameters: ["projectKey", "summary", "issueType"],
50
+ optional_parameters: ["description", "assignee", "priority", "labels", "customFields"],
51
+ examples: [
52
+ {
53
+ description: "Create a basic issue",
54
+ code: { operation: "create", projectKey: "PROJ", summary: "New feature request", issueType: "Story" }
55
+ },
56
+ {
57
+ description: "Create a detailed bug report",
58
+ code: {
59
+ operation: "create", projectKey: "PROJ", summary: "Search functionality not working",
60
+ issueType: "Bug", description: "The search function returns no results when using special characters.",
61
+ priority: "High", labels: ["search", "frontend"],
62
+ customFields: { "Story Points": 5, "Team": "Platform" }
63
+ }
64
+ }
65
+ ]
66
+ },
67
+ update: {
68
+ description: "Updates an existing issue",
69
+ required_parameters: ["issueKey"],
70
+ optional_parameters: ["summary", "description", "assignee", "priority", "labels", "customFields"],
71
+ examples: [
72
+ {
73
+ description: "Update issue summary",
74
+ code: { operation: "update", issueKey: "PROJ-123", summary: "Updated feature request" }
75
+ },
76
+ {
77
+ description: "Add worklog to issue",
78
+ code: {
79
+ operation: "update", issueKey: "PROJ-123",
80
+ customFields: { "worklog": { "timeSpent": "3h 30m", "comment": "Implemented feature X", "started": "2025-04-09T09:00:00.000Z" } }
81
+ }
82
+ }
83
+ ]
84
+ },
85
+ transition: {
86
+ description: "Transitions an issue to a new status",
87
+ required_parameters: ["issueKey", "transitionId"],
88
+ optional_parameters: ["comment"],
89
+ examples: [
90
+ { description: "Transition issue to 'In Progress'", code: { operation: "transition", issueKey: "PROJ-123", transitionId: "11" } },
91
+ { description: "Transition issue with comment", code: { operation: "transition", issueKey: "PROJ-123", transitionId: "21", comment: "Closing this issue as it's been completed and tested." } }
92
+ ]
93
+ },
94
+ comment: {
95
+ description: "Adds a comment to an issue",
96
+ required_parameters: ["issueKey", "comment"],
97
+ examples: [{ description: "Add a comment to an issue", code: { operation: "comment", issueKey: "PROJ-123", comment: "This has been reviewed and looks good." } }]
98
+ },
99
+ delete: {
100
+ description: "Permanently deletes an issue",
101
+ required_parameters: ["issueKey"],
102
+ examples: [
103
+ { description: "Delete an issue", code: { operation: "delete", issueKey: "PROJ-123" } }
104
+ ]
105
+ },
106
+ move: {
107
+ description: "Moves an issue to a different project and/or issue type",
108
+ required_parameters: ["issueKey", "targetProjectKey", "targetIssueType"],
109
+ examples: [
110
+ { description: "Move issue to another project", code: { operation: "move", issueKey: "PROJ-123", targetProjectKey: "NEWPROJ", targetIssueType: "Task" } }
111
+ ]
112
+ },
113
+ link: {
114
+ description: "Creates a link between two issues",
115
+ required_parameters: ["issueKey", "linkedIssueKey", "linkType"],
116
+ examples: [
117
+ { description: "Link issue as blocking another", code: { operation: "link", issueKey: "PROJ-123", linkedIssueKey: "PROJ-456", linkType: "blocks" } },
118
+ { description: "Link issue to an epic", code: { operation: "link", issueKey: "PROJ-123", linkedIssueKey: "PROJ-100", linkType: "is part of" } }
119
+ ]
120
+ }
121
+ },
122
+ common_use_cases: [
123
+ {
124
+ title: "Tracking work logs",
125
+ description: "To track time spent on issues:",
126
+ steps: [
127
+ { description: "Add a work log to an issue", code: { operation: "update", issueKey: "PROJ-123", customFields: { "worklog": { "timeSpent": "3h 30m", "comment": "Implemented feature X", "started": "2025-04-09T09:00:00.000Z" } } } },
128
+ { description: "View work logs for an issue", code: { operation: "get", issueKey: "PROJ-123", expand: ["worklog"] } }
129
+ ]
130
+ },
131
+ {
132
+ title: "Working with attachments",
133
+ description: "To manage attachments on issues:",
134
+ steps: [{ description: "View attachments on an issue", code: { operation: "get", issueKey: "PROJ-123", expand: ["attachments"] } }]
135
+ },
136
+ {
137
+ title: "Epic management",
138
+ description: "To manage epics and their issues:",
139
+ steps: [
140
+ { description: "Link an issue to an epic", code: { operation: "link", issueKey: "PROJ-123", linkedIssueKey: "PROJ-100", linkType: "is part of" } },
141
+ { description: "Find all issues in an epic", tool: "manage_jira_filter", code: { operation: "execute_jql", jql: '"Epic Link" = PROJ-100' } }
142
+ ]
143
+ }
144
+ ],
145
+ custom_fields: {
146
+ description: "Custom fields are discovered automatically at startup. Use field names (not IDs) in the customFields parameter.",
147
+ discovery: "Read jira://custom-fields to see the master catalog of discovered fields with types and descriptions.",
148
+ context: "Read jira://custom-fields/{projectKey}/{issueType} to see fields valid for a specific project and issue type.",
149
+ name_resolution: "Field names are resolved to IDs automatically — use human-readable names like 'Story Points', not 'customfield_10035'.",
150
+ requirement: "Only fields with descriptions in Jira are discoverable. Fields without descriptions must use raw field IDs.",
151
+ },
152
+ related_resources: [
153
+ { name: "Project Overview", uri: "jira://projects/{projectKey}/overview", description: "Get detailed information about a project" },
154
+ { name: "Issue Link Types", uri: "jira://issue-link-types", description: "List of all available issue link types" },
155
+ { name: "Custom Fields Catalog", uri: "jira://custom-fields", description: "Discovered custom fields with types, descriptions, and usage scores" },
156
+ { name: "Context Custom Fields", uri: "jira://custom-fields/{projectKey}/{issueType}", description: "Custom fields available for a specific project and issue type" }
157
+ ]
158
+ };
159
+ }
160
+ function generateBoardToolDocumentation(schema) {
161
+ return {
162
+ name: "Board Management (Read-Only)",
163
+ description: schema.description,
164
+ operations: {
165
+ get: {
166
+ description: "Retrieves board details",
167
+ required_parameters: ["boardId"], optional_parameters: ["expand"],
168
+ expand_options: ["sprints", "issues", "configuration"],
169
+ examples: [
170
+ { description: "Get basic board details", code: { operation: "get", boardId: 123 } },
171
+ { description: "Get board with sprints", code: { operation: "get", boardId: 123, expand: ["sprints"] } }
172
+ ]
173
+ },
174
+ list: {
175
+ description: "Lists all available boards",
176
+ required_parameters: [], optional_parameters: ["maxResults", "startAt"],
177
+ examples: [
178
+ { description: "List all boards", code: { operation: "list" } },
179
+ { description: "List boards with pagination", code: { operation: "list", startAt: 10, maxResults: 20 } }
180
+ ]
181
+ }
182
+ },
183
+ common_use_cases: [
184
+ {
185
+ title: "Working with board sprints",
186
+ description: "To manage sprints on a board:",
187
+ steps: [
188
+ { description: "Get board with sprints", code: { operation: "get", boardId: 123, expand: ["sprints"] } },
189
+ { description: "Create a new sprint", tool: "manage_jira_sprint", code: { operation: "create", boardId: 123, name: "Sprint 1", goal: "Complete core features" } }
190
+ ]
191
+ }
192
+ ],
193
+ related_resources: [
194
+ { name: "Board Overview", uri: "jira://boards/{boardId}/overview", description: "Get detailed information about a board" }
195
+ ]
196
+ };
197
+ }
198
+ function generateSprintToolDocumentation(schema) {
199
+ return {
200
+ name: "Sprint Management",
201
+ description: schema.description,
202
+ operations: {
203
+ get: {
204
+ description: "Retrieves sprint details",
205
+ required_parameters: ["sprintId"], optional_parameters: ["expand"],
206
+ expand_options: ["issues", "report", "board"],
207
+ examples: [
208
+ { description: "Get basic sprint details", code: { operation: "get", sprintId: 123 } },
209
+ { description: "Get sprint with issues", code: { operation: "get", sprintId: 123, expand: ["issues"] } }
210
+ ]
211
+ },
212
+ list: {
213
+ description: "Lists sprints for a board",
214
+ required_parameters: ["boardId"], optional_parameters: ["state", "maxResults", "startAt"],
215
+ examples: [
216
+ { description: "List all sprints for a board", code: { operation: "list", boardId: 123 } },
217
+ { description: "List active sprints for a board", code: { operation: "list", boardId: 123, state: "active" } }
218
+ ]
219
+ },
220
+ create: {
221
+ description: "Creates a new sprint",
222
+ required_parameters: ["name", "boardId"], optional_parameters: ["startDate", "endDate", "goal"],
223
+ examples: [
224
+ { description: "Create a basic sprint", code: { operation: "create", name: "Sprint 1", boardId: 123 } },
225
+ { description: "Create a sprint with dates and goal", code: { operation: "create", name: "Sprint 2", boardId: 123, startDate: "2025-04-10T00:00:00.000Z", endDate: "2025-04-24T00:00:00.000Z", goal: "Complete user authentication features" } }
226
+ ]
227
+ },
228
+ update: {
229
+ description: "Updates a sprint",
230
+ required_parameters: ["sprintId"], optional_parameters: ["name", "goal", "state"],
231
+ examples: [
232
+ { description: "Update sprint name and goal", code: { operation: "update", sprintId: 123, name: "Sprint 1 - Revised", goal: "Updated sprint goal" } },
233
+ { description: "Start a sprint", code: { operation: "update", sprintId: 123, state: "active" } },
234
+ { description: "Close a sprint", code: { operation: "update", sprintId: 123, state: "closed" } }
235
+ ]
236
+ },
237
+ delete: {
238
+ description: "Deletes a sprint",
239
+ required_parameters: ["sprintId"],
240
+ examples: [{ description: "Delete a sprint", code: { operation: "delete", sprintId: 123 } }]
241
+ },
242
+ manage_issues: {
243
+ description: "Adds/removes issues from a sprint",
244
+ required_parameters: ["sprintId"], optional_parameters: ["add", "remove"],
245
+ examples: [
246
+ { description: "Add issues to a sprint", code: { operation: "manage_issues", sprintId: 123, add: ["PROJ-123", "PROJ-124", "PROJ-125"] } },
247
+ { description: "Remove issues from a sprint", code: { operation: "manage_issues", sprintId: 123, remove: ["PROJ-126", "PROJ-127"] } },
248
+ { description: "Add and remove issues in one operation", code: { operation: "manage_issues", sprintId: 123, add: ["PROJ-128", "PROJ-129"], remove: ["PROJ-130"] } }
249
+ ]
250
+ }
251
+ },
252
+ common_use_cases: [
253
+ {
254
+ title: "Sprint planning",
255
+ description: "To plan and start a new sprint:",
256
+ steps: [
257
+ { description: "Create a new sprint", code: { operation: "create", name: "Sprint 1", boardId: 123, goal: "Complete core features" } },
258
+ { description: "Add issues to the sprint", code: { operation: "manage_issues", sprintId: 456, add: ["PROJ-123", "PROJ-124", "PROJ-125"] } },
259
+ { description: "Start the sprint", code: { operation: "update", sprintId: 456, state: "active" } }
260
+ ]
261
+ },
262
+ {
263
+ title: "Sprint review and closure",
264
+ description: "To review and close a completed sprint:",
265
+ steps: [
266
+ { description: "Get sprint with issues", code: { operation: "get", sprintId: 456, expand: ["issues"] } },
267
+ { description: "Close the sprint", code: { operation: "update", sprintId: 456, state: "closed" } }
268
+ ]
269
+ }
270
+ ],
271
+ related_resources: [
272
+ { name: "Board Overview", uri: "jira://boards/{boardId}/overview", description: "Get detailed information about a board including its sprints" }
273
+ ]
274
+ };
275
+ }
276
+ function generateFilterToolDocumentation(schema) {
277
+ return {
278
+ name: "Filter Management",
279
+ description: schema.description,
280
+ operations: {
281
+ get: {
282
+ description: "Retrieves filter details",
283
+ required_parameters: ["filterId"], optional_parameters: ["expand"],
284
+ expand_options: ["jql", "description", "permissions", "issue_count"],
285
+ examples: [
286
+ { description: "Get basic filter details", code: { operation: "get", filterId: "12345" } },
287
+ { description: "Get filter with JQL and permissions", code: { operation: "get", filterId: "12345", expand: ["jql", "permissions"] } }
288
+ ]
289
+ },
290
+ create: {
291
+ description: "Creates a new filter",
292
+ required_parameters: ["name", "jql"], optional_parameters: ["description", "favourite", "sharePermissions"],
293
+ examples: [
294
+ { description: "Create a basic filter", code: { operation: "create", name: "My Issues", jql: "assignee = currentUser() AND status != Done" } },
295
+ { description: "Create a shared filter", code: { operation: "create", name: "Team Bugs", jql: "project = PROJ AND issuetype = Bug AND status = Open", description: "All open bugs for our project", favourite: true, sharePermissions: [{ type: "group", group: "developers" }] } }
296
+ ]
297
+ },
298
+ update: {
299
+ description: "Updates a filter",
300
+ required_parameters: ["filterId"], optional_parameters: ["name", "jql", "description", "favourite", "sharePermissions"],
301
+ examples: [
302
+ { description: "Update filter name and JQL", code: { operation: "update", filterId: "12345", name: "Updated Filter Name", jql: "project = PROJ AND status = 'In Progress'" } },
303
+ { description: "Update filter sharing", code: { operation: "update", filterId: "12345", sharePermissions: [{ type: "global" }] } }
304
+ ]
305
+ },
306
+ delete: {
307
+ description: "Deletes a filter",
308
+ required_parameters: ["filterId"],
309
+ examples: [{ description: "Delete a filter", code: { operation: "delete", filterId: "12345" } }]
310
+ },
311
+ list: {
312
+ description: "Lists all filters",
313
+ required_parameters: [], optional_parameters: ["maxResults", "startAt"],
314
+ examples: [
315
+ { description: "List all filters", code: { operation: "list" } },
316
+ { description: "List filters with pagination", code: { operation: "list", startAt: 10, maxResults: 20 } }
317
+ ]
318
+ },
319
+ execute_filter: {
320
+ description: "Runs a saved filter",
321
+ required_parameters: ["filterId"], optional_parameters: ["maxResults", "startAt", "expand"],
322
+ examples: [
323
+ { description: "Execute a filter", code: { operation: "execute_filter", filterId: "12345" } },
324
+ { description: "Execute a filter with expanded issue details", code: { operation: "execute_filter", filterId: "12345", maxResults: 100, expand: ["issue_details"] } }
325
+ ]
326
+ },
327
+ execute_jql: {
328
+ description: "Runs a JQL query",
329
+ required_parameters: ["jql"], optional_parameters: ["maxResults", "startAt", "expand"],
330
+ examples: [
331
+ { description: "Execute a simple JQL query", code: { operation: "execute_jql", jql: "project = PROJ AND status = 'In Progress'" } },
332
+ { description: "Execute a complex JQL query with expanded issue details", code: { operation: "execute_jql", jql: "project = PROJ AND issuetype = Bug AND priority in (High, Highest) ORDER BY created DESC", maxResults: 50, expand: ["issue_details", "transitions"] } }
333
+ ]
334
+ }
335
+ },
336
+ common_use_cases: [
337
+ {
338
+ title: "Creating and sharing team filters",
339
+ description: "To create and share filters for team use:",
340
+ steps: [
341
+ { description: "Create a team filter", code: { operation: "create", name: "Team Backlog", jql: "project = PROJ AND status = 'To Do' ORDER BY priority DESC", description: "All backlog items for our team", sharePermissions: [{ type: "group", group: "developers" }] } },
342
+ { description: "Execute the filter to verify results", code: { operation: "execute_filter", filterId: "12345" } }
343
+ ]
344
+ },
345
+ {
346
+ title: "Advanced JQL queries",
347
+ description: "Examples of advanced JQL queries for specific use cases:",
348
+ steps: [
349
+ { description: "Find recently updated issues", code: { operation: "execute_jql", jql: "project = PROJ AND updated >= -7d ORDER BY updated DESC" } },
350
+ { description: "Find issues with status changes", code: { operation: "execute_jql", jql: "project = PROJ AND status CHANGED DURING (startOfWeek(), endOfWeek())" } },
351
+ { description: "Find issues assigned to a team", code: { operation: "execute_jql", jql: "project = PROJ AND assignee IN membersOf('developers')" } }
352
+ ]
353
+ }
354
+ ],
355
+ related_resources: [
356
+ { name: "Issue Link Types", uri: "jira://issue-link-types", description: "List of all available issue link types for use in JQL queries" }
357
+ ]
358
+ };
359
+ }
360
+ function generateProjectToolDocumentation(schema) {
361
+ return {
362
+ name: "Project Management (Read-Only)",
363
+ description: schema.description,
364
+ operations: {
365
+ get: {
366
+ description: "Retrieves project details",
367
+ required_parameters: ["projectKey"], optional_parameters: ["expand"],
368
+ expand_options: ["boards", "components", "versions", "recent_issues"],
369
+ examples: [
370
+ { description: "Get basic project details", code: { operation: "get", projectKey: "PROJ" } },
371
+ { description: "Get project with boards and components", code: { operation: "get", projectKey: "PROJ", expand: ["boards", "components"] } }
372
+ ]
373
+ },
374
+ list: {
375
+ description: "Lists all projects",
376
+ required_parameters: [], optional_parameters: ["maxResults", "startAt"],
377
+ examples: [
378
+ { description: "List all projects", code: { operation: "list" } },
379
+ { description: "List projects with pagination", code: { operation: "list", startAt: 10, maxResults: 20 } }
380
+ ]
381
+ }
382
+ },
383
+ common_use_cases: [
384
+ {
385
+ title: "Project reporting",
386
+ description: "To get project statistics and reports:",
387
+ steps: [
388
+ { description: "Get project details with status counts", code: { operation: "get", projectKey: "PROJ", include_status_counts: true } },
389
+ { description: "Get all issues in a project", tool: "manage_jira_filter", code: { operation: "execute_jql", jql: "project = PROJ ORDER BY created DESC" } }
390
+ ]
391
+ }
392
+ ],
393
+ related_resources: [
394
+ { name: "Project Overview", uri: "jira://projects/{projectKey}/overview", description: "Get detailed information about a project" }
395
+ ]
396
+ };
397
+ }
398
+ function generateQueueToolDocumentation(_schema) {
399
+ return {
400
+ name: "Queue Jira Operations",
401
+ description: "Execute multiple Jira operations in a single call. Operations run sequentially with result references and per-operation error strategies.",
402
+ parameters: {
403
+ operations: {
404
+ type: "array (max 10)",
405
+ description: "Ordered list of operations. Each has: tool (string), args (object), onError ('bail' | 'continue', default 'bail').",
406
+ },
407
+ },
408
+ error_strategies: {
409
+ bail: "Stop the queue on error. Remaining operations are skipped. This is the default.",
410
+ continue: "Log the error, proceed to the next operation.",
411
+ },
412
+ result_references: {
413
+ description: "Reference results from earlier operations using $N.field syntax (0-based index).",
414
+ supported_fields: {
415
+ key: "Issue key (e.g., PROJ-123) — extracted from markdown output",
416
+ id: "Numeric ID — extracted from response",
417
+ filterId: "Filter ID",
418
+ sprintId: "Sprint ID",
419
+ boardId: "Board ID",
420
+ },
421
+ example: "$0.key refers to the issue key from the first operation's result",
422
+ },
423
+ common_use_cases: [
424
+ {
425
+ title: "Create issue and set up",
426
+ description: "Create an issue, link it, add a comment, and transition — all in one call:",
427
+ steps: [
428
+ {
429
+ description: "Full workflow",
430
+ code: {
431
+ operations: [
432
+ { tool: "manage_jira_issue", args: { operation: "create", projectKey: "PROJ", summary: "New task", issueType: "Task" } },
433
+ { tool: "manage_jira_issue", args: { operation: "link", issueKey: "$0.key", linkedIssueKey: "PROJ-100", linkType: "relates to" } },
434
+ { tool: "manage_jira_issue", args: { operation: "comment", issueKey: "$0.key", comment: "Created and linked" }, onError: "continue" },
435
+ ],
436
+ },
437
+ },
438
+ ],
439
+ },
440
+ {
441
+ title: "Search and act",
442
+ description: "Run a JQL query then get details on specific results:",
443
+ steps: [
444
+ {
445
+ description: "Search then fetch",
446
+ code: {
447
+ operations: [
448
+ { tool: "manage_jira_filter", args: { operation: "execute_jql", jql: "project = PROJ AND status = Open", maxResults: 5 } },
449
+ { tool: "manage_jira_issue", args: { operation: "get", issueKey: "PROJ-100", expand: ["transitions"] } },
450
+ ],
451
+ },
452
+ },
453
+ ],
454
+ },
455
+ ],
456
+ guardrails: {
457
+ description: "Destructive operations (delete, move) are pre-scanned against the bulk-destructive limit. If the queue would exceed the limit, the entire queue is refused before any operations execute.",
458
+ max_operations: 10,
459
+ },
460
+ related_resources: [],
461
+ };
462
+ }
463
+ function generateGenericToolDocumentation(toolName, schema) {
464
+ const operations = {};
465
+ if (schema.inputSchema?.properties?.operation?.enum) {
466
+ for (const op of schema.inputSchema.properties.operation.enum) {
467
+ operations[op] = {
468
+ description: `Performs the ${op} operation`,
469
+ required_parameters: ["operation"],
470
+ examples: [{ description: `Example ${op} operation`, code: { operation: op } }]
471
+ };
472
+ }
473
+ }
474
+ return {
475
+ name: formatToolName(toolName),
476
+ description: schema.description,
477
+ operations,
478
+ common_use_cases: [],
479
+ related_resources: []
480
+ };
481
+ }