harmony-mcp 1.3.1 → 1.3.2

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/README.md CHANGED
@@ -8,6 +8,7 @@ MCP (Model Context Protocol) server for Harmony Kanban board. Enables AI coding
8
8
  - **Card Linking** - create relationships between cards (blocks, relates_to, duplicates, is_part_of)
9
9
  - **Prompt Builder** - generate AI-ready prompts from cards with context
10
10
  - **Agent Session Tracking** - track work progress with timer badges
11
+ - **Auto-Assignment** - automatically assign cards to you when starting agent sessions
11
12
  - **Multi-Agent Support** - works with Claude Code, Codex, Cursor, Windsurf
12
13
  - **One-Command Setup** - auto-configure all supported agents
13
14
  - **Natural Language Processing** via voice-nlu edge function
@@ -32,6 +33,9 @@ npm install -g harmony-mcp
32
33
 
33
34
  ```bash
34
35
  harmony-mcp configure --api-key hmy_your_key_here
36
+
37
+ # Optional: Set your email for auto-assignment
38
+ harmony-mcp configure --api-key hmy_your_key_here --user-email you@example.com
35
39
  ```
36
40
 
37
41
  ### 4. Initialize for Your AI Agents
@@ -86,26 +90,30 @@ When you start working on a card (e.g., `/hmy #42`):
86
90
  1. **Find** - Locates the card by short ID, UUID, or name
87
91
  2. **Move** - Moves the card to "In Progress" column
88
92
  3. **Label** - Adds the "agent" label to indicate AI is working
89
- 4. **Track** - Starts a session timer visible in the UI
90
- 5. **Implement** - Work on the task with progress updates
91
- 6. **Complete** - Move to "Review" when done
93
+ 4. **Assign** - Auto-assigns the card to you (if `userEmail` is configured)
94
+ 5. **Track** - Starts a session timer visible in the UI
95
+ 6. **Implement** - Work on the task with progress updates
96
+ 7. **Complete** - Move to "Review" when done
92
97
 
93
98
  ## CLI Commands
94
99
 
95
100
  ```bash
96
- harmony-mcp configure # Set up API key
97
- harmony-mcp init # Initialize for AI agents (interactive)
98
- harmony-mcp init --all # Configure all supported agents
99
- harmony-mcp init --detect # Auto-detect and configure installed agents
100
- harmony-mcp init --agent X Y # Configure specific agents
101
- harmony-mcp init -w WS -p PROJ # Initialize with local workspace/project context
102
- harmony-mcp status # Show current config (global and local)
103
- harmony-mcp reset # Clear configuration
104
- harmony-mcp set-workspace ID # Set active workspace (global)
105
- harmony-mcp set-workspace ID -l # Set active workspace (local project)
106
- harmony-mcp set-project ID # Set active project (global)
107
- harmony-mcp set-project ID -l # Set active project (local project)
108
- harmony-mcp serve # Start MCP server
101
+ harmony-mcp configure # Set up API key (interactive)
102
+ harmony-mcp configure -k KEY -e EMAIL # Set up with API key and email
103
+ harmony-mcp init # Initialize for AI agents (interactive)
104
+ harmony-mcp init --all # Configure all supported agents
105
+ harmony-mcp init --detect # Auto-detect and configure installed agents
106
+ harmony-mcp init --agent X Y # Configure specific agents
107
+ harmony-mcp init -w WS -p PROJ # Initialize with local workspace/project context
108
+ harmony-mcp status # Show current config (global and local)
109
+ harmony-mcp reset # Clear configuration
110
+ harmony-mcp set-workspace ID # Set active workspace (global)
111
+ harmony-mcp set-workspace ID -l # Set active workspace (local project)
112
+ harmony-mcp set-project ID # Set active project (global)
113
+ harmony-mcp set-project ID -l # Set active project (local project)
114
+ harmony-mcp set-user-email EMAIL # Set email for auto-assignment
115
+ harmony-mcp clear-user-email # Disable auto-assignment
116
+ harmony-mcp serve # Start MCP server
109
117
  ```
110
118
 
111
119
  ## Available Tools
@@ -245,10 +253,27 @@ Your global configuration is stored in `~/.harmony-mcp/config.json`:
245
253
  "apiKey": "hmy_...",
246
254
  "apiUrl": "https://gethmy.com/api",
247
255
  "activeWorkspaceId": null,
248
- "activeProjectId": null
256
+ "activeProjectId": null,
257
+ "userEmail": "you@example.com"
249
258
  }
