@gethmy/mcp 2.21.0 → 2.23.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/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # @gethmy/mcp
2
2
 
3
- MCP (Model Context Protocol) server for [Harmony](https://gethmy.com).
4
- Enables AI coding agents (Claude Code, OpenAI Codex, Cursor) to interact with your Harmony boards.
3
+ MCP (Model Context Protocol) server for [Harmony](https://gethmy.com), the shared surface for human–agent teams.
4
+ Claude Code, OpenAI Codex, Cursor, and any MCP client claim cards, report progress, and move work on your board.
5
5
 
6
6
  ## Features
7
7
 
8
- - **71 MCP Tools** for full board control, knowledge graph, and workflow plans
9
- - **7 Global Skills** — `/hmy`, `/hmy-plan`, `/hmy-cleanup`, `/hmy-standup`, `/hmy-memory-prune`, `/hmy-upgrade`, `/hmy-review`, served from the DB-backed [skill hub](../../docs/skills.md) with auto-update and admin-managed versioning
8
+ - **78 MCP Tools** for full board control, knowledge graph, and workflow plans
9
+ - **Global Skills** — installable in one command, served from the DB-backed [skill hub](../../docs/skills.md) with auto-update and admin-managed versioning
10
10
  - **Knowledge Graph Memory** — Phase 1 surface: hybrid retrieval (vector + lexical + RRF), session-scoped working memory, activity feed. See [docs/memory.md](../../docs/memory.md)
11
11
  - **GSD Workflow Plans** - plan/execute/verify/done lifecycle with auto card creation
12
12
  - **Card Linking** - create relationships between cards (blocks, relates_to, duplicates, is_part_of)
@@ -16,7 +16,7 @@ Enables AI coding agents (Claude Code, OpenAI Codex, Cursor) to interact with yo
16
16
  - **Auto-Assignment** - automatically assign cards to you when starting agent sessions
17
17
  - **Memory Sync** - bidirectional sync between local markdown files and remote database
18
18
  - **Multi-Agent Support** - works with Claude Code, Codex, Cursor, Claude.ai
19
- - **Smart Setup** - one command configures everything
19
+ - **One-Command Setup** - one command configures everything
20
20
  - **Browser Sign-In** - secure OAuth setup (loopback + PKCE), no key to copy or paste; API keys still supported for CI
21
21
 
22
22
  ## Prerequisites
@@ -32,7 +32,7 @@ Enables AI coding agents (Claude Code, OpenAI Codex, Cursor) to interact with yo
32
32
  npx @gethmy/mcp setup
33
33
  ```
34
34
 
35
- The smart setup wizard will:
35
+ The setup wizard will:
36
36
 
37
37
  - Sign you in through your browser (OAuth — no API key to copy or paste). You can also create a free account or paste an existing key from the same prompt.
38
38
  - Detect installed AI agents (Claude Code, Cursor, Codex)
@@ -89,7 +89,7 @@ If you prefer to configure manually (e.g., in Claude.ai's UI):
89
89
  1. Get an API key from [Harmony](https://gethmy.com/user/keys)
90
90
  2. In Claude.ai, add a remote MCP server with URL `https://mcp.gethmy.com/mcp`
91
91
  3. Set the Authorization header to `Bearer hmy_your_key_here`
92
- 4. All 70 Harmony tools become available in your conversation
92
+ 4. All 78 Harmony tools become available in your conversation
93
93
 
94
94
  **Session management** is automatic - sessions have a 1-hour TTL and are created/renewed transparently.
95
95
 
@@ -110,7 +110,7 @@ It detects your existing configuration and only asks for the project context.
110
110
 
111
111
  ```bash
112
112
  # Setup (recommended) — authorizes in your browser, no API key handling
113
- npx @gethmy/mcp setup # Smart setup wizard
113
+ npx @gethmy/mcp setup # Setup wizard
114
114
 
115
115
  # Setup with flags (non-interactive)
116
116
  npx @gethmy/mcp setup --global --workspace ID --project ID
@@ -150,9 +150,9 @@ npx @gethmy/mcp serve # Start MCP server
150
150
 
151
151
  ## Skills
152
152
 
153
- Seven global skills ship with the MCP server and are installed automatically by `npx @gethmy/mcp setup`. They live in the `skill_resource` Postgres table, are fetched via `GET /v1/skills/<name>`, and render-time composed with a shared auto-update preamble.
153
+ Global skills ship with the MCP server and are installed automatically by `npx @gethmy/mcp setup`. They live in the `skill_resource` Postgres table, are fetched via `GET /v1/skills/<name>`, and render-time composed.
154
154
 
155
- For the full skill hub architecture (storage, versioning, auto-update, admin management), see [docs/skills.md](../../docs/skills.md).
155
+ For the full skill list and the hub architecture (storage, versioning, auto-update, admin management), see [docs/skills.md](../../docs/skills.md).
156
156
 
157
157
  ### `/hmy` — Card Workflow
158
158
 
@@ -200,7 +200,7 @@ Generates a structured standup summary: what shipped, what's in progress, what's
200
200
 
201
201
  ### Auto-Update
202
202
 
203
- Every skill ships with an `hmy-update-check` preamble that fires on invocation. It compares local versions against `/v1/skills/version` and prompts (or silently auto-installs, if `~/.hmy/config.yaml` has `auto_upgrade: true`). Snooze levels: 24h / 48h / 7d.
203
+ The server owns auto-update. `refreshSkills()` runs at `serve` startup, calls `GET /v1/skills/version` at most once per 24h, and atomically rewrites only the installed skill files that are behind. Two knobs live in `~/.hmy/config.yaml`: `update_check` (master switch) and `pin` (freeze on the installed version).
204
204
 
205
205
  ## Available Tools
206
206
 
@@ -296,7 +296,7 @@ Sessions are automatically started when agents call card-mutating tools without
296
296
  |-----------|-------------|
297
297
  | `cardId` | Card UUID to generate prompt from |
298
298
  | `shortId` | Alternative: Card short ID (e.g., 42 for #42) |
299
- | `variant` | `analysis` (understand/plan), `draft` (design solution), `execute` (implement fully) |
299
+ | `variant` | `analysis` (understand/plan), `draft` (design the approach), `execute` (implement fully) |
300
300
  | `includeDescription` | Include card description (default: true) |
301
301
  | `includeSubtasks` | Include subtasks in prompt (default: true) |
302
302
  | `includeLinks` | Include linked cards in prompt (default: true) |
@@ -340,7 +340,7 @@ Create and manage project plans with a phased workflow: **plan** → **execute**
340
340
  - `harmony_get_plan` - Get plan by ID or card ID
341
341
  - `harmony_update_plan` - Update plan title, content, status, or phase
342
342
  - `harmony_advance_plan` - Advance to next phase with side effects:
343
- - **plan → execute:** auto-creates Kanban cards from plan tasks, sets plan active
343
+ - **plan → execute:** auto-creates board cards from plan tasks, sets plan active
344
344
  - **execute → verify:** checks card completion status
345
345
  - **verify → done:** archives plan, creates memory entities
346
346
 
@@ -349,7 +349,7 @@ Create and manage project plans with a phased workflow: **plan** → **execute**
349
349
  - `harmony_onboard` - Complete end-to-end onboarding: signup → workspace → project → API key
350
350
  - `harmony_signup` - Create a new user account
351
351
  - `harmony_create_workspace` - Create a new workspace
352
- - `harmony_create_project` - Create a new project with template columns (kanban, scrum, or simple)
352
+ - `harmony_create_project` - Create a new project with template columns (kanban, scrum, or simple) <!-- copy-guard-ignore: template enum value of the public API, not copy -->
353
353
  - `harmony_send_invitations` - Send workspace invitations to team members
354
354
  - `harmony_generate_api_key` - Generate an API key for the authenticated user
355
355
 
package/dist/cli.js CHANGED
@@ -4657,6 +4657,11 @@ var TOOLS = {
4657
4657
  steerable: {
4658
4658
  type: "boolean",
4659
4659
  description: "Set true only if this session will poll harmony_get_pending_messages at its checkpoints. Enables the live steering composer for the run; leave unset/false if you won't consume steering messages."
4660
+ },
4661
+ driver: {
4662
+ type: "string",
4663
+ enum: ["daemon", "interactive", "script"],
4664
+ description: 'Who is calling: the agent daemon, a human-driven interactive session, or an automation script. Names you as the holder if another caller hits a 409 on this card. Defaults to "interactive".'
4660
4665
  }
4661
4666
  },
4662
4667
  required: ["cardId", "agentIdentifier", "agentName"]
@@ -6411,7 +6416,8 @@ ${options}
6411
6416
  status: "working",
6412
6417
  currentTask: args.currentTask,
6413
6418
  estimatedMinutesRemaining: optionalNonNegativeNumberArg(args.estimatedMinutesRemaining, "estimatedMinutesRemaining"),
6414
- steerable: args.steerable === true || args.steerable === "true" ? true : undefined
6419
+ steerable: args.steerable === true || args.steerable === "true" ? true : undefined,
6420
+ driver: args.driver ?? "interactive"
6415
6421
  });
6416
6422
  markExplicit(cardId, {
6417
6423
  agentIdentifier,
@@ -9395,7 +9401,7 @@ Specify the workspace with --workspace <id>, or select one below.`);
9395
9401
  // src/cli.ts
9396
9402
  var require2 = createRequire2(import.meta.url);
9397
9403
  var { version } = require2("../package.json");
9398
- program.name("@gethmy/mcp").description("MCP server for Harmony Kanban board").version(version);
9404
+ program.name("@gethmy/mcp").description("MCP server for Harmony the shared surface for human–agent teams").version(version);
9399
9405
  program.command("serve").description("Start the MCP server (stdio transport)").action(async () => {
9400
9406
  if (!isConfigured()) {
9401
9407
  console.error("No API key configured.");
@@ -9479,7 +9485,7 @@ program.command("reset").description("Remove stored configuration").action(() =>
9479
9485
  console.log(`
9480
9486
  To reconfigure, run: npx @gethmy/mcp setup`);
9481
9487
  });
9482
- program.command("setup").description("Smart setup wizard for Harmony MCP (recommended)").argument("[slug]", "Project slug — resolves to workspace + project in one step (e.g. harmony-6590761b)").option("-f, --force", "Overwrite existing configuration files").option("-k, --api-key <key>", "DEPRECATED (insecure: key leaks via argv/shell history). For unattended CI only — interactive setup uses browser sign-in.").option("-e, --email <email>", "Your email for auto-assignment").option("-a, --agents <agents...>", "Agents to configure: claude, codex, cursor, windsurf").option("-l, --local", "Install skills locally in project directory").option("-g, --global", "Install skills globally (recommended)").option("-w, --workspace <id>", "Set workspace context (UUID)").option("-p, --project <id>", "Set project context (UUID)").option("--skip-context", "Skip workspace/project selection").option("--skip-docs", "Skip project docs scaffold/verification").option("-y, --yes", "Non-interactive: answer every yes/no confirmation with its default. Implied when there is no TTY (pipe / coding agent / CI). Provide the other inputs via flags (--api-key, --agents, --workspace/--project or --skip-context, --skip-docs).").option("--new", "Create a new account (skip the choice prompt)").option("-n, --name <name>", "Full name (for account creation)").option("--allow-all-tools", "Allowlist every Harmony tool (incl. destructive: delete/archive/api-key/invite) without confirmation. Default allowlists only read + routine-write tools; destructive tools keep prompting.").action(async (slug, options) => {
9488
+ program.command("setup").description("Setup wizard for Harmony MCP (recommended)").argument("[slug]", "Project slug — resolves to workspace + project in one step (e.g. harmony-6590761b)").option("-f, --force", "Overwrite existing configuration files").option("-k, --api-key <key>", "DEPRECATED (insecure: key leaks via argv/shell history). For unattended CI only — interactive setup uses browser sign-in.").option("-e, --email <email>", "Your email for auto-assignment").option("-a, --agents <agents...>", "Agents to configure: claude, codex, cursor, windsurf").option("-l, --local", "Install skills locally in project directory").option("-g, --global", "Install skills globally (recommended)").option("-w, --workspace <id>", "Set workspace context (UUID)").option("-p, --project <id>", "Set project context (UUID)").option("--skip-context", "Skip workspace/project selection").option("--skip-docs", "Skip project docs scaffold/verification").option("-y, --yes", "Non-interactive: answer every yes/no confirmation with its default. Implied when there is no TTY (pipe / coding agent / CI). Provide the other inputs via flags (--api-key, --agents, --workspace/--project or --skip-context, --skip-docs).").option("--new", "Create a new account (skip the choice prompt)").option("-n, --name <name>", "Full name (for account creation)").option("--allow-all-tools", "Allowlist every Harmony tool (incl. destructive: delete/archive/api-key/invite) without confirmation. Default allowlists only read + routine-write tools; destructive tools keep prompting.").action(async (slug, options) => {
9483
9489
  await runSetup({
9484
9490
  force: options.force,
9485
9491
  apiKey: options.apiKey,
package/dist/index.js CHANGED
@@ -4652,6 +4652,11 @@ var TOOLS = {
4652
4652
  steerable: {
4653
4653
  type: "boolean",
4654
4654
  description: "Set true only if this session will poll harmony_get_pending_messages at its checkpoints. Enables the live steering composer for the run; leave unset/false if you won't consume steering messages."
4655
+ },
4656
+ driver: {
4657
+ type: "string",
4658
+ enum: ["daemon", "interactive", "script"],
4659
+ description: 'Who is calling: the agent daemon, a human-driven interactive session, or an automation script. Names you as the holder if another caller hits a 409 on this card. Defaults to "interactive".'
4655
4660
  }
4656
4661
  },
4657
4662
  required: ["cardId", "agentIdentifier", "agentName"]
@@ -6406,7 +6411,8 @@ ${options}
6406
6411
  status: "working",
6407
6412
  currentTask: args.currentTask,
6408
6413
  estimatedMinutesRemaining: optionalNonNegativeNumberArg(args.estimatedMinutesRemaining, "estimatedMinutesRemaining"),
6409
- steerable: args.steerable === true || args.steerable === "true" ? true : undefined
6414
+ steerable: args.steerable === true || args.steerable === "true" ? true : undefined,
6415
+ driver: args.driver ?? "interactive"
6410
6416
  });
6411
6417
  markExplicit(cardId, {
6412
6418
  agentIdentifier,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gethmy/mcp",
3
- "version": "2.21.0",
4
- "description": "MCP server for Harmony Kanban board - enables AI coding agents to manage your boards",
3
+ "version": "2.23.0",
4
+ "description": "MCP server for Harmony, the shared surface for human–agent teams agents claim cards, report progress, and move work on your board.",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -63,8 +63,9 @@
63
63
  "build:bun": "bun build src/index.ts src/http.ts src/remote.ts src/cli.ts --outdir dist --target bun",
64
64
  "serve:remote": "bun src/remote.ts",
65
65
  "dev": "bun --watch src/index.ts",
66
- "test": "bun run test:unit && bun run test:integration",
67
- "test:unit": "bun test src/__tests__/active-learning.test.ts src/__tests__/context-assembly.test.ts src/__tests__/prompt-builder.test.ts src/__tests__/memory-audit.test.ts src/__tests__/skills.test.ts src/__tests__/hmy-config.test.ts src/__tests__/tool-dispatch.test.ts src/__tests__/mcp-integration.test.ts src/__tests__/auto-session.test.ts src/__tests__/remote-routing.test.ts src/__tests__/setup-confirm.test.ts",
66
+ "test": "bun run test:unit",
67
+ "test:unit": "bun scripts/test-isolated.mjs",
68
+ "test:unit:fast": "bun test src/__tests__ --path-ignore-patterns='**/integration-*'",
68
69
  "test:integration": "bun test src/__tests__/integration-memory-system.test.ts src/__tests__/integration-memory-crud.test.ts",
69
70
  "typecheck": "tsc --noEmit",
70
71
  "prepublishOnly": "bun run typecheck && bun run build"
package/src/api-client.ts CHANGED
@@ -1081,6 +1081,22 @@ export class HarmonyApiClient {
1081
1081
  currentTask?: string;
1082
1082
  blockers?: string[];
1083
1083
  estimatedMinutesRemaining?: number;
1084
+ /**
1085
+ * Model the run was spawned with (#819). Persisted to
1086
+ * `card_agent_context.model_name` at session creation so the board's
1087
+ * "Agent Stats" shows the model from run start — previously it stayed
1088
+ * NULL until the terminal cost frame reported the observed model.
1089
+ */
1090
+ modelName?: string;
1091
+ /**
1092
+ * Who is calling (Task 5, "the drivers"): `daemon` (the local agent
1093
+ * daemon), `interactive` (a human-driven `/hmy` session), or `script`
1094
+ * (e.g. the e2e harness). Names the holder in a 409 conflict message so
1095
+ * a second caller knows who to wait on. Optional and nullable
1096
+ * server-side — omitting it is unchanged (pre-existing callers keep
1097
+ * working); the MCP tool dispatch defaults to `interactive`.
1098
+ */
1099
+ driver?: "daemon" | "interactive" | "script";
1084
1100
  },
1085
1101
  ): Promise<{
1086
1102
  session: unknown;
package/src/cli.ts CHANGED
@@ -22,7 +22,9 @@ const { version } = require("../package.json");
22
22
 
23
23
  program
24
24
  .name("@gethmy/mcp")
25
- .description("MCP server for Harmony Kanban board")
25
+ .description(
26
+ "MCP server for Harmony — the shared surface for human–agent teams",
27
+ )
26
28
  .version(version);
27
29
 
28
30
  program
@@ -146,7 +148,7 @@ program
146
148
 
147
149
  program
148
150
  .command("setup")
149
- .description("Smart setup wizard for Harmony MCP (recommended)")
151
+ .description("Setup wizard for Harmony MCP (recommended)")
150
152
  .argument(
151
153
  "[slug]",
152
154
  "Project slug — resolves to workspace + project in one step (e.g. harmony-6590761b)",
package/src/server.ts CHANGED
@@ -1550,6 +1550,12 @@ export const TOOLS = {
1550
1550
  description:
1551
1551
  "Set true only if this session will poll harmony_get_pending_messages at its checkpoints. Enables the live steering composer for the run; leave unset/false if you won't consume steering messages.",
1552
1552
  },
1553
+ driver: {
1554
+ type: "string",
1555
+ enum: ["daemon", "interactive", "script"],
1556
+ description:
1557
+ 'Who is calling: the agent daemon, a human-driven interactive session, or an automation script. Names you as the holder if another caller hits a 409 on this card. Defaults to "interactive".',
1558
+ },
1553
1559
  },
1554
1560
  required: ["cardId", "agentIdentifier", "agentName"],
1555
1561
  },
@@ -3920,6 +3926,11 @@ async function handleToolCall(
3920
3926
  args.steerable === true || args.steerable === "true"
3921
3927
  ? true
3922
3928
  : undefined,
3929
+ // Every MCP caller is interactive unless it says otherwise — this is
3930
+ // the human-driven `/hmy` surface, not the daemon or the e2e script.
3931
+ driver:
3932
+ (args.driver as "daemon" | "interactive" | "script" | undefined) ??
3933
+ "interactive",
3923
3934
  });
3924
3935
 
3925
3936
  // Mark as explicit so auto-session won't interfere