@grec0/memory-bank-mcp 0.0.2 → 0.0.3

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.
@@ -1,186 +0,0 @@
1
- /**
2
- * @fileoverview Board membership operations for the MCP Kanban server
3
- *
4
- * This module provides functions for managing board memberships in the Planka Kanban system,
5
- * including creating, retrieving, updating, and deleting board memberships, which control
6
- * user access and permissions to boards.
7
- */
8
- import { z } from "zod";
9
- import { plankaRequest } from "../common/utils.js";
10
- // Schema definitions
11
- /**
12
- * Schema for creating a new board membership
13
- * @property {string} boardId - The ID of the board to add the user to
14
- * @property {string} userId - The ID of the user to add to the board
15
- * @property {string} role - The role of the user on the board (editor or viewer)
16
- */
17
- export const CreateBoardMembershipSchema = z.object({
18
- boardId: z.string().describe("Board ID"),
19
- userId: z.string().describe("User ID"),
20
- role: z.enum(["editor", "viewer"]).describe("Membership role (editor or viewer)"),
21
- });
22
- /**
23
- * Schema for retrieving board memberships
24
- * @property {string} boardId - The ID of the board to get memberships for
25
- */
26
- export const GetBoardMembershipsSchema = z.object({
27
- boardId: z.string().describe("Board ID"),
28
- });
29
- /**
30
- * Schema for retrieving a specific board membership
31
- * @property {string} id - The ID of the board membership to retrieve
32
- */
33
- export const GetBoardMembershipSchema = z.object({
34
- id: z.string().describe("Board Membership ID"),
35
- });
36
- /**
37
- * Schema for updating a board membership
38
- * @property {string} id - The ID of the board membership to update
39
- * @property {string} role - The new role for the user (editor or viewer)
40
- * @property {boolean} [canComment] - Whether the user can comment on cards
41
- */
42
- export const UpdateBoardMembershipSchema = z.object({
43
- id: z.string().describe("Board Membership ID"),
44
- role: z.enum(["editor", "viewer"]).describe("Membership role (editor or viewer)"),
45
- canComment: z.boolean().optional().describe("Whether the user can comment on cards"),
46
- });
47
- /**
48
- * Schema for deleting a board membership
49
- * @property {string} id - The ID of the board membership to delete
50
- */
51
- export const DeleteBoardMembershipSchema = z.object({
52
- id: z.string().describe("Board Membership ID"),
53
- });
54
- // Board membership schema
55
- const BoardMembershipSchema = z.object({
56
- id: z.string(),
57
- boardId: z.string(),
58
- userId: z.string(),
59
- role: z.string(),
60
- canComment: z.boolean().nullable(),
61
- createdAt: z.string(),
62
- updatedAt: z.string().nullable(),
63
- });
64
- // Response schemas
65
- const BoardMembershipsResponseSchema = z.object({
66
- items: z.array(BoardMembershipSchema),
67
- included: z.record(z.any()).optional(),
68
- });
69
- const BoardMembershipResponseSchema = z.object({
70
- item: BoardMembershipSchema,
71
- included: z.record(z.any()).optional(),
72
- });
73
- // Function implementations
74
- /**
75
- * Creates a new board membership (adds a user to a board with specified permissions)
76
- *
77
- * @param {CreateBoardMembershipOptions} options - Options for creating the board membership
78
- * @param {string} options.boardId - The ID of the board to add the user to
79
- * @param {string} options.userId - The ID of the user to add to the board
80
- * @param {string} options.role - The role of the user on the board (editor or viewer)
81
- * @returns {Promise<object>} The created board membership
82
- * @throws {Error} If the board membership creation fails
83
- */
84
- export async function createBoardMembership(options) {
85
- try {
86
- const response = await plankaRequest(`/api/boards/${options.boardId}/memberships`, {
87
- method: "POST",
88
- body: {
89
- userId: options.userId,
90
- role: options.role,
91
- },
92
- });
93
- const parsedResponse = BoardMembershipResponseSchema.parse(response);
94
- return parsedResponse.item;
95
- }
96
- catch (error) {
97
- throw new Error(`Failed to create board membership: ${error instanceof Error ? error.message : String(error)}`);
98
- }
99
- }
100
- /**
101
- * Retrieves all memberships for a specific board
102
- *
103
- * @param {string} boardId - The ID of the board to get memberships for
104
- * @returns {Promise<Array<object>>} Array of board memberships
105
- * @throws {Error} If retrieving board memberships fails
106
- */
107
- export async function getBoardMemberships(boardId) {
108
- try {
109
- const response = await plankaRequest(`/api/boards/${boardId}/memberships`);
110
- try {
111
- // Try to parse as a BoardMembershipsResponseSchema first
112
- const parsedResponse = BoardMembershipsResponseSchema.parse(response);
113
- return parsedResponse.items;
114
- }
115
- catch (parseError) {
116
- // If that fails, try to parse as an array directly
117
- if (Array.isArray(response)) {
118
- return z.array(BoardMembershipSchema).parse(response);
119
- }
120
- // If we get here, we couldn't parse the response in any expected format
121
- throw new Error(`Could not parse board memberships response: ${JSON.stringify(response)}`);
122
- }
123
- }
124
- catch (error) {
125
- // If all else fails, return an empty array
126
- return [];
127
- }
128
- }
129
- /**
130
- * Retrieves a specific board membership by ID
131
- *
132
- * @param {string} id - The ID of the board membership to retrieve
133
- * @returns {Promise<object>} The requested board membership
134
- * @throws {Error} If retrieving the board membership fails
135
- */
136
- export async function getBoardMembership(id) {
137
- try {
138
- const response = await plankaRequest(`/api/board-memberships/${id}`);
139
- const parsedResponse = BoardMembershipResponseSchema.parse(response);
140
- return parsedResponse.item;
141
- }
142
- catch (error) {
143
- throw new Error(`Failed to get board membership: ${error instanceof Error ? error.message : String(error)}`);
144
- }
145
- }
146
- /**
147
- * Updates a board membership's properties (user permissions on a board)
148
- *
149
- * @param {string} id - The ID of the board membership to update
150
- * @param {Partial<Omit<CreateBoardMembershipOptions, "boardId" | "userId">>} options - The properties to update
151
- * @param {string} [options.role] - The new role for the user (editor or viewer)
152
- * @param {boolean} [options.canComment] - Whether the user can comment on cards
153
- * @returns {Promise<object>} The updated board membership
154
- * @throws {Error} If updating the board membership fails
155
- */
156
- export async function updateBoardMembership(id, options) {
157
- try {
158
- const response = await plankaRequest(`/api/board-memberships/${id}`, {
159
- method: "PATCH",
160
- body: options,
161
- });
162
- const parsedResponse = BoardMembershipResponseSchema.parse(response);
163
- return parsedResponse.item;
164
- }
165
- catch (error) {
166
- throw new Error(`Failed to update board membership: ${error instanceof Error ? error.message : String(error)}`);
167
- }
168
- }
169
- /**
170
- * Deletes a board membership by ID (removes a user from a board)
171
- *
172
- * @param {string} id - The ID of the board membership to delete
173
- * @returns {Promise<{success: boolean}>} Success indicator
174
- * @throws {Error} If deleting the board membership fails
175
- */
176
- export async function deleteBoardMembership(id) {
177
- try {
178
- await plankaRequest(`/api/board-memberships/${id}`, {
179
- method: "DELETE",
180
- });
181
- return { success: true };
182
- }
183
- catch (error) {
184
- throw new Error(`Failed to delete board membership: ${error instanceof Error ? error.message : String(error)}`);
185
- }
186
- }
@@ -1,268 +0,0 @@
1
- /**
2
- * @fileoverview Board operations for the MCP Kanban server
3
- *
4
- * This module provides functions for interacting with boards in the Planka Kanban system,
5
- * including creating, retrieving, updating, and deleting boards. It also handles
6
- * the creation of default lists and labels when a new board is created.
7
- */
8
- import { z } from "zod";
9
- import { plankaRequest } from "../common/utils.js";
10
- import { PlankaBoardSchema } from "../common/types.js";
11
- import { getAdminUserId } from "../common/setup.js";
12
- import * as boardMemberships from "./boardMemberships.js";
13
- import * as lists from "./lists.js";
14
- import * as labels from "./labels.js";
15
- // Schema definitions
16
- /**
17
- * Schema for creating a new board
18
- * @property {string} projectId - The ID of the project to create the board in
19
- * @property {string} name - The name of the board
20
- * @property {number} [position] - The position of the board in the project (default: 65535)
21
- */
22
- export const CreateBoardSchema = z.object({
23
- projectId: z.string().describe("Project ID"),
24
- name: z.string().describe("Board name"),
25
- position: z.number().default(65535).describe("Board position (default: 65535)"),
26
- });
27
- /**
28
- * Schema for retrieving boards from a project
29
- * @property {string} projectId - The ID of the project to get boards from
30
- */
31
- export const GetBoardsSchema = z.object({
32
- projectId: z.string().describe("Project ID"),
33
- });
34
- /**
35
- * Schema for retrieving a specific board
36
- * @property {string} id - The ID of the board to retrieve
37
- */
38
- export const GetBoardSchema = z.object({
39
- id: z.string().describe("Board ID"),
40
- });
41
- /**
42
- * Schema for updating a board
43
- * @property {string} id - The ID of the board to update
44
- * @property {string} [name] - The new name for the board
45
- * @property {number} [position] - The new position for the board
46
- * @property {string} [type] - The type of the board
47
- */
48
- export const UpdateBoardSchema = z.object({
49
- id: z.string().describe("Board ID"),
50
- name: z.string().optional().describe("Board name"),
51
- position: z.number().optional().describe("Board position"),
52
- type: z.string().optional().describe("Board type"),
53
- });
54
- /**
55
- * Schema for deleting a board
56
- * @property {string} id - The ID of the board to delete
57
- */
58
- export const DeleteBoardSchema = z.object({
59
- id: z.string().describe("Board ID"),
60
- });
61
- // Response schemas
62
- const BoardsResponseSchema = z.object({
63
- items: z.array(PlankaBoardSchema),
64
- included: z.record(z.any()).optional(),
65
- });
66
- const BoardResponseSchema = z.object({
67
- item: PlankaBoardSchema,
68
- included: z.record(z.any()).optional(),
69
- });
70
- // Function implementations
71
- /**
72
- * Creates default lists for a new board
73
- *
74
- * @param {string} boardId - The ID of the board to create lists for
75
- * @returns {Promise<void>}
76
- * @private
77
- */
78
- async function createDefaultLists(boardId) {
79
- try {
80
- const defaultLists = [
81
- { name: "Backlog", position: 65535 },
82
- { name: "To Do", position: 131070 },
83
- { name: "In Progress", position: 196605 },
84
- { name: "On Hold", position: 262140 },
85
- { name: "Review", position: 327675 },
86
- { name: "Done", position: 393210 },
87
- ];
88
- for (const list of defaultLists) {
89
- await lists.createList({
90
- boardId,
91
- name: list.name,
92
- position: list.position,
93
- });
94
- }
95
- }
96
- catch (error) {
97
- console.error(`Error creating default lists for board ${boardId}:`, error instanceof Error ? error.message : String(error));
98
- }
99
- }
100
- /**
101
- * Creates default labels for a new board
102
- * @param boardId The ID of the board to create labels for
103
- */
104
- async function createDefaultLabels(boardId) {
105
- try {
106
- // Priority labels
107
- const priorityLabels = [
108
- { name: "P0: Critical", color: "berry-red", position: 65535 },
109
- { name: "P1: High", color: "red-burgundy", position: 131070 },
110
- { name: "P2: Medium", color: "pumpkin-orange", position: 196605 },
111
- { name: "P3: Low", color: "sunny-grass", position: 262140 },
112
- ];
113
- // Type labels
114
- const typeLabels = [
115
- { name: "Bug", color: "coral-green", position: 327675 },
116
- { name: "Feature", color: "lagoon-blue", position: 393210 },
117
- { name: "Enhancement", color: "bright-moss", position: 458745 },
118
- { name: "Documentation", color: "light-orange", position: 524280 },
119
- ];
120
- // Status labels
121
- const statusLabels = [
122
- { name: "Blocked", color: "midnight-blue", position: 589815 },
123
- { name: "Needs Info", color: "desert-sand", position: 655350 },
124
- { name: "Ready", color: "egg-yellow", position: 720885 },
125
- ];
126
- // Combine all labels
127
- const defaultLabels = [
128
- ...priorityLabels,
129
- ...typeLabels,
130
- ...statusLabels,
131
- ];
132
- for (const label of defaultLabels) {
133
- await labels.createLabel({
134
- boardId,
135
- name: label.name,
136
- color: label.color, // Type assertion needed due to enum constraints
137
- position: label.position,
138
- });
139
- }
140
- }
141
- catch (error) {
142
- console.error(`Error creating default labels for board ${boardId}:`, error instanceof Error ? error.message : String(error));
143
- }
144
- }
145
- /**
146
- * Creates a new board in a project with default lists and labels
147
- *
148
- * @param {CreateBoardOptions} options - Options for creating the board
149
- * @param {string} options.projectId - The ID of the project to create the board in
150
- * @param {string} options.name - The name of the board
151
- * @param {number} [options.position] - The position of the board in the project
152
- * @returns {Promise<object>} The created board
153
- * @throws {Error} If the board creation fails
154
- */
155
- export async function createBoard(options) {
156
- try {
157
- const response = await plankaRequest(`/api/projects/${options.projectId}/boards`, {
158
- method: "POST",
159
- body: {
160
- name: options.name,
161
- position: options.position,
162
- },
163
- });
164
- const parsedResponse = BoardResponseSchema.parse(response);
165
- const board = parsedResponse.item;
166
- // Add the admin user as a board member
167
- try {
168
- const adminUserId = await getAdminUserId();
169
- if (adminUserId) {
170
- await boardMemberships.createBoardMembership({
171
- boardId: board.id,
172
- userId: adminUserId,
173
- role: "editor",
174
- });
175
- }
176
- else {
177
- console.error("Could not add admin user as board member: Admin user ID not found");
178
- }
179
- }
180
- catch (error) {
181
- console.error("Error adding admin user as board member:", error);
182
- }
183
- // Create default lists and labels
184
- await createDefaultLists(board.id);
185
- await createDefaultLabels(board.id);
186
- return board;
187
- }
188
- catch (error) {
189
- throw new Error(`Failed to create board: ${error instanceof Error ? error.message : String(error)}`);
190
- }
191
- }
192
- /**
193
- * Retrieves all boards for a specific project
194
- *
195
- * @param {string} projectId - The ID of the project to get boards from
196
- * @returns {Promise<Array<object>>} Array of boards in the project
197
- * @throws {Error} If retrieving boards fails
198
- */
199
- export async function getBoards(projectId) {
200
- try {
201
- // Get all projects which includes boards in the response
202
- const response = await plankaRequest(`/api/projects`);
203
- // Check if the response has the expected structure
204
- if (response &&
205
- typeof response === "object" &&
206
- "included" in response &&
207
- response.included &&
208
- typeof response.included === "object" &&
209
- "boards" in response.included) {
210
- // Filter boards by projectId
211
- const allBoards = response.included.boards;
212
- if (Array.isArray(allBoards)) {
213
- const filteredBoards = allBoards.filter((board) => typeof board === "object" &&
214
- board !== null &&
215
- "projectId" in board &&
216
- board.projectId === projectId);
217
- return filteredBoards;
218
- }
219
- }
220
- // If we can't find boards in the expected format, return an empty array
221
- return [];
222
- }
223
- catch (error) {
224
- // If all else fails, return an empty array
225
- return [];
226
- }
227
- }
228
- /**
229
- * Retrieves a specific board by ID
230
- *
231
- * @param {string} id - The ID of the board to retrieve
232
- * @returns {Promise<object>} The requested board
233
- * @throws {Error} If retrieving the board fails
234
- */
235
- export async function getBoard(id) {
236
- const response = await plankaRequest(`/api/boards/${id}`);
237
- const parsedResponse = BoardResponseSchema.parse(response);
238
- return parsedResponse.item;
239
- }
240
- /**
241
- * Updates a board's properties
242
- *
243
- * @param {string} id - The ID of the board to update
244
- * @param {Partial<Omit<CreateBoardOptions, "projectId">>} options - The properties to update
245
- * @returns {Promise<object>} The updated board
246
- * @throws {Error} If updating the board fails
247
- */
248
- export async function updateBoard(id, options) {
249
- const response = await plankaRequest(`/api/boards/${id}`, {
250
- method: "PATCH",
251
- body: options,
252
- });
253
- const parsedResponse = BoardResponseSchema.parse(response);
254
- return parsedResponse.item;
255
- }
256
- /**
257
- * Deletes a board by ID
258
- *
259
- * @param {string} id - The ID of the board to delete
260
- * @returns {Promise<{success: boolean}>} Success indicator
261
- * @throws {Error} If deleting the board fails
262
- */
263
- export async function deleteBoard(id) {
264
- await plankaRequest(`/api/boards/${id}`, {
265
- method: "DELETE",
266
- });
267
- return { success: true };
268
- }