projoflow-mcp-server 1.1.5 → 1.2.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 +415 -2
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -275,7 +275,7 @@ const TOOLS = [
|
|
|
275
275
|
},
|
|
276
276
|
{
|
|
277
277
|
name: "update_task",
|
|
278
|
-
description: "Update a task's details or
|
|
278
|
+
description: "Update a task's details, status, or assignment. Use list_workspace_members to find user IDs.",
|
|
279
279
|
inputSchema: {
|
|
280
280
|
type: "object",
|
|
281
281
|
properties: {
|
|
@@ -284,7 +284,9 @@ const TOOLS = [
|
|
|
284
284
|
description: { type: "string" },
|
|
285
285
|
status: { type: "string", enum: ["todo", "in_progress", "review", "done"] },
|
|
286
286
|
priority: { type: "string", enum: ["low", "medium", "high", "urgent"] },
|
|
287
|
-
due_date: { type: "string" }
|
|
287
|
+
due_date: { type: "string", description: "Due date (YYYY-MM-DD)" },
|
|
288
|
+
assigned_to: { type: "string", description: "User ID to assign/reassign the task to (get from list_workspace_members)" },
|
|
289
|
+
estimated_hours: { type: "number", description: "Estimated hours to complete" }
|
|
288
290
|
},
|
|
289
291
|
required: ["task_id"]
|
|
290
292
|
}
|
|
@@ -489,6 +491,218 @@ const TOOLS = [
|
|
|
489
491
|
},
|
|
490
492
|
required: ["file_path"]
|
|
491
493
|
}
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
name: "get_task",
|
|
497
|
+
description: "Get full details of a specific task including assignee info",
|
|
498
|
+
inputSchema: {
|
|
499
|
+
type: "object",
|
|
500
|
+
properties: {
|
|
501
|
+
task_id: { type: "string", description: "Task ID" }
|
|
502
|
+
},
|
|
503
|
+
required: ["task_id"]
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
name: "delete_task",
|
|
508
|
+
description: "Delete a task permanently",
|
|
509
|
+
inputSchema: {
|
|
510
|
+
type: "object",
|
|
511
|
+
properties: {
|
|
512
|
+
task_id: { type: "string", description: "Task ID" }
|
|
513
|
+
},
|
|
514
|
+
required: ["task_id"]
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
name: "get_client",
|
|
519
|
+
description: "Get full details of a specific client",
|
|
520
|
+
inputSchema: {
|
|
521
|
+
type: "object",
|
|
522
|
+
properties: {
|
|
523
|
+
client_id: { type: "string", description: "Client ID" }
|
|
524
|
+
},
|
|
525
|
+
required: ["client_id"]
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
name: "update_client",
|
|
530
|
+
description: "Update a client's details",
|
|
531
|
+
inputSchema: {
|
|
532
|
+
type: "object",
|
|
533
|
+
properties: {
|
|
534
|
+
client_id: { type: "string", description: "Client ID" },
|
|
535
|
+
name: { type: "string" },
|
|
536
|
+
contact_name: { type: "string" },
|
|
537
|
+
email: { type: "string" },
|
|
538
|
+
phone: { type: "string" },
|
|
539
|
+
company: { type: "string" },
|
|
540
|
+
notes: { type: "string" }
|
|
541
|
+
},
|
|
542
|
+
required: ["client_id"]
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
name: "delete_client",
|
|
547
|
+
description: "Delete a client permanently. Will fail if client has linked projects.",
|
|
548
|
+
inputSchema: {
|
|
549
|
+
type: "object",
|
|
550
|
+
properties: {
|
|
551
|
+
client_id: { type: "string", description: "Client ID" }
|
|
552
|
+
},
|
|
553
|
+
required: ["client_id"]
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
name: "create_lead",
|
|
558
|
+
description: "Create a new lead/inquiry",
|
|
559
|
+
inputSchema: {
|
|
560
|
+
type: "object",
|
|
561
|
+
properties: {
|
|
562
|
+
company_name: { type: "string", description: "Company or person name" },
|
|
563
|
+
contact_name: { type: "string", description: "Contact person name" },
|
|
564
|
+
email: { type: "string" },
|
|
565
|
+
phone: { type: "string" },
|
|
566
|
+
budget_range: { type: "string", enum: ["under_5k", "5k_10k", "10k_25k", "25k_50k", "50k_plus", "not_sure"] },
|
|
567
|
+
timeline: { type: "string", enum: ["asap", "1_month", "2_3_months", "3_6_months", "flexible"] },
|
|
568
|
+
project_description: { type: "string", description: "What the lead needs" },
|
|
569
|
+
source: { type: "string", description: "How they found you" },
|
|
570
|
+
notes: { type: "string" },
|
|
571
|
+
status: { type: "string", enum: ["new", "contacted", "qualified", "converted", "lost"], default: "new" }
|
|
572
|
+
},
|
|
573
|
+
required: ["company_name", "email"]
|
|
574
|
+
}
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
name: "get_lead",
|
|
578
|
+
description: "Get full details of a specific lead",
|
|
579
|
+
inputSchema: {
|
|
580
|
+
type: "object",
|
|
581
|
+
properties: {
|
|
582
|
+
lead_id: { type: "string", description: "Lead ID" }
|
|
583
|
+
},
|
|
584
|
+
required: ["lead_id"]
|
|
585
|
+
}
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
name: "delete_lead",
|
|
589
|
+
description: "Delete a lead permanently",
|
|
590
|
+
inputSchema: {
|
|
591
|
+
type: "object",
|
|
592
|
+
properties: {
|
|
593
|
+
lead_id: { type: "string", description: "Lead ID" }
|
|
594
|
+
},
|
|
595
|
+
required: ["lead_id"]
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
name: "list_notes",
|
|
600
|
+
description: "List notes for a project, optionally filtered by type",
|
|
601
|
+
inputSchema: {
|
|
602
|
+
type: "object",
|
|
603
|
+
properties: {
|
|
604
|
+
project_id: { type: "string", description: "Project ID" },
|
|
605
|
+
note_type: { type: "string", enum: ["general", "meeting", "technical", "decision"], description: "Filter by note type" }
|
|
606
|
+
},
|
|
607
|
+
required: ["project_id"]
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
name: "update_note",
|
|
612
|
+
description: "Update a project note",
|
|
613
|
+
inputSchema: {
|
|
614
|
+
type: "object",
|
|
615
|
+
properties: {
|
|
616
|
+
note_id: { type: "string", description: "Note ID" },
|
|
617
|
+
title: { type: "string" },
|
|
618
|
+
content: { type: "string" },
|
|
619
|
+
note_type: { type: "string", enum: ["general", "meeting", "technical", "decision"] }
|
|
620
|
+
},
|
|
621
|
+
required: ["note_id"]
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
name: "delete_note",
|
|
626
|
+
description: "Delete a project note permanently",
|
|
627
|
+
inputSchema: {
|
|
628
|
+
type: "object",
|
|
629
|
+
properties: {
|
|
630
|
+
note_id: { type: "string", description: "Note ID" }
|
|
631
|
+
},
|
|
632
|
+
required: ["note_id"]
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
name: "delete_document",
|
|
637
|
+
description: "Delete a project document from storage and database",
|
|
638
|
+
inputSchema: {
|
|
639
|
+
type: "object",
|
|
640
|
+
properties: {
|
|
641
|
+
document_id: { type: "string", description: "Document ID from list_project_documents" }
|
|
642
|
+
},
|
|
643
|
+
required: ["document_id"]
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "update_time_entry",
|
|
648
|
+
description: "Update a time entry",
|
|
649
|
+
inputSchema: {
|
|
650
|
+
type: "object",
|
|
651
|
+
properties: {
|
|
652
|
+
time_entry_id: { type: "string", description: "Time entry ID" },
|
|
653
|
+
duration_minutes: { type: "number" },
|
|
654
|
+
description: { type: "string" },
|
|
655
|
+
date: { type: "string", description: "Date (YYYY-MM-DD)" },
|
|
656
|
+
billable: { type: "boolean" },
|
|
657
|
+
task_id: { type: "string" }
|
|
658
|
+
},
|
|
659
|
+
required: ["time_entry_id"]
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
name: "delete_time_entry",
|
|
664
|
+
description: "Delete a time entry permanently",
|
|
665
|
+
inputSchema: {
|
|
666
|
+
type: "object",
|
|
667
|
+
properties: {
|
|
668
|
+
time_entry_id: { type: "string", description: "Time entry ID" }
|
|
669
|
+
},
|
|
670
|
+
required: ["time_entry_id"]
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
name: "update_comment",
|
|
675
|
+
description: "Update a task comment's content",
|
|
676
|
+
inputSchema: {
|
|
677
|
+
type: "object",
|
|
678
|
+
properties: {
|
|
679
|
+
comment_id: { type: "string", description: "Comment ID" },
|
|
680
|
+
content: { type: "string", description: "New comment content" }
|
|
681
|
+
},
|
|
682
|
+
required: ["comment_id", "content"]
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
name: "delete_comment",
|
|
687
|
+
description: "Delete a task comment permanently",
|
|
688
|
+
inputSchema: {
|
|
689
|
+
type: "object",
|
|
690
|
+
properties: {
|
|
691
|
+
comment_id: { type: "string", description: "Comment ID" }
|
|
692
|
+
},
|
|
693
|
+
required: ["comment_id"]
|
|
694
|
+
}
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
name: "delete_project",
|
|
698
|
+
description: "Delete a project and all its related data (tasks, time entries, notes, documents) permanently",
|
|
699
|
+
inputSchema: {
|
|
700
|
+
type: "object",
|
|
701
|
+
properties: {
|
|
702
|
+
project_id: { type: "string", description: "Project ID" }
|
|
703
|
+
},
|
|
704
|
+
required: ["project_id"]
|
|
705
|
+
}
|
|
492
706
|
}
|
|
493
707
|
];
|
|
494
708
|
|
|
@@ -940,6 +1154,205 @@ async function handleTool(name, args) {
|
|
|
940
1154
|
};
|
|
941
1155
|
}
|
|
942
1156
|
|
|
1157
|
+
case "get_task": {
|
|
1158
|
+
const { data, error } = await supabase
|
|
1159
|
+
.from("tasks")
|
|
1160
|
+
.select("*, users(id, email, name), projects(id, name)")
|
|
1161
|
+
.eq("id", args.task_id)
|
|
1162
|
+
.single();
|
|
1163
|
+
if (error) throw new Error(error.message);
|
|
1164
|
+
return data;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
case "delete_task": {
|
|
1168
|
+
const { error } = await supabase
|
|
1169
|
+
.from("tasks")
|
|
1170
|
+
.delete()
|
|
1171
|
+
.eq("id", args.task_id);
|
|
1172
|
+
if (error) throw new Error(error.message);
|
|
1173
|
+
return { success: true, message: "Task deleted" };
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
case "get_client": {
|
|
1177
|
+
const { data, error } = await supabase
|
|
1178
|
+
.from("clients")
|
|
1179
|
+
.select("*")
|
|
1180
|
+
.eq("id", args.client_id)
|
|
1181
|
+
.single();
|
|
1182
|
+
if (error) throw new Error(error.message);
|
|
1183
|
+
return data;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
case "update_client": {
|
|
1187
|
+
const { client_id, ...updates } = args;
|
|
1188
|
+
const { data, error } = await supabase
|
|
1189
|
+
.from("clients")
|
|
1190
|
+
.update(updates)
|
|
1191
|
+
.eq("id", client_id)
|
|
1192
|
+
.select()
|
|
1193
|
+
.single();
|
|
1194
|
+
if (error) throw new Error(error.message);
|
|
1195
|
+
return data;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
case "delete_client": {
|
|
1199
|
+
const { error } = await supabase
|
|
1200
|
+
.from("clients")
|
|
1201
|
+
.delete()
|
|
1202
|
+
.eq("id", args.client_id);
|
|
1203
|
+
if (error) throw new Error(error.message);
|
|
1204
|
+
return { success: true, message: "Client deleted" };
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
case "create_lead": {
|
|
1208
|
+
const { data, error } = await supabase
|
|
1209
|
+
.from("leads")
|
|
1210
|
+
.insert({
|
|
1211
|
+
company_name: args.company_name,
|
|
1212
|
+
contact_name: args.contact_name,
|
|
1213
|
+
email: args.email,
|
|
1214
|
+
phone: args.phone,
|
|
1215
|
+
budget_range: args.budget_range,
|
|
1216
|
+
timeline: args.timeline,
|
|
1217
|
+
project_description: args.project_description,
|
|
1218
|
+
source: args.source,
|
|
1219
|
+
notes: args.notes,
|
|
1220
|
+
status: args.status || "new"
|
|
1221
|
+
})
|
|
1222
|
+
.select()
|
|
1223
|
+
.single();
|
|
1224
|
+
if (error) throw new Error(error.message);
|
|
1225
|
+
return data;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
case "get_lead": {
|
|
1229
|
+
const { data, error } = await supabase
|
|
1230
|
+
.from("leads")
|
|
1231
|
+
.select("*")
|
|
1232
|
+
.eq("id", args.lead_id)
|
|
1233
|
+
.single();
|
|
1234
|
+
if (error) throw new Error(error.message);
|
|
1235
|
+
return data;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
case "delete_lead": {
|
|
1239
|
+
const { error } = await supabase
|
|
1240
|
+
.from("leads")
|
|
1241
|
+
.delete()
|
|
1242
|
+
.eq("id", args.lead_id);
|
|
1243
|
+
if (error) throw new Error(error.message);
|
|
1244
|
+
return { success: true, message: "Lead deleted" };
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
case "list_notes": {
|
|
1248
|
+
let query = supabase
|
|
1249
|
+
.from("notes")
|
|
1250
|
+
.select("*")
|
|
1251
|
+
.eq("project_id", args.project_id)
|
|
1252
|
+
.order("created_at", { ascending: false });
|
|
1253
|
+
if (args.note_type) query = query.eq("note_type", args.note_type);
|
|
1254
|
+
const { data, error } = await query;
|
|
1255
|
+
if (error) throw new Error(error.message);
|
|
1256
|
+
return data;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
case "update_note": {
|
|
1260
|
+
const { note_id, ...updates } = args;
|
|
1261
|
+
const { data, error } = await supabase
|
|
1262
|
+
.from("notes")
|
|
1263
|
+
.update(updates)
|
|
1264
|
+
.eq("id", note_id)
|
|
1265
|
+
.select()
|
|
1266
|
+
.single();
|
|
1267
|
+
if (error) throw new Error(error.message);
|
|
1268
|
+
return data;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
case "delete_note": {
|
|
1272
|
+
const { error } = await supabase
|
|
1273
|
+
.from("notes")
|
|
1274
|
+
.delete()
|
|
1275
|
+
.eq("id", args.note_id);
|
|
1276
|
+
if (error) throw new Error(error.message);
|
|
1277
|
+
return { success: true, message: "Note deleted" };
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
case "delete_document": {
|
|
1281
|
+
// Get the file path first
|
|
1282
|
+
const { data: doc, error: fetchError } = await supabase
|
|
1283
|
+
.from("project_documents")
|
|
1284
|
+
.select("file_path")
|
|
1285
|
+
.eq("id", args.document_id)
|
|
1286
|
+
.single();
|
|
1287
|
+
if (fetchError) throw new Error(fetchError.message);
|
|
1288
|
+
|
|
1289
|
+
// Delete from storage
|
|
1290
|
+
if (doc.file_path) {
|
|
1291
|
+
const { error: storageError } = await supabase.storage
|
|
1292
|
+
.from("project-documents")
|
|
1293
|
+
.remove([doc.file_path]);
|
|
1294
|
+
if (storageError) throw new Error(`Storage deletion failed: ${storageError.message}`);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// Delete from database
|
|
1298
|
+
const { error } = await supabase
|
|
1299
|
+
.from("project_documents")
|
|
1300
|
+
.delete()
|
|
1301
|
+
.eq("id", args.document_id);
|
|
1302
|
+
if (error) throw new Error(error.message);
|
|
1303
|
+
return { success: true, message: "Document deleted" };
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
case "update_time_entry": {
|
|
1307
|
+
const { time_entry_id, ...updates } = args;
|
|
1308
|
+
const { data, error } = await supabase
|
|
1309
|
+
.from("time_entries")
|
|
1310
|
+
.update(updates)
|
|
1311
|
+
.eq("id", time_entry_id)
|
|
1312
|
+
.select("*, projects(name), tasks(title)")
|
|
1313
|
+
.single();
|
|
1314
|
+
if (error) throw new Error(error.message);
|
|
1315
|
+
return data;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
case "delete_time_entry": {
|
|
1319
|
+
const { error } = await supabase
|
|
1320
|
+
.from("time_entries")
|
|
1321
|
+
.delete()
|
|
1322
|
+
.eq("id", args.time_entry_id);
|
|
1323
|
+
if (error) throw new Error(error.message);
|
|
1324
|
+
return { success: true, message: "Time entry deleted" };
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
case "update_comment": {
|
|
1328
|
+
const { data, error } = await supabase
|
|
1329
|
+
.from("task_comments")
|
|
1330
|
+
.update({ content: args.content })
|
|
1331
|
+
.eq("id", args.comment_id)
|
|
1332
|
+
.select()
|
|
1333
|
+
.single();
|
|
1334
|
+
if (error) throw new Error(error.message);
|
|
1335
|
+
return data;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
case "delete_comment": {
|
|
1339
|
+
const { error } = await supabase
|
|
1340
|
+
.from("task_comments")
|
|
1341
|
+
.delete()
|
|
1342
|
+
.eq("id", args.comment_id);
|
|
1343
|
+
if (error) throw new Error(error.message);
|
|
1344
|
+
return { success: true, message: "Comment deleted" };
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
case "delete_project": {
|
|
1348
|
+
const { error } = await supabase
|
|
1349
|
+
.from("projects")
|
|
1350
|
+
.delete()
|
|
1351
|
+
.eq("id", args.project_id);
|
|
1352
|
+
if (error) throw new Error(error.message);
|
|
1353
|
+
return { success: true, message: "Project and all related data deleted" };
|
|
1354
|
+
}
|
|
1355
|
+
|
|
943
1356
|
default:
|
|
944
1357
|
throw new Error(`Unknown tool: ${name}`);
|
|
945
1358
|
}
|