@gethmy/mcp 2.8.3 → 2.8.4

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/dist/cli.js CHANGED
@@ -1551,6 +1551,9 @@ class HarmonyApiClient {
1551
1551
  async toggleSubtask(subtaskId) {
1552
1552
  return this.request("POST", `/subtasks/${subtaskId}/toggle`);
1553
1553
  }
1554
+ async updateSubtask(subtaskId, updates) {
1555
+ return this.request("PATCH", `/subtasks/${subtaskId}`, updates);
1556
+ }
1554
1557
  async deleteSubtask(subtaskId) {
1555
1558
  return this.request("DELETE", `/subtasks/${subtaskId}`);
1556
1559
  }
@@ -2026,7 +2029,8 @@ var AUTO_START_TRIGGERS = new Set([
2026
2029
  "harmony_generate_prompt",
2027
2030
  "harmony_update_card",
2028
2031
  "harmony_create_subtask",
2029
- "harmony_toggle_subtask"
2032
+ "harmony_toggle_subtask",
2033
+ "harmony_update_subtask"
2030
2034
  ]);
2031
2035
  var INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;
2032
2036
  var CHECK_INTERVAL_MS = 60 * 1000;
@@ -2944,7 +2948,12 @@ var TOOLS = {
2944
2948
  priority: { type: "string", enum: ["low", "medium", "high", "urgent"] },
2945
2949
  assigneeId: { type: "string", nullable: true },
2946
2950
  dueDate: { type: "string", nullable: true },
2947
- done: { type: "boolean", description: "Mark card as done or not done" }
2951
+ done: { type: "boolean", description: "Mark card as done or not done" },
2952
+ planId: {
2953
+ type: "string",
2954
+ nullable: true,
2955
+ description: "Plan ID to link this card to, or null to unlink. Sets cards.plan_id. The plan must exist and belong to the same project."
2956
+ }
2948
2957
  },
2949
2958
  required: ["cardId"]
2950
2959
  }
@@ -3243,6 +3252,25 @@ var TOOLS = {
3243
3252
  required: ["subtaskId"]
3244
3253
  }
3245
3254
  },
