@thelabnyc/redmine-mcp 0.1.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.
- package/LICENSE +15 -0
- package/README.md +227 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/redmine.d.ts +188 -0
- package/dist/redmine.js +165 -0
- package/dist/redmine.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +27 -0
- package/dist/server.js.map +1 -0
- package/dist/test-utils.d.ts +107 -0
- package/dist/test-utils.js +66 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/tools/__tests__/get-issue.test.d.ts +1 -0
- package/dist/tools/__tests__/get-issue.test.js +204 -0
- package/dist/tools/__tests__/get-issue.test.js.map +1 -0
- package/dist/tools/__tests__/list-issue-statuses.test.d.ts +1 -0
- package/dist/tools/__tests__/list-issue-statuses.test.js +75 -0
- package/dist/tools/__tests__/list-issue-statuses.test.js.map +1 -0
- package/dist/tools/__tests__/list-project-members.test.d.ts +1 -0
- package/dist/tools/__tests__/list-project-members.test.js +109 -0
- package/dist/tools/__tests__/list-project-members.test.js.map +1 -0
- package/dist/tools/__tests__/update-issue.test.d.ts +1 -0
- package/dist/tools/__tests__/update-issue.test.js +455 -0
- package/dist/tools/__tests__/update-issue.test.js.map +1 -0
- package/dist/tools/__tests__/whoami.test.d.ts +1 -0
- package/dist/tools/__tests__/whoami.test.js +122 -0
- package/dist/tools/__tests__/whoami.test.js.map +1 -0
- package/dist/tools/get-issue.d.ts +3 -0
- package/dist/tools/get-issue.js +71 -0
- package/dist/tools/get-issue.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-issue-statuses.d.ts +3 -0
- package/dist/tools/list-issue-statuses.js +32 -0
- package/dist/tools/list-issue-statuses.js.map +1 -0
- package/dist/tools/list-project-members.d.ts +3 -0
- package/dist/tools/list-project-members.js +48 -0
- package/dist/tools/list-project-members.js.map +1 -0
- package/dist/tools/update-issue.d.ts +3 -0
- package/dist/tools/update-issue.js +192 -0
- package/dist/tools/update-issue.js.map +1 -0
- package/dist/tools/utils.d.ts +12 -0
- package/dist/tools/utils.js +14 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/whoami.d.ts +3 -0
- package/dist/tools/whoami.js +32 -0
- package/dist/tools/whoami.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { parseIssueId } from "./utils.js";
|
|
3
|
+
export function registerGetIssueTool(server, redmineClient) {
|
|
4
|
+
server.registerTool("get-issue", {
|
|
5
|
+
title: "Get Redmine Issue",
|
|
6
|
+
description: "Fetch details about a Redmine issue by ID. Returns issue information including subject, description, status, priority, assignee, and change history (journals).",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
issueId: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("Issue ID (e.g., '#12345' or '12345')"),
|
|
11
|
+
includeAttachments: z
|
|
12
|
+
.boolean()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Include file attachments"),
|
|
15
|
+
includeWatchers: z
|
|
16
|
+
.boolean()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Include watchers list"),
|
|
19
|
+
includeRelations: z
|
|
20
|
+
.boolean()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Include related issues"),
|
|
23
|
+
includeChildren: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Include child issues"),
|
|
27
|
+
},
|
|
28
|
+
}, async ({ issueId, includeAttachments, includeWatchers, includeRelations, includeChildren, }) => {
|
|
29
|
+
try {
|
|
30
|
+
const parsed = parseIssueId(issueId);
|
|
31
|
+
if (!parsed.success) {
|
|
32
|
+
return {
|
|
33
|
+
isError: true,
|
|
34
|
+
content: [
|
|
35
|
+
{
|
|
36
|
+
type: "text",
|
|
37
|
+
text: parsed.error,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const issue = await redmineClient.getIssue(parsed.numericId, {
|
|
43
|
+
includeAttachments,
|
|
44
|
+
includeWatchers,
|
|
45
|
+
includeRelations,
|
|
46
|
+
includeChildren,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: JSON.stringify(issue, null, 2),
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
59
|
+
return {
|
|
60
|
+
isError: true,
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: `Error fetching issue: ${message}`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=get-issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-issue.js","sourceRoot":"","sources":["../../src/tools/get-issue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,oBAAoB,CAChC,MAAiB,EACjB,aAA4B;IAE5B,MAAM,CAAC,YAAY,CACf,WAAW,EACX;QACI,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACP,iKAAiK;QACrK,WAAW,EAAE;YACT,OAAO,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,sCAAsC,CAAC;YACrD,kBAAkB,EAAE,CAAC;iBAChB,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,0BAA0B,CAAC;YACzC,eAAe,EAAE,CAAC;iBACb,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,uBAAuB,CAAC;YACtC,gBAAgB,EAAE,CAAC;iBACd,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,wBAAwB,CAAC;YACvC,eAAe,EAAE,CAAC;iBACb,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,sBAAsB,CAAC;SACxC;KACJ,EACD,KAAK,EAAE,EACH,OAAO,EACP,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,eAAe,GAClB,EAAE,EAAE;QACD,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO;oBACH,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE;wBACL;4BACI,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,MAAM,CAAC,KAAK;yBACrB;qBACJ;iBACJ,CAAC;YACN,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE;gBACzD,kBAAkB;gBAClB,eAAe;gBACf,gBAAgB;gBAChB,eAAe;aAClB,CAAC,CAAC;YAEH,OAAO;gBACH,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;qBACvC;iBACJ;aACJ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,yBAAyB,OAAO,EAAE;qBAC3C;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { RedmineClient } from "../redmine.js";
|
|
3
|
+
import { registerGetIssueTool } from "./get-issue.js";
|
|
4
|
+
import { registerListIssueStatusesTool } from "./list-issue-statuses.js";
|
|
5
|
+
import { registerListProjectMembersTool } from "./list-project-members.js";
|
|
6
|
+
import { registerUpdateIssueTool } from "./update-issue.js";
|
|
7
|
+
import { registerWhoamiTool } from "./whoami.js";
|
|
8
|
+
export declare function registerAllTools(server: McpServer, redmineClient: RedmineClient): void;
|
|
9
|
+
export { registerGetIssueTool, registerListIssueStatusesTool, registerListProjectMembersTool, registerUpdateIssueTool, registerWhoamiTool, };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { registerGetIssueTool } from "./get-issue.js";
|
|
2
|
+
import { registerListIssueStatusesTool } from "./list-issue-statuses.js";
|
|
3
|
+
import { registerListProjectMembersTool } from "./list-project-members.js";
|
|
4
|
+
import { registerUpdateIssueTool } from "./update-issue.js";
|
|
5
|
+
import { registerWhoamiTool } from "./whoami.js";
|
|
6
|
+
export function registerAllTools(server, redmineClient) {
|
|
7
|
+
registerGetIssueTool(server, redmineClient);
|
|
8
|
+
registerListProjectMembersTool(server, redmineClient);
|
|
9
|
+
registerUpdateIssueTool(server, redmineClient);
|
|
10
|
+
registerListIssueStatusesTool(server, redmineClient);
|
|
11
|
+
registerWhoamiTool(server, redmineClient);
|
|
12
|
+
}
|
|
13
|
+
export { registerGetIssueTool, registerListIssueStatusesTool, registerListProjectMembersTool, registerUpdateIssueTool, registerWhoamiTool, };
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,UAAU,gBAAgB,CAC5B,MAAiB,EACjB,aAA4B;IAE5B,oBAAoB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,8BAA8B,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtD,uBAAuB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC/C,6BAA6B,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrD,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,OAAO,EACH,oBAAoB,EACpB,6BAA6B,EAC7B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,GACrB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function registerListIssueStatusesTool(server, redmineClient) {
|
|
2
|
+
server.registerTool("list-issue-statuses", {
|
|
3
|
+
title: "List Issue Statuses",
|
|
4
|
+
description: "List all available issue statuses in Redmine. Returns status IDs, names, and whether they represent a closed state. Use this to find valid status IDs when updating issues.",
|
|
5
|
+
inputSchema: {},
|
|
6
|
+
}, async () => {
|
|
7
|
+
try {
|
|
8
|
+
const statuses = await redmineClient.listIssueStatuses();
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: JSON.stringify(statuses, null, 2),
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
return {
|
|
21
|
+
isError: true,
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: `Error fetching issue statuses: ${message}`,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=list-issue-statuses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-issue-statuses.js","sourceRoot":"","sources":["../../src/tools/list-issue-statuses.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,6BAA6B,CACzC,MAAiB,EACjB,aAA4B;IAE5B,MAAM,CAAC,YAAY,CACf,qBAAqB,EACrB;QACI,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACP,6KAA6K;QACjL,WAAW,EAAE,EAAE;KAClB,EACD,KAAK,IAAI,EAAE;QACP,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,iBAAiB,EAAE,CAAC;YAEzD,OAAO;gBACH,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;qBAC1C;iBACJ;aACJ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kCAAkC,OAAO,EAAE;qBACpD;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
export function registerListProjectMembersTool(server, redmineClient) {
|
|
3
|
+
server.registerTool("list-project-members", {
|
|
4
|
+
title: "List Project Members",
|
|
5
|
+
description: "List all members of a Redmine project. Returns users and groups with their roles. Use this to find user IDs for assigning issues.",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
projectId: z
|
|
8
|
+
.string()
|
|
9
|
+
.describe("Project ID or identifier (e.g., 'my-project' or '1')"),
|
|
10
|
+
limit: z
|
|
11
|
+
.number()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Maximum number of members to return (default 25)"),
|
|
14
|
+
offset: z
|
|
15
|
+
.number()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Number of members to skip for pagination"),
|
|
18
|
+
},
|
|
19
|
+
}, async ({ projectId, limit, offset }) => {
|
|
20
|
+
try {
|
|
21
|
+
const result = await redmineClient.listProjectMembers(projectId, {
|
|
22
|
+
limit,
|
|
23
|
+
offset,
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: JSON.stringify(result, null, 2),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
return {
|
|
37
|
+
isError: true,
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: `Error listing project members: ${message}`,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=list-project-members.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-project-members.js","sourceRoot":"","sources":["../../src/tools/list-project-members.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAIzB,MAAM,UAAU,8BAA8B,CAC1C,MAAiB,EACjB,aAA4B;IAE5B,MAAM,CAAC,YAAY,CACf,sBAAsB,EACtB;QACI,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACP,mIAAmI;QACvI,WAAW,EAAE;YACT,SAAS,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,CACL,sDAAsD,CACzD;YACL,KAAK,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACL,kDAAkD,CACrD;YACL,MAAM,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,0CAA0C,CAAC;SAC5D;KACJ,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QACnC,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,kBAAkB,CACjD,SAAS,EACT;gBACI,KAAK;gBACL,MAAM;aACT,CACJ,CAAC;YAEF,OAAO;gBACH,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACxC;iBACJ;aACJ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kCAAkC,OAAO,EAAE;qBACpD;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { parseIssueId } from "./utils.js";
|
|
3
|
+
export function registerUpdateIssueTool(server, redmineClient) {
|
|
4
|
+
server.registerTool("update-issue", {
|
|
5
|
+
title: "Update Redmine Issue",
|
|
6
|
+
description: "Update a Redmine issue. Can update fields like status, assignee, add notes, and optionally log time spent. All parameters except issueId are optional.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
issueId: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("Issue ID (e.g., '#12345' or '12345')"),
|
|
11
|
+
// Issue fields
|
|
12
|
+
subject: z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("New issue subject/title"),
|
|
16
|
+
description: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("New issue description"),
|
|
20
|
+
statusId: z.number().optional().describe("Status ID to set"),
|
|
21
|
+
priorityId: z
|
|
22
|
+
.number()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Priority ID to set"),
|
|
25
|
+
assignedToId: z
|
|
26
|
+
.number()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("User ID to assign (use 0 to unassign)"),
|
|
29
|
+
trackerId: z.number().optional().describe("Tracker ID to set"),
|
|
30
|
+
parentIssueId: z
|
|
31
|
+
.number()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Parent issue ID"),
|
|
34
|
+
startDate: z
|
|
35
|
+
.string()
|
|
36
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD format")
|
|
37
|
+
.optional()
|
|
38
|
+
.describe("Start date (YYYY-MM-DD format)"),
|
|
39
|
+
dueDate: z
|
|
40
|
+
.string()
|
|
41
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD format")
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("Due date (YYYY-MM-DD format)"),
|
|
44
|
+
doneRatio: z
|
|
45
|
+
.number()
|
|
46
|
+
.min(0)
|
|
47
|
+
.max(100)
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Percent done (0-100)"),
|
|
50
|
+
estimatedHours: z
|
|
51
|
+
.number()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe("Estimated hours for the issue"),
|
|
54
|
+
notes: z
|
|
55
|
+
.string()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe("Comment/note to add to the issue journal"),
|
|
58
|
+
privateNotes: z
|
|
59
|
+
.boolean()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Make the notes private (default false)"),
|
|
62
|
+
// Time logging
|
|
63
|
+
logHours: z
|
|
64
|
+
.number()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe("Hours to log as a time entry"),
|
|
67
|
+
logActivityId: z
|
|
68
|
+
.number()
|
|
69
|
+
.optional()
|
|
70
|
+
.describe("Activity ID for time entry (uses default activity if omitted)"),
|
|
71
|
+
logComments: z
|
|
72
|
+
.string()
|
|
73
|
+
.optional()
|
|
74
|
+
.describe("Comments for the time entry"),
|
|
75
|
+
logSpentOn: z
|
|
76
|
+
.string()
|
|
77
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD format")
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("Date for time entry (YYYY-MM-DD, defaults to today)"),
|
|
80
|
+
},
|
|
81
|
+
}, async ({ issueId, subject, description, statusId, priorityId, assignedToId, trackerId, parentIssueId, startDate, dueDate, doneRatio, estimatedHours, notes, privateNotes, logHours, logActivityId, logComments, logSpentOn, }) => {
|
|
82
|
+
try {
|
|
83
|
+
const parsed = parseIssueId(issueId);
|
|
84
|
+
if (!parsed.success) {
|
|
85
|
+
return {
|
|
86
|
+
isError: true,
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: parsed.error,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const numericId = parsed.numericId;
|
|
96
|
+
// Build update data (convert camelCase to snake_case)
|
|
97
|
+
const updateData = {};
|
|
98
|
+
if (subject !== undefined)
|
|
99
|
+
updateData.subject = subject;
|
|
100
|
+
if (description !== undefined)
|
|
101
|
+
updateData.description = description;
|
|
102
|
+
if (statusId !== undefined)
|
|
103
|
+
updateData.status_id = statusId;
|
|
104
|
+
if (priorityId !== undefined)
|
|
105
|
+
updateData.priority_id = priorityId;
|
|
106
|
+
if (assignedToId !== undefined)
|
|
107
|
+
updateData.assigned_to_id = assignedToId;
|
|
108
|
+
if (trackerId !== undefined)
|
|
109
|
+
updateData.tracker_id = trackerId;
|
|
110
|
+
if (parentIssueId !== undefined)
|
|
111
|
+
updateData.parent_issue_id = parentIssueId;
|
|
112
|
+
if (startDate !== undefined)
|
|
113
|
+
updateData.start_date = startDate;
|
|
114
|
+
if (dueDate !== undefined)
|
|
115
|
+
updateData.due_date = dueDate;
|
|
116
|
+
if (doneRatio !== undefined)
|
|
117
|
+
updateData.done_ratio = doneRatio;
|
|
118
|
+
if (estimatedHours !== undefined)
|
|
119
|
+
updateData.estimated_hours = estimatedHours;
|
|
120
|
+
if (notes !== undefined)
|
|
121
|
+
updateData.notes = notes;
|
|
122
|
+
if (privateNotes !== undefined)
|
|
123
|
+
updateData.private_notes = privateNotes;
|
|
124
|
+
// Update the issue
|
|
125
|
+
const updatedIssue = await redmineClient.updateIssue(numericId, updateData);
|
|
126
|
+
// Handle time logging if requested
|
|
127
|
+
let timeEntry = undefined;
|
|
128
|
+
let timeEntryError = undefined;
|
|
129
|
+
if (logHours !== undefined) {
|
|
130
|
+
try {
|
|
131
|
+
// Get activity ID - use provided or find default
|
|
132
|
+
let activityId = logActivityId;
|
|
133
|
+
if (activityId === undefined) {
|
|
134
|
+
const activities = await redmineClient.getTimeEntryActivities();
|
|
135
|
+
const defaultActivity = activities.find((a) => a.is_default);
|
|
136
|
+
if (defaultActivity) {
|
|
137
|
+
activityId = defaultActivity.id;
|
|
138
|
+
}
|
|
139
|
+
else if (activities.length > 0) {
|
|
140
|
+
// Fall back to first activity if no default
|
|
141
|
+
activityId = activities[0].id;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
timeEntry = await redmineClient.createTimeEntry({
|
|
145
|
+
issue_id: numericId,
|
|
146
|
+
hours: logHours,
|
|
147
|
+
activity_id: activityId,
|
|
148
|
+
comments: logComments,
|
|
149
|
+
spent_on: logSpentOn,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
const message = error instanceof Error
|
|
154
|
+
? error.message
|
|
155
|
+
: String(error);
|
|
156
|
+
timeEntryError = `Failed to create time entry: ${message}`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Build response
|
|
160
|
+
const response = {
|
|
161
|
+
issue: updatedIssue,
|
|
162
|
+
};
|
|
163
|
+
if (timeEntry) {
|
|
164
|
+
response.time_entry = timeEntry;
|
|
165
|
+
}
|
|
166
|
+
if (timeEntryError) {
|
|
167
|
+
response.time_entry_error = timeEntryError;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: JSON.stringify(response, null, 2),
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
180
|
+
return {
|
|
181
|
+
isError: true,
|
|
182
|
+
content: [
|
|
183
|
+
{
|
|
184
|
+
type: "text",
|
|
185
|
+
text: `Error updating issue: ${message}`,
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=update-issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-issue.js","sourceRoot":"","sources":["../../src/tools/update-issue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,uBAAuB,CACnC,MAAiB,EACjB,aAA4B;IAE5B,MAAM,CAAC,YAAY,CACf,cAAc,EACd;QACI,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACP,wJAAwJ;QAC5J,WAAW,EAAE;YACT,OAAO,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,sCAAsC,CAAC;YACrD,eAAe;YACf,OAAO,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yBAAyB,CAAC;YACxC,WAAW,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,uBAAuB,CAAC;YACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAC5D,UAAU,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,oBAAoB,CAAC;YACnC,YAAY,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,uCAAuC,CAAC;YACtD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAC9D,aAAa,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iBAAiB,CAAC;YAChC,SAAS,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,KAAK,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;iBACzD,QAAQ,EAAE;iBACV,QAAQ,CAAC,gCAAgC,CAAC;YAC/C,OAAO,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,KAAK,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;iBACzD,QAAQ,EAAE;iBACV,QAAQ,CAAC,8BAA8B,CAAC;YAC7C,SAAS,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,GAAG,CAAC;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,sBAAsB,CAAC;YACrC,cAAc,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,+BAA+B,CAAC;YAC9C,KAAK,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,0CAA0C,CAAC;YACzD,YAAY,EAAE,CAAC;iBACV,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,wCAAwC,CAAC;YACvD,eAAe;YACf,QAAQ,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,8BAA8B,CAAC;YAC7C,aAAa,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACL,+DAA+D,CAClE;YACL,WAAW,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,6BAA6B,CAAC;YAC5C,UAAU,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,KAAK,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;iBACzD,QAAQ,EAAE;iBACV,QAAQ,CACL,qDAAqD,CACxD;SACR;KACJ,EACD,KAAK,EAAE,EACH,OAAO,EACP,OAAO,EACP,WAAW,EACX,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,EACT,aAAa,EACb,SAAS,EACT,OAAO,EACP,SAAS,EACT,cAAc,EACd,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,WAAW,EACX,UAAU,GACb,EAAE,EAAE;QACD,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO;oBACH,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE;wBACL;4BACI,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,MAAM,CAAC,KAAK;yBACrB;qBACJ;iBACJ,CAAC;YACN,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;YAEnC,sDAAsD;YACtD,MAAM,UAAU,GAA4B,EAAE,CAAC;YAC/C,IAAI,OAAO,KAAK,SAAS;gBAAE,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;YACxD,IAAI,WAAW,KAAK,SAAS;gBACzB,UAAU,CAAC,WAAW,GAAG,WAAW,CAAC;YACzC,IAAI,QAAQ,KAAK,SAAS;gBAAE,UAAU,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC5D,IAAI,UAAU,KAAK,SAAS;gBACxB,UAAU,CAAC,WAAW,GAAG,UAAU,CAAC;YACxC,IAAI,YAAY,KAAK,SAAS;gBAC1B,UAAU,CAAC,cAAc,GAAG,YAAY,CAAC;YAC7C,IAAI,SAAS,KAAK,SAAS;gBAAE,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC;YAC/D,IAAI,aAAa,KAAK,SAAS;gBAC3B,UAAU,CAAC,eAAe,GAAG,aAAa,CAAC;YAC/C,IAAI,SAAS,KAAK,SAAS;gBAAE,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC;YAC/D,IAAI,OAAO,KAAK,SAAS;gBAAE,UAAU,CAAC,QAAQ,GAAG,OAAO,CAAC;YACzD,IAAI,SAAS,KAAK,SAAS;gBAAE,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC;YAC/D,IAAI,cAAc,KAAK,SAAS;gBAC5B,UAAU,CAAC,eAAe,GAAG,cAAc,CAAC;YAChD,IAAI,KAAK,KAAK,SAAS;gBAAE,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC;YAClD,IAAI,YAAY,KAAK,SAAS;gBAC1B,UAAU,CAAC,aAAa,GAAG,YAAY,CAAC;YAE5C,mBAAmB;YACnB,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,WAAW,CAChD,SAAS,EACT,UAAU,CACb,CAAC;YAEF,mCAAmC;YACnC,IAAI,SAAS,GAAG,SAAS,CAAC;YAC1B,IAAI,cAAc,GAAG,SAAS,CAAC;YAE/B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACD,iDAAiD;oBACjD,IAAI,UAAU,GAAG,aAAa,CAAC;oBAC/B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;wBAC3B,MAAM,UAAU,GACZ,MAAM,aAAa,CAAC,sBAAsB,EAAE,CAAC;wBACjD,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CACtB,CAAC;wBACF,IAAI,eAAe,EAAE,CAAC;4BAClB,UAAU,GAAG,eAAe,CAAC,EAAE,CAAC;wBACpC,CAAC;6BAAM,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAC/B,4CAA4C;4BAC5C,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClC,CAAC;oBACL,CAAC;oBAED,SAAS,GAAG,MAAM,aAAa,CAAC,eAAe,CAAC;wBAC5C,QAAQ,EAAE,SAAS;wBACnB,KAAK,EAAE,QAAQ;wBACf,WAAW,EAAE,UAAU;wBACvB,QAAQ,EAAE,WAAW;wBACrB,QAAQ,EAAE,UAAU;qBACvB,CAAC,CAAC;gBACP,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,MAAM,OAAO,GACT,KAAK,YAAY,KAAK;wBAClB,CAAC,CAAC,KAAK,CAAC,OAAO;wBACf,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACxB,cAAc,GAAG,gCAAgC,OAAO,EAAE,CAAC;gBAC/D,CAAC;YACL,CAAC;YAED,iBAAiB;YACjB,MAAM,QAAQ,GAA4B;gBACtC,KAAK,EAAE,YAAY;aACtB,CAAC;YACF,IAAI,SAAS,EAAE,CAAC;gBACZ,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC;YACpC,CAAC;YACD,IAAI,cAAc,EAAE,CAAC;gBACjB,QAAQ,CAAC,gBAAgB,GAAG,cAAc,CAAC;YAC/C,CAAC;YAED,OAAO;gBACH,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;qBAC1C;iBACJ;aACJ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,yBAAyB,OAAO,EAAE;qBAC3C;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse an issue ID string, handling optional # prefix
|
|
3
|
+
* @param issueId - Issue ID string (e.g., "#12345" or "12345")
|
|
4
|
+
* @returns Object with either numericId or error
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseIssueId(issueId: string): {
|
|
7
|
+
success: true;
|
|
8
|
+
numericId: number;
|
|
9
|
+
} | {
|
|
10
|
+
success: false;
|
|
11
|
+
error: string;
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse an issue ID string, handling optional # prefix
|
|
3
|
+
* @param issueId - Issue ID string (e.g., "#12345" or "12345")
|
|
4
|
+
* @returns Object with either numericId or error
|
|
5
|
+
*/
|
|
6
|
+
export function parseIssueId(issueId) {
|
|
7
|
+
const cleanId = issueId.replace(/^#/, "");
|
|
8
|
+
const numericId = parseInt(cleanId, 10);
|
|
9
|
+
if (isNaN(numericId)) {
|
|
10
|
+
return { success: false, error: `Invalid issue ID: ${issueId}` };
|
|
11
|
+
}
|
|
12
|
+
return { success: true, numericId };
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,YAAY,CACxB,OAAe;IAEf,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAExC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,OAAO,EAAE,EAAE,CAAC;IACrE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function registerWhoamiTool(server, redmineClient) {
|
|
2
|
+
server.registerTool("whoami", {
|
|
3
|
+
title: "Who Am I",
|
|
4
|
+
description: "Get the current user's account information. Returns the user ID, login, name, email, and other account details. Use this to identify yourself when you need to assign issues to yourself or perform other user-specific actions.",
|
|
5
|
+
inputSchema: {},
|
|
6
|
+
}, async () => {
|
|
7
|
+
try {
|
|
8
|
+
const user = await redmineClient.getCurrentUser();
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: JSON.stringify(user, null, 2),
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
return {
|
|
21
|
+
isError: true,
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: `Error fetching current user: ${message}`,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,kBAAkB,CAC9B,MAAiB,EACjB,aAA4B;IAE5B,MAAM,CAAC,YAAY,CACf,QAAQ,EACR;QACI,KAAK,EAAE,UAAU;QACjB,WAAW,EACP,kOAAkO;QACtO,WAAW,EAAE,EAAE;KAClB,EACD,KAAK,IAAI,EAAE;QACP,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,cAAc,EAAE,CAAC;YAElD,OAAO;gBACH,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;qBACtC;iBACJ;aACJ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,gCAAgC,OAAO,EAAE;qBAClD;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thelabnyc/redmine-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "ISC",
|
|
5
|
+
"author": "thelab <thelabdev@thelab.co>",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://gitlab.com/thelabnyc/redmine-mcp.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/**/*"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc --noEmit false",
|
|
18
|
+
"lint": "eslint ./src",
|
|
19
|
+
"start": "./cli.js",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"redmine-mcp": "dist/cli.js"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
28
|
+
"zod": "^3.24.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@thelabnyc/standards": "^0.5.0",
|
|
32
|
+
"@tsconfig/node-lts": "^24.0.0",
|
|
33
|
+
"@types/node": "^24.0.14",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"vitest": "^4.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"npm": ">=11.6.2",
|
|
39
|
+
"node": ">=24.11.1"
|
|
40
|
+
}
|
|
41
|
+
}
|