@codazen/harmonica-mcp 3.0.0 → 3.1.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 +102 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26837,6 +26837,86 @@ var RevisionClaimSchema = external_exports.object({
26837
26837
  var RevisionClaimsResponseSchema = external_exports.object({
26838
26838
  claims: external_exports.array(RevisionClaimSchema)
26839
26839
  }).passthrough();
26840
+ var ProposedRevisionSchema = external_exports.object({
26841
+ revisionId: external_exports.string(),
26842
+ title: external_exports.string(),
26843
+ state: external_exports.string(),
26844
+ beatId: external_exports.string(),
26845
+ beatTitle: external_exports.string().optional(),
26846
+ projectId: external_exports.string(),
26847
+ projectTitle: external_exports.string().optional()
26848
+ }).passthrough();
26849
+ var ReleaseIntervalSchema = external_exports.object({
26850
+ averageIntervalDays: external_exports.number(),
26851
+ sampleSize: external_exports.number(),
26852
+ isFallback: external_exports.boolean()
26853
+ }).passthrough();
26854
+ var EligibleBeatVersionForDropSchema = external_exports.object({
26855
+ beatVersionId: external_exports.string(),
26856
+ title: external_exports.string(),
26857
+ state: external_exports.string(),
26858
+ beatId: external_exports.string(),
26859
+ beatTitle: external_exports.string().optional(),
26860
+ projectId: external_exports.string(),
26861
+ projectTitle: external_exports.string().optional(),
26862
+ createdAt: external_exports.string(),
26863
+ updatedAt: external_exports.string(),
26864
+ humanAssignee: external_exports.object({ email: external_exports.string(), name: external_exports.string() }).optional(),
26865
+ currentDropAssignment: external_exports.object({ dropId: external_exports.string(), dropCode: external_exports.string().optional(), state: external_exports.string() }).optional()
26866
+ }).passthrough();
26867
+ var ScoredDropCandidateSchema = external_exports.object({
26868
+ bv: EligibleBeatVersionForDropSchema,
26869
+ // Score fields are nullable — the ranking engine returns null when there is
26870
+ // insufficient historical data to compute a metric (e.g. no prior releases).
26871
+ score: external_exports.object({
26872
+ vu: external_exports.number().nullable(),
26873
+ slope: external_exports.number().nullable(),
26874
+ roi: external_exports.number().nullable(),
26875
+ valuePrimary: external_exports.number().nullable(),
26876
+ chosen: external_exports.number().nullable(),
26877
+ lens: external_exports.string()
26878
+ }).passthrough(),
26879
+ atRisk: external_exports.boolean(),
26880
+ requiredSlope: external_exports.number().nullable().optional()
26881
+ }).passthrough();
26882
+ var DUTY_ALTITUDES = ["portfolio", "system", "account"];
26883
+ var DUTY_HOLDER_TYPES = ["human", "agent"];
26884
+ var DUTY_MODES = ["accountable", "responsible"];
26885
+ var DutyAltitudeApiSchema = external_exports.enum(DUTY_ALTITUDES);
26886
+ var DutyHolderTypeApiSchema = external_exports.enum(DUTY_HOLDER_TYPES);
26887
+ var DutyModeApiSchema = external_exports.enum(DUTY_MODES);
26888
+ var DerivedStaffingStateApiSchema = external_exports.enum(["agent-held", "supported", "observed"]);
26889
+ var DutyAssignmentApiSchema = external_exports.object({
26890
+ dutyAssignmentId: external_exports.string(),
26891
+ accountId: external_exports.string(),
26892
+ orgId: external_exports.string(),
26893
+ role: external_exports.string(),
26894
+ altitude: DutyAltitudeApiSchema,
26895
+ scopeId: external_exports.string(),
26896
+ holderType: DutyHolderTypeApiSchema,
26897
+ holderId: external_exports.string(),
26898
+ supportingAssistantId: external_exports.string().optional(),
26899
+ mode: DutyModeApiSchema,
26900
+ parentDutyAssignmentId: external_exports.string().optional(),
26901
+ effectiveFrom: external_exports.string(),
26902
+ effectiveTo: external_exports.string().optional(),
26903
+ createdBy: external_exports.string().optional(),
26904
+ version: external_exports.number().optional(),
26905
+ createdAt: external_exports.string(),
26906
+ updatedAt: external_exports.string()
26907
+ }).passthrough();
26908
+ var DutyAssignmentsResponseSchema = external_exports.object({ dutyAssignments: external_exports.array(DutyAssignmentApiSchema).optional() }).passthrough();
26909
+ var DutyAssignmentResponseSchema = external_exports.object({ dutyAssignment: DutyAssignmentApiSchema }).passthrough();
26910
+ var DropProposalApiSchema = external_exports.object({
26911
+ accountId: external_exports.string(),
26912
+ revisionIds: external_exports.array(external_exports.string()),
26913
+ revisions: external_exports.array(ProposedRevisionSchema),
26914
+ suggestedTargetDate: external_exports.string(),
26915
+ releaseInterval: ReleaseIntervalSchema,
26916
+ rationale: external_exports.string(),
26917
+ isEmpty: external_exports.boolean(),
26918
+ scoredCandidates: external_exports.array(ScoredDropCandidateSchema).optional()
26919
+ }).passthrough();
26840
26920
 
26841
26921
  // ../../libs/harmonica-services/src/mcp/tools/note-element-tools.ts
26842
26922
  var parentKindSchema = external_exports.enum(["notebook", "note"]);
@@ -30161,6 +30241,13 @@ function registerProjectLifecycleTools(server, ctx, client) {
30161
30241
 
30162
30242
  // ../../libs/harmonica-services/src/mcp/tools/system-tools.ts
30163
30243
  var import_crypto5 = require("crypto");
30244
+
30245
+ // ../../libs/harmonica-services/src/utils/normalize-create-account-id.ts
30246
+ function normalizeCreateAccountId(accountId) {
30247
+ return accountId?.trim() || void 0;
30248
+ }
30249
+
30250
+ // ../../libs/harmonica-services/src/mcp/tools/system-tools.ts
30164
30251
  function accountLine(request, resolved) {
30165
30252
  const requested = request["accountId"];
30166
30253
  if (requested === null || requested === "") return "**Account:** (unlinked)";
@@ -30314,11 +30401,12 @@ function registerProjectTools(server, ctx, client) {
30314
30401
  description: external_exports.string().optional().describe("System description"),
30315
30402
  strategy: external_exports.string().optional().describe('System strategy markdown \u2014 Org Strategy + System Strategy ("System Coda")'),
30316
30403
  teamspaceId: external_exports.string().optional().describe("Teamspace ID to associate this system with"),
30404
+ accountId: external_exports.string().optional().describe("Account that owns this System \u2014 the client or internal org unit. Set it at creation so the System appears in the Account's Systems list; omit only for a System that belongs to no Account."),
30317
30405
  repoOwner: external_exports.string().optional().describe("GitHub repository owner (org or user)"),
30318
30406
  repoName: external_exports.string().optional().describe("GitHub repository name"),
30319
30407
  repoDefaultBranch: external_exports.string().optional().describe('Default branch for code check (defaults to "main")')
30320
30408
  };
30321
- const createSystemHandler = async ({ title, description, strategy, teamspaceId, repoOwner, repoName, repoDefaultBranch }) => {
30409
+ const createSystemHandler = async ({ title, description, strategy, teamspaceId, accountId, repoOwner, repoName, repoDefaultBranch }) => {
30322
30410
  if (teamspaceId) {
30323
30411
  const teamspace = await client.getTeamspace(teamspaceId);
30324
30412
  if (!teamspace) {
@@ -30328,6 +30416,7 @@ function registerProjectTools(server, ctx, client) {
30328
30416
  return { content: [{ type: "text", text: "Teamspace does not belong to this organization" }], isError: true };
30329
30417
  }
30330
30418
  }
30419
+ const account = normalizeCreateAccountId(accountId);
30331
30420
  try {
30332
30421
  const project = await client.createSystem({
30333
30422
  projectId: (0, import_crypto5.randomUUID)(),
@@ -30338,6 +30427,7 @@ function registerProjectTools(server, ctx, client) {
30338
30427
  strategy,
30339
30428
  status: "active",
30340
30429
  teamspaceId,
30430
+ ...account !== void 0 && { accountId: account },
30341
30431
  repoOwner,
30342
30432
  repoName,
30343
30433
  repoDefaultBranch
@@ -30348,6 +30438,7 @@ function registerProjectTools(server, ctx, client) {
30348
30438
  `**ID:** ${project.projectId}`,
30349
30439
  `**Title:** ${project.title}`,
30350
30440
  `**Status:** ${project.status}`,
30441
+ project.accountId ? `**Account:** ${project.accountId}` : "",
30351
30442
  project.description ? `**Description:** ${project.description}` : "",
30352
30443
  project.repoOwner ? `**Repo:** ${project.repoOwner}/${project.repoName}` : "",
30353
30444
  project.repoDefaultBranch ? `**Default Branch:** ${project.repoDefaultBranch}` : ""
@@ -30358,7 +30449,7 @@ function registerProjectTools(server, ctx, client) {
30358
30449
  return { content: [{ type: "text", text: `Failed to create system: ${message}` }], isError: true };
30359
30450
  }
30360
30451
  };
30361
- server.tool("create_system", "Create a new system in the configured organization", createSystemSchema, createSystemHandler);
30452
+ server.tool("create_system", "Create a new system in the configured organization. Pass accountId whenever the system belongs to a client \u2014 a system created without it is not listed under any Account.", createSystemSchema, createSystemHandler);
30362
30453
  }
30363
30454
 
30364
30455
  // ../../libs/harmonica-services/src/mcp/tools/teamspace-tools.ts
@@ -31811,7 +31902,10 @@ function createHttpClient(config2) {
31811
31902
  teamspaceId: input.teamspaceId,
31812
31903
  name: input.title,
31813
31904
  description: input.description,
31814
- strategy: input.strategy
31905
+ strategy: input.strategy,
31906
+ // Without this the owning Account is dropped on the wire and the System
31907
+ // is created unlinked — invisible in the Account's Systems list.
31908
+ ...input.accountId !== void 0 && { accountId: input.accountId }
31815
31909
  });
31816
31910
  return { ...raw, projectId: raw?.id ?? raw?.projectId, title: raw?.name ?? raw?.title, orgId: raw?.organizationId ?? raw?.orgId };
31817
31911
  },
@@ -31846,7 +31940,10 @@ function createHttpClient(config2) {
31846
31940
  teamspaceId: input.teamspaceId,
31847
31941
  name: input.title,
31848
31942
  description: input.description,
31849
- strategy: input.strategy
31943
+ strategy: input.strategy,
31944
+ // Without this the owning Account is dropped on the wire and the System
31945
+ // is created unlinked — invisible in the Account's Systems list.
31946
+ ...input.accountId !== void 0 && { accountId: input.accountId }
31850
31947
  });
31851
31948
  return { ...raw, orgId: raw?.organizationId ?? raw?.orgId };
31852
31949
  },
@@ -33776,7 +33873,7 @@ function loadConfig() {
33776
33873
  };
33777
33874
  }
33778
33875
  async function main() {
33779
- console.error(`[harmonica-mcp] v${"3.0.0"} starting\u2026`);
33876
+ console.error(`[harmonica-mcp] v${"3.1.0"} starting\u2026`);
33780
33877
  const config2 = loadConfig();
33781
33878
  const client = createHttpClient({
33782
33879
  apiBaseUrl: config2.apiBaseUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codazen/harmonica-mcp",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "MCP server for Harmonica — connect any MCP-compatible AI assistant to Harmonica",
5
5
  "license": "MIT",
6
6
  "bin": {