3255
+ harmony_update_subtask: {
3256
+ description: "Update a subtask: rename its title, set an explicit completion state, and/or reorder it. Unlike harmony_toggle_subtask (which flips completion), `completed` here sets an explicit value — safe to call idempotently. At least one of title/completed/position is required.",
3257
+ inputSchema: {
3258
+ type: "object",
3259
+ properties: {
3260
+ subtaskId: { type: "string" },
3261
+ title: { type: "string", description: "New title (1–500 chars)" },
3262
+ completed: {
3263
+ type: "boolean",
3264
+ description: "Explicit completion state (set, not toggle)"
3265
+ },
3266
+ position: {
3267
+ type: "number",
3268
+ description: "New position (0-based ordering within the card)"
3269
+ }
3270
+ },
3271
+ required: ["subtaskId"]
3272
+ }
3273
+ },
3246
3274
  harmony_delete_subtask: {
3247
3275
  description: "Delete a subtask",
3248
3276
  inputSchema: {
@@ -4360,13 +4388,15 @@ async function handleToolCall(name, args, deps) {
4360
4388
  }
4361
4389
  case "harmony_update_card": {
4362
4390
  const cardId = z.string().uuid().parse(args.cardId);
4391
+ const planId = args.planId === undefined ? undefined : args.planId === null ? null : z.string().uuid().parse(args.planId);
4363
4392
  const result = await client3.updateCard(cardId, {
4364
4393
  title: args.title,
4365
4394
  description: args.description,
4366
4395
  priority: args.priority,
4367
4396
  assigneeId: args.assigneeId,
4368
4397
  dueDate: args.dueDate,
4369
- done: args.done
4398
+ done: args.done,
4399
+ planId
4370
4400
  });
4371
4401
  return { success: true, ...result };
4372
4402
  }
@@ -4569,6 +4599,24 @@ async function handleToolCall(name, args, deps) {
4569
4599
  const result = await client3.toggleSubtask(subtaskId);
4570
4600
  return { success: true, ...result };
4571
4601
  }
4602
+ case "harmony_update_subtask": {
4603
+ const subtaskId = z.string().uuid().parse(args.subtaskId);
4604
+ const updates = {};
4605
+ if (args.title !== undefined) {
4606
+ updates.title = z.string().min(1).max(500).parse(args.title);
4607
+ }
4608
+ if (args.completed !== undefined) {
4609
+ updates.completed = z.boolean().parse(args.completed);
4610
+ }
4611
+ if (args.position !== undefined) {
4612
+ updates.position = z.number().int().min(0).parse(args.position);
4613
+ }
4614
+ if (Object.keys(updates).length === 0) {
4615
+ throw new Error("harmony_update_subtask requires at least one of: title, completed, position");
4616
+ }
4617
+ const result = await client3.updateSubtask(subtaskId, updates);
4618
+ return { success: true, ...result };
4619
+ }
4572
4620
  case "harmony_delete_subtask": {
4573
4621
  const subtaskId = z.string().uuid().parse(args.subtaskId);
4574
4622
  await client3.deleteSubtask(subtaskId);
package/dist/index.js CHANGED
@@ -1547,6 +1547,9 @@ class HarmonyApiClient {
1547
1547
  async toggleSubtask(subtaskId) {
1548
1548
  return this.request("POST", `/subtasks/${subtaskId}/toggle`);
1549
1549
  }
1550
+ async updateSubtask(subtaskId, updates) {
1551
+ return this.request("PATCH", `/subtasks/${subtaskId}`, updates);
1552
+ }
1550
1553
  async deleteSubtask(subtaskId) {
1551
1554
  return this.request("DELETE", `/subtasks/${subtaskId}`);
1552
1555
  }
@@ -2022,7 +2025,8 @@ var AUTO_START_TRIGGERS = new Set([
2022
2025
  "harmony_generate_prompt",
2023
2026
  "harmony_update_card",
2024
2027
  "harmony_create_subtask",
2025
- "harmony_toggle_subtask"
2028
+ "harmony_toggle_subtask",
2029
+ "harmony_update_subtask"
2026
2030
  ]);
2027
2031
  var INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;
2028
2032
  var CHECK_INTERVAL_MS = 60 * 1000;
@@ -2940,7 +2944,12 @@ var TOOLS = {
2940
2944
  priority: { type: "string", enum: ["low", "medium", "high", "urgent"] },
2941
2945
  assigneeId: { type: "string", nullable: true },
2942
2946
  dueDate: { type: "string", nullable: true },
2943
- done: { type: "boolean", description: "Mark card as done or not done" }
2947
+ done: { type: "boolean", description: "Mark card as done or not done" },
2948
+ planId: {
2949
+ type: "string",
2950
+ nullable: true,
2951
+ description: "Plan ID to link this card to, or null to unlink. Sets cards.plan_id. The plan must exist and belong to the same project."
2952
+ }
2944
2953
  },
2945
2954
  required: ["cardId"]
2946
2955
  }
@@ -3239,6 +3248,25 @@ var TOOLS = {
3239
3248
  required: ["subtaskId"]
3240
3249
  }
3241
3250
  },
3251
+ harmony_update_subtask: {
3252
+ description: "Update a subtask: rename its title, set an explicit completion state, and/or reorder it. Unlike harmony_toggle_subtask (which flips completion), `completed` here sets an explicit value — safe to call idempotently. At least one of title/completed/position is required.",
3253
+ inputSchema: {
3254
+ type: "object",
3255
+ properties: {
3256
+ subtaskId: { type: "string" },
3257
+ title: { type: "string", description: "New title (1–500 chars)" },
3258
+ completed: {
3259
+ type: "boolean",
3260
+ description: "Explicit completion state (set, not toggle)"
3261
+ },
3262
+ position: {
3263
+ type: "number",
3264
+ description: "New position (0-based ordering within the card)"
3265
+ }
3266
+ },
3267
+ required: ["subtaskId"]
3268
+ }
3269
+ },
3242
3270
  harmony_delete_subtask: {
3243
3271
  description: "Delete a subtask",
3244
3272
  inputSchema: {
@@ -4356,13 +4384,15 @@ async function handleToolCall(name, args, deps) {
4356
4384
  }
4357
4385
  case "harmony_update_card": {
4358
4386
  const cardId = z.string().uuid().parse(args.cardId);
4387
+ const planId = args.planId === undefined ? undefined : args.planId === null ? null : z.string().uuid().parse(args.planId);
4359
4388
  const result = await client3.updateCard(cardId, {
4360
4389
  title: args.title,
4361
4390
  description: args.description,
4362
4391
  priority: args.priority,
4363
4392
  assigneeId: args.assigneeId,
4364
4393
  dueDate: args.dueDate,
4365
- done: args.done
4394
+ done: args.done,
4395
+ planId
4366
4396
  });
4367
4397
  return { success: true, ...result };
4368
4398
  }
@@ -4565,6 +4595,24 @@ async function handleToolCall(name, args, deps) {
4565
4595
  const result = await client3.toggleSubtask(subtaskId);
4566
4596
  return { success: true, ...result };
4567
4597
  }
4598
+ case "harmony_update_subtask": {
4599
+ const subtaskId = z.string().uuid().parse(args.subtaskId);
4600
+ const updates = {};
4601
+ if (args.title !== undefined) {
4602
+ updates.title = z.string().min(1).max(500).parse(args.title);
4603
+ }
4604
+ if (args.completed !== undefined) {
4605
+ updates.completed = z.boolean().parse(args.completed);
4606
+ }
4607
+ if (args.position !== undefined) {
4608
+ updates.position = z.number().int().min(0).parse(args.position);
4609
+ }
4610
+ if (Object.keys(updates).length === 0) {
4611
+ throw new Error("harmony_update_subtask requires at least one of: title, completed, position");
4612
+ }
4613
+ const result = await client3.updateSubtask(subtaskId, updates);
4614
+ return { success: true, ...result };
4615
+ }
4568
4616
  case "harmony_delete_subtask": {
4569
4617
  const subtaskId = z.string().uuid().parse(args.subtaskId);
4570
4618
  await client3.deleteSubtask(subtaskId);
@@ -1154,6 +1154,9 @@ class HarmonyApiClient {
1154
1154
  async toggleSubtask(subtaskId) {
1155
1155
  return this.request("POST", `/subtasks/${subtaskId}/toggle`);
1156
1156
  }
1157
+ async updateSubtask(subtaskId, updates) {
1158
+ return this.request("PATCH", `/subtasks/${subtaskId}`, updates);
1159
+ }
1157
1160
  async deleteSubtask(subtaskId) {
1158
1161
  return this.request("DELETE", `/subtasks/${subtaskId}`);
1159
1162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gethmy/mcp",
3
- "version": "2.8.3",
3
+ "version": "2.8.4",
4
4
  "description": "MCP server for Harmony Kanban board - enables AI coding agents to manage your boards",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/api-client.ts CHANGED
@@ -474,6 +474,7 @@ export class HarmonyApiClient {
474
474
  dueDate?: string | null;
475
475
  done?: boolean;
476
476
  archivedAt?: string | null;
477
+ planId?: string | null;
477
478
  },
478
479
  ): Promise<{ card: unknown }> {
479
480
  return this.request("PATCH", `/cards/${cardId}`, updates);
@@ -617,6 +618,13 @@ export class HarmonyApiClient {
617
618
  return this.request("POST", `/subtasks/${subtaskId}/toggle`);
618
619
  }
619
620
 
621
+ async updateSubtask(
622
+ subtaskId: string,
623
+ updates: { title?: string; completed?: boolean; position?: number },
624
+ ): Promise<{ subtask: unknown }> {
625
+ return this.request("PATCH", `/subtasks/${subtaskId}`, updates);
626
+ }
627
+
620
628
  async deleteSubtask(subtaskId: string): Promise<{ success: boolean }> {
621
629
  return this.request("DELETE", `/subtasks/${subtaskId}`);
622
630
  }
@@ -78,6 +78,7 @@ export const AUTO_START_TRIGGERS = new Set([
78
78
  "harmony_update_card",
79
79
  "harmony_create_subtask",
80
80
  "harmony_toggle_subtask",
81
+ "harmony_update_subtask",
81
82
  ]);
82
83
 
83
84
  export const INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
package/src/server.ts CHANGED
@@ -308,6 +308,12 @@ export const TOOLS = {
308
308
  assigneeId: { type: "string", nullable: true },
309
309
  dueDate: { type: "string", nullable: true },
310
310
  done: { type: "boolean", description: "Mark card as done or not done" },
311
+ planId: {
312
+ type: "string",
313
+ nullable: true,
314
+ description:
315
+ "Plan ID to link this card to, or null to unlink. Sets cards.plan_id. The plan must exist and belong to the same project.",
316
+ },
311
317
  },
312
318
  required: ["cardId"],
313
319
  },
@@ -625,6 +631,26 @@ export const TOOLS = {
625
631
  required: ["subtaskId"],
626
632
  },
627
633
  },
634
+ harmony_update_subtask: {
635
+ description:
636
+ "Update a subtask: rename its title, set an explicit completion state, and/or reorder it. Unlike harmony_toggle_subtask (which flips completion), `completed` here sets an explicit value — safe to call idempotently. At least one of title/completed/position is required.",
637
+ inputSchema: {
638
+ type: "object",
639
+ properties: {
640
+ subtaskId: { type: "string" },
641
+ title: { type: "string", description: "New title (1–500 chars)" },
642
+ completed: {
643
+ type: "boolean",
644
+ description: "Explicit completion state (set, not toggle)",
645
+ },
646
+ position: {
647
+ type: "number",
648
+ description: "New position (0-based ordering within the card)",
649
+ },
650
+ },
651
+ required: ["subtaskId"],
652
+ },
653
+ },
628
654
  harmony_delete_subtask: {
629
655
  description: "Delete a subtask",
630
656
  inputSchema: {
@@ -1944,6 +1970,13 @@ async function handleToolCall(
1944
1970
 
1945
1971
  case "harmony_update_card": {
1946
1972
  const cardId = z.string().uuid().parse(args.cardId);
1973
+ // null = unlink, undefined = leave untouched, otherwise must be a UUID.
1974
+ const planId =
1975
+ args.planId === undefined
1976
+ ? undefined
1977
+ : args.planId === null
1978
+ ? null
1979
+ : z.string().uuid().parse(args.planId);
1947
1980
  const result = await client.updateCard(cardId, {
1948
1981
  title: args.title as string | undefined,
1949
1982
  description: args.description as string | undefined,
@@ -1951,6 +1984,7 @@ async function handleToolCall(
1951
1984
  assigneeId: args.assigneeId as string | null | undefined,
1952
1985
  dueDate: args.dueDate as string | null | undefined,
1953
1986
  done: args.done as boolean | undefined,
1987
+ planId,
1954
1988
  });
1955
1989
  return { success: true, ...result };
1956
1990
  }
@@ -2237,6 +2271,31 @@ async function handleToolCall(
2237
2271
  return { success: true, ...result };
2238
2272
  }
2239
2273
 
2274
+ case "harmony_update_subtask": {
2275
+ const subtaskId = z.string().uuid().parse(args.subtaskId);
2276
+ const updates: {
2277
+ title?: string;
2278
+ completed?: boolean;
2279
+ position?: number;
2280
+ } = {};
2281
+ if (args.title !== undefined) {
2282
+ updates.title = z.string().min(1).max(500).parse(args.title);
2283
+ }
2284
+ if (args.completed !== undefined) {
2285
+ updates.completed = z.boolean().parse(args.completed);
2286
+ }
2287
+ if (args.position !== undefined) {
2288
+ updates.position = z.number().int().min(0).parse(args.position);
2289
+ }
2290
+ if (Object.keys(updates).length === 0) {
2291
+ throw new Error(
2292
+ "harmony_update_subtask requires at least one of: title, completed, position",
2293
+ );
2294
+ }
2295
+ const result = await client.updateSubtask(subtaskId, updates);
2296
+ return { success: true, ...result };
2297
+ }
2298
+
2240
2299
  case "harmony_delete_subtask": {
2241
2300
  const subtaskId = z.string().uuid().parse(args.subtaskId);
2242
2301
  await client.deleteSubtask(subtaskId);