@codazen/harmonica-mcp 0.22.0 → 0.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.
Files changed (2) hide show
  1. package/dist/index.js +39 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22966,28 +22966,45 @@ function registerDropTools(server, ctx, client) {
22966
22966
  );
22967
22967
  server.tool(
22968
22968
  "get_drop",
22969
- "Get full details of a Drop by ID \u2014 state, member Revisions, target date, and audit trail.",
22969
+ "Get full details of a Drop by ID \u2014 state, member Revisions, target date, and audit trail. Accepts either a UUID (drop-abc123) or a drop code (D-086). When passing a code, teamspaceId is required.",
22970
22970
  {
22971
- dropId: external_exports.string().describe("The Drop ID (UUID)")
22971
+ dropId: external_exports.string().describe("The Drop ID (UUID, e.g. drop-abc123) or drop code (e.g. D-086). When passing a code, teamspaceId is required."),
22972
+ teamspaceId: external_exports.string().optional().describe("Required when dropId is a drop code like D-086")
22972
22973
  },
22973
- async ({ dropId }) => {
22974
- const d = await client.getDrop(dropId);
22975
- if (!d) return { content: [{ type: "text", text: `Drop not found: ${dropId}` }], isError: true };
22976
- const lines = [
22977
- `ID: ${d.dropId}`,
22978
- `Code: ${d.dropCode}`,
22979
- `Name: ${d.name}`,
22980
- `Teamspace: ${d.teamspaceId}`,
22981
- `State: ${d.state}`,
22982
- d.description ? `Description: ${d.description}` : null,
22983
- d.targetDate ? `Target: ${d.targetDate}` : null,
22984
- d.releasedAt ? `Released: ${d.releasedAt}` : null,
22985
- d.rolledBackAt ? `Rolled back: ${d.rolledBackAt}` : null,
22986
- `Revisions (${d.revisionIds.length}): ${d.revisionIds.length === 0 ? "(none)" : d.revisionIds.join(", ")}`,
22987
- `Version: ${d.version}`,
22988
- `Created: ${d.createdAt}`
22989
- ].filter(Boolean);
22990
- return { content: [{ type: "text", text: lines.join("\n") }] };
22974
+ async ({ dropId, teamspaceId }) => {
22975
+ try {
22976
+ let resolvedId = dropId;
22977
+ if (/^D-\d+$/i.test(dropId)) {
22978
+ if (!teamspaceId) {
22979
+ return { content: [{ type: "text", text: `teamspaceId is required when dropId is a drop code (e.g. D-086)` }], isError: true };
22980
+ }
22981
+ const normalizedCode = dropId.toUpperCase();
22982
+ const drops = await client.listTeamspaceDrops(teamspaceId, void 0);
22983
+ const match = drops.find((d2) => d2.dropCode.toUpperCase() === normalizedCode);
22984
+ if (!match) return { content: [{ type: "text", text: `Drop not found: ${dropId}` }], isError: true };
22985
+ resolvedId = match.dropId;
22986
+ }
22987
+ const d = await client.getDrop(resolvedId);
22988
+ const notFoundMsg = resolvedId !== dropId ? `Drop not found: ${resolvedId} (code: ${dropId})` : `Drop not found: ${dropId}`;
22989
+ if (!d) return { content: [{ type: "text", text: notFoundMsg }], isError: true };
22990
+ const lines = [
22991
+ `ID: ${d.dropId}`,
22992
+ `Code: ${d.dropCode}`,
22993
+ `Name: ${d.name}`,
22994
+ `Teamspace: ${d.teamspaceId}`,
22995
+ `State: ${d.state}`,
22996
+ d.description ? `Description: ${d.description}` : null,
22997
+ d.targetDate ? `Target: ${d.targetDate}` : null,
22998
+ d.releasedAt ? `Released: ${d.releasedAt}` : null,
22999
+ d.rolledBackAt ? `Rolled back: ${d.rolledBackAt}` : null,
23000
+ `Revisions (${d.revisionIds.length}): ${d.revisionIds.length === 0 ? "(none)" : d.revisionIds.join(", ")}`,
23001
+ `Version: ${d.version}`,
23002
+ `Created: ${d.createdAt}`
23003
+ ].filter(Boolean);
23004
+ return { content: [{ type: "text", text: lines.join("\n") }] };
23005
+ } catch (err) {
23006
+ return { content: [{ type: "text", text: `Failed to get drop: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
23007
+ }
22991
23008
  }
22992
23009
  );
22993
23010
  server.tool(
@@ -24398,7 +24415,7 @@ function registerPlanQualityTools(server, ctx, client) {
24398
24415
  "check_plan_quality",
24399
24416
  "Enqueue a Revision plan quality check across 6 dimensions (Scoped, Directional, Testable, Traceable, Assignable, Risk-aware). By default returns a taskId immediately (fire-and-forget) \u2014 use get_task_status or list_checks to retrieve results. Set wait=true to block until the check completes and receive the scorecard inline.",
24400
24417
  {
24401
- revisionId: external_exports.string().describe("The revision ID (e.g., rev-abc123)"),
24418
+ revisionId: external_exports.string().describe("The revision or Beat Version ID (e.g., rev-abc123 or bv-abc123)"),
24402
24419
  projectId: external_exports.string().describe("The project ID"),
24403
24420
  wait: external_exports.boolean().optional().describe("If true, block until the check completes and return the scorecard inline. Default: false (returns taskId immediately).")
24404
24421
  },
@@ -26708,7 +26725,7 @@ function loadConfig() {
26708
26725
  };
26709
26726
  }
26710
26727
  async function main() {
26711
- console.error(`[harmonica-mcp] v${"0.22.0"} starting\u2026`);
26728
+ console.error(`[harmonica-mcp] v${"0.23.0"} starting\u2026`);
26712
26729
  const config2 = loadConfig();
26713
26730
  const client = createHttpClient({
26714
26731
  apiBaseUrl: config2.apiBaseUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codazen/harmonica-mcp",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "MCP server for Harmonica — connect Claude to your Harmonica projects",
5
5
  "license": "MIT",
6
6
  "bin": {