@pschroee/redmine-mcp 0.4.5 → 0.5.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.
Files changed (54) hide show
  1. package/dist/formatters/account.d.ts +2 -0
  2. package/dist/formatters/account.js +48 -0
  3. package/dist/formatters/agile.d.ts +6 -0
  4. package/dist/formatters/agile.js +53 -0
  5. package/dist/formatters/checklist.d.ts +5 -0
  6. package/dist/formatters/checklist.js +30 -0
  7. package/dist/formatters/file.d.ts +5 -0
  8. package/dist/formatters/file.js +61 -0
  9. package/dist/formatters/group.d.ts +11 -0
  10. package/dist/formatters/group.js +53 -0
  11. package/dist/formatters/index.d.ts +15 -1
  12. package/dist/formatters/index.js +15 -1
  13. package/dist/formatters/issue.d.ts +13 -3
  14. package/dist/formatters/issue.js +43 -10
  15. package/dist/formatters/journals.d.ts +7 -1
  16. package/dist/formatters/journals.js +13 -15
  17. package/dist/formatters/membership.d.ts +5 -0
  18. package/dist/formatters/membership.js +41 -0
  19. package/dist/formatters/metadata.d.ts +135 -0
  20. package/dist/formatters/metadata.js +213 -0
  21. package/dist/formatters/project.d.ts +11 -0
  22. package/dist/formatters/project.js +82 -0
  23. package/dist/formatters/relation.d.ts +5 -0
  24. package/dist/formatters/relation.js +55 -0
  25. package/dist/formatters/search.d.ts +5 -0
  26. package/dist/formatters/search.js +61 -0
  27. package/dist/formatters/time.d.ts +11 -0
  28. package/dist/formatters/time.js +47 -0
  29. package/dist/formatters/user.d.ts +11 -0
  30. package/dist/formatters/user.js +83 -0
  31. package/dist/formatters/utils.d.ts +12 -0
  32. package/dist/formatters/utils.js +31 -0
  33. package/dist/formatters/version.d.ts +11 -0
  34. package/dist/formatters/version.js +75 -0
  35. package/dist/formatters/wiki.d.ts +11 -0
  36. package/dist/formatters/wiki.js +86 -0
  37. package/dist/redmine/client.d.ts +4 -0
  38. package/dist/redmine/client.js +6 -0
  39. package/dist/server.js +1 -1
  40. package/dist/tools/account.js +7 -1
  41. package/dist/tools/admin.js +25 -4
  42. package/dist/tools/agile.js +19 -3
  43. package/dist/tools/checklists.js +13 -2
  44. package/dist/tools/core.js +23 -5
  45. package/dist/tools/enumerations.js +19 -3
  46. package/dist/tools/files.js +13 -2
  47. package/dist/tools/memberships.js +13 -2
  48. package/dist/tools/metadata.js +37 -6
  49. package/dist/tools/relations.js +25 -4
  50. package/dist/tools/roles.js +13 -2
  51. package/dist/tools/search.js +7 -1
  52. package/dist/tools/time.js +13 -2
  53. package/dist/tools/wiki.js +13 -2
  54. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { formatMembership, formatMembershipList } from "../formatters/index.js";
