backlog-mcp-server 0.4.0

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +440 -0
  3. package/README.md +501 -0
  4. package/build/backlog/backlogErrorHandler.js +8 -0
  5. package/build/backlog/customFields.js +16 -0
  6. package/build/backlog/parseBacklogAPIError.js +38 -0
  7. package/build/createTranslationHelper.js +28 -0
  8. package/build/handlers/builders/composeToolHandler.js +26 -0
  9. package/build/handlers/transformers/wrapWithErrorHandling.js +4 -0
  10. package/build/handlers/transformers/wrapWithFieldPicking.js +55 -0
  11. package/build/handlers/transformers/wrapWithTokenLimit.js +21 -0
  12. package/build/handlers/transformers/wrapWithToolResult.js +39 -0
  13. package/build/index.js +102 -0
  14. package/build/registerTools.js +37 -0
  15. package/build/tools/addIssue.js +94 -0
  16. package/build/tools/addIssueComment.js +44 -0
  17. package/build/tools/addProject.js +39 -0
  18. package/build/tools/addPullRequest.js +65 -0
  19. package/build/tools/addPullRequestComment.js +52 -0
  20. package/build/tools/addWiki.js +29 -0
  21. package/build/tools/countIssues.js +111 -0
  22. package/build/tools/deleteIssue.js +29 -0
  23. package/build/tools/deleteProject.js +29 -0
  24. package/build/tools/downloadDocumentAttachment.js +1 -0
  25. package/build/tools/dynamicTools/toolsets.js +103 -0
  26. package/build/tools/getCategories.js +30 -0
  27. package/build/tools/getCustomFields.js +37 -0
  28. package/build/tools/getDocument.js +20 -0
  29. package/build/tools/getDocumentTree.js +20 -0
  30. package/build/tools/getDocuments.js +25 -0
  31. package/build/tools/getGitRepositories.js +29 -0
  32. package/build/tools/getGitRepository.js +41 -0
  33. package/build/tools/getIssue.js +29 -0
  34. package/build/tools/getIssueComments.js +45 -0
  35. package/build/tools/getIssueTypes.js +30 -0
  36. package/build/tools/getIssues.js +155 -0
  37. package/build/tools/getMyself.js +14 -0
  38. package/build/tools/getNotifications.js +35 -0
  39. package/build/tools/getNotificationsCount.js +20 -0
  40. package/build/tools/getPriorities.js +13 -0
  41. package/build/tools/getProject.js +29 -0
  42. package/build/tools/getProjectList.js +23 -0
  43. package/build/tools/getPullRequest.js +44 -0
  44. package/build/tools/getPullRequestComments.js +60 -0
  45. package/build/tools/getPullRequests.js +65 -0
  46. package/build/tools/getPullRequestsCount.js +57 -0
  47. package/build/tools/getResolutions.js +13 -0
  48. package/build/tools/getSpace.js +14 -0
  49. package/build/tools/getUsers.js +14 -0
  50. package/build/tools/getWatchingListCount.js +17 -0
  51. package/build/tools/getWatchingListItems.js +17 -0
  52. package/build/tools/getWiki.js +21 -0
  53. package/build/tools/getWikiPages.js +37 -0
  54. package/build/tools/getWikisCount.js +29 -0
  55. package/build/tools/markNotificationAsRead.js +26 -0
  56. package/build/tools/resetUnreadNotificationCount.js +13 -0
  57. package/build/tools/tools.js +143 -0
  58. package/build/tools/updateIssue.js +116 -0
  59. package/build/tools/updateProject.js +57 -0
  60. package/build/tools/updatePullRequest.js +68 -0
  61. package/build/tools/updatePullRequestComment.js +51 -0
  62. package/build/types/mcp.js +1 -0
  63. package/build/types/result.js +3 -0
  64. package/build/types/tool.js +1 -0
  65. package/build/types/toolsets.js +1 -0
  66. package/build/types/zod/backlogOutputDefinition.js +468 -0
  67. package/build/utils/generateFieldsDescription.js +47 -0
  68. package/build/utils/resolveIdOrKey.js +25 -0
  69. package/build/utils/runToolSafely.js +18 -0
  70. package/build/utils/tokenCounter.js +11 -0
  71. package/build/utils/toolRegistrar.js +12 -0
  72. package/build/utils/toolsetUtils.js +48 -0
  73. package/build/utils/wrapServerWithToolRegistry.js +16 -0
  74. package/build/version.js +1 -0
  75. package/build/version.template.js +1 -0
  76. package/package.json +52 -0
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { ProjectSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const deleteProjectSchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_DELETE_PROJECT_PROJECT_ID', 'The numeric ID of the project (e.g., 12345)')),
10
+ projectKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_DELETE_PROJECT_PROJECT_KEY', "The key of the project (e.g., 'PROJECT')")),
14
+ }));
15
+ export const deleteProjectTool = (backlog, { t }) => {
16
+ return {
17
+ name: 'delete_project',
18
+ description: t('TOOL_DELETE_PROJECT_DESCRIPTION', 'Deletes a project'),
19
+ schema: z.object(deleteProjectSchema(t)),
20
+ outputSchema: ProjectSchema,
21
+ handler: async ({ projectId, projectKey }) => {
22
+ const result = resolveIdOrKey('project', { id: projectId, key: projectKey }, t);
23
+ if (!result.ok) {
24
+ throw result.error;
25
+ }
26
+ return backlog.deleteProject(result.value);
27
+ },
28
+ };
29
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,103 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema, } from '../../types/tool.js';
3
+ export const dynamicTools = function (toolRegistrar, helper, toolsetGroup) {
4
+ return {
5
+ toolsets: [
6
+ {
7
+ name: 'dynamic_tools',
8
+ description: 'Tools for managing Backlog space settings and general information.',
9
+ enabled: true,
10
+ tools: [
11
+ enableToolsetTool(toolRegistrar, helper),
12
+ listAvailableToolsets(helper, toolsetGroup),
13
+ getToolsetTools(helper, toolsetGroup),
14
+ ],
15
+ },
16
+ ],
17
+ };
18
+ };
19
+ const enableToolsetSchema = buildToolSchema((t) => ({
20
+ toolset: z
21
+ .string()
22
+ .describe(t('TOOL_ENABLE_TOOLSET_TOOLSET', 'Enable a toolset')),
23
+ }));
24
+ export const enableToolsetTool = (toolRegistrar, { t }) => {
25
+ return {
26
+ name: 'enable_toolset',
27
+ description: t('TOOL_ENABLE_TOOLSET_DESCRIPTION', 'Enable one of the sets of tools the GitHub MCP server provides, use get_toolset_tools and list_available_toolsets first to see what this will enable'),
28
+ schema: z.object(enableToolsetSchema(t)),
29
+ handler: async ({ toolset }) => {
30
+ const msg = await toolRegistrar.enableToolsetAndRefresh(toolset);
31
+ return {
32
+ content: [
33
+ {
34
+ type: 'text',
35
+ text: msg,
36
+ },
37
+ ],
38
+ };
39
+ },
40
+ };
41
+ };
42
+ export const listAvailableToolsets = ({ t }, toolsetGroup) => {
43
+ return {
44
+ name: 'list_available_toolsets',
45
+ description: t('TOOL_LIST_AVAILABLE_TOOLSETS_DESCRIPTION', 'List all available toolsets.'),
46
+ schema: z.object({}),
47
+ handler: async () => {
48
+ const result = toolsetGroup.toolsets.map((ts) => ({
49
+ name: ts.name,
50
+ description: ts.description,
51
+ currentlyEnabled: ts.enabled,
52
+ canEnable: true,
53
+ }));
54
+ return {
55
+ content: [
56
+ {
57
+ type: 'text',
58
+ text: JSON.stringify(result, null, 2),
59
+ },
60
+ ],
61
+ };
62
+ },
63
+ };
64
+ };
65
+ const getToolsetToolsSchema = buildToolSchema((t) => ({
66
+ toolset: z
67
+ .string()
68
+ .describe(t('TOOL_GET_TOOLSET_TOOLS_TOOLSET', 'Toolset name to inspect')),
69
+ }));
70
+ export const getToolsetTools = ({ t }, toolsetGroup) => {
71
+ return {
72
+ name: 'get_toolset_tools',
73
+ description: t('TOOL_GET_TOOLSET_TOOLS_DESCRIPTION', 'List all tools in a specific toolset.'),
74
+ schema: z.object(getToolsetToolsSchema(t)),
75
+ handler: async ({ toolset }) => {
76
+ const found = toolsetGroup.toolsets.find((ts) => ts.name === toolset);
77
+ if (!found) {
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: `Toolset '${toolset}' not found.`,
83
+ },
84
+ ],
85
+ };
86
+ }
87
+ const tools = found.tools.map((tool) => ({
88
+ name: tool.name,
89
+ description: tool.description,
90
+ toolset: found.name,
91
+ canEnable: true,
92
+ }));
93
+ return {
94
+ content: [
95
+ {
96
+ type: 'text',
97
+ text: JSON.stringify(tools, null, 2),
98
+ },
99
+ ],
100
+ };
101
+ },
102
+ };
103
+ };
@@ -0,0 +1,30 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { CategorySchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const getCategoriesSchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_CATEGORIES_PROJECT_ID', 'The numeric ID of the project (e.g., 12345)')),
10
+ projectKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_CATEGORIES_PROJECT_ID', "The key of the project (e.g., 'PROJECT')")),
14
+ }));
15
+ export const getCategoriesTool = (backlog, { t }) => {
16
+ return {
17
+ name: 'get_categories',
18
+ description: t('TOOL_GET_CATEGORIES_DESCRIPTION', 'Returns list of categories for a project'),
19
+ schema: z.object(getCategoriesSchema(t)),
20
+ importantFields: ['id', 'projectId', 'name'],
21
+ outputSchema: CategorySchema,
22
+ handler: async ({ projectId, projectKey }) => {
23
+ const result = resolveIdOrKey('project', { id: projectId, key: projectKey }, t);
24
+ if (!result.ok) {
25
+ throw result.error;
26
+ }
27
+ return backlog.getCategories(result.value);
28
+ },
29
+ };
30
+ };
@@ -0,0 +1,37 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { CustomFieldSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const getCustomFieldsInputSchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_CUSTOM_FIELDS_PROJECT_ID', 'The numeric ID of the project (e.g., 12345)')),
10
+ projectKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_CUSTOM_FIELDS_PROJECT_KEY', "The key of the project (e.g., 'PROJECT')")),
14
+ }));
15
+ export const getCustomFieldsTool = (backlog, { t }) => {
16
+ const inputSchemaObject = z.object(getCustomFieldsInputSchema(t)); // Create the ZodObject for input
17
+ return {
18
+ name: 'get_custom_fields',
19
+ description: t('TOOL_GET_CUSTOM_FIELDS_DESCRIPTION', 'Returns list of custom fields for a project'),
20
+ schema: inputSchemaObject,
21
+ outputSchema: CustomFieldSchema,
22
+ importantFields: [
23
+ 'id',
24
+ 'name',
25
+ 'typeId',
26
+ 'required',
27
+ 'applicableIssueTypes',
28
+ ],
29
+ handler: async ({ projectId, projectKey }) => {
30
+ const result = resolveIdOrKey('project', { id: projectId, key: projectKey }, t);
31
+ if (!result.ok) {
32
+ throw result.error;
33
+ }
34
+ return backlog.getCustomFields(result.value);
35
+ },
36
+ };
37
+ };
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ import { DocumentItemSchema } from '../types/zod/backlogOutputDefinition.js';
3
+ import { buildToolSchema } from '../types/tool.js';
4
+ const getDocumentSchema = buildToolSchema((t) => ({
5
+ documentId: z
6
+ .string()
7
+ .describe(t('TOOL_GET_DOCUMENT_DOCUMENT_ID', 'Document ID')),
8
+ }));
9
+ export const getDocumentTool = (backlog, { t }) => {
10
+ return {
11
+ name: 'get_document',
12
+ description: t('TOOL_GET_DOCUMENT_DESCRIPTION', 'Gets information about a document.'),
13
+ schema: z.object(getDocumentSchema(t)),
14
+ outputSchema: DocumentItemSchema,
15
+ importantFields: ['id', 'title', 'createdUser'],
16
+ handler: async ({ documentId }) => {
17
+ return backlog.getDocument(documentId);
18
+ },
19
+ };
20
+ };
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ import { DocumentTreeFullSchemaZ, } from '../types/zod/backlogOutputDefinition.js';
3
+ import { buildToolSchema } from '../types/tool.js';
4
+ const getDocumentTreeSchema = buildToolSchema((t) => ({
5
+ projectIdOrKey: z
6
+ .union([z.string(), z.number()])
7
+ .describe(t('TOOL_GET_DOCUMENT_TREE_PROJECT_ID_OR_KEY', 'Project ID or Key')),
8
+ }));
9
+ export const getDocumentTreeTool = (backlog, { t }) => {
10
+ return {
11
+ name: 'get_document_tree',
12
+ description: t('TOOL_GET_DOCUMENT_TREE_DESCRIPTION', 'Gets the document tree of a project.'),
13
+ schema: z.object(getDocumentTreeSchema(t)),
14
+ outputSchema: DocumentTreeFullSchemaZ,
15
+ importantFields: ['projectId', 'activeTree', 'trashTree'],
16
+ handler: async ({ projectIdOrKey }) => {
17
+ return backlog.getDocumentTree(projectIdOrKey);
18
+ },
19
+ };
20
+ };
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod';
2
+ import { DocumentItemSchema } from '../types/zod/backlogOutputDefinition.js';
3
+ import { buildToolSchema } from '../types/tool.js';
4
+ const getDocumentsSchema = buildToolSchema((t) => ({
5
+ projectIds: z
6
+ .array(z.number())
7
+ .describe(t('TOOL_GET_DOCUMENTS_PROJECT_ID_LIST', 'Project ID List')),
8
+ offset: z
9
+ .number()
10
+ .optional()
11
+ .default(0)
12
+ .describe(t('TOOL_GET_DOCUMENTS_OFFSET', 'Offset for pagination (default is 0)')),
13
+ }));
14
+ export const getDocumentsTool = (backlog, { t }) => {
15
+ return {
16
+ name: 'get_documents',
17
+ description: t('TOOL_GET_DOCUMENTS_DESCRIPTION', 'Gets a list of documents in a project.'),
18
+ schema: z.object(getDocumentsSchema(t)),
19
+ outputSchema: DocumentItemSchema,
20
+ importantFields: ['id', 'projectId', 'title', 'plain'],
21
+ handler: async ({ projectIds, offset }) => {
22
+ return backlog.getDocuments({ projectId: projectIds, offset });
23
+ },
24
+ };
25
+ };
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { GitRepositorySchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const getGitRepositoriesSchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_GIT_REPOSITORIES_PROJECT_ID', 'The numeric ID of the project (e.g., 12345)')),
10
+ projectKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_GIT_REPOSITORIES_PROJECT_KEY', "The key of the project (e.g., 'PROJECT')")),
14
+ }));
15
+ export const getGitRepositoriesTool = (backlog, { t }) => {
16
+ return {
17
+ name: 'get_git_repositories',
18
+ description: t('TOOL_GET_GIT_REPOSITORIES_DESCRIPTION', 'Returns list of Git repositories for a project'),
19
+ schema: z.object(getGitRepositoriesSchema(t)),
20
+ outputSchema: GitRepositorySchema,
21
+ handler: async ({ projectId, projectKey }) => {
22
+ const result = resolveIdOrKey('project', { id: projectId, key: projectKey }, t);
23
+ if (!result.ok) {
24
+ throw result.error;
25
+ }
26
+ return backlog.getGitRepositories(result.value);
27
+ },
28
+ };
29
+ };
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { GitRepositorySchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey, resolveIdOrName } from '../utils/resolveIdOrKey.js';
5
+ const getGitRepositorySchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_GIT_REPOSITORY_PROJECT_ID', 'The numeric ID of the project (e.g., 12345)')),
10
+ projectKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_GIT_REPOSITORY_PROJECT_KEY', "The key of the project (e.g., 'PROJECT')")),
14
+ repoId: z
15
+ .number()
16
+ .optional()
17
+ .describe(t('TOOL_GET_GIT_REPOSITORY_REPO_ID', 'Repository ID')),
18
+ repoName: z
19
+ .string()
20
+ .optional()
21
+ .describe(t('TOOL_GET_GIT_REPOSITORY_REPO_NAME', 'Repository name')),
22
+ }));
23
+ export const getGitRepositoryTool = (backlog, { t }) => {
24
+ return {
25
+ name: 'get_git_repository',
26
+ description: t('TOOL_GET_GIT_REPOSITORY_DESCRIPTION', 'Returns information about a specific Git repository'),
27
+ schema: z.object(getGitRepositorySchema(t)),
28
+ outputSchema: GitRepositorySchema,
29
+ handler: async ({ projectId, projectKey, repoId, repoName }) => {
30
+ const result = resolveIdOrKey('project', { id: projectId, key: projectKey }, t);
31
+ if (!result.ok) {
32
+ throw result.error;
33
+ }
34
+ const repoResult = resolveIdOrName('repository', { id: repoId, name: repoName }, t);
35
+ if (!repoResult.ok) {
36
+ throw repoResult.error;
37
+ }
38
+ return backlog.getGitRepository(result.value, String(repoResult.value));
39
+ },
40
+ };
41
+ };
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { IssueSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const getIssueSchema = buildToolSchema((t) => ({
6
+ issueId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_ISSUE_ISSUE_ID', 'The numeric ID of the issue (e.g., 12345)')),
10
+ issueKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_ISSUE_ISSUE_KEY', "The key of the issue (e.g., 'PROJ-123')")),
14
+ }));
15
+ export const getIssueTool = (backlog, { t }) => {
16
+ return {
17
+ name: 'get_issue',
18
+ description: t('TOOL_GET_ISSUE_DESCRIPTION', 'Returns information about a specific issue'),
19
+ outputSchema: IssueSchema,
20
+ schema: z.object(getIssueSchema(t)),
21
+ handler: async ({ issueId, issueKey }) => {
22
+ const result = resolveIdOrKey('issue', { id: issueId, key: issueKey }, t);
23
+ if (!result.ok) {
24
+ throw result.error;
25
+ }
26
+ return backlog.getIssue(result.value);
27
+ },
28
+ };
29
+ };
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { IssueCommentSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const getIssueCommentsSchema = buildToolSchema((t) => ({
6
+ issueId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_ISSUE_COMMENTS_ISSUE_ID', 'The numeric ID of the issue (e.g., 12345)')),
10
+ issueKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_ISSUE_COMMENTS_ISSUE_KEY', "The key of the issue (e.g., 'PROJ-123')")),
14
+ minId: z
15
+ .number()
16
+ .optional()
17
+ .describe(t('TOOL_GET_ISSUE_COMMENTS_MIN_ID', 'Minimum comment ID')),
18
+ maxId: z
19
+ .number()
20
+ .optional()
21
+ .describe(t('TOOL_GET_ISSUE_COMMENTS_MAX_ID', 'Maximum comment ID')),
22
+ count: z
23
+ .number()
24
+ .optional()
25
+ .describe(t('TOOL_GET_ISSUE_COMMENTS_COUNT', 'Number of comments to retrieve')),
26
+ order: z
27
+ .enum(['asc', 'desc'])
28
+ .optional()
29
+ .describe(t('TOOL_GET_ISSUE_COMMENTS_ORDER', 'Sort order')),
30
+ }));
31
+ export const getIssueCommentsTool = (backlog, { t }) => {
32
+ return {
33
+ name: 'get_issue_comments',
34
+ description: t('TOOL_GET_ISSUE_COMMENTS_DESCRIPTION', 'Returns list of comments for an issue'),
35
+ schema: z.object(getIssueCommentsSchema(t)),
36
+ outputSchema: IssueCommentSchema,
37
+ handler: async ({ issueId, issueKey, ...params }) => {
38
+ const result = resolveIdOrKey('issue', { id: issueId, key: issueKey }, t);
39
+ if (!result.ok) {
40
+ throw result.error;
41
+ }
42
+ return backlog.getIssueComments(result.value, params);
43
+ },
44
+ };
45
+ };
@@ -0,0 +1,30 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { IssueTypeSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { resolveIdOrKey } from '../utils/resolveIdOrKey.js';
5
+ const getIssueTypesSchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .number()
8
+ .optional()
9
+ .describe(t('TOOL_GET_GIT_REPOSITORIES_PROJECT_ID', 'The numeric ID of the project (e.g., 12345)')),
10
+ projectKey: z
11
+ .string()
12
+ .optional()
13
+ .describe(t('TOOL_GET_GIT_REPOSITORIES_PROJECT_KEY', "The key of the project (e.g., 'PROJECT')")),
14
+ }));
15
+ export const getIssueTypesTool = (backlog, { t }) => {
16
+ return {
17
+ name: 'get_issue_types',
18
+ description: t('TOOL_GET_ISSUE_TYPES_DESCRIPTION', 'Returns list of issue types for a project'),
19
+ schema: z.object(getIssueTypesSchema(t)),
20
+ outputSchema: IssueTypeSchema,
21
+ importantFields: ['id', 'name'],
22
+ handler: async ({ projectId, projectKey }) => {
23
+ const result = resolveIdOrKey('project', { id: projectId, key: projectKey }, t);
24
+ if (!result.ok) {
25
+ throw result.error;
26
+ }
27
+ return backlog.getIssueTypes(result.value);
28
+ },
29
+ };
30
+ };
@@ -0,0 +1,155 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { IssueSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ import { customFieldsToPayload } from '../backlog/customFields.js';
5
+ const getIssuesSchema = buildToolSchema((t) => ({
6
+ projectId: z
7
+ .array(z.number())
8
+ .optional()
9
+ .describe(t('TOOL_GET_ISSUES_PROJECT_ID', 'Project IDs')),
10
+ issueTypeId: z
11
+ .array(z.number())
12
+ .optional()
13
+ .describe(t('TOOL_GET_ISSUES_ISSUE_TYPE_ID', 'Issue type IDs')),
14
+ categoryId: z
15
+ .array(z.number())
16
+ .optional()
17
+ .describe(t('TOOL_GET_ISSUES_CATEGORY_ID', 'Category IDs')),
18
+ versionId: z
19
+ .array(z.number())
20
+ .optional()
21
+ .describe(t('TOOL_GET_ISSUES_VERSION_ID', 'Version IDs')),
22
+ milestoneId: z
23
+ .array(z.number())
24
+ .optional()
25
+ .describe(t('TOOL_GET_ISSUES_MILESTONE_ID', 'Milestone IDs')),
26
+ statusId: z
27
+ .array(z.number())
28
+ .optional()
29
+ .describe(t('TOOL_GET_ISSUES_STATUS_ID', 'Status IDs')),
30
+ priorityId: z
31
+ .array(z.number())
32
+ .optional()
33
+ .describe(t('TOOL_GET_ISSUES_PRIORITY_ID', 'Priority IDs')),
34
+ assigneeId: z
35
+ .array(z.number())
36
+ .optional()
37
+ .describe(t('TOOL_GET_ISSUES_ASSIGNEE_ID', 'Assignee user IDs')),
38
+ createdUserId: z
39
+ .array(z.number())
40
+ .optional()
41
+ .describe(t('TOOL_GET_ISSUES_CREATED_USER_ID', 'Created user IDs')),
42
+ resolutionId: z
43
+ .array(z.number())
44
+ .optional()
45
+ .describe(t('TOOL_GET_ISSUES_RESOLUTION_ID', 'Resolution IDs')),
46
+ parentIssueId: z
47
+ .array(z.number())
48
+ .optional()
49
+ .describe(t('TOOL_GET_ISSUES_PARENT_ISSUE_ID', 'Parent issue IDs')),
50
+ keyword: z
51
+ .string()
52
+ .optional()
53
+ .describe(t('TOOL_GET_ISSUES_KEYWORD', 'Keyword to search for in issues')),
54
+ startDateSince: z
55
+ .string()
56
+ .optional()
57
+ .describe(t('TOOL_GET_ISSUES_START_DATE_SINCE', 'Start date since (yyyy-MM-dd)')),
58
+ startDateUntil: z
59
+ .string()
60
+ .optional()
61
+ .describe(t('TOOL_GET_ISSUES_START_DATE_UNTIL', 'Start date until (yyyy-MM-dd)')),
62
+ dueDateSince: z
63
+ .string()
64
+ .optional()
65
+ .describe(t('TOOL_GET_ISSUES_DUE_DATE_SINCE', 'Due date since (yyyy-MM-dd)')),
66
+ dueDateUntil: z
67
+ .string()
68
+ .optional()
69
+ .describe(t('TOOL_GET_ISSUES_DUE_DATE_UNTIL', 'Due date until (yyyy-MM-dd)')),
70
+ createdSince: z
71
+ .string()
72
+ .optional()
73
+ .describe(t('TOOL_GET_ISSUES_CREATED_SINCE', 'Created since (yyyy-MM-dd)')),
74
+ createdUntil: z
75
+ .string()
76
+ .optional()
77
+ .describe(t('TOOL_GET_ISSUES_CREATED_UNTIL', 'Created until (yyyy-MM-dd)')),
78
+ updatedSince: z
79
+ .string()
80
+ .optional()
81
+ .describe(t('TOOL_GET_ISSUES_UPDATED_SINCE', 'Updated since (yyyy-MM-dd)')),
82
+ updatedUntil: z
83
+ .string()
84
+ .optional()
85
+ .describe(t('TOOL_GET_ISSUES_UPDATED_UNTIL', 'Updated until (yyyy-MM-dd)')),
86
+ sort: z
87
+ .enum([
88
+ 'issueType',
89
+ 'category',
90
+ 'version',
91
+ 'milestone',
92
+ 'summary',
93
+ 'status',
94
+ 'priority',
95
+ 'attachment',
96
+ 'sharedFile',
97
+ 'created',
98
+ 'createdUser',
99
+ 'updated',
100
+ 'updatedUser',
101
+ 'assignee',
102
+ 'startDate',
103
+ 'dueDate',
104
+ 'estimatedHours',
105
+ 'actualHours',
106
+ 'childIssue',
107
+ ])
108
+ .optional()
109
+ .describe(t('TOOL_GET_ISSUES_SORT', 'Sort field')),
110
+ order: z
111
+ .enum(['asc', 'desc'])
112
+ .optional()
113
+ .describe(t('TOOL_GET_ISSUES_ORDER', 'Sort order')),
114
+ offset: z
115
+ .number()
116
+ .optional()
117
+ .describe(t('TOOL_GET_ISSUES_OFFSET', 'Offset for pagination')),
118
+ count: z
119
+ .number()
120
+ .optional()
121
+ .describe(t('TOOL_GET_ISSUES_COUNT', 'Number of issues to retrieve')),
122
+ customFields: z
123
+ .array(z.object({
124
+ id: z
125
+ .number()
126
+ .describe(t('TOOL_GET_ISSUES_CUSTOM_FIELD_ID', 'Custom field ID')),
127
+ value: z
128
+ .union([z.string(), z.number(), z.array(z.string())])
129
+ .describe(t('TOOL_GET_ISSUES_CUSTOM_FIELD_VALUE', 'Custom field value')),
130
+ }))
131
+ .optional()
132
+ .describe(t('TOOL_GET_ISSUES_CUSTOM_FIELDS', 'Custom fields')),
133
+ }));
134
+ export const getIssuesTool = (backlog, { t }) => {
135
+ return {
136
+ name: 'get_issues',
137
+ description: t('TOOL_GET_ISSUES_DESCRIPTION', 'Returns list of issues'),
138
+ schema: z.object(getIssuesSchema(t)),
139
+ importantFields: [
140
+ 'projectId',
141
+ 'issueKey',
142
+ 'keyId',
143
+ 'summary',
144
+ 'description',
145
+ 'issueType',
146
+ ],
147
+ outputSchema: IssueSchema,
148
+ handler: async ({ customFields, ...rest }) => {
149
+ return backlog.getIssues({
150
+ ...rest,
151
+ ...customFieldsToPayload(customFields),
152
+ });
153
+ },
154
+ };
155
+ };
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { UserSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ const getMyselfSchema = buildToolSchema((_t) => ({}));
5
+ export const getMyselfTool = (backlog, { t }) => {
6
+ return {
7
+ name: 'get_myself',
8
+ description: t('TOOL_GET_MYSELF_DESCRIPTION', 'Returns information about the authenticated user'),
9
+ schema: z.object(getMyselfSchema(t)),
10
+ outputSchema: UserSchema,
11
+ importantFields: ['id', 'userId', 'name', 'roleType'],
12
+ handler: async () => backlog.getMyself(),
13
+ };
14
+ };
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { buildToolSchema } from '../types/tool.js';
3
+ import { NotificationSchema } from '../types/zod/backlogOutputDefinition.js';
4
+ const getNotificationsSchema = buildToolSchema((t) => ({
5
+ minId: z
6
+ .number()
7
+ .optional()
8
+ .describe(t('TOOL_GET_NOTIFICATIONS_MIN_ID', 'Minimum notification ID')),
9
+ maxId: z
10
+ .number()
11
+ .optional()
12
+ .describe(t('TOOL_GET_NOTIFICATIONS_MAX_ID', 'Maximum notification ID')),
13
+ count: z
14
+ .number()
15
+ .optional()
16
+ .describe(t('TOOL_GET_NOTIFICATIONS_COUNT', 'Number of notifications to retrieve')),
17
+ order: z
18
+ .enum(['asc', 'desc'])
19
+ .optional()
20
+ .describe(t('TOOL_GET_NOTIFICATIONS_ORDER', 'Sort order')),
21
+ }));
22
+ export const getNotificationsTool = (backlog, { t }) => {
23
+ return {
24
+ name: 'get_notifications',
25
+ description: t('TOOL_GET_NOTIFICATIONS_DESCRIPTION', 'Returns list of notifications'),
26
+ schema: z.object(getNotificationsSchema(t)),
27
+ outputSchema: NotificationSchema,
28
+ handler: async ({ minId, maxId, count, order }) => backlog.getNotifications({
29
+ minId,
30
+ maxId,
31
+ count,
32
+ order,
33
+ }),
34
+ };
35
+ };