brioright-mcp 1.2.1 → 1.3.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/index.js CHANGED
@@ -155,6 +155,41 @@ function buildServer() {
155
155
  }
156
156
  )
157
157
 
158
+ // ── bulk_create_tasks ─────────────────────────────────────────────────────
159
+ server.tool('bulk_create_tasks', 'Create multiple tasks at once in a Brioright project',
160
+ {
161
+ projectId: z.string().describe('Project ID'),
162
+ tasks: z.array(z.object({
163
+ title: z.string().describe('Task title'),
164
+ description: z.string().optional(),
165
+ status: z.enum(['todo', 'in_progress', 'in_review', 'done']).optional().default('todo'),
166
+ priority: z.enum(['low', 'medium', 'high', 'urgent']).optional().default('medium'),
167
+ dueDate: z.string().optional().describe('ISO date string e.g. 2026-03-15'),
168
+ assigneeId: z.string().optional(),
169
+ parentTaskId: z.string().optional(),
170
+ tags: z.array(z.string()).optional()
171
+ })).describe('Array of tasks to create'),
172
+ workspaceId: z.string().optional(),
173
+ apiKey: z.string().optional().describe('Brioright API Key')
174
+ },
175
+ async ({ projectId, tasks, workspaceId, apiKey }) => {
176
+ const ws = workspaceId || DEFAULT_WORKSPACE
177
+ if (!ws) throw new Error('workspaceId is required')
178
+
179
+ // Format dates
180
+ const formattedTasks = tasks.map(t => ({
181
+ ...t,
182
+ dueDate: t.dueDate ? new Date(t.dueDate).toISOString() : undefined
183
+ }))
184
+
185
+ const data = await call('POST', `/workspaces/${ws}/projects/${projectId}/tasks/bulk`, {
186
+ tasks: formattedTasks
187
+ }, apiKey)
188
+
189
+ return { content: [{ type: 'text', text: `✅ Successfully created ${data.count} tasks!` }] }
190
+ }
191
+ )
192
+
158
193
  // ── update_task ───────────────────────────────────────────────────────────
159
194
  server.tool('update_task', 'Update fields on an existing task',
160
195
  {
@@ -175,7 +210,7 @@ function buildServer() {
175
210
  if (updates.dueDate) updates.dueDate = new Date(updates.dueDate).toISOString()
176
211
  const data = await call('PATCH', `/workspaces/${ws}/tasks/${taskId}`, updates, apiKey)
177
212
  const task = data.task || data
178
- return { content: [{ type: 'text', text: `✅ Task updated!\n\n${JSON.stringify({ id: task.id, title: task.title, status: task.status, priority: task.priority }, null, 2)}` }] }
213
+ return { content: [{ type: 'text', text: `✅ Task updated!\n\n${JSON.stringify({ id: task.id, title: task.title, status: task.status, priority: task.priority, description: task.description, dueDate: task.dueDate }, null, 2)}` }] }
179
214
  }
180
215
  )
181
216
 
@@ -231,6 +266,65 @@ function buildServer() {
231
266
  }
232
267
  )
233
268
 
