mergestorm-mcp 0.2.26 → 0.2.28

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 (73) hide show
  1. package/README.md +16 -2
  2. package/dist/index.js +828 -223
  3. package/dist/lib/brand-icons.d.ts +16 -0
  4. package/dist/lib/brand-icons.js +23 -0
  5. package/dist/lib/hosted.d.ts +7 -0
  6. package/dist/lib/hosted.js +21 -0
  7. package/dist/lib/index.d.ts +1 -0
  8. package/dist/lib/index.js +5 -0
  9. package/dist/lib/pr-loop-instructions.d.ts +14 -0
  10. package/dist/lib/pr-loop-instructions.js +73 -0
  11. package/dist/lib/server.d.ts +24 -0
  12. package/dist/lib/server.js +644 -0
  13. package/dist/lib/tools/agent-request.d.ts +6 -0
  14. package/dist/lib/tools/agent-request.js +25 -0
  15. package/dist/lib/tools/chat-task.d.ts +18 -0
  16. package/dist/lib/tools/chat-task.js +28 -0
  17. package/dist/lib/tools/credits.d.ts +3 -0
  18. package/dist/lib/tools/credits.js +38 -0
  19. package/dist/lib/tools/cyclone-job.d.ts +28 -0
  20. package/dist/lib/tools/cyclone-job.js +71 -0
  21. package/dist/lib/tools/envelope.d.ts +5 -0
  22. package/dist/lib/tools/envelope.js +30 -0
  23. package/dist/lib/tools/issue-create.d.ts +47 -0
  24. package/dist/lib/tools/issue-create.js +53 -0
  25. package/dist/lib/tools/memory.d.ts +68 -0
  26. package/dist/lib/tools/memory.js +74 -0
  27. package/dist/lib/tools/queue-status.d.ts +3 -0
  28. package/dist/lib/tools/queue-status.js +79 -0
  29. package/dist/lib/tools/repo-settings.d.ts +6 -0
  30. package/dist/lib/tools/repo-settings.js +78 -0
  31. package/dist/lib/tools/review-dismiss.d.ts +16 -0
  32. package/dist/lib/tools/review-dismiss.js +68 -0
  33. package/dist/lib/tools/review-get-pr.d.ts +22 -0
  34. package/dist/lib/tools/review-get-pr.js +52 -0
  35. package/dist/lib/tools/review-get.d.ts +3 -0
  36. package/dist/lib/tools/review-get.js +27 -0
  37. package/dist/lib/tools/review-list.d.ts +3 -0
  38. package/dist/lib/tools/review-list.js +10 -0
  39. package/dist/lib/tools/review-start.d.ts +11 -0
  40. package/dist/lib/tools/review-start.js +22 -0
  41. package/dist/lib/tools/review-submit.d.ts +36 -0
  42. package/dist/lib/tools/review-submit.js +172 -0
  43. package/dist/lib/tools/review-wait-pr.d.ts +11 -0
  44. package/dist/lib/tools/review-wait-pr.js +66 -0
  45. package/dist/lib/tools/review-wait.d.ts +6 -0
  46. package/dist/lib/tools/review-wait.js +33 -0
  47. package/dist/lib/tools/settings-get.d.ts +8 -0
  48. package/dist/lib/tools/settings-get.js +33 -0
  49. package/dist/lib/tools/settings-set.d.ts +11 -0
  50. package/dist/lib/tools/settings-set.js +62 -0
  51. package/dist/lib/tools/stack-actions.d.ts +4 -0
  52. package/dist/lib/tools/stack-actions.js +22 -0
  53. package/dist/lib/tools/stack-adopt.d.ts +44 -0
  54. package/dist/lib/tools/stack-adopt.js +55 -0
  55. package/dist/lib/tools/stack-list.d.ts +3 -0
  56. package/dist/lib/tools/stack-list.js +30 -0
  57. package/dist/lib/tools/stack-publish.d.ts +78 -0
  58. package/dist/lib/tools/stack-publish.js +89 -0
  59. package/dist/lib/tools/stack-set.d.ts +16 -0
  60. package/dist/lib/tools/stack-set.js +69 -0
  61. package/dist/lib/tools/stack-status.d.ts +3 -0
  62. package/dist/lib/tools/stack-status.js +57 -0
  63. package/dist/lib/tools/stack-summary.d.ts +2 -0
  64. package/dist/lib/tools/stack-summary.js +29 -0
  65. package/dist/lib/tools/stack-wait.d.ts +44 -0
  66. package/dist/lib/tools/stack-wait.js +146 -0
  67. package/dist/lib/tools/surge-setup.d.ts +6 -0
  68. package/dist/lib/tools/surge-setup.js +4 -0
  69. package/dist/lib/tools/types.d.ts +5 -0
  70. package/dist/lib/tools/types.js +1 -0
  71. package/dist/lib/tools/whoami.d.ts +3 -0
  72. package/dist/lib/tools/whoami.js +27 -0
  73. package/package.json +13 -3
