mergestorm-mcp 0.2.21 → 0.2.22

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +114 -15
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # mergestorm-mcp
2
2
 
3
- Stdio MCP server for Mergestorm. Tools: `whoami`, `credits`, `review_list`, `review_submit`, `review_wait`, `review_wait_pr`, `review_dismiss`, `issue_create`, `stack_adopt`, `stack_list`, `stack_publish`, `stack_publish_status`, `stack_set`, `stack_status`, `stack_wait`, `queue_status`, `settings_get`, `settings_set`.
3
+ Stdio MCP server for Mergestorm. Tools: `whoami`, `credits`, `review_list`, `review_submit`, `review_wait`, `review_wait_pr`, `review_dismiss`, `issue_create`, `stack_adopt`, `stack_list`, `stack_publish`, `stack_publish_status`, `stack_set`, `stack_status`, `stack_wait`, `queue_status`, `settings_get`, `settings_set`, `repo_settings_get`, `repo_settings_set`.
4
4
 
5
5
  Every tool declares MCP `annotations` for read-only access, destructive changes, idempotence, and external systems. Reads are read-only; submission, adoption, dismissal, and policy changes are writes. Tools that can change existing policy, topology, or review gates are marked potentially destructive even when some inputs only preview or read. Annotations describe effects; the client still controls approval and authorization.
6
6
 
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
6
6
  // src/server.ts
7
7
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
8
  import { z as z5 } from "zod";
9
- import { CommandError as CommandError13, BEARER_SETTINGS as BEARER_SETTINGS2 } from "mergestorm/client";
9
+ import { CommandError as CommandError14, BEARER_SETTINGS as BEARER_SETTINGS2 } from "mergestorm/client";
10
10
 
11
11
  // src/brand-icons.ts
12
12
  var MARK_RECTS = [
@@ -897,8 +897,70 @@ async function settingsSet(args, cfg) {
897
897
  };
898
898
  }
899
899
 
900
+ // src/tools/repo-settings.ts
901
+ import {
902
+ CommandError as CommandError10,
903
+ REPO_SETTINGS_KEYS,
904
+ listRepoSettings,
905
+ patchRepoSettings
906
+ } from "mergestorm/client";
907
+ var ARG_BY_KEY = {
908
+ auto_patch_enabled: "auto_patch",
909
+ auto_review_enabled: "auto_review",
910
+ auto_land_default: "auto_land"
911
+ };
912
+ function parseRepo(raw) {
913
+ const match = typeof raw === "string" ? /^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(raw.trim()) : null;
914
+ if (!match) throw new CommandError10("repo takes <owner>/<repo>.", 2, "usage");
915
+ return { owner: match[1], repo: match[2] };
916
+ }
917
+ function words(value) {
918
+ return value === null ? "inherit" : value ? "on" : "off";
919
+ }
920
+ function repoSettingsSummary(entry) {
921
+ return `${entry.owner}/${entry.repo}: ${REPO_SETTINGS_KEYS.map((key) => `${ARG_BY_KEY[key]} ${words(entry[key])}`).join(" \xB7 ")}`;
922
+ }
923
+ function repoSettingsPatchFromArgs(args) {
924
+ const patch = {};
925
+ for (const key of REPO_SETTINGS_KEYS) {
926
+ const value = args[ARG_BY_KEY[key]];
927
+ if (value === void 0) continue;
928
+ if (value !== null && typeof value !== "boolean") {
929
+ throw new CommandError10(`${ARG_BY_KEY[key]} takes true, false, or null.`, 2, "usage");
930
+ }
931
+ patch[key] = value;
932
+ }
933
+ if (Object.keys(patch).length === 0) {
934
+ throw new CommandError10(
935
+ `At least one of ${Object.values(ARG_BY_KEY).join(", ")} is required.`,
936
+ 2,
937
+ "usage"
938
+ );
939
+ }
940
+ return patch;
941
+ }
942
+ async function repoSettingsGet(args, cfg) {
943
+ const wanted = args.repo === void 0 ? null : parseRepo(args.repo);
944
+ const all = await listRepoSettings(cfg);
945
+ if (!wanted) {
946
+ return {
947
+ summary: all.length === 0 ? "No repositories are connected to this account." : all.map(repoSettingsSummary).join("\n"),
948
+ data: { repos: all }
949
+ };
950
+ }
951
+ const slug = `${wanted.owner}/${wanted.repo}`.toLowerCase();
952
+ const entry = all.find((candidate) => `${candidate.owner}/${candidate.repo}`.toLowerCase() === slug);
953
+ if (!entry) throw new CommandError10(`${wanted.owner}/${wanted.repo} is not connected to this account.`);
954
+ return { summary: repoSettingsSummary(entry), data: { ...entry } };
955
+ }
956
+ async function repoSettingsSet(args, cfg) {
957
+ const { owner, repo } = parseRepo(args.repo);
958
+ const entry = await patchRepoSettings(owner, repo, repoSettingsPatchFromArgs(args), cfg);
959
+ return { summary: repoSettingsSummary(entry), data: { ...entry } };
960
+ }
961
+
900
962
  // src/tools/stack-adopt.ts
