@createtodo/mcp 0.1.2 → 0.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.
Files changed (2) hide show
  1. package/dist/index.js +115 -76
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -97,9 +97,7 @@ var labelTools = {
97
97
  description: "List all labels in the workspace. Uses the Electric SQL shape proxy to fetch label data.",
98
98
  inputSchema: z2.object({}),
99
99
  handler: async () => {
100
- const result = await apiRequest("/shape", {
101
- params: { table: "labels" }
102
- });
100
+ const result = await apiRequest("/workspace/labels");
103
101
  return JSON.stringify(result, null, 2);
104
102
  }
105
103
  },
@@ -231,8 +229,10 @@ var listTools = {
231
229
  listId: z3.string().describe("The ID of the list")
232
230
  }),
233
231
  handler: async ({ listId }) => {
234
- const result = await apiRequest(`/todo-lists/${listId}`);
235
- return JSON.stringify(result, null, 2);
232
+ const result = await apiRequest(
233
+ `/todo-lists/${listId}`
234
+ );
235
+ return JSON.stringify(result.todoList ?? result, null, 2);
236
236
  }
237
237
  },
238
238
  create_list: {
@@ -342,50 +342,121 @@ var listTools = {
342
342
  };
343
343
 
344
344
  // src/tools/todos.ts
345
+ import { z as z5 } from "zod";
346
+
347
+ // src/tools/workspace.ts
345
348
  import { z as z4 } from "zod";
346
349
  var cachedStates;
350
+ var cachedLists;
347
351
  async function getWorkflowStates() {
348
352
  if (cachedStates) return cachedStates;
349
- cachedStates = await apiRequest("/shape", {
350
- params: { table: "workflow_states" }
351
- });
353
+ cachedStates = await apiRequest(
354
+ "/workspace/workflow-states"
355
+ );
352
356
  return cachedStates;
353
357
  }
354
- async function getDefaultStateId() {
358
+ async function getLists() {
359
+ if (cachedLists) return cachedLists;
360
+ const result = await apiRequest(
361
+ "/todo-lists"
362
+ );
363
+ cachedLists = result.todoLists ?? [];
364
+ return cachedLists;
365
+ }
366
+ async function resolveStateId(stateIdOrName) {
355
367
  const states = await getWorkflowStates();
356
- const todo = states.find((s) => s.type === "unstarted" && s.name === "Todo");
357
- if (!todo) throw new Error('No default "Todo" workflow state found');
358
- return todo.id;
368
+ if (!stateIdOrName) {
369
+ const def = states.find((s) => s.isDefault) ?? states.find((s) => s.type === "unstarted");
370
+ if (!def) throw new Error("No default workflow state found");
371
+ return def.id;
372
+ }
373
+ const byId = states.find((s) => s.id === stateIdOrName);
374
+ if (byId) return byId.id;
375
+ const byName = states.find(
376
+ (s) => s.name.toLowerCase() === stateIdOrName.toLowerCase()
377
+ );
378
+ if (byName) return byName.id;
379
+ const byType = states.find((s) => s.type === stateIdOrName.toLowerCase());
380
+ if (byType) return byType.id;
381
+ throw new Error(
382
+ `Workflow state "${stateIdOrName}" not found. Available: ${states.map((s) => s.name).join(", ")}`
383
+ );
384
+ }
385
+ async function resolveListId(listIdOrName) {
386
+ const lists = await getLists();
387
+ const byId = lists.find((l) => l.id === listIdOrName);
388
+ if (byId) return byId.id;
389
+ const byName = lists.find(
390
+ (l) => l.name.toLowerCase() === listIdOrName.toLowerCase()
391
+ );
392
+ if (byName) return byName.id;
393
+ throw new Error(
394
+ `List "${listIdOrName}" not found. Available: ${lists.map((l) => l.name).join(", ")}`
395
+ );
359
396
  }
360
397
  function isCompletedState(stateId, states) {
361
398
  const state = states.find((s) => s.id === stateId);
362
399
  return state?.type === "completed";
363
400
  }
401
+ var workspaceTools = {
402
+ list_workflow_states: {
403
+ description: "List all workflow states (e.g., Todo, In Progress, Done) in the workspace",
404
+ inputSchema: z4.object({}),
405
+ handler: async () => {
406
+ const result = await getWorkflowStates();
407
+ return JSON.stringify(result, null, 2);
408
+ }
409
+ },
410
+ list_teams: {
411
+ description: "List all teams in the workspace",
412
+ inputSchema: z4.object({}),
413
+ handler: async () => {
414
+ const result = await apiRequest("/workspace/teams");
415
+ return JSON.stringify(result, null, 2);
416
+ }
417
+ },
418
+ list_members: {
419
+ description: "List all members in the workspace",
420
+ inputSchema: z4.object({}),
421
+ handler: async () => {
422
+ const result = await apiRequest("/workspace/members");
423
+ return JSON.stringify(result, null, 2);
424
+ }
425
+ }
426
+ };
427
+
428
+ // src/tools/todos.ts
364
429
  var todoTools = {
365
430
  list_todos: {
366
- description: "List todos in a specific list/container",
367
- inputSchema: z4.object({
368
- listId: z4.string().describe("The ID of the list to get todos from")
431
+ description: "List todos in a specific list/container. You can pass a list ID or name.",
432
+ inputSchema: z5.object({
433
+ listId: z5.string().describe("The ID or name of the list to get todos from")
369
434
  }),
370
435
  handler: async ({ listId }) => {
371
- const result = await apiRequest(`/todo-lists/${listId}`);
372
- return JSON.stringify(result.todoList ?? result, null, 2);
436
+ const resolvedId = await resolveListId(listId);
437
+ const result = await apiRequest(`/todo-lists/${resolvedId}`);
438
+ return JSON.stringify(result.todoList?.items ?? [], null, 2);
373
439
  }
374
440
  },
375
441
  create_todo: {
376
- description: "Create a new todo item in a list with optional description, priority, assignee, and state.",
377
- inputSchema: z4.object({
378
- name: z4.string().describe("The title of the todo"),
379
- containerId: z4.string().describe("The ID of the list/container to add the todo to"),
380
- description: z4.string().optional().describe("Description of the todo"),
381
- priority: z4.enum(["low", "medium", "high", "urgent"]).optional().describe("Priority level"),
382
- assigneeId: z4.string().optional().describe("Member ID to assign the todo to"),
383
- stateId: z4.string().optional().describe("Workflow state ID")
442
+ description: 'Create a new todo item in a list. You can use names instead of IDs for list and state (e.g., list: "Inbox", state: "Done").',
443
+ inputSchema: z5.object({
444
+ name: z5.string().describe("The title of the todo"),
445
+ containerId: z5.string().describe("The ID or name of the list/container to add the todo to"),
446
+ description: z5.string().optional().describe("Description of the todo"),
447
+ priority: z5.enum(["low", "medium", "high", "urgent"]).optional().describe("Priority level"),
448
+ assigneeId: z5.string().optional().describe("Member ID to assign the todo to"),
449
+ stateId: z5.string().optional().describe(
450
+ 'Workflow state ID or name (e.g., "Todo", "In Progress", "Done"). Defaults to the default state.'
451
+ )
384
452
  }),
385
453
  handler: async (input) => {
386
454
  const id = crypto.randomUUID();
387
455
  const now = (/* @__PURE__ */ new Date()).toISOString();
388
- const stateId = input.stateId ?? await getDefaultStateId();
456
+ const [containerId, stateId] = await Promise.all([
457
+ resolveListId(input.containerId),
458
+ resolveStateId(input.stateId)
459
+ ]);
389
460
  const states = await getWorkflowStates();
390
461
  const completed = isCompletedState(stateId, states);
391
462
  const modifiedColumns = ["name", "container_id", "state_id"];
@@ -400,7 +471,7 @@ var todoTools = {
400
471
  {
401
472
  id,
402
473
  name: input.name,
403
- container_id: input.containerId,
474
+ container_id: containerId,
404
475
  description: input.description ?? null,
405
476
  priority: input.priority ?? null,
406
477
  assignee_id: input.assigneeId ?? null,
@@ -425,15 +496,17 @@ var todoTools = {
425
496
  }
426
497
  },
427
498
  update_todo: {
428
- description: "Update an existing todo item",
429
- inputSchema: z4.object({
430
- id: z4.string().describe("The ID of the todo to update"),
431
- name: z4.string().optional().describe("New title"),
432
- description: z4.string().optional().describe("New description"),
433
- priority: z4.enum(["low", "medium", "high", "urgent"]).optional().describe("New priority"),
434
- assigneeId: z4.string().optional().describe("New assignee member ID"),
435
- stateId: z4.string().optional().describe("New workflow state ID"),
436
- containerId: z4.string().optional().describe("Move to a different list/container")
499
+ description: 'Update an existing todo item. State can be a name (e.g., "Done") or ID.',
500
+ inputSchema: z5.object({
501
+ id: z5.string().describe("The ID of the todo to update"),
502
+ name: z5.string().optional().describe("New title"),
503
+ description: z5.string().optional().describe("New description"),
504
+ priority: z5.enum(["low", "medium", "high", "urgent"]).optional().describe("New priority"),
505
+ assigneeId: z5.string().optional().describe("New assignee member ID"),
506
+ stateId: z5.string().optional().describe(
507
+ 'New workflow state ID or name (e.g., "Todo", "In Progress", "Done")'
508
+ ),
509
+ containerId: z5.string().optional().describe("Move to a different list (ID or name)")
437
510
  }),
438
511
  handler: async (input) => {
439
512
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -460,14 +533,15 @@ var todoTools = {
460
533
  modifiedColumns.push("assignee_id");
461
534
  }
462
535
  if (input.stateId !== void 0) {
463
- change.state_id = input.stateId;
536
+ const stateId = await resolveStateId(input.stateId);
537
+ change.state_id = stateId;
464
538
  modifiedColumns.push("state_id");
465
539
  const states = await getWorkflowStates();
466
- change.completed_at = isCompletedState(input.stateId, states) ? now : null;
540
+ change.completed_at = isCompletedState(stateId, states) ? now : null;
467
541
  modifiedColumns.push("completed_at");
468
542
  }
469
543
  if (input.containerId !== void 0) {
470
- change.container_id = input.containerId;
544
+ change.container_id = await resolveListId(input.containerId);
471
545
  modifiedColumns.push("container_id");
472
546
  }
473
547
  change.modified_columns = modifiedColumns;
@@ -489,8 +563,8 @@ var todoTools = {
489
563
  },
490
564
  delete_todo: {
491
565
  description: "Delete a todo item (soft delete)",
492
- inputSchema: z4.object({
493
- id: z4.string().describe("The ID of the todo to delete")
566
+ inputSchema: z5.object({
567
+ id: z5.string().describe("The ID of the todo to delete")
494
568
  }),
495
569
  handler: async ({ id }) => {
496
570
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -520,41 +594,6 @@ var todoTools = {
520
594
  }
521
595
  };
522
596
 
523
- // src/tools/workspace.ts
524
- import { z as z5 } from "zod";
525
- var workspaceTools = {
526
- list_workflow_states: {
527
- description: "List all workflow states (e.g., Todo, In Progress, Done) in the workspace",
528
- inputSchema: z5.object({}),
529
- handler: async () => {
530
- const result = await apiRequest("/shape", {
531
- params: { table: "workflow_states" }
532
- });
533
- return JSON.stringify(result, null, 2);
534
- }
535
- },
536
- list_teams: {
537
- description: "List all teams in the workspace",
538
- inputSchema: z5.object({}),
539
- handler: async () => {
540
- const result = await apiRequest("/shape", {
541
- params: { table: "teams" }
542
- });
543
- return JSON.stringify(result, null, 2);
544
- }
545
- },
546
- list_members: {
547
- description: "List all members in the workspace",
548
- inputSchema: z5.object({}),
549
- handler: async () => {
550
- const result = await apiRequest("/shape", {
551
- params: { table: "members" }
552
- });
553
- return JSON.stringify(result, null, 2);
554
- }
555
- }
556
- };
557
-
558
597
  // src/index.ts
559
598
  var server = new McpServer({
560
599
  name: "createtodo",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@createtodo/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server for managing createtodo tasks, lists, labels, and more",
5
5
  "type": "module",
6
6
  "license": "MIT",