@@ -0,0 +1,16 @@
1
+ export type MarkRect = {
2
+ x: number;
3
+ y: number;
4
+ width: number;
5
+ height: number;
6
+ };
7
+ export type McpIcon = {
8
+ src: string;
9
+ mimeType: string;
10
+ sizes: string[];
11
+ theme?: "light" | "dark";
12
+ };
13
+ export declare const MARK_RECTS: readonly MarkRect[];
14
+ export declare function markSvg(fill: string): string;
15
+ export declare const MCP_SERVER_ICONS: McpIcon[];
16
+ export declare const MCP_WEBSITE_URL = "https://mergestorm.ai";
@@ -0,0 +1,23 @@
1
+ export const MARK_RECTS = [
2
+ { x: 103.685, y: 79.639, width: 336.635, height: 32.005 },
3
+ { x: 71.68, y: 143.816, width: 288.545, height: 32.005 },
4
+ { x: 103.685, y: 207.993, width: 192.363, height: 32.005 },
5
+ { x: 151.775, y: 272.002, width: 176.277, height: 32.005 },
6
+ { x: 215.952, y: 336.179, width: 96.182, height: 32.005 },
7
+ { x: 264.043, y: 400.356, width: 32.005, height: 32.005 },
8
+ ];
9
+ const SITE = "https://mergestorm.ai";
10
+ export function markSvg(fill) {
11
+ const rects = MARK_RECTS.map((r) => `<rect x="${r.x}" y="${r.y}" width="${r.width}" height="${r.height}" fill="${fill}"/>`).join("");
12
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="64 64 384 384">${rects}</svg>`;
13
+ }
14
+ function svgDataUri(svg) {
15
+ return `data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}`;
16
+ }
17
+ export const MCP_SERVER_ICONS = [
18
+ { src: svgDataUri(markSvg("#000000")), mimeType: "image/svg+xml", sizes: ["any"], theme: "light" },
19
+ { src: svgDataUri(markSvg("#ffffff")), mimeType: "image/svg+xml", sizes: ["any"], theme: "dark" },
20
+ { src: `${SITE}/images/android-chrome-192x192.png`, mimeType: "image/png", sizes: ["192x192"] },
21
+ { src: `${SITE}/images/android-chrome-512x512.png`, mimeType: "image/png", sizes: ["512x512"] },
22
+ ];
23
+ export const MCP_WEBSITE_URL = SITE;
@@ -0,0 +1,7 @@
1
+ export { MCP_HOSTED_SERVER_INSTRUCTIONS, MCP_HOSTED_TOOL_NAMES, MCP_SERVER_INSTRUCTIONS, MCP_SERVER_NAME, MCP_SERVER_VERSION } from "./server.js";
2
+ export type HostedMcpCaller = {
3
+ apiKey: string;
4
+ apiBase: string;
5
+ chatId?: string | null;
6
+ };
7
+ export declare function handleHostedMcpRequest(request: Request, caller: HostedMcpCaller): Promise<Response>;
@@ -0,0 +1,21 @@
1
+ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
2
+ import { createMergestormMcpServer } from "./server.js";
3
+ export { MCP_HOSTED_SERVER_INSTRUCTIONS, MCP_HOSTED_TOOL_NAMES, MCP_SERVER_INSTRUCTIONS, MCP_SERVER_NAME, MCP_SERVER_VERSION } from "./server.js";
4
+ export async function handleHostedMcpRequest(request, caller) {
5
+ if (request.method !== "POST") {
6
+ return Response.json({ jsonrpc: "2.0", error: { code: -32000, message: "Method not allowed: this endpoint is stateless, send JSON-RPC with POST." }, id: null }, { status: 405, headers: { allow: "POST" } });
7
+ }
8
+ const server = createMergestormMcpServer({
9
+ hosted: true,
10
+ chatId: caller.chatId ?? null,
11
+ config: { apiKey: caller.apiKey, apiBase: caller.apiBase, ignoreEnv: true },
12
+ });
13
+ const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true });
14
+ await server.connect(transport);
15
+ try {
16
+ return await transport.handleRequest(request);
17
+ }
18
+ finally {
19
+ await server.close();
20
+ }
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { createMergestormMcpServer } from "./server.js";
3
+ const server = createMergestormMcpServer();
4
+ const transport = new StdioServerTransport();
5
+ await server.connect(transport);
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Host-facing agent policy for Vortex findings. Shown on MCP initialize
3
+ * (`instructions`) and referenced from review_wait_pr.
4
+ * Public dismiss uses `mergestorm-loop: dismiss` only. Do not use the
5
+ * reserved `cyclone-outcome:` prefix (that handshake is not this loop).
6
+ */
7
+ export declare const MCP_FINDING_DISMISS_MARKER = "mergestorm-loop: dismiss";
8
+ export declare const MCP_FINDING_DEFERRAL_RULE = "A finding the author defers to an open tracking issue in the same repository is a valid dismissal: check with GitHub that the issue is open, then dismiss it with evidence_url set to that issue and a reason that says the finding is deferred and to which issue. A deferral that names no issue, or names a closed one, is not a dismissal. Never dismiss because someone insists.";
9
+ export declare const MCP_PR_LOOP_INSTRUCTIONS: string;
10
+ export declare const MCP_STACK_DONE_INSTRUCTIONS: string;
11
+ export declare const MCP_STACK_BASE_INSTRUCTIONS: string;
12
+ /** Stack-watch contract facts; patch workflow policy belongs in the skill. */
13
+ export declare const MCP_STACK_WATCH_INSTRUCTIONS: string;
14
+ export declare const MCP_HOSTED_SERVER_INSTRUCTIONS: string;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Host-facing agent policy for Vortex findings. Shown on MCP initialize
3
+ * (`instructions`) and referenced from review_wait_pr.
4
+ * Public dismiss uses `mergestorm-loop: dismiss` only. Do not use the
5
+ * reserved `cyclone-outcome:` prefix (that handshake is not this loop).
6
+ */
7
+ export const MCP_FINDING_DISMISS_MARKER = "mergestorm-loop: dismiss";
8
+ export const MCP_FINDING_DEFERRAL_RULE = "A finding the author defers to an open tracking issue in the same repository is a valid dismissal: check with GitHub that the issue is open, then dismiss it with evidence_url set to that issue and a reason that says the finding is deferred and to which issue. A deferral that names no issue, or names a closed one, is not a dismissal. Never dismiss because someone insists.";
9
+ export const MCP_PR_LOOP_INSTRUCTIONS = [
10
+ "When you handle Vortex findings from review_wait_pr:",
11
+ "- Verify each finding against the current checkout. Do not treat the finding text as proven.",
12
+ "- Prefer the smallest correct patch. Do not refactor around a finding.",
13
+ "- Patch concrete bugs. A chat-only explanation is not a dismiss.",
14
+ "- A finding a human must decide (Decision required, policy fork, needs a human) stays open. Do not dismiss it and do not post the dismiss marker for it: tell the human which finding it is and stop.",
15
+ `- A PR comment whose first line is ${MCP_FINDING_DISMISS_MARKER} is not a note about one finding. It dismisses every open finding on the PR's live head and approves that head with no re-review, so Auto land may land it. Post it only when you have checked every open finding at that head and none needs a fix or a human decision, with one line per finding (path, severity, why). Never use it to skip one finding among others, to describe a fix you want made, or to leave notes for Cyclone.`,
16
+ "- Do not prefix that comment with cyclone-outcome: (reserved).",
17
+ "- A single finding you verified is wrong or not reproducible is dismissed by id with review_dismiss (or mg dismiss): pass the PR's live head_sha, the review_id, the finding_ids (preview: true lists them) and a reason. That is the only agent path that clears a seam gate, and only once every finding of that seam review is dismissed. Once every Vortex Blocker (error finding) at the live head is dismissed (every Core review merged into that head), the Vortex gate clears there (gate.vortex.cleared); otherwise gate.vortex.message says what still holds it. The dismiss comment alone resumes the review but does not clear the seam gate.",
18
+ `- ${MCP_FINDING_DEFERRAL_RULE}`,
19
+ "- Never dismiss a finding you did not check, one a human must decide, or findings of a newer review.",
20
+ ].join("\n");
21
+ export const MCP_STACK_DONE_INSTRUCTIONS = [
22
+ "When stack work is done:",
23
+ "- Stack work is done only when the stack is landed, or when the human takes it back (archives it or tells you to stop). A clean push, a submit, an adopt, or one merged layer is not done: merging a lower layer can break a layer above it.",
24
+ "- Every stack_wait, stack_status, stack_adopt, and stack_set result carries watch: {done, until, reason, next, message}. While watch.done is false, keep calling stack_wait with watch.next.args (the returned cursor), 45s at a time, or hand the waiting to the background watcher below, and do not end your task. Stop only when watch.done is true.",
25
+ "- Only when your host has a confirmed notification that resumes this task, run `mg stack watch <stack-id>` as a background command with a notification on output matching `MS-WATCH (ATTENTION|LANDED)`, then end your turn. The watcher runs stack_wait against the Mergestorm API in slices of at most 300s, carries the cursor, stays silent while the stack is waiting or in_progress (busy[] holds and actAfter included), and costs no model tokens. It exits on attention (`MS-WATCH ATTENTION pr=<n> head=<sha> blocker=... repair=<kind>`, exit 3), on reads that keep failing (`MS-WATCH ATTENTION failed`, exit 3, after an auth or other permanent error twice, or after 15 minutes with no stack read (timeouts, 5xx, rate limits); tell the human the stack is no longer watched), or when the command cannot start (`MS-WATCH ATTENTION failed` with exit 2 for bad flags, exit 1 for no config or another startup error; tell the human the stack is not watched), on a closed, archived, or missing stack (`MS-WATCH ATTENTION stack=<id> reason=<reason>`, exit 3; verify missing stacks before reporting a landing), or on a confirmed landing (`MS-WATCH LANDED stack=<id> reason=landed`, exit 0). On an attention wake, read stack_status once, fix the blocker per mergestorm-bounce-watch, push, and start `mg stack watch <stack-id> --head <pushed-sha>` again. The command monitors the stack; it cannot wake an agent by itself. A confirmed notification is a host feature you can name that turns the command's exit or matching output into your next turn; a process left running, or output written to a log or terminal you do not read, is not one. Without a confirmed notification, keep using stack_wait with watch.next.args, or report that automatic follow-up is unavailable before ending the turn. Ending your turn while the watcher runs is not ending the task. Do not subscribe to GitHub events to wait on a stack.",
26
+ "- A layer PR shown as merged is merged into mg-stack-<n>, not main. The stack is landed only when the land PR (head mg-stack-<n>) merges into main or watch.done says landed. Never judge landing from GitHub PR state alone.",
27
+ "- attention means something for you to fix; repair, when present, names the concrete fix. A pending land gate (landGatePending: ci_pending) is a wait, not attention. attention covers every open layer, not only currentCandidate: it names the lowest layer with a blocker an agent must fix and no Vortex or Cyclone run working on it; once that blocker clears, the next read names the next blocked layer.",
28
+ ].join("\n");
29
+ export const MCP_STACK_BASE_INSTRUCTIONS = [
30
+ "Stack PR bases (Mergestorm sets these; leave them):",
31
+ "- Stack of 2+ PRs: after adopt (stack_adopt, mg stack adopt, or mg stack submit) the bottom PR's GitHub base is the owned trunk mg-stack-<n>, not main. That is correct. Layer 2 is based on layer 1; layer 3+ on the mg-park-* freeze; the git parent of layer 2+ is still the layer below. A 1-PR stack stays on main and gets no mg-stack-<n>.",
32
+ "- Never retarget a stack PR's GitHub base (gh pr edit --base, a REST base change, or the UI). Moving the bottom to main makes Mergestorm abandon the stack's review unit; setting mg-stack-<n> again does not restore it. If a base was already moved, stop and tell the human; do not run stack land or re-adopt to repair it.",
33
+ "- mg-stack-<n> is the bottom PR's live parent: merging it into the bottom branch is that PR's conflict repair (bounce-watch rules). Never push to mg-stack-<n> except as the land PR's own repair: once every layer is promoted, the land PR's head is mg-stack-<n> and its live parent is its base (main), so merging main into mg-stack-<n>, or a CI fix on it, with an ordinary push (no force) is that repair. Fix the land PR only when busy[] shows no Cyclone run on it. Never rebase or merge layer 2+ onto mg-stack-<n> or onto main. mg-park-* is never a merge or rebase target.",
34
+ "- mg stack submit prints the base each PR opened with; the bottom moves to mg-stack-<n> right after. stack_status trunkBranch is the current trunk.",
35
+ ].join("\n");
36
+ /** Stack-watch contract facts; patch workflow policy belongs in the skill. */
37
+ export const MCP_STACK_WATCH_INSTRUCTIONS = [
38
+ "Stack-watch facts (mergestorm.stack_watch/v1):",
39
+ "- waiting with nonempty issues[] is not idle; in_progress can also carry issues[].",
40
+ "- assessment unavailable does not mean issue-free. timeout_s: 0 reads one enrich and one queue snapshot.",
41
+ "- Restack clean does not mean mergeable or CI-green.",
42
+ "- attention names the blocked PR via prNumber/headSha; currentCandidate is the promote candidate. Attention is not a mutation or authorization to change policy.",
43
+ "- verifyHeadSha is a queue verification SHA, not the live PR head.",
44
+ "- Do not patch a bounced PR while Cyclone or Vortex is still working on it. stack_wait and stack_status enforce this: they return in_progress instead of attention, with busy[] naming the PR, blocker, and agent, and agents carrying that PR's vortexStatus, cycloneStatus, vortexReview, and busy flags. in_progress with a nonempty busy[] means wait. Recheck the live remote PR head right before pushing.",
45
+ "- seam_pending alone, and a queued Vortex run older than 15 minutes, do not hold. A queued Vortex run holds for at most 15 minutes; reviewing and patching hold until the run finishes or its lease or check run is cleared; if it looks stuck, refresh stack_status and tell the human.",
46
+ "- A blocker no Vortex or Cyclone run clears (a merge conflict vs the live parent, a restack Conflict or Restack failed, a Draft PR, a seam review pending with no review running, \"Seam review stuck in reviewing, no review running\", \"Seam re-review pending, no review running\", \"Seam verdict is for an older head, no review running\", or a review skipped for review quota) stays in_progress during the hold but is named in blocker, prNumber, headSha, and issues[], with actAfter: \"agents_idle\" and waitingOn listing the busy agents. Plan the fix; act only when a snapshot after the agents finish returns attention, and re-read the blocker then. Blockers the agents can change keep blocker null and appear only in busy[]. For the three stuck-seam blockers, repair kind seam_review_stuck: do not patch or push; tell the human to click Continue, which re-queues the seam review at the live head.",
47
+ "- stack.autoEnqueueSettle with action ready or promote means Auto land found Cyclone and Vortex idle on that PR's green head and started its settle clock. action mergeability is published earlier, on a head that may not be green or idle yet.",
48
+ "- mg-park-* is a frozen GitHub base, not a repair target: never merge or rebase onto mg-park-*.",
49
+ "- merge_failed, gh_error, and ci_timeout bounces turn Auto land off, and stack autoLandOff then reads reason bounced with that queue entry's id; any other autoLandOff reason (user, archive, watcher, cancelled, landed) is not a bounce to undo. The watching agent turns Auto land back on with stack_set auto_land: true once it has handled that bounce, at most once per bounce and 3 times per watch; mergestorm-bounce-watch has the conditions.",
50
+ "- A stack whose layers are all merged into mg-stack-N but which has no open land PR (the branch was deleted, or the land PR cannot be opened) returns attention: blocker \"No open land PR for mg-stack-N ...\", repair kind land_pr_unavailable. Do not patch or push; tell the human to restore the branch from the closed land PR's head or close the stack.",
51
+ "- While stack autoLandOff reads reason bounced, the watch returns attention: blocker \"Auto land off after <kind> bounce\", the bounce in issues[], repair kind auto_land_off.",
52
+ "- While stack autoLandOff reads reason cancelled or watcher and the current PR has no live blocker of its own (a live blocker is reported first, with its own repair), the watch returns attention: blocker \"Auto land switched off: <why>\", repair kind auto_land_switched_off. No bounce did it and the layers need no change: do not patch, push or turn Auto land back on yourself; tell the human, who decides whether to turn it back on.",
53
+ "- A stack whose review unit was abandoned (a human moved its bottom PR off mg-stack-N) returns attention: blocker \"Review unit abandoned: based on <base>\", repair kind unit_abandoned. Do not patch or retarget; ask the human whether to re-root it. If at least two PRs remain open, tell them that mg stack adopt owner/repo#<bottom PR> re-roots it on a new review unit. With only one open PR, re-adopting will not create a review unit, so tell them to close and resubmit it to create a fresh stack.",
54
+ "- Auto land records why it is waiting (stack autoLandWait: reason, prNumber, headSha, since). The watch returns attention on that PR when the wait cannot clear on its own: a failing check Auto land reads live on GitHub, even while the ledger shows CI green (blocker \"CI failed — Auto land reads a failing check on GitHub at this head\", repair kind ci_failure); a check pending for 45 minutes (repair kind ci_pending); no approving Vortex review for 30 minutes with no Vortex run working (repair kind vortex_not_green); and a promote GitHub refused 3 times with merge_failed, after which Auto land stops retrying that head (repair kind promote_failed). It also returns attention when GitHub refuses to let Mergestorm read the head's check runs or commit statuses (blocker \"Mergestorm cannot read ... on this head\", repair kind ci_unreadable: do not patch or push; tell the human to grant the Mergestorm GitHub App the permission the repair names), and when any other wait reason has held for 45 minutes, a land gate left pending or running on the land PR included (blocker \"Auto land has waited <N>m: <reason in plain words>\", repair kind auto_land_waiting: read stack_status, fix what a commit on the named branch can fix, otherwise tell the human what Auto land waits for and since when). A more specific blocker on that PR is named first. A new head clears the wait.",
55
+ "- While the stack has a live merge queue entry, stack_wait carries queueWait (the entry's wait reason, how long it has been held, and the stack queued ahead of it) and the status line names it. The watch returns attention, blocker \"Merge queue stuck: ...\" and repair kind queue_stalled, when the entry (or the entry ahead of it) has been held for 45 minutes without landing or bouncing, or has sat queued for 45 minutes with nothing working on it or ahead of it.",
56
+ "- When no Vortex run works on the head and its review was skipped because auto-review is off (blocker \"Vortex auto-review is off, so this head was not reviewed\") or because billing could not be confirmed (\"Vortex skipped this head: it could not confirm billing\"), or it covered only part of the PR (\"Vortex reviewed only part of this PR\"), the watch returns attention at once with repair kind vortex_skipped. Do not patch for it; the repair names the mention or setting that gets the head reviewed.",
57
+ "- A live-head Vortex request_changes handoff returns attention with blocker \"Vortex findings need a person\" and repair kind vortex_findings; verify the review and inline findings against the live head before repair.",
58
+ "- Cyclone, with auto-patch on, patches only Vortex review findings (Core and seam, on any layer, the land PR included). It does not fix merge conflicts, restack conflicts, failing CI, or any other landing blocker by itself; the watching agent fixes those, whatever the auto-patch setting, and does not turn auto-patch off to do it. With auto-resolve conflicts on for the stack, Cyclone resolves a layer conflict itself (never the land PR's conflict with main): while busy[] shows Cyclone, wait, and fix the conflict only after its handoff, when the watch returns attention. With auto-fix CI on for the stack, Cyclone fixes a settled red check on a layer itself (never the land PR), or asks Surge for one re-run of a flaky one: while busy[] shows Cyclone, wait, and fix the failure only after its handoff, when the watch returns attention.",
59
+ "- Cyclone patches Vortex findings on a land PR when auto-patch is on for that stack (its override, else the account setting); every other land PR blocker, a conflict with main or failing CI included, is fixed by the watching agent on mg-stack-<n>.",
60
+ "- More states the watch names: a Vortex review skipped because the PR author is on the ignored authors list or because reviews are turned off for the repository is attention at once with repair kind vortex_skipped; a Vortex retry that is scheduled (\"Vortex hit a temporary error on this head and will retry by itself\") is a wait listed in issues[], never attention; \"Review failed\" carries repair kind vortex_failed (comment @mergestorm-vortex review or push a new commit; if it fails again tell the human); a PR open on mg-stack-N that is not a layer of the stack is attention at once, blocker \"The land PR cannot be queued: ...\", repair kind members_remaining (do not patch or push; close, retarget or adopt that PR).",
61
+ "- Use the mergestorm-bounce-watch skill for the fix-then-watch policy.",
62
+ ].join("\n");
63
+ export const MCP_HOSTED_SERVER_INSTRUCTIONS = [
64
+ "Stacks:",
65
+ "- A stack is done only when it is landed, or when the human takes it back (archives it or tells you to stop). A submit, an adopt or one merged layer is not done: merging a lower layer can break a layer above it.",
66
+ "- A layer PR shown as merged is merged into mg-stack-<n>, not main. The stack is landed only when its land PR (head mg-stack-<n>) merges into main, which watch.done with reason landed reports. Never judge landing from GitHub PR state alone.",
67
+ "- Results of the stack tools and review_dismiss carry watch: {done, reason, next, message}. While watch.done is false, call stack_wait with watch.next.args, which carry the cursor. Stop when watch.done is true.",
68
+ "- attention means a layer needs a fix: it names the PR and the blocker, and repair, when present, names the fix. in_progress means Vortex or Cyclone is still working on it (busy[] says which) or a blocker waits for them to finish (actAfter agents_idle): wait, do not act. A pending land gate (landGatePending) is a wait, not attention.",
69
+ "",
70
+ "Vortex findings:",
71
+ "- Dismiss a finding only after you checked it against the PR's live head and found it wrong or not actionable, with review_dismiss and a reason that gives your evidence. Never dismiss a finding you did not check or one from a newer review.",
72
+ "- A finding a human must decide (Decision required, policy fork, needs a human) stays open: do not dismiss it; tell the human which finding it is.",
73
+ ].join("\n");
@@ -0,0 +1,24 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type Config } from "mergestorm/client";
3
+ import { MCP_HOSTED_SERVER_INSTRUCTIONS } from "./pr-loop-instructions.js";
4
+ export { MCP_HOSTED_SERVER_INSTRUCTIONS };
5
+ export declare const MCP_SERVER_NAME = "mergestorm";
6
+ export declare const MCP_SERVER_VERSION = "0.2.28";
7
+ export declare const MCP_TOOL_NAMES: readonly ["whoami", "credits", "review_list", "review_submit", "review_wait", "review_wait_pr", "review_dismiss", "review_start_pr", "review_stop_pr", "cyclone_start", "cyclone_job", "issue_create", "stack_adopt", "stack_enqueue", "stack_list", "stack_publish", "stack_publish_status", "stack_restack", "stack_set", "stack_status", "stack_wait", "queue_status", "settings_get", "settings_set", "repo_settings_get", "repo_settings_set", "surge_setup", "list_memories", "search_memory", "remember", "update_memory", "forget_memory", "get_memory_mode", "set_memory_mode"];
8
+ export declare const MCP_SERVER_INSTRUCTIONS: string;
9
+ export declare function fail(err: unknown): {
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ structuredContent: Record<string, unknown>;
15
+ isError?: boolean | undefined;
16
+ };
17
+ export declare const MCP_WORKSPACE_TOOL_NAMES: readonly ["review_submit", "review_wait", "stack_publish", "stack_publish_status"];
18
+ export declare const MCP_HOSTED_TOOL_NAMES: ("stack_wait" | "credits" | "whoami" | "review_list" | "review_submit" | "review_wait" | "review_wait_pr" | "review_dismiss" | "review_start_pr" | "review_stop_pr" | "cyclone_start" | "cyclone_job" | "issue_create" | "stack_adopt" | "stack_enqueue" | "stack_list" | "stack_publish" | "stack_publish_status" | "stack_restack" | "stack_set" | "stack_status" | "queue_status" | "settings_get" | "settings_set" | "repo_settings_get" | "repo_settings_set" | "surge_setup" | "list_memories" | "search_memory" | "remember" | "update_memory" | "forget_memory" | "get_memory_mode" | "set_memory_mode")[];
19
+ export type MergestormMcpServerOptions = {
20
+ config?: Config;
21
+ hosted?: boolean;
22
+ chatId?: string | null;
23
+ };
24
+ export declare function createMergestormMcpServer(options?: MergestormMcpServerOptions): McpServer;