269
+ // ── add_comment ───────────────────────────────────────────────────────────
270
+ server.tool('add_comment', 'Add a comment to a task',
271
+ {
272
+ taskId: z.string(),
273
+ text: z.string().describe('The content of the comment'),
274
+ workspaceId: z.string().optional(),
275
+ apiKey: z.string().optional().describe('Brioright API Key')
276
+ },
277
+ async ({ taskId, text, workspaceId, apiKey }) => {
278
+ const ws = workspaceId || DEFAULT_WORKSPACE
279
+ if (!ws) throw new Error('workspaceId is required')
280
+ const data = await call('POST', `/workspaces/${ws}/tasks/${taskId}/comments`, { text }, apiKey)
281
+ const comment = data.comment || data
282
+ return { content: [{ type: 'text', text: `✅ Comment added!\n\n${JSON.stringify(comment, null, 2)}` }] }
283
+ }
284
+ )
285
+
286
+ // ── get_task_comments ─────────────────────────────────────────────────────
287
+ server.tool('get_task_comments', 'Get all comments for a given task',
288
+ {
289
+ taskId: z.string(),
290
+ workspaceId: z.string().optional(),
291
+ apiKey: z.string().optional().describe('Brioright API Key')
292
+ },
293
+ async ({ taskId, workspaceId, apiKey }) => {
294
+ const ws = workspaceId || DEFAULT_WORKSPACE
295
+ if (!ws) throw new Error('workspaceId is required')
296
+ const data = await call('GET', `/workspaces/${ws}/tasks/${taskId}/comments`, null, apiKey)
297
+ const comments = data.comments || data
298
+ return { content: [{ type: 'text', text: JSON.stringify(comments.map(c => ({ id: c.id, text: c.text, author: c.author?.name, createdAt: c.createdAt })), null, 2) }] }
299
+ }
300
+ )
301
+
302
+ // ── log_time ──────────────────────────────────────────────────────────────
303
+ server.tool('log_time', 'Log time entry for a project/task',
304
+ {
305
+ projectId: z.string(),
306
+ taskId: z.string().optional(),
307
+ description: z.string().optional(),
308
+ startTime: z.string().optional().describe('ISO date string for start time. Defaults to now.'),
309
+ endTime: z.string().optional().describe('ISO date string for end time. If omitted, starts a running timer.'),
310
+ workspaceId: z.string().optional(),
311
+ apiKey: z.string().optional().describe('Brioright API Key')
312
+ },
313
+ async ({ projectId, taskId, description, startTime, endTime, workspaceId, apiKey }) => {
314
+ const ws = workspaceId || DEFAULT_WORKSPACE
315
+ if (!ws) throw new Error('workspaceId is required')
316
+ const start = startTime ? new Date(startTime).toISOString() : new Date().toISOString()
317
+ const end = endTime ? new Date(endTime).toISOString() : undefined
318
+
319
+ const payload = { projectId, description, startTime: start, endTime: end }
320
+ if (taskId) payload.taskId = taskId
321
+
322
+ const data = await call('POST', `/workspaces/${ws}/time-entries`, payload, apiKey)
323
+ const entry = data.entry || data
324
+ return { content: [{ type: 'text', text: `✅ Time logged (Duration: ${entry.duration ? entry.duration + ' seconds' : 'Running timer ...'})!\n\n${JSON.stringify({ id: entry.id, description: entry.description, startTime: entry.startTime, endTime: entry.endTime, duration: entry.duration }, null, 2)}` }] }
325
+ }
326
+ )
327
+
234
328
  return server
235
329
  }
236
330
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brioright-mcp",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "MCP server for Brioright — lets AI assistants create and manage tasks via natural language",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/test-axios.mjs DELETED
@@ -1,20 +0,0 @@
1
- import axios from 'axios';
2
-
3
- async function test() {
4
- const api = axios.create({
5
- baseURL: 'https://brioright.online/api',
6
- headers: { 'X-API-Key': 'brio_9847f9c385632d4d1c888afc42c8c3906ffad22bf7713c062a2d1c6db90adadf', 'Content-Type': 'application/json' },
7
- timeout: 10000,
8
- });
9
-
10
- try {
11
- const res = await api({ method: 'GET', url: '/workspaces', data: null });
12
- console.log("SUCCESS:");
13
- console.log(res.data);
14
- } catch (err) {
15
- console.log("ERROR:");
16
- console.log(err.response?.data || err.message);
17
- }
18
- }
19
-
20
- test();
package/test-axios2.mjs DELETED
@@ -1,20 +0,0 @@
1
- import axios from 'axios';
2
-
3
- async function test() {
4
- const api = axios.create({
5
- baseURL: 'https://brioright.online/api',
6
- headers: { 'X-API-Key': 'brio_9847f9c385632d4d1c888afc42c8c3906ffad22bf7713c062a2d1c6db90adadf', 'Content-Type': 'application/json' },
7
- timeout: 10000,
8
- });
9
-
10
- try {
11
- const res = await api({ method: 'GET', url: '/workspaces' }); // data: undefined
12
- console.log("SUCCESS:");
13
- console.log(res.data);
14
- } catch (err) {
15
- console.log("ERROR:");
16
- console.log(err.response?.data || err.message);
17
- }
18
- }
19
-
20
- test();