250
259
  ```
251
260
 
261
+ ### Auto-Assignment
262
+
263
+ When `userEmail` is configured, cards are automatically assigned to you when you start an agent session (e.g., via `/hmy #42`). This helps track who is working on what.
264
+
265
+ To enable auto-assignment:
266
+ ```bash
267
+ harmony-mcp set-user-email you@example.com
268
+ ```
269
+
270
+ To disable auto-assignment:
271
+ ```bash
272
+ harmony-mcp clear-user-email
273
+ ```
274
+
275
+ The email must match your Harmony account email to work correctly.
276
+
252
277
  ### Local Project Configuration
253
278
 
254
279
  For multi-project workflows, you can set project-specific context using local configuration. This is stored in `.harmony-mcp.json` in your project root:
@@ -287,6 +312,7 @@ Example output:
287
312
  Status: Configured
288
313
  API Key: hmy_abc1...
289
314
  API URL: https://gethmy.com/api
315
+ User Email: y***@example.com
290
316
 
291
317
  Global Context:
292
318
  Workspace: <global-ws-id>
package/dist/cli.js CHANGED
@@ -25251,7 +25251,8 @@ function loadConfig() {
25251
25251
  apiKey: null,
25252
25252
  apiUrl: DEFAULT_API_URL,
25253
25253
  activeWorkspaceId: null,
25254
- activeProjectId: null
25254
+ activeProjectId: null,
25255
+ userEmail: null
25255
25256
  };
25256
25257
  }
25257
25258
  try {
@@ -25261,14 +25262,16 @@ function loadConfig() {
25261
25262
  apiKey: config2.apiKey || null,
25262
25263
  apiUrl: config2.apiUrl || DEFAULT_API_URL,
25263
25264
  activeWorkspaceId: config2.activeWorkspaceId || null,
25264
- activeProjectId: config2.activeProjectId || null
25265
+ activeProjectId: config2.activeProjectId || null,
25266
+ userEmail: config2.userEmail || null
25265
25267
  };
25266
25268
  } catch {
25267
25269
  return {
25268
25270
  apiKey: null,
25269
25271
  apiUrl: DEFAULT_API_URL,
25270
25272
  activeWorkspaceId: null,
25271
- activeProjectId: null
25273
+ activeProjectId: null,
25274
+ userEmail: null
25272
25275
  };
25273
25276
  }
25274
25277
  }
@@ -25327,6 +25330,13 @@ function getApiUrl() {
25327
25330
  const config2 = loadConfig();
25328
25331
  return config2.apiUrl;
25329
25332
  }
25333
+ function getUserEmail() {
25334
+ const config2 = loadConfig();
25335
+ return config2.userEmail;
25336
+ }
25337
+ function setUserEmail(email2) {
25338
+ saveConfig({ userEmail: email2 });
25339
+ }
25330
25340
  function setActiveWorkspace(workspaceId, options) {
25331
25341
  if (options?.local) {
25332
25342
  saveLocalConfig({ workspaceId }, options.cwd);
@@ -26521,6 +26531,21 @@ Include: cards moved recently, current in-progress items, blocked or high-priori
26521
26531
  const cardId = exports_external.string().uuid().parse(args.cardId);
26522
26532
  const agentIdentifier = exports_external.string().min(1).parse(args.agentIdentifier);
26523
26533
  const agentName = exports_external.string().min(1).parse(args.agentName);
26534
+ let assignedTo = null;
26535
+ const userEmail = getUserEmail();
26536
+ if (userEmail) {
26537
+ try {
26538
+ const workspaceId = getActiveWorkspaceId();
26539
+ if (workspaceId) {
26540
+ const { members } = await client2.getWorkspaceMembers(workspaceId);
26541
+ const user = members.find((m) => m.email === userEmail);
26542
+ if (user) {
26543
+ await client2.updateCard(cardId, { assigneeId: user.id });
26544
+ assignedTo = user.email;
26545
+ }
26546
+ }
26547
+ } catch {}
26548
+ }
26524
26549
  const result = await client2.startAgentSession(cardId, {
26525
26550
  agentIdentifier,
26526
26551
  agentName,
@@ -26528,7 +26553,7 @@ Include: cards moved recently, current in-progress items, blocked or high-priori
26528
26553
  currentTask: args.currentTask,
26529
26554
  estimatedMinutesRemaining: args.estimatedMinutesRemaining
26530
26555
  });
26531
- return { success: true, ...result };
26556
+ return { success: true, assignedTo, ...result };
26532
26557
  }
26533
26558
  case "harmony_update_agent_progress": {
26534
26559
  const cardId = exports_external.string().uuid().parse(args.cardId);
@@ -26643,10 +26668,11 @@ program.command("serve").description("Start the MCP server (stdio transport)").a
26643
26668
  const server = new HarmonyMCPServer;
26644
26669
  await server.run();
26645
26670
  });