2
3
  export function registerMembershipsTools(server, client) {
3
4
  server.registerTool("list_project_memberships", {
4
5
  description: "List all memberships (users and groups) for a project",
@@ -10,8 +11,13 @@ export function registerMembershipsTools(server, client) {
10
11
  }, async (params) => {
11
12
  const { project_id, ...rest } = params;
12
13
  const result = await client.listProjectMemberships(project_id, rest);
14
+ if ("error" in result) {
15
+ return {
16
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
17
+ };
18
+ }
13
19
  return {
14
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
20
+ content: [{ type: "text", text: formatMembershipList(result) }],
15
21
  };
16
22
  });
17
23
  server.registerTool("get_membership", {
@@ -21,8 +27,13 @@ export function registerMembershipsTools(server, client) {
21
27
  },
22
28
  }, async (params) => {
23
29
  const result = await client.getMembership(params.membership_id);
30
+ if ("error" in result) {
31
+ return {
32
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
33
+ };
34
+ }
24
35
  return {
25
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
36
+ content: [{ type: "text", text: formatMembership(result) }],
26
37
  };
27
38
  });
28
39
  server.registerTool("create_project_membership", {
@@ -1,12 +1,18 @@
1
1
  import { z } from "zod";
2
+ import { formatTrackerList, formatStatusList, formatCategoryList, formatCategory, formatCustomFieldList, formatQueryList } from "../formatters/index.js";
2
3
  export function registerMetadataTools(server, client) {
3
4
  // === TRACKERS ===
4
5
  server.registerTool("list_trackers", {
5
6
  description: "List all available trackers (issue types like Bug, Feature, etc.)",
6
7
  }, async () => {
7
8
  const result = await client.listTrackers();
9
+ if ("error" in result) {
10
+ return {
11
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
12
+ };
13
+ }
8
14
  return {
9
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
15
+ content: [{ type: "text", text: formatTrackerList(result) }],
10
16
  };
11
17
  });
12
18
  // === ISSUE STATUSES ===
@@ -14,8 +20,13 @@ export function registerMetadataTools(server, client) {
14
20
  description: "List all available issue statuses (New, In Progress, Closed, etc.)",
15
21
  }, async () => {
16
22
  const result = await client.listIssueStatuses();
23
+ if ("error" in result) {
24
+ return {
25
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
26
+ };
27
+ }
17
28
  return {
18
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
29
+ content: [{ type: "text", text: formatStatusList(result) }],
19
30
  };
20
31
  });
21
32
  // === ISSUE CATEGORIES ===
@@ -26,8 +37,13 @@ export function registerMetadataTools(server, client) {
26
37
  },
27
38
  }, async (params) => {
28
39
  const result = await client.listIssueCategories(params.project_id);
40
+ if ("error" in result) {
41
+ return {
42
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
43
+ };
44
+ }
29
45
  return {
30
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
46
+ content: [{ type: "text", text: formatCategoryList(result) }],
31
47
  };
32
48
  });
33
49
  server.registerTool("get_issue_category", {
@@ -37,8 +53,13 @@ export function registerMetadataTools(server, client) {
37
53
  },
38
54
  }, async (params) => {
39
55
  const result = await client.getIssueCategory(params.category_id);
56
+ if ("error" in result) {
57
+ return {
58
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
59
+ };
60
+ }
40
61
  return {
41
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
62
+ content: [{ type: "text", text: formatCategory(result) }],
42
63
  };
43
64
  });
44
65
  server.registerTool("create_issue_category", {
@@ -86,8 +107,13 @@ export function registerMetadataTools(server, client) {
86
107
  description: "List all custom field definitions (requires admin privileges)",
87
108
  }, async () => {
88
109
  const result = await client.listCustomFields();
110
+ if ("error" in result) {
111
+ return {
112
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
113
+ };
114
+ }
89
115
  return {
90
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
116
+ content: [{ type: "text", text: formatCustomFieldList(result) }],
91
117
  };
92
118
  });
93
119
  // === QUERIES ===
@@ -95,8 +121,13 @@ export function registerMetadataTools(server, client) {
95
121
  description: "List all saved issue queries (public and private)",
96
122
  }, async () => {
97
123
  const result = await client.listQueries();
124
+ if ("error" in result) {
125
+ return {
126
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
127
+ };
128
+ }
98
129
  return {
99
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
130
+ content: [{ type: "text", text: formatQueryList(result) }],
100
131
  };
101
132
  });
102
133
  }
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { formatVersion, formatVersionList, formatRelation, formatRelationList } from "../formatters/index.js";
2
3
  export function registerRelationsTools(server, client) {
3
4
  // === ISSUE RELATIONS ===
4
5
  server.registerTool("list_issue_relations", {
@@ -8,8 +9,13 @@ export function registerRelationsTools(server, client) {
8
9
  },
9
10
  }, async (params) => {
10
11
  const result = await client.listIssueRelations(params.issue_id);
12
+ if ("error" in result) {
13
+ return {
14
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
15
+ };
16
+ }
11
17
  return {
12
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
18
+ content: [{ type: "text", text: formatRelationList(result) }],
13
19
  };
14
20
  });
15
21
  server.registerTool("get_relation", {
@@ -19,8 +25,13 @@ export function registerRelationsTools(server, client) {
19
25
  },
20
26
  }, async (params) => {
21
27
  const result = await client.getRelation(params.relation_id);
28
+ if ("error" in result) {
29
+ return {
30
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
31
+ };
32
+ }
22
33
  return {
23
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
34
+ content: [{ type: "text", text: formatRelation(result) }],
24
35
  };
25
36
  });
26
37
  server.registerTool("create_issue_relation", {
@@ -76,8 +87,13 @@ export function registerRelationsTools(server, client) {
76
87
  },
77
88
  }, async (params) => {
78
89
  const result = await client.listVersions(params.project_id);
90
+ if ("error" in result) {
91
+ return {
92
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
93
+ };
94
+ }
79
95
  return {
80
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
96
+ content: [{ type: "text", text: formatVersionList(result) }],
81
97
  };
82
98
  });
83
99
  server.registerTool("get_version", {
@@ -87,8 +103,13 @@ export function registerRelationsTools(server, client) {
87
103
  },
88
104
  }, async (params) => {
89
105
  const result = await client.getVersion(params.version_id);
106
+ if ("error" in result) {
107
+ return {
108
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
109
+ };
110
+ }
90
111
  return {
91
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
112
+ content: [{ type: "text", text: formatVersion(result) }],
92
113
  };
93
114
  });
94
115
  server.registerTool("create_version", {
@@ -1,11 +1,17 @@
1
1
  import { z } from "zod";
2
+ import { formatRoleList, formatRole } from "../formatters/index.js";
2
3
  export function registerRolesTools(server, client) {
3
4
  server.registerTool("list_roles", {
4
5
  description: "List all available roles (Manager, Developer, Reporter, etc.)",
5
6
  }, async () => {
6
7
  const result = await client.listRoles();
8
+ if ("error" in result) {
9
+ return {
10
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
11
+ };
12
+ }
7
13
  return {
8
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
14
+ content: [{ type: "text", text: formatRoleList(result) }],
9
15
  };
10
16
  });
11
17
  server.registerTool("get_role", {
@@ -15,8 +21,13 @@ export function registerRolesTools(server, client) {
15
21
  },
16
22
  }, async (params) => {
17
23
  const result = await client.getRole(params.role_id);
24
+ if ("error" in result) {
25
+ return {
26
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
27
+ };
28
+ }
18
29
  return {
19
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
30
+ content: [{ type: "text", text: formatRole(result) }],
20
31
  };
21
32
  });
22
33
  }
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { formatSearchResults } from "../formatters/index.js";
2
3
  export function registerSearchTools(server, client) {
3
4
  server.registerTool("search", {
4
5
  description: "Search across Redmine (issues, wiki, news, etc.)",
@@ -21,8 +22,13 @@ export function registerSearchTools(server, client) {
21
22
  },
22
23
  }, async (params) => {
23
24
  const result = await client.search(params);
25
+ if ("error" in result) {
26
+ return {
27
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
28
+ };
29
+ }
24
30
  return {
25
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
31
+ content: [{ type: "text", text: formatSearchResults(result) }],
26
32
  };
27
33
  });
28
34
  }
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { formatTimeEntry, formatTimeEntryList } from "../formatters/index.js";
2
3
  export function registerTimeTools(server, client) {
3
4
  server.registerTool("list_time_entries", {
4
5
  description: "List time entries with optional filters",
@@ -13,8 +14,13 @@ export function registerTimeTools(server, client) {
13
14
  },
14
15
  }, async (params) => {
15
16
  const result = await client.listTimeEntries(params);
17
+ if ("error" in result) {
18
+ return {
19
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
20
+ };
21
+ }
16
22
  return {
17
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
23
+ content: [{ type: "text", text: formatTimeEntryList(result) }],
18
24
  };
19
25
  });
20
26
  server.registerTool("get_time_entry", {
@@ -24,8 +30,13 @@ export function registerTimeTools(server, client) {
24
30
  },
25
31
  }, async (params) => {
26
32
  const result = await client.getTimeEntry(params.time_entry_id);
33
+ if ("error" in result) {
34
+ return {
35
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
36
+ };
37
+ }
27
38
  return {
28
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
39
+ content: [{ type: "text", text: formatTimeEntry(result) }],
29
40
  };
30
41
  });
31
42
  server.registerTool("create_time_entry", {
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { formatWikiPage, formatWikiPageList } from "../formatters/index.js";
2
3
  export function registerWikiTools(server, client) {
3
4
  server.registerTool("list_wiki_pages", {
4
5
  description: "List all wiki pages in a project",
@@ -7,8 +8,13 @@ export function registerWikiTools(server, client) {
7
8
  },
8
9
  }, async (params) => {
9
10
  const result = await client.listWikiPages(params.project_id);
11
+ if ("error" in result) {
12
+ return {
13
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
14
+ };
15
+ }
10
16
  return {
11
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
17
+ content: [{ type: "text", text: formatWikiPageList(result) }],
12
18
  };
13
19
  });
14
20
  server.registerTool("get_wiki_page", {
@@ -24,8 +30,13 @@ export function registerWikiTools(server, client) {
24
30
  version: params.version,
25
31
  include: params.include,
26
32
  });
33
+ if ("error" in result) {
34
+ return {
35
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
36
+ };
37
+ }
27
38
  return {
28
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
39
+ content: [{ type: "text", text: formatWikiPage(result) }],
29
40
  };
30
41
  });
31
42
  server.registerTool("create_wiki_page", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pschroee/redmine-mcp",
3
- "version": "0.4.5",
3
+ "version": "0.5.1",
4
4
  "description": "MCP server for Redmine - full API access with configurable tool groups",
5
5
  "type": "module",
6
6
  "bin": {