Documentation
Reference for the three Mergestorm GitHub Apps — Vortex (reviews), Cyclone (auto-patch) and Mergestorm Surge (CI runners, the merge queue, Auto land and dashboard stacks) — plus dashboard settings, credits, the local reviews, stacked PRs via mg, and troubleshooting. New here? Start with How it works for the full setup walkthrough, or the API reference for every endpoint the CLI and MCP server use.
main to your first reviewed PR.Quick start
Mergestorm is three GitHub Apps. Install only the ones you want:
- Vortex — install it to run the reviews: inline comments and a check run on every PR and push.
- Cyclone — install it if you want auto patch. It commits fixes from review findings and does nothing else.
- Mergestorm Surge — install it if you want our CI runners, the merge queue, Auto land or dashboard stacks. See Surge — CI runners.
Connect agents and pick which repositories they watch on Agents, tune how they behave (auto-review, auto-patch, auto land) in Settings, then open a PR. Add Cyclone later only if you want it.
Vortex — reviews
When Automatically review new PRs and commits is on, Vortex reviews on every PR open and new push — no command needed. Each review posts inline comments and a GitHub check run named vortex-v2.
Set ignored bot authors and review check colors in Settings → Vortex (see Dashboard settings).
Trigger a manual review by commenting on a pull request (not a standalone issue):
@mergestorm-vortex review
Variants such as @mergestorm-vortex[bot] review or @mergestorm-vortex please review work as long as the comment mentions the bot and includes the word review.
- Must be a human comment (bot comments are ignored).
- Only fires on newly created comments — editing an old comment does not re-trigger.
- Draft PRs are skipped.
- Vortex reacts with 👀 while the review runs.
- History badges: Auto (automatic), Mention (manual
@mergestorm-vortex review), or Manual (triggered from the dashboard).
Linked issue context
Use proper GitHub Issue workflows and Vortex reviews against the ticket — not just the diff. Open an Issue for the work, then link it from the PR with Closes #N, Fixes #N, Resolves #N, or the Development sidebar. Vortex pulls up to three linked issues into the review as background for intent and acceptance criteria (opening description, plus short discussion when the thread is small).
Cyclone — auto-patch
Cyclone has no @mention command. It runs automatically when auto-patch is enabled and Cyclone is connected (a separate GitHub App, mergestorm-cyclone). It reacts to:
- Submitted PR reviews with actionable findings (including Vortex reviews).
- Inline review comments (batched when the review is submitted).
- Comments from bots on your Bots Cyclone patches list (Settings → Cyclone). Vortex is on it by default. Add other bots there. Cyclone skips comments from bots not on the list.
After a batch completes, Cyclone posts a plain outcome comment whose first sentence says what happened and what, if anything, you need to do. A pushed fix needs no marker: the push itself triggers the next Vortex review. When Cyclone leaves the findings open (nothing to change, failed, stopped), the comment carries a hidden mergestorm-loop: dismiss marker, the same command you or a coding agent post as the first line of a comment to dismiss findings, and Vortex resumes its paused review of that commit. Check runs appear as cyclone-v1 when enabled. Include stopreview in a finding body to stop Cyclone from processing that batch.
Surge — CI runners
Surge runs your GitHub Actions jobs on on-demand self-hosted runners: shared cloud servers that start when CI needs them and shut down once they sit idle. Each job runs in its own fresh sandbox, and you pay only for the minutes your jobs run. Nothing runs and no Surge minutes are counted while CI is quiet, so Surge scales to zero.
The Mergestorm Surge GitHub App also runs the merge queue, Auto land and dashboard stacks. Install it to use them. It is free to install; you pay only for runner minutes.
Surge is in public beta. Surge minutes are included with paid plans, each credit period: 100 on Builder, 300 on Scale, 1,000 per credit pack on Pro, and 3,000 per credit pack on Maelstrom (up to 20 packs), while the subscription is active or trialing. See Billing. When the beta has no room for more runners, Surge does not start one for you and your jobs run on GitHub-hosted runners as they always have.
Requirements
- You sign in to Mergestorm with GitHub.
- The repository is private. Public and internal repositories are refused.
- You are an admin of that repository on GitHub.
- The Mergestorm Surge GitHub App is installed on the repository. Mergestorm opens the CI setup PR through it and learns from it when CI runs.
- Surge minutes: a Builder, Scale, Pro or Maelstrom plan with an active or trialing subscription includes them, and any account can buy a minute pack on Billing.
Setup
- Install the Mergestorm Surge GitHub App on the private repository. Surge does not need Cyclone.
- Open Dashboard → Surge, choose the first repository from the list, and choose Set up Surge. Surge is set per account: it can serve every private repository you connect. Add more with Serve on Surge under Repositories. On/off, scaling, watched workflows and the spend cap apply to all of them, and you change them once in Settings → Surge. A repository is served by one account at a time.
Under Repositories, choose Set up CI. Mergestorm opens a pull request that points each job on
ubuntu-latest,ubuntu-24.04orubuntu-22.04at the routing variable and lists the jobs it left alone. Merge it, and the repository shows Connected. Each served repository needs its own setup PR. A connected repository that Surge does not serve yet keeps running on GitHub-hosted runners.To do it by hand instead, set this on each job you want on Surge:
jobs: test: runs-on: ${{ vars.CI_SURGE_RUNNER || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4Mergestorm sets the repository variable
CI_SURGE_RUNNERto your pool's runner label only while a Surge runner is online, and deletes it when Surge is off. With the variable unset the expression falls back toubuntu-latest, so the same workflow keeps running on GitHub-hosted runners with no edits.- Turn Surge on in the Surge tab:
- Manual — keep Surge on. Jobs that ask for a runner get one as they queue, and Surge turns off by itself after 30 minutes with no jobs.
- Auto — Surge starts runners when a watched workflow run needs them and scales back to zero when CI goes quiet. Set the watched workflow names (default
CI) in Settings → Surge. Auto learns about workflow runs from GitHub webhooks that Mergestorm receives through the Mergestorm Surge GitHub App. The Surge tab's job list comes from the same webhooks.
Runner sizes
Every job runs on a standard runner unless you ask for more. A job that is held back by CPU, such as a test suite that runs files in parallel, a compiler, a bundler or a Docker build, can ask for a large runner, which gets twice the CPU and memory and uses Surge minutes twice as fast.
| Size | Runner label | CPU | Memory | Surge minutes per minute |
|---|---|---|---|---|
| Standard | ms-surge | about 2.6 vCPU | about 4.4 GB | 1 |
| Large | ms-surge-large | about 5.3 vCPU | about 8.8 GB | 2 |
Choose the size per job, so only the jobs that need it pay double. To put a job on a large runner, set this on that job:
jobs:
test:
runs-on: ${{ vars.CI_SURGE_RUNNER && 'ms-surge-large' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4It keys on the same CI_SURGE_RUNNER variable, so while Surge is off or paused the job still runs on ubuntu-latest. Set up CI only writes standard runners; switching a job to large is a one-line change you make yourself. Inside the job, nproc reports the CPUs the job has (3 on standard, 6 on large), so test runners size their worker count to it. A large job waits for room on one server, so when Surge is busy it can start a little later than a standard job. Large does not speed up a job that mostly waits on the network, a database or a single-threaded step.
Surge minutes
One minute of a job running on a standard runner is one Surge minute, and one minute on a large runner is two, counted from when the job starts until it ends and rounded up per job. Starting servers, idle time and caches cost you nothing. The Surge tab and the Billing page show minutes used and left this period and when the period resets. When your minutes run out, or you reach your spend cap, Surge pauses the repository for an hour, or until you buy minutes or raise the cap. While it is paused new jobs run on GitHub-hosted runners, and jobs already running finish.
Minute packs are sold on Billing: 1,000 minutes for $5, 5,000 for $25 and 20,000 for $100. Purchased minutes are used after the plan's included minutes and carry over between periods.
An account without a paid plan (Free or Starter, or a subscription that is not active or trialing) has 0 included Surge minutes. Until it buys a minute pack Surge will not turn on: starting runners in Manual shows “No Surge minutes left.”, Auto pauses as soon as CI asks for a runner, and your jobs keep running on GitHub-hosted runners.
Isolation
- Surge servers are shared between customers. Each job runs in its own gVisor sandbox: a fresh container with its own user-space kernel, thrown away when the job ends. A job can't see other jobs or the server.
- Jobs can't reach the cloud metadata service, private networks, the server or other jobs. Servers accept no inbound connections, and a job only ever holds a single-use runner registration for its own repository.
- Dependency caches (npm, Yarn, pip and
~/.cache) are kept per repository on the server's disk and mounted only into that repository's jobs. All jobs of a repository, including pull requests, share its cache.
Limits
- Runners are Linux x64. A job gets a share of a server: about 2.6 vCPU and 4.4 GB of memory on a standard runner, twice that on a large one (see Runner sizes). Jobs run as root inside their sandbox, so
sudoandapt-getwork. - Docker works inside a job on the host network:
docker runanddocker buildwork, and a port mapping works when both ports match (for example-p 5432:5432). Service containers (services:) and container jobs (container:) are not supported; Set up CI leaves those jobs on GitHub-hosted runners. - Install toolchains in the job (for example with
actions/setup-node) rather than relying on software preinstalled on GitHub-hosted images. - Stop Surge, or switching Manual off, clears the routing variable and lets running jobs finish. Stop Surge in Auto also switches the pool back to Manual.
- Stop serving a repository in Settings → Surge once Surge is off and its runners have shut down. Recorded usage stays on your account.
Troubleshooting
- Jobs still run on ubuntu-latest — the job's
runs-onmust readvars.CI_SURGE_RUNNER, Surge must be on with a runner online (the variable stays unset until then), and you need Surge minutes left. In Auto, check the workflow name is in the watched list and the Mergestorm Surge app is installed on the repository. - A run was cancelled and started again — when Surge turns off or pauses while a job is already waiting for a Surge runner, that job has no runner to take it. After 30 minutes Surge cancels the run and re-runs it, and the new run uses GitHub-hosted runners.
- "Surge runs only on private repositories" — the repository is public or internal. Use a private repository.
- "Surge can't use that repository" — the Mergestorm Surge app is not installed on it (or has no access to it), or you are not an admin of the repository.
Dashboard settings
Two tabs, two jobs. Agents is where you connect Vortex, Cyclone and Mergestorm Surge, configure the specialist fleet, and choose scope: Review all repositories (every repo in your GitHub App installation is eligible) or a hand-picked list from the monitored repos below it. Settings controls how the installed agents behave and how Surge runners are configured, grouped as Vortex, Cyclone, Surge, and Stacks:
- Automatically review new PRs and commits — when off, Vortex skips reviews until you turn this back on (or use @mergestorm-vortex review).
- Ignore bot PR authors (Settings → Vortex) — skip automatic reviews for PRs opened by these GitHub logins. Cyclone follows the same list: no automatic CI fix, conflict resolution or patch on those PRs. The PR author decides, so commits another bot pushes onto the PR (such as a hash refresh by
github-actions[bot]) keep it skipped.renovateandrenovate[bot]are one entry. Leave empty to review bot PRs as today; @mention and dashboard triggers still force a review on skipped PRs. - Check on skipped bot PRs (Vortex) — No check (default, nothing posted) or Neutral check (completed · skipped). A skip never posts a review comment.
- When review has findings (Vortex) — Neutral (default) or Fail for a completed review with findings. Clean or approved reviews are always green; incomplete reviews and continue-wave handoffs are always neutral.
- Reset to defaults (Vortex) — clears the ignore list, returns skipped bot PRs to No check, and findings to Neutral. Does not change auto-review, Cyclone (including skip-CI), or Stacks.
- Automatically apply fixes from MergeStorm reviews — when on, Cyclone commits fixes from review comments to the PR branch. Off by default; requires Cyclone connected on Agents.
- When a patch batch fails (Settings → Cyclone) — Fail check (default, today’s red X) or Neutral check. Infrastructure retries and exhausted credits are unchanged. Vortex reset does not touch it.
- Surge — configure runners per CI run, watched workflows and the spend cap for your account, and stop serving a repository.
- Auto land new stacks — when on, stacks you open afterwards start with Auto land enabled and enter the merge queue once green. Off by default. Needs Mergestorm Surge.
- Merge queue (under Surge) — Batch the merge queue, when on, makes the merge queue test several queued pull requests on one CI run, off by default; Lands alone if it changes lists the paths whose changes keep a pull request out of any batch. Account defaults that any repository can override on Repositories. Needs Mergestorm Surge. See Merge queue batching.
API keys for the API and the CLI, plus the unlink (danger zone) control, also live on Settings.
Work chat
The agent chat rail on Dashboard → Work supports three kinds of input:
- Quote a PR, layer, or stack — the quote icon on any Work row (or typing
#in the composer) attaches it as a chip. Chat then starts the right agent: re-review or explain via Vortex, fixes via Cyclone, restacks via Mergestorm. - Paste a GitHub PR URL (
https://github.com/owner/repo/pull/N) — it is quoted as a chip automatically, same as quoting the row. - Ask for an account action — no quote needed.
set up Surge on owner/reposerves the repository on Surge when your account does not serve it yet, then opens the Surge CI setup pull request, andturn on merge queue batchingorturn off merge queue batchingchanges merge queue batching. - General questions — setup and product help; reviews and fixes need Vortex connected on Agents. Chat takes no file uploads and does not write code — it acts on connected Work objects only.
The recommended workflow is the GitHub loop: open an Issue, open a PR that closes it, let Vortex review on pushes with that issue as context; add Cyclone later for optional auto-patch. Chat is supplementary.
Credits & billing
Billing uses one monthly credit pool shared by every agent. Your period starts on your signup date (free) or your Stripe renewal date (paid), not the 1st of the month. Free tier: 30 credits / month.
- Vortex completed review = 1 credit · Cyclone patch applied = 1 credit.
Every agent debits the same monthly pool — Vortex 1 · Cyclone 1. There is no separate premium balance.
See Usage & Billing for paid tiers, credit meters, and Stripe subscription management.
Local reviews
Get code reviews on a diff without opening a GitHub PR, for local loops and CI. Reviews run on the same engine as PR reviews and debit 1 credit each.
curl -fsSL https://mergestorm.ai/install.sh | bash mergestorm login mergestorm review
- Endpoints: every API endpoint, with parameters, responses and curl examples, is on the API reference.
- Keys:
mergestorm loginstores one after you approve it in the browser. For your own scripts, create one on Dashboard → Settings → API. - Thread chains: reuse the same thread slug on follow-up submissions so prior findings carry over. View chains under Work.
- History: see your recent API and CLI reviews (status, time, thread, submitting key, credits) on Dashboard → Billing.
CLI — stacked PRs
The same mergestorm / mg binary opens chained GitHub PRs from your terminal. Happy path: create → commit → submit → restack → land. Install with curl -fsSL https://mergestorm.ai/install.sh | bash; endpoints are on the API reference; narrative + demo video on the stacks tutorial.
Requires Node.js 22+, mg login (Mergestorm API key), and local git + gh auth for push/PR open. Stack authoring state is managed under ~/.mergestorm/ — do not edit it by hand. Stacks, the merge queue and Auto land need the Mergestorm Surge GitHub App on the repository.
Explicitly enqueueing a stack is the only unattended auto-land path. mg stack land is a manual skip-queue escape. Neither MCP nor the review skill can land.
npm i -g mergestorm # or: curl -fsSL https://mergestorm.ai/install.sh | bash mg login mg stack create feat/layer-one # edit, then commit as usual git commit -am "feat: layer one" mg stack create feat/layer-two --extend git commit -am "feat: layer two" mg stack submit
| Command | What it does |
|---|---|
| mg stack create [name] | A new single PR from trunk. --extend stacks it on the checked-out branch (or --onto) instead. |
| mg stack submit | Push layers, open chained PRs with gh, register the stack in Mergestorm. |
| mg stack restack <stack-id> | Restack descendant layers after a base changes. |
| mg stack land <stack-id> | Promote into the review unit when one exists; otherwise land the bottom open PR. This is a manual skip-queue escape. |
| mg queue | List merge-queue entries. |
| mg queue add <stack-id> | Explicitly enqueue a stack for verified unattended landing. |
| mg queue rm <entry-or-stack-id> | Cancel a queue entry. |
| mg stack list | List stacks registered with Mergestorm (via submit/ adopt). |
| mg stack adopt <owner/repo>#<pr> | Import an existing GitHub PR chain (also used internally by submit). |
| mg stack reset --force | Clear local pre-submit authoring state only — never deletes branches or PRs. |
Source (MIT): github.com/marginsystems/mergestorm-cli. npm: mergestorm. Confirm flags with mg stack --help.
Merge queue batching
The merge queue normally tests one queued pull request per CI run. With batching on, it tests several on one CI run. It merges the queued pull requests, in queue order, onto the tip of the base branch on a branch named mq-batch-<id>, waits for CI on that branch, and when CI is green lands the pull requests one by one. After each land it checks that the base branch holds exactly the tree the batch tested. If it does not, the batch stops and the pull requests that have not landed go back to the queue. The queue deletes the batch branch when the batch ends.
Batching saves CI runs and waiting when several pull requests are queued at once. It is off by default and set per account, so it applies to every repository on your account.
Turn it on
- In Settings → Surge → Merge queue, turn on Batch the merge queue. That is the account default; on Settings → Repositories any repository can set its own value or inherit the account's.
- In the Work chat, type
turn on merge queue batchingorturn off merge queue batching. Askis batching on?to read the current setting.
Batch size
Pull requests per batch is the most pull requests the queue tests together: 2 to 10, 4 by default. A bigger batch lands more per CI run and loses more time when one pull request in it fails. Set it in Settings → Surge → Merge queue, per repository on Settings → Repositories, or in chat with turn on merge queue batching with 6 per batch. A batch needs at least two queued pull requests that can batch; one on its own lands the usual way.
Overdrive
When a repository's queue backs up, turn on Overdrive: the queue tests up to 10 queued pull requests together in that repository, even with batching off, and your batch size stays as it is for when Overdrive is off. It is off by default and stays on until you turn it off. The account setting in Settings is the default; each repository can override it (Inherit, On or Off) under Settings → Repositories, or with the speedometer on its lane in the merge queue on Work. In the CLI it is mergestorm settings --merge-queue-overdrive on for the account and mergestorm settings --repo owner/repo --merge-queue-overdrive on for one repository.
What always lands alone
These get their own CI run, as they do with batching off:
- A pull request that changes a file matching Lands alone if it changes on Settings → Surge → Merge queue: one path pattern per line, a folder prefix or a glob (
*within a folder,**across folders). By default**/migrations/**,db/migrate/**and.github/workflows/**, so migrations and workflow changes land alone in any repository layout. A repository can replace the list on Settings → Repositories; an empty list keeps only the rules below. - A stack with more than one open pull request, and a stack that lands through a review unit land PR.
- A pull request whose own CI is failing. One with no CI on its newest commit can still join a batch.
- A pull request that conflicts with the ones ahead of it in the batch, or that targets a different base branch than the front of the queue.
The mq-batch-** trigger
A repository can batch only when its CI runs on pushes to the batch branch. Every workflow that runs on pull requests needs this push trigger too:
on:
pull_request:
push:
branches: ["mq-batch-**"]The Surge CI setup pull request adds it for you: choose Set up CI under Dashboard → Surge, or type set up Surge on owner/repo in the Work chat. It gives each workflow the same path filters on the batch push as on its pull request trigger, and lists the workflows it could not change.
Without the trigger, no CI starts on the batch branch. After 5 minutes the queue stops the batch and lands that repository's pull requests one at a time for the next hour, then tries a batch again.
When a batch fails CI
- The queue finds the pull request that broke the batch by testing partial batches: the first pull request alone, the first two together, and so on. It pushes each one as
mq-batch-<id>-partial-<n>, so they run on the same trigger at the same time, and it reads only the checks that failed on the batch. - It bounces one pull request: the one whose addition first turns those checks red. The bounce names the batch and the other pull requests in it, and those go back to the queue.
- When the partial batches cannot answer, nothing is bounced on the batch result. That happens when a failed check is skipped or never starts on a partial batch, or when the failure is a commit status. The queue then retests the front pull request alone, and the rest go back to the queue behind it.
- A check that runs past the CI timeout is handled the same way: the front pull request is retested alone.
Troubleshooting
- Review did not run — check auto-review is on, the repo is enabled, the PR is not a draft, and you have credits remaining.
- Mention ignored — confirm the PR is open (not draft), the comment is new (not an edit), and you used @mergestorm-vortex review on the PR itself.
- Cyclone did not patch — connect Cyclone on Agents, turn on auto-patch in Settings, and ensure the review had actionable inline findings (not an approve/all-clear summary).
- Chat dispatch not running — connect Vortex on Agents, then quote a PR or stack (or paste a public
github.com/owner/repo/pull/NURL) to run reviews and fixes.
Contact
Questions or feedback: contact@mergestorm.ai