26646
- program.command("configure").description("Configure the MCP server with your Harmony API key").option("-k, --api-key <key>", "API key (generate at gethmy.com → Settings → API Keys)").option("-u, --api-url <url>", "API URL (optional, for self-hosted instances)").action(async (options) => {
26671
+ program.command("configure").description("Configure the MCP server with your Harmony API key").option("-k, --api-key <key>", "API key (generate at gethmy.com → Settings → API Keys)").option("-u, --api-url <url>", "API URL (optional, for self-hosted instances)").option("-e, --user-email <email>", "Your email for auto-assignment when starting agent sessions").action(async (options) => {
26647
26672
  try {
26648
26673
  let apiKey = options.apiKey;
26649
26674
  let apiUrl = options.apiUrl;
26675
+ let userEmail = options.userEmail;
26650
26676
  if (!apiKey) {
26651
26677
  console.log(`Configure Harmony MCP Server
26652
26678
  `);
@@ -26663,10 +26689,16 @@ program.command("configure").description("Configure the MCP server with your Har
26663
26689
  if (apiUrl) {
26664
26690
  config2.apiUrl = apiUrl;
26665
26691
  }
26692
+ if (userEmail) {
26693
+ config2.userEmail = userEmail;
26694
+ }
26666
26695
  saveConfig(config2);
26667
26696
  console.log(`
26668
26697
  Configuration saved successfully!`);
26669
26698
  console.log(`Config file: ${getConfigPath()}`);
26699
+ if (userEmail) {
26700
+ console.log(`User email: ${userEmail}`);
26701
+ }
26670
26702
  console.log(`
26671
26703
  You can now use the MCP server with Claude Code.`);
26672
26704
  console.log(`Add this to your ~/.claude/settings.json:
@@ -26690,10 +26722,17 @@ program.command("status").description("Show configuration status").action(() =>
26690
26722
  const globalConfig2 = loadConfig();
26691
26723
  const localConfig = loadLocalConfig();
26692
26724
  const hasLocal = hasLocalConfig();
26725
+ const maskEmail = (email2) => {
26726
+ const [local, domain] = email2.split("@");
26727
+ if (!domain)
26728
+ return email2;
26729
+ return `${local[0]}***@${domain}`;
26730
+ };
26693
26731
  if (isConfigured()) {
26694
26732
  console.log("Status: Configured");
26695
26733
  console.log(`API Key: ${globalConfig2.apiKey?.slice(0, 8)}...`);
26696
26734
  console.log(`API URL: ${globalConfig2.apiUrl}`);
26735
+ console.log(`User Email: ${globalConfig2.userEmail ? maskEmail(globalConfig2.userEmail) : "(not set)"}`);
26697
26736
  console.log(`
26698
26737
  Global Context:`);
26699
26738
  console.log(` Workspace: ${globalConfig2.activeWorkspaceId || "(not set)"}`);
@@ -26728,7 +26767,8 @@ program.command("reset").description("Remove stored configuration").action(() =>
26728
26767
  saveConfig({
26729
26768
  apiKey: null,
26730
26769
  activeWorkspaceId: null,
26731
- activeProjectId: null
26770
+ activeProjectId: null,
26771
+ userEmail: null
26732
26772
  });
26733
26773
  console.log("Configuration reset successfully");
26734
26774
  });
@@ -26752,6 +26792,22 @@ program.command("set-project <projectId>").description("Set the active project c
26752
26792
  console.log(`Global project set to: ${projectId}`);
26753
26793
  }
26754
26794
  });
26795
+ program.command("set-user-email <email>").description("Set your email for auto-assignment when starting agent sessions").action((email2) => {
26796
+ if (!email2.includes("@") || !email2.includes(".")) {
26797
+ console.error("Error: Invalid email format");
26798
+ process.exit(1);
26799
+ }
26800
+ setUserEmail(email2);
26801
+ console.log(`User email set to: ${email2}`);
26802
+ console.log(`
26803
+ Cards will be automatically assigned to you when starting agent sessions.`);
26804
+ });
26805
+ program.command("clear-user-email").description("Clear the configured user email (disables auto-assignment)").action(() => {
26806
+ setUserEmail(null);
26807
+ console.log("User email cleared");
26808
+ console.log(`
26809
+ Auto-assignment is now disabled.`);
26810
+ });
26755
26811
  program.command("init").description("Initialize Harmony MCP for AI coding agents (Claude Code, Codex, Cursor, Windsurf)").option("-a, --agent <agents...>", `Agent(s) to configure: ${SUPPORTED_AGENTS.join(", ")}`).option("--all", "Configure all supported agents").option("--detect", "Auto-detect installed agents and configure them").option("-f, --force", "Overwrite existing configuration files").option("-d, --directory <path>", "Project directory (default: current directory)").option("-w, --workspace <id>", "Set local workspace context for this project").option("-p, --project <id>", "Set local project context for this project").action(async (options) => {
26756
26812
  console.log(`Harmony MCP Initialization
26757
26813
  `);
package/dist/index.js CHANGED
@@ -23013,7 +23013,8 @@ function loadConfig() {
23013
23013
  apiKey: null,
23014
23014
  apiUrl: DEFAULT_API_URL,
23015
23015
  activeWorkspaceId: null,
23016
- activeProjectId: null
23016
+ activeProjectId: null,
23017
+ userEmail: null
23017
23018
  };
23018
23019
  }
23019
23020
  try {
@@ -23023,14 +23024,16 @@ function loadConfig() {
23023
23024
  apiKey: config2.apiKey || null,
23024
23025
  apiUrl: config2.apiUrl || DEFAULT_API_URL,
23025
23026
  activeWorkspaceId: config2.activeWorkspaceId || null,
23026
- activeProjectId: config2.activeProjectId || null
23027
+ activeProjectId: config2.activeProjectId || null,
23028
+ userEmail: config2.userEmail || null
23027
23029
  };
23028
23030
  } catch {
23029
23031
  return {
23030
23032
  apiKey: null,
23031
23033
  apiUrl: DEFAULT_API_URL,
23032
23034
  activeWorkspaceId: null,
23033
- activeProjectId: null
23035
+ activeProjectId: null,
23036
+ userEmail: null
23034
23037
  };
23035
23038
  }
23036
23039
  }
@@ -23089,6 +23092,13 @@ function getApiUrl() {
23089
23092
  const config2 = loadConfig();
23090
23093
  return config2.apiUrl;
23091
23094
  }
23095
+ function getUserEmail() {
23096
+ const config2 = loadConfig();
23097
+ return config2.userEmail;
23098
+ }
23099
+ function setUserEmail(email2) {
23100
+ saveConfig({ userEmail: email2 });
23101
+ }
23092
23102
  function setActiveWorkspace(workspaceId, options) {
23093
23103
  if (options?.local) {
23094
23104
  saveLocalConfig({ workspaceId }, options.cwd);
@@ -24283,6 +24293,21 @@ Include: cards moved recently, current in-progress items, blocked or high-priori
24283
24293
  const cardId = exports_external.string().uuid().parse(args.cardId);
24284
24294
  const agentIdentifier = exports_external.string().min(1).parse(args.agentIdentifier);
24285
24295
  const agentName = exports_external.string().min(1).parse(args.agentName);
24296
+ let assignedTo = null;
24297
+ const userEmail = getUserEmail();
24298
+ if (userEmail) {
24299
+ try {
24300
+ const workspaceId = getActiveWorkspaceId();
24301
+ if (workspaceId) {
24302
+ const { members } = await client2.getWorkspaceMembers(workspaceId);
24303
+ const user = members.find((m) => m.email === userEmail);
24304
+ if (user) {
24305
+ await client2.updateCard(cardId, { assigneeId: user.id });
24306
+ assignedTo = user.email;
24307
+ }
24308
+ }
24309
+ } catch {}
24310
+ }
24286
24311
  const result = await client2.startAgentSession(cardId, {
24287
24312
  agentIdentifier,
24288
24313
  agentName,
@@ -24290,7 +24315,7 @@ Include: cards moved recently, current in-progress items, blocked or high-priori
24290
24315
  currentTask: args.currentTask,
24291
24316
  estimatedMinutesRemaining: args.estimatedMinutesRemaining
24292
24317
  });
24293
- return { success: true, ...result };
24318
+ return { success: true, assignedTo, ...result };
24294
24319
  }
24295
24320
  case "harmony_update_agent_progress": {
24296
24321
  const cardId = exports_external.string().uuid().parse(args.cardId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harmony-mcp",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "MCP server for Harmony Kanban board - enables AI coding agents to manage your boards",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",