901
- import { adoptStack, CommandError as CommandError10, stackWatchObligation as stackWatchObligation4 } from "mergestorm/client";
963
+ import { adoptStack, CommandError as CommandError11, stackWatchObligation as stackWatchObligation4 } from "mergestorm/client";
902
964
  import { z as z3 } from "zod";
903
965
 
904
966
  // src/tools/stack-set.ts
@@ -1008,11 +1070,11 @@ async function stackAdopt(input, cfg) {
1008
1070
  summary: message,
1009
1071
  data: {
1010
1072
  error: {
1011
- code: err instanceof CommandError10 ? err.code ?? "stack_adopt_failed" : "stack_adopt_failed",
1073
+ code: err instanceof CommandError11 ? err.code ?? "stack_adopt_failed" : "stack_adopt_failed",
1012
1074
  message,
1013
- ...err instanceof CommandError10 ? { exit_code: err.exitCode } : {},
1014
- ...err instanceof CommandError10 && err.reason !== void 0 ? { reason: err.reason } : {},
1015
- ...err instanceof CommandError10 && err.retryAfterSeconds !== void 0 ? { retry_after_seconds: err.retryAfterSeconds } : {}
1075
+ ...err instanceof CommandError11 ? { exit_code: err.exitCode } : {},
1076
+ ...err instanceof CommandError11 && err.reason !== void 0 ? { reason: err.reason } : {},
1077
+ ...err instanceof CommandError11 && err.retryAfterSeconds !== void 0 ? { retry_after_seconds: err.retryAfterSeconds } : {}
1016
1078
  }
1017
1079
  },
1018
1080
  isError: true
@@ -1083,7 +1145,7 @@ async function stackList(cfg) {
1083
1145
 
1084
1146
  // src/tools/stack-publish.ts
1085
1147
  import {
1086
- CommandError as CommandError11,
1148
+ CommandError as CommandError12,
1087
1149
  publishWorkingBranch,
1088
1150
  stackWatchObligation as stackWatchObligation5,
1089
1151
  workingBranchPublication
@@ -1112,9 +1174,9 @@ function failure(err, fallback) {
1112
1174
  summary: message,
1113
1175
  data: {
1114
1176
  error: {
1115
- code: err instanceof CommandError11 ? err.code ?? fallback : fallback,
1177
+ code: err instanceof CommandError12 ? err.code ?? fallback : fallback,
1116
1178
  message,
1117
- ...err instanceof CommandError11 && err.retryAfterSeconds !== void 0 ? { retry_after_seconds: err.retryAfterSeconds } : {}
1179
+ ...err instanceof CommandError12 && err.retryAfterSeconds !== void 0 ? { retry_after_seconds: err.retryAfterSeconds } : {}
1118
1180
  }
1119
1181
  },
1120
1182
  isError: true
@@ -1246,7 +1308,7 @@ async function stackStatus(stackId, cfg) {
1246
1308
 
1247
1309
  // src/tools/whoami.ts
1248
1310
  import {
1249
- CommandError as CommandError12,
1311
+ CommandError as CommandError13,
1250
1312
  apiBase,
1251
1313
  configPath,
1252
1314
  getMe as getMe2,
@@ -1257,7 +1319,7 @@ async function whoami(cfg, serverVersion) {
1257
1319
  const resolved = cfg ?? await loadConfig7();
1258
1320
  const key = resolveApiKey(resolved);
1259
1321
  if (!key) {
1260
- throw new CommandError12(
1322
+ throw new CommandError13(
1261
1323
  "No API key. Run `mergestorm login` (agents: `mergestorm login --start`, then `--finish`) or set MERGESTORM_API_KEY.",
1262
1324
  1,
1263
1325
  "missing_api_key"
@@ -1265,7 +1327,7 @@ async function whoami(cfg, serverVersion) {
1265
1327
  }
1266
1328
  const me = await getMe2(resolved);
1267
1329
  if (!me) {
1268
- throw new CommandError12("Live account details unavailable. Could not verify account with /me.");
1330
+ throw new CommandError13("Live account details unavailable. Could not verify account with /me.");
1269
1331
  }
1270
1332
  const data = {
1271
1333
  key_prefix: me.key.prefix,
@@ -1340,7 +1402,7 @@ var MCP_STACK_WATCH_INSTRUCTIONS = [
1340
1402
 
1341
1403
  // src/server.ts
1342
1404
  var MCP_SERVER_NAME = "mergestorm";
1343
- var MCP_SERVER_VERSION = "0.2.21";
1405
+ var MCP_SERVER_VERSION = "0.2.22";
1344
1406
  var MCP_SERVER_INSTRUCTIONS = [
1345
1407
  MCP_STACK_DONE_INSTRUCTIONS,
1346
1408
  MCP_PR_LOOP_INSTRUCTIONS,
@@ -1359,14 +1421,14 @@ function ok(payload) {
1359
1421
  };
1360
1422
  }
1361
1423
  function fail(err) {
1362
- const message = err instanceof CommandError13 ? err.code ? `Mergestorm request failed (${err.code}${err.reason ? `, reason ${err.reason}` : ""}): ${err.message}.` : err.message : err instanceof Error ? err.message : String(err);
1424
+ const message = err instanceof CommandError14 ? err.code ? `Mergestorm request failed (${err.code}${err.reason ? `, reason ${err.reason}` : ""}): ${err.message}.` : err.message : err instanceof Error ? err.message : String(err);
1363
1425
  return ok({
1364
1426
  isError: true,
1365
1427
  summary: message,
1366
1428
  data: {
1367
1429
  error: {
1368
1430
  message: err instanceof Error ? err.message : String(err),
1369
- ...err instanceof CommandError13 ? {
1431
+ ...err instanceof CommandError14 ? {
1370
1432
  exit_code: err.exitCode,
1371
1433
  ...err.code !== void 0 ? { code: err.code } : {},
1372
1434
  ...err.reason !== void 0 ? { reason: err.reason } : {},
@@ -1708,6 +1770,43 @@ function createMergestormMcpServer() {
1708
1770
  }
1709
1771
  }
1710
1772
  );
1773
+ addTool(
1774
+ "repo_settings_get",
1775
+ {
1776
+ title: "Get repository settings",
1777
+ description: "Read the repository-level Auto patch, Auto review and Auto land values for the repositories connected to this account. Each value is true, false, or null; null means not set, so the account setting applies. Auto patch and Auto review precedence is the stack override (stack_set), then the repository value, then the account setting (settings_get). The Auto land repository value only seeds new stacks at adoption; it does not override an existing stack. Pass repo as owner/repo for one repository, or omit it for all.",
1778
+ inputSchema: { repo: z5.string().min(3).optional() },
1779
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
1780
+ },
1781
+ async (args) => {
1782
+ try {
1783
+ return ok(await repoSettingsGet(args ?? {}));
1784
+ } catch (err) {
1785
+ return fail(err);
1786
+ }
1787
+ }
1788
+ );
1789
+ addTool(
1790
+ "repo_settings_set",
1791
+ {
1792
+ title: "Update repository settings",
1793
+ description: "Set Auto patch (Cyclone), Auto review (Vortex) or the Auto land default for every stack and pull request in one repository connected to this account, and return the stored result. true or false sets the repository value; null clears it so the account setting applies again. A stack override (stack_set) still wins for that stack. auto_patch and auto_review apply to open stacks without an override from their next decision; nothing is cancelled or re-queued. auto_land only seeds new stacks. Only the account that connected the repository can change it. Never changes account settings.",
1794
+ inputSchema: {
1795
+ repo: z5.string().min(3),
1796
+ auto_patch: z5.boolean().nullable().optional(),
1797
+ auto_review: z5.boolean().nullable().optional(),
1798
+ auto_land: z5.boolean().nullable().optional()
1799
+ },
1800
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }
1801
+ },
1802
+ async (args) => {
1803
+ try {
1804
+ return ok(await repoSettingsSet(args ?? {}));
1805
+ } catch (err) {
1806
+ return fail(err);
1807
+ }
1808
+ }
1809
+ );
1711
1810
  addTool(
1712
1811
  "settings_get",
1713
1812
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mergestorm-mcp",
3
- "version": "0.2.21",
3
+ "version": "0.2.22",
4
4
  "description": "Mergestorm MCP server — identity, review, and read-only stack tools over stdio",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@modelcontextprotocol/sdk": "^1.30.0",
32
- "mergestorm": "0.3.54",
32
+ "mergestorm": "0.3.56",
33
33
  "zod": "^3.24.2"
34
34
  },
35
35
  "devDependencies": {