@createtodo/mcp 0.1.3 → 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 +110 -73
  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
  },
@@ -344,50 +342,121 @@ var listTools = {
344
342
  };
345
343
 
346
344
  // src/tools/todos.ts
345
+ import { z as z5 } from "zod";
346
+
347
+ // src/tools/workspace.ts
347
348
  import { z as z4 } from "zod";
348
349
  var cachedStates;
350
+ var cachedLists;
349
351
  async function getWorkflowStates() {
350
352
  if (cachedStates) return cachedStates;
351
- cachedStates = await apiRequest("/shape", {
352
- params: { table: "workflow_states" }
353
- });
353
+ cachedStates = await apiRequest(
354
+ "/workspace/workflow-states"
355
+ );
354
356
  return cachedStates;
355
357
  }
356
- 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) {
357
367
  const states = await getWorkflowStates();
358
- const todo = states.find((s) => s.type === "unstarted" && s.name === "Todo");
359
- if (!todo) throw new Error('No default "Todo" workflow state found');
360
- 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
+ );
361
396
  }
362
397
  function isCompletedState(stateId, states) {
363
398
  const state = states.find((s) => s.id === stateId);
364
399
  return state?.type === "completed";
365
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
366
429
  var todoTools = {
367
430
  list_todos: {
368
- description: "List todos in a specific list/container",
369
- inputSchema: z4.object({
370
- 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")
371
434
  }),
372
435
  handler: async ({ listId }) => {
373
- const result = await apiRequest(`/todo-lists/${listId}`);
436
+ const resolvedId = await resolveListId(listId);
437
+ const result = await apiRequest(`/todo-lists/${resolvedId}`);
374
438
  return JSON.stringify(result.todoList?.items ?? [], null, 2);
375
439
  }
376
440
  },
377
441
  create_todo: {
378
- description: "Create a new todo item in a list with optional description, priority, assignee, and state.",
379
- inputSchema: z4.object({
380
- name: z4.string().describe("The title of the todo"),
381
- containerId: z4.string().describe("The ID of the list/container to add the todo to"),
382
- description: z4.string().optional().describe("Description of the todo"),
383
- priority: z4.enum(["low", "medium", "high", "urgent"]).optional().describe("Priority level"),
384
- assigneeId: z4.string().optional().describe("Member ID to assign the todo to"),
385
- 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
+ )
386
452
  }),
387
453
  handler: async (input) => {
388
454
  const id = crypto.randomUUID();
389
455
  const now = (/* @__PURE__ */ new Date()).toISOString();
390
- const stateId = input.stateId ?? await getDefaultStateId();
456
+ const [containerId, stateId] = await Promise.all([
457
+ resolveListId(input.containerId),
458
+ resolveStateId(input.stateId)
459
+ ]);
391
460
  const states = await getWorkflowStates();
392
461
  const completed = isCompletedState(stateId, states);
393
462
  const modifiedColumns = ["name", "container_id", "state_id"];
@@ -402,7 +471,7 @@ var todoTools = {
402
471
  {
403
472
  id,
404
473
  name: input.name,
405
- container_id: input.containerId,
474
+ container_id: containerId,
406
475
  description: input.description ?? null,
407
476
  priority: input.priority ?? null,
408
477
  assignee_id: input.assigneeId ?? null,
@@ -427,15 +496,17 @@ var todoTools = {
427
496
  }
428
497
  },
429
498
  update_todo: {
430
- description: "Update an existing todo item",
431
- inputSchema: z4.object({
432
- id: z4.string().describe("The ID of the todo to update"),
433
- name: z4.string().optional().describe("New title"),
434
- description: z4.string().optional().describe("New description"),
435
- priority: z4.enum(["low", "medium", "high", "urgent"]).optional().describe("New priority"),
436
- assigneeId: z4.string().optional().describe("New assignee member ID"),
437
- stateId: z4.string().optional().describe("New workflow state ID"),
438
- 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)")
439
510
  }),
440
511
  handler: async (input) => {
441
512
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -462,14 +533,15 @@ var todoTools = {
462
533
  modifiedColumns.push("assignee_id");
463
534
  }
464
535
  if (input.stateId !== void 0) {
465
- change.state_id = input.stateId;
536
+ const stateId = await resolveStateId(input.stateId);
537
+ change.state_id = stateId;
466
538
  modifiedColumns.push("state_id");
467
539
  const states = await getWorkflowStates();
468
- change.completed_at = isCompletedState(input.stateId, states) ? now : null;
540
+ change.completed_at = isCompletedState(stateId, states) ? now : null;
469
541
  modifiedColumns.push("completed_at");
470
542
  }
471
543
  if (input.containerId !== void 0) {
472
- change.container_id = input.containerId;
544
+ change.container_id = await resolveListId(input.containerId);
473
545
  modifiedColumns.push("container_id");
474
546
  }
475
547
  change.modified_columns = modifiedColumns;
@@ -491,8 +563,8 @@ var todoTools = {
491
563
  },
492
564
  delete_todo: {
493
565
  description: "Delete a todo item (soft delete)",
494
- inputSchema: z4.object({
495
- 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")
496
568
  }),
497
569
  handler: async ({ id }) => {
498
570
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -522,41 +594,6 @@ var todoTools = {
522
594
  }
523
595
  };
524
596
 
525
- // src/tools/workspace.ts
526
- import { z as z5 } from "zod";
527
- var workspaceTools = {
528
- list_workflow_states: {
529
- description: "List all workflow states (e.g., Todo, In Progress, Done) in the workspace",
530
- inputSchema: z5.object({}),
531
- handler: async () => {
532
- const result = await apiRequest("/shape", {
533
- params: { table: "workflow_states" }
534
- });
535
- return JSON.stringify(result, null, 2);
536
- }
537
- },
538
- list_teams: {
539
- description: "List all teams in the workspace",
540
- inputSchema: z5.object({}),
541
- handler: async () => {
542
- const result = await apiRequest("/shape", {
543
- params: { table: "teams" }
544
- });
545
- return JSON.stringify(result, null, 2);
546
- }
547
- },
548
- list_members: {
549
- description: "List all members in the workspace",
550
- inputSchema: z5.object({}),
551
- handler: async () => {
552
- const result = await apiRequest("/shape", {
553
- params: { table: "members" }
554
- });
555
- return JSON.stringify(result, null, 2);
556
- }
557
- }
558
- };
559
-
560
597
  // src/index.ts
561
598
  var server = new McpServer({
562
599
  name: "createtodo",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@createtodo/mcp",
3
- "version": "0.1.3",
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",