mergetai/merget
Connects your coding agent to Merget, a semantic merge queue for GitHub: set it up, operate it, read a pull request's findings and verdict, query code graphs.
Changelog — Merget's plugin for coding agents
The plugin's version lives in packaging/source.json, and
node packaging/build.mjs writes it into every manifest this repository
ships: .claude-plugin/plugin.json, .claude-plugin/marketplace.json, the
root plugin.json, .antigravity-plugin/plugin.json and server.json.
node packaging/build.mjs --check fails when one of them, or this file's top
heading, says something else. A plugin release never changes what the server
answers, only what the skills teach and how the plugin is packaged. To take a
release back, release the content before it again under a new, higher version
(0.4.1 with 0.3.1's skills, say), so this list stays in order: a client that
pins the version updates its copy whenever the version differs from the one
it has.
The API versions the shape of its documents, the findings document among
them (api_version, also sent as the Merget-Api-Version response header):
within a version fields are only added, and a removed or renamed field bumps
it. Merget's rename to its own name (see 0.4.0) is the one exception, made
once within api_version 2026-09, and Merget serves these under their new
names or values only:
- the MCP tool ids,
sema_*nowmerget_*, and the server's name (serverInfo.name),semanowmerget; - the
_metakeyssema.api_version,sema.scopeandsema.error, nowmerget.api_version,merget.scopeandmerget.error; - the count keys of run and analytics rows and of a run's report,
sema_l1…git_clean_but_sema_flagged, nowmerget_l1…git_clean_but_merget_flagged; - a finding's
resolver, now alwaysnull, and a graph edge's resolver, nownameorreceiver: the provenance tier alone.
The version header became Merget-Api-Version at the same time;
Sema-Api-Version comes beside it until a later Merget release drops it.
0.8.2 — 2026-11-02
Antigravity gets the server. Needs no particular Merget release.
mcp_config.json. A new generated file,{"mcpServers": {"merget": {"serverUrl": "https://sema.merget.ai/mcp"}}}, the only file Antigravity reads a plugin's servers from: with 0.8.1,agy plugin install https://github.com/MergetAI/merget-plugin(agy 1.4.12) installed the four skills and no server. Now it installs both, asagy plugin listshows. Other clients do not read the file.- Documentation link.
.claude-plugin/plugin.jsongainsdocumentationUrl,https://sema.merget.ai/docs/coding-agents(the docs' "Install in your coding agent" page, live since 2026-11-01). - merget-setup's client notes say Antigravity reads
.antigravity-plugin/plugin.jsonandmcp_config.json, not the rootplugin.json.
0.8.1 — 2026-10-30
Ready for the directories. Needs no particular Merget release: the server is the one 0.8.0 connects to, and the skills teach what 0.8.0 teaches.
- merget-operate within the skill limit. The skill's body is under the 24,000-byte limit a skill body may have; the detail that put it over moved into its references.
- Square logo.
assets/logo.svgis a 128 × 128 square with the mark centred, 12 px of transparent padding at the sides and 19 px above and below, legible on light and dark (Antigravity wants at least 128 × 128 square; Devin's maintainers and Cursor's cross-listing form ask for 1:1).assets/logo.png, new, is the same geometry at 1024 × 1024, rendered from the mark's flat variant, for the directories that take a PNG. - Author url.
authorcarriesurl(https://sema.merget.ai) in every manifest whose schema allows it:.claude-plugin/plugin.json,.claude-plugin/marketplace.json(the owner and the plugin entry), the rootplugin.jsonand.antigravity-plugin/plugin.json, the last two as exactly{name, url}, which Antigravity's validator expects since 1.4.8. - Suggested prompts.
.antigravity-plugin/plugin.jsongainssuggestedPrompts, the three chips Antigravity shows on a plugin's page: set Merget up for this repository, is this pull request safe to merge, what is waiting in the merge queue. Not in the Agent Plugins schema, so the rootplugin.jsondoes without. - Listing fields.
.claude-plugin/plugin.jsongainsdisplayName(Merget), which Claude Code accepts, and the fields Anthropic's directory reads and Claude Code ignores at load:supportUrl(https://sema.merget.ai/docs/help) andicon(./assets/logo.png), from a newlistingobject insource.json.build.mjsemitsdocumentationUrl,privacyPolicyUrlandtermsOfServiceUrlfrom the same object once they are set, which waits for the privacy and terms pages to be served; the LICENSE waits with them (RELEASING.md, Open items). None of it goes intomarketplace.json, whereclaude plugin validateflags it as unknown. - Shorter description. One sentence of 158 characters that still says
what Merget is and what the plugin adds: Antigravity recommends 120–160,
Devin one action-oriented sentence.
build.mjs --checknow holds the description to 120–160 characters, where it allowed 400. --checkon a Windows checkout. The generated-file comparison now reads the files with line endings normalised, as every other rule does, so a checkout with CRLF endings no longer reports every manifest out of date.- CI.
validate.ymlrunsclaude plugin validate . --profile directoryafter the strict validator, advisory until a LICENSE is chosen: its findings (LICENSE_MISSING,PRIVACY_URL_MISSING) show in the log without failing the job.
0.8.0 — 2026-10-30
One plugin for every coding agent. The repository is now
MergetAI/merget-plugin; GitHub redirects the old name,
merget-claude-plugin. The marketplace (merget-queue), the plugin id
(merget@merget-queue), the server key (merget) and the four skill names
are unchanged, so an installed copy updates in place. Needs no particular
Merget release: the server is the one 0.7.0 connects to.
-
Generated manifests.
packaging/source.jsonis the single source of the plugin's name, version, description, addresses and keywords, andpackaging/build.mjswrites every manifest from it, each with only the fields its reader's schema allows:.claude-plugin/plugin.json,.claude-plugin/marketplace.jsonand.mcp.json— Claude Code, and the clients that read the Claude plugin format as is: Codex, Copilot CLI, VS Code, Devin and Factory Droid;- the root
plugin.jsonandmcp.json— Agent Plugins 1.0 (type: "streamable-http"), read by Codex, Cursor, VS Code, Copilot CLI and Kiro; .antigravity-plugin/plugin.json— Google Antigravity, withdisplayName,logoandauthor;server.json— the official MCP Registry, asai.merget/mergetwith onestreamable-httpremote.
The description is about 250 characters and names no tool count (0.7.0's was 1,734 characters long);
displayNameisMerget;assets/logo.svgis Merget's symbol. -
Dropped the tool-title block.
.mcp.jsonno longer carries_meta.ideToolTitles: the server sends each tool's title itself, so IDEs label the tools the same with or without it. -
Client-neutral skills. The four skills no longer name one client. Tools carry the server's names (
merget_status), and whether an agent adds a prefix of its own is the agent's affair; the sign-in passages say the human signs the agent in again from their agent's MCP settings; "Claude Code passes only the text" became "many clients pass only the text"; the frontmatter lostdisable-model-invocationand gainedcompatibility(Merget's MCP server, connected and signed in); the descriptions are as 0.7.0 wrote them. The per-client steps — how the server is listed and its tool prefix, signing in and signing in again, reload or restart, updating and auto-update — moved into one file,skills/merget-setup/references/clients.md: Claude Code, Codex, Copilot CLI, VS Code, Cursor, Devin, Kiro, Antigravity and Gemini CLI, skills-only installs (Replit among them), any other client (claude.ai, Claude Desktop and the ChatGPT desktop app among them) and the dead ends. merget-setup's last step offers automatic updates where the agent has them, with the Claude Codesettings.jsonprocedure now in that file; the other three skills name merget-setup instead of linking across skills. -
README and RELEASING. The README covers every client with the same commands Merget's setup prompt and dashboard use, and
RELEASING.mdsays how a version is cut and what is checked by hand. The "Merget's new tool names" and "Upgrading from 0.2.0" sections are gone; the 0.4.0 and 0.3.0 entries below keep that history. -
CI.
.github/workflows/validate.ymlrunsbuild.mjs --check(generated files current, CHANGELOG heading, skill frontmatter and links, no client-specific tool prefix outside clients.md, nosemaoutside the server's host and this file, and on a pull request the release rule: a change to a file a client reads comes with a version bump),build.mjs --validateagainst the schemas pinned inpackaging/schemas/and ajv over the same pairs, the Agent Skills reference validator,claude plugin validate --strict, and an install from the checkout into a clean home in Claude Code (asserting the four skills and exactly onemergetserver), Copilot CLI and Codex CLI.release.ymltagsvX.Y.Zand publishes a GitHub release with a zip when a version without a tag lands onmain;registry-publish.ymlpublishesserver.jsonto the MCP Registry on request.
0.7.0 — 2026-10-21
Needs the Merget release that serves merget_queue_code, the queue's Code
view for agents: twenty-nine tools, thirteen that read and sixteen
operating ones. Against an earlier Merget, merget_queue_code is not among
its tools (a call to it is refused unknown_tool); the rest works as 0.6.1
teaches it. 0.6.1 still works against the new release; it does not teach
the new tool.
- New tool
merget_queue_code(merget:queue.read, read-only;repo,number,with,symbol,generation,branch,max_tokens): the queue's Code view, as the dashboard's Code view shows it, joined by Merget — the symbols the plan's open pull requests change or sit one call away from, the edges between them, and the evidence (witnesses) behind every pair that interferes — as markdown withinmax_tokens(default 2000, clamped to 8000) andstructuredContentholding exactly the rows the text shows, with the plan's totals. Withoutnumberorsymbol, the overview: the pull requests, the pairs, the symbols two of them share and the edges across them; withnumber, one pull request: its pairs, what it changes by file, its context and what the witnesses implied; withnumberandwith, one pair: every witness with its two ends, Layer-1 findings first and precise before the rest, then dependence chains, shared symbols and files; withsymbol, one symbol: the pull requests that change it, are one call away from it or have a witness naming it, where each head has it, and its edges. A pull request no longer open is left out with its pairs and listed indeparted.merget-operatenames the tool in its tools table and under The merge queue, its refusals table gainsambiguous,symbol_not_found,entry_not_foundandcode_view_busy, and itsstale_generationrow says to call again withoutgenerationonce the new plan is published. Its tools reference gives the arguments, the answer and every refusal: 400invalid_argument(withwithoutnumberor equal to it,symbolwith either), 400ambiguousand 404symbol_not_foundwithsuggestions, 404entry_not_found(departed,entries), 409stale_generation, 404queue_not_foundfor a branch with no queue, and 429code_view_busy(retryable) andrate_limited, each withretry_after_secs..mcp.jsontitles it "Merget: code view of a queue". - Its budget: a section cut between its rows ends with how many it left out
and a hint, and a closing
Left out for room:line names each section left out whole;truncatedistrueanddroppednames each cut. In the overview the skill narrows withnumber,withorsymbolrather than raise the budget; one pull request, pair or symbol has nothing narrower, so there it raisesmax_tokens. Every call reads and joins the whole plan, so Merget builds one Code view at a time per person, across all their agents, at a lower rate than the other tools: the skill calls it one at a time and waitsretry_after_secs. An empty or partial view (has_codeorhas_graphfalse) is no evidence that pull requests do not interact. follow_up: for each method shown that a pull request's head can open (at most 40),{rev: "pr:N:head", at: "file:line", name, key}to pass tomerget_graph_slice; none for a finding site, a symbol only a witness named or a type. In a pair, each witness carries both its ends' (from_follow_up,to_follow_up, each at its own pull request's head), and a Layer-1 witness itssite_at.merget-graphanchors on it: its protocol's first step names the queue's Code view beside a finding and a file.- The queue reference names the Code view beside the views of
merget_queue_get, and the tools reference'sinclude: codeon therelationshipsview points at it: the same records, joined and within a budget.merget-pr's references send the Code view tomerget-operate. - README: what agents can do,
merget-operate's line andmerget:queue.readname the queue's Code view. - Plugin description: twenty-nine tools, sixteen that set up and operate
Merget, and what the new one does. The skill descriptions are unchanged;
merget-operate's stays at 1,019 of the 1,024 characters a description may have.
0.6.1 — 2026-10-17
Needs the Merget release that serves what was submitted to Merget for a
pull request whatever its state (the amendments view of
merget_queue_get), and, in merget_analytics's outcomes report, the
findings resolved with fixes and resolutions submitted to Merget counted
apart from those Merget resolved (resolved_with_submitted). The tools are
still twenty-eight. Against an earlier Merget, merget_queue_get refuses
the view (invalid_argument: the view is not one it knows); the
outcomes report has no resolved_with_submitted: its resolved counts
those findings as Merget's (so merget-operate calls them resolved before
landing there), and its repaired counts a run whose only repair was a fix
submitted to Merget once Merget published the fix to the branch; and a
hand-off's handled_count counts the conflicts a person's resolution
resolved once Merget published it to the branch. The rest works as 0.6.0
teaches it. 0.6.0 still works against the new release; it does not teach
the view or the new count.
merget_queue_getviewamendments(numberrequired): what was submitted to Merget for one pull request — the fixes for its failed batches and its resolutions for merge time — in every state, newest first, whatever the pull request's state (in the queue, landed, closed or never queued), as{items, next_cursor}(limitat most 100). Each item is served as the plan'sresolutionsand a batch row'samendmentsserve one, withoutrelationor its diff;itemsis[]when nothing was submitted. The plan'sresolutionsand a pull request'squeue.resolutionserve a resolution only while it stands, and a batch row'samendmentslists fixes only (a batch that carried a resolution names it inmember_commits[].person_resolution, without its status), so this is where a resolution is read, with how it ended, once it has ended.merget-operatenames the view in its tools table and under The merge queue, and follows a resolution there once the pull request lands or leaves the queue; its tools reference gives the arguments and the answer (400invalid_argumentwithoutnumber, 400invalid_cursorfor a cursor of another pull request), and its queue reference lists the view and, under How a resolution shows, where a resolution reads once it ends.merget_analyticsoutcomes:findings.resolvedno longer counts a finding resolved on a merge that carried a fix or a resolution submitted to Merget, unless Merget had resolved it on an earlier merge of the pull request that carried neither and no merge since left it standing: the person's work may have cleared it. Those findings are counted apart, infindings.resolved_with_submitted, by kind (findings.by_kind[].resolved_with_submitted) and inrows[], the top 20 pull requests by blocking findings (rows[].resolved_with_submitted_findings, besideresolved_findings).repairedno longer counts a run whose only repair was a fix submitted to Merget once Merget published the fix to the branch, as it already left it out while the fix was held.merget-operateand its tools reference teach the counts, and to say those findings were resolved with fixes and resolutions submitted to Merget, never by Merget.merget-pr's findings schema: a hand-off'shandled_countnever counts the conflicts a resolution submitted to Merget for merge time resolved, even once Merget published it to the branch, where an earlier Merget counted them. The findings schema'squeue.resolutionrow and the skill's references send what was submitted for a pull request that left the queue tomerget-operate.- README:
merget:queue.readalso reads what was submitted to Merget for a pull request, in the queue or not, and what agents can do says the same. - The skill descriptions and the plugin description are unchanged;
merget-operate's stays at 1,019 of the 1,024 characters a description may have.
0.6.0 — 2026-10-16
Needs the Merget release that serves resolve for merge time and
merget_pr_receipt: the resolve action of merget_queue_action, the
offer on a hand-off that needs the user (handoff.resolve), where the
repository takes resolutions, the queue's resolutions and a batch
member's person_resolution, and the read tool merget_pr_receipt, with
billing in credits. The tools are twenty-eight, thirteen that read and
fifteen operating ones. Against an earlier Merget, merget_pr_receipt is
not among its tools, merget_queue_action refuses resolve
(invalid_argument: the action is not one it knows) and no hand-off
carries resolve, so the skills offer resolving on the branch alone, and
merget_org_get may answer the monthly LLM budget instead of credits;
the rest works as 0.5.0 teaches it. 0.5.0 still works against the new
release; it does not teach resolving for merge time or
merget_pr_receipt, and it names the monthly LLM budget, which the new
release no longer serves.
merget_queue_actionresolve(number,base_commit,patch,reason): a resolution of a pull request's handed-off conflicts, made on R0 — the pull request's head merged onto the queue's predicted base, with Merget's own resolutions where it has them and conflict markers in the rest, published atrefs/merget-queue/resolve/<number>, on no branch — and handed to Merget instead of pushed to the branch. Merget checks it as it checks its own resolutions, keeps it beside the pull request and lands it with the pull request, never on the branch while the queue order stands. Resolving on the branch stays the first way;resolveis offered beside it.withdraw_amendmenttakes a resolution back as it takes a fix.- The queue reference describes the offer a hand-off that needs the user
(
needs_youorwaiting_on) carries in queue and autonomous mode withbatch.amendmentson (handoff.resolve:eligible,base_commit,ref,queue_base,over,paths,merget_paths,prompt_url,previous) and every reason one is not eligible (not_enforced,fork_head,stacked,resolution_standing,not_qualifying,rule_first,too_many_files,preparing,unavailable,untrusted_base,nothing_to_resolve); the patch's rules (a fix's limits, and no conflict marker left in a file the offer lists, checked at submission and again on the applied file); a resolution's statuses; how it shows — the plan'sresolutions, a pull request'squeue.resolution, a batch member'smember_commits[].person_resolutionwith what it leaves out of either side (left_out); one resolution per pull request beside at most one fix; and every refusal, among them the three a fix never gets:not_handed_off,stale_resolution_baseandunresolved_conflict. Afterstale_resolution_base, which keeps nothing, it carries the resolution over to the new R0: read the hand-off again (its files and prompt may differ), apply the earlier patch withgit apply --3way, resolve what remains and submit again. merget-operate, new: When conflicts need the user — read the hand-off and Merget's prompt withmerget_queue_status, offer both ways with the branch first, resolve on R0 fetched by its ref, write the patch with the prompt'sgit diffline, confirm,resolve, and follow it to where it lands. The skill confirms with the user beforeresolve, which is recorded under their name, and its refusals table gains the three new codes. When a batch fails, a member that carries a resolution (member_commits[].person_resolution) is named before a push to its branch, which sets the resolution aside too.merget-operate's description names resolving a pull request's conflicts for merge time. To stay within the 1,024 characters a skill's description may have, it no longer calls repository settings a JSON merge patch checked againstpolicy_schema, which the skill still teaches.merget-prreads ablockedorwaitingpull request's queue block in queue and autonomous mode, and hands conflicts offered for merge time, or a resolution of them that stands, tomerget-operate, as it hands a failed batch. Its vocabulary names the queue block'shandoff, and the skill and its interpretation reference say that a push to the branch sets a standing resolution aside: the author hears that before being told to merge the target and push. The findings schema'squeuetable gainshandoffandresolution, andsequence_ready,held,verificationandqueue_break, which Merget served already and the table left out.- The policy reference says
batch.amendmentsalso governs resolutions submitted for merge time, andmerget_batch's reference that itsamendmentsnever list one. That release labels the setting Accept fixes and conflict resolutions submitted to Merget in the dashboard (it was Accept fixes submitted to Merget), and the queue reference names it so. - README:
merget:queue.writealso submits resolutions of pull requests' conflicts for merge time, which Merget lands with the pull request; what agents can do, andmerget-operate's line, say the same.merget-pr's line and what agents can do add what a pull request cost in credits (merget_pr_receipt), as does its permissions table undermerget:findings.read, and the owner's steps name the plan and the spending cap where they named the monthly LLM budget. - Plugin description: resolving a pull request's conflicts on the commit the queue lands for it, and that the agent asks before it submits a resolution. Also what a pull request cost in credits, and twenty-eight tools: thirteen that read and fifteen that set up and operate Merget.
- New tool
merget_pr_receipt(merget:findings.read, read-only;repo,number): what a pull request cost in Merget credits — every run Merget made for it, in order, with its kind, cause, outcome and credits (a run Merget failed or abandoned is listed free), the totals and the periods they fall in, andmode, live billing or a preview that charges nothing. The receipt's only unit is credits: it serves no model or token detail.merget-prteaches it in its tools table and safe set, its findings schema reference gives the answer's fields,merget-setup's permissions table names credits undermerget:findings.read, and.mcp.jsontitles it "Merget: credits of a pull request". - That release bills in credits, and the skills say so.
merget_org_getanswers the plan andbilling(used, included, cap, status,paused_reason) instead of the monthly LLM budget, andmerget_run_geta run's credits (receipt) in place of its LLM usage; where Merget serves a run's usage, it is tokens by rung and phase (llm_usage), never a model or a price. The plan and the spending cap are an owner's, under Settings › Billing, inmerget-operate's human-only list. An organization that used its monthly credits getsmerget_status's next stepcredits_exhausted(merget-setup),billing_holdon its row and on its queues, and 402credits_exhaustedonretryandskip_blocked(merget-operate); landings continue.merget-operate's description says credits and its billing where it said LLM spend and budget. - What a queued pull request waits for: the plan's
items[].waitandbatch_summaryin the queue reference, and the findings document'squeue.waitinmerget-pr, which keeps a pull requestwaitingwhateverblockersholds. merget-pr: a blocking finding that breaks the merge into the target branch as it is readsblockedinadvisorymode too, and Merget's check fails, though Merget changes no branch there. Merget already served this, and the skill said only "would block in queue mode", which stays the sentence for anadvisoryverdict.- The queue reference's
not_qualifyingreason also names an agent instruction file, a symbolic link and a submodule, and says that R0, on no branch, is meant to start no CI.merget-pradds tolifecycle: resolvedon a conflict that, where the run's held entry for that path has rung person, a resolution submitted to Merget for merge time resolved it.
0.5.0 — 2026-10-15
Needs the Merget release that serves merget_batch, the batches view of
merget_queue_get, and the amend and withdraw_amendment actions of
merget_queue_action: twenty-seven tools, fifteen of them operating ones.
Against an earlier Merget, merget_batch is not among its tools and the
view and the two actions are refused; the rest works as 0.4.0 teaches it.
0.4.0 still works against the new release; it does not teach the new tool,
view or actions.
- New tool
merget_batch(merget:queue.read, read-only): one batch, by its id orb-xxxxxxxxname — its state, its members and the commit each entered at, CI on the batch commit, what broke with Merget's prompt for a coding agent (Fix with your agent in the dashboard), the batches that isolated the cause, and the fixes submitted to Merget for the batch or carried by its pull requests, each with its diff.merget-operateand its tools reference teach it, and.mcp.jsontitles it "Merget: one batch". merget_queue_getviewbatches: the repository's batches newest first, settled and live;statekeeps one state, orlive, andfailed: trueonly the batches whose CI failed a required check;limitat most 50. The queue reference describes a batch's row as the plan, the view andmerget_batchserve it — itsbreakagewith the prompt,amendmentsandamendable— the plan'samendments_enabled, and an entry'squeue_break.merget_queue_actionamendandwithdraw_amendment: a fix for a batch whose CI failed, handed to Merget instead of pushed to the pull request's branch. Merget tests the batch again with it and lands it with the pull request, never on the branch while the queue order stands. Pushing the branch stays the first way;amendis for a user who wants the branch left untouched. The queue reference gives the arguments, the patch's limits (text only, at most 1 MiB, nothing under.github/or the other paths Merget never writes), one fix per pull request (amendment_exists), that Merget takes one only where GitHub requires the Merget check (amendment_unenforced), the fix's states and every refusal.merget-operate, new: When a batch fails — find the failed batch (viewbatcheswithfailed: true, or the plan's batches), read it withmerget_batch, follow its prompt (reproduce on the commit it names, fix, verify), then push the branch or, if the user wants it untouched,amendwith the prompt's base commit and diff;withdraw_amendmenttakes a fix back. The skill confirms with the user beforeamend, which is recorded under their name, and beforewithdraw_amendment, as beforecancel_land: the fix may be a colleague's.dismissandundismiss, which Merget already serves, are documented for the first time:dismiss(number,fingerprint,reason) says a finding is wrong, so it stops blocking from the next run on, in every mode, and stays dismissed across pushes while it keeps its fingerprint;undismissundoes it.merget-operateconfirms with the user first, since the dismissal is recorded under their name, and dismisses only a finding shown false, never to get past a real break.merget-prhands a batch whose CI failed, its fix and dismissing a finding tomerget-operate, with the queue work it already handed over; it said dismissing a finding happens on GitHub.merget-operate's description namesmerget_batch, a failed batch and dismissing a finding. To stay within the 1,024 characters a skill's description may have, it no longer namesmerget_repo_updateandmerget_secrets, which the skill still teaches.- README:
merget:queue.writealso dismisses findings and submits fixes for failed batches, which Merget lands with the pull request; what agents can do, andmerget-operate's line, say the same. - Plugin description: twenty-seven tools, fifteen that set up and operate Merget, and what the new ones do.
- The policy reference lists
batch.amendments(Queue behavior, bool, on unless false): whether Merget accepts fixes submitted to it for the repository's failed batches. land'scommit_shaandtree_sha, which earlier releases left out, are documented: Merget refuses a land withoutcommit_shain autonomous mode ("Land it now"), withoverrideand withkind: "lane"(invalid_body).
0.4.0 — 2026-10-06
Needs the Merget release that renamed its tools to merget_*: its
tools/list names them, its initialize answer names the server merget
(serverInfo.name), and its MCP responses carry Merget-Api-Version. Its
api_version is still 2026-09: the rename is the one exception to what a
version promises (see above). It no longer answers to the sema_* ids that
0.3.1 and earlier teach: a call to one is refused with unknown_tool, which
names the new id.
- Tool ids are
merget_*, each in place of itssema_*id: the twelve that read pull requests and graphs,merget_pr_findings,merget_pr_runs,merget_run_findings,merget_queue_status,merget_graph_symbols,merget_graph_finding,merget_graph_slice,merget_graph_callers,merget_graph_callees,merget_graph_def_use,merget_graph_diffandmerget_graph_intent, and the fourteen that set up and operate Merget,merget_status,merget_repos_list,merget_repo_settings_get,merget_repo_update,merget_queues_overview,merget_queue_get,merget_queue_action,merget_runs_list,merget_run_get,merget_analytics,merget_org_get,merget_installation_sync,merget_secretsandmerget_docs..mcp.jsontitles them under the new ids, and the four skills and their references teach them: through this plugin Claude Code names themmcp__plugin_merget_merget__merget_<name>, andmcp__merget__merget_<name>for a server added by hand asmerget. - Claude Code permission rules naming the old tools
(
mcp__plugin_merget_merget__sema_pr_findings,mcp__plugin_merget_merget__sema_queue_action,mcp__merget__sema_graph_slice, …) no longer match and must be approved again: approve each tool when Claude Code asks, and rewrite adenyoraskrule with the new name (mcp__plugin_merget_merget__merget_<name>, ormcp__merget__merget_<name>for a server added by hand), since one naming an old tool applies to no tool. A rule naming only the server (mcp__plugin_merget_merget, ormcp__merget) still covers every tool. Claude Code names the tools from the list the server sends, so the old rules stop matching once Merget serves the new names, whichever version of the plugin runs. README, new: Merget's new tool names, with the same advice. - The same holds for a choice another client keeps per tool: a tool
switched off in claude.ai, Claude Desktop, Cursor or VS Code, or a list
of the server's tools in Codex's
config.toml, names asema_*id and applies to no tool once Merget serves the new names; it has to be made again under them. README, Merget's new tool names, says so, and that switching an agent'smerget:repos.writeandmerget:queue.writeoff in Merget keeps it from changing repositories or the merge queue whatever its client calls the tools. - Copies of the skills outside the plugin, in
~/.claude/skills/or in another agent, do not update with it and keep teaching thesema_*ids. README, Skills in other agents, new: theskillstool that Merget's setup prompt installs them with (npx -y skills add …) updates them too (npx -y skills update -gwith the four skills' names), and a copy made by hand has to be made again; Merget's new tool names points there. - The MCP server names itself
merget(serverInfo.name, wassema); this plugin's server was alreadymerget, so/mcpstill listsplugin:merget:merget. The server's_metakeys aremerget.api_version,merget.scopeandmerget.error(the references point a client that exposes_metaat_meta["merget.error"]), and the API's version header isMerget-Api-Version(Sema-Api-Versioncomes beside it for now). - Permissions are
merget:*:merget:findings.read,merget:graph.read,merget:queue.read,merget:org.read,merget:repos.writeandmerget:queue.write, each in place of itssema:*name (offline_accessis unchanged), in the skills' refusal advice, the tools references, the findings schema and the README's permissions table and consent page. Merget's refusals,merget_statusandmerget_org_getname them so from that Merget release; the tokens Merget's sign-in service issues may carry thesema:*names until shortly after it, and Merget accepts both meanwhile, so a connection approved under the old names keeps working and nothing needs signing in again. Merget's product id becomesmerget(it wassema) on the same schedule. - The setup tools reference gives a repository's default queue label as
merget:queue, where it wassema:queue. - Provenance is the tier only: a finding's
provenanceispreciseorsyntactic(gitfor a conflict) and itsresolverisnull; a graph edge'sprovenance.resolverisnameorreceiver, where it wassema-link:nameorsema-link:receiver. The skills read the class, never the resolver: apreciseedge from the receiver pass is precise, and the classreceiveris left for an edge no pass graded.merget-graphdescribessyntacticwithout Merget's internals, as name matching that could not prove a unique binding. merget-pr's references point at Merget's docs — thefindingspage for the provenance tiers, thestatespage for the queue's states (merget_docs, or the dashboard's Docs) — where they named documents that only Merget's own repository holds.- No command-line fallbacks: the skills and the README no longer describe
Merget's internal command-line tool, its commands or its environment
variables; for an agent, the MCP server is the way in.
merget-pr's safe set lists its four tools only, and the README drops the tool's section, its token recipe and the note that the tool ids still carried an internal codename. A client that cannot sign in through OAuth gets its token from an OAuth client of its own (README, Without OAuth), and the 0.2.0 upgrade steps no longer name the tool. - README, claude.ai and Claude Desktop: choose Use Claude's published identity, as Merget's docs and setup prompt advise: the connector doesn't register with Merget, so it doesn't lapse, and Merget can reuse an approval. Register automatically works too, for when Merget can't check Claude's published details. The README said to choose Register automatically, not the published identity.
0.3.1 — 2026-10-05
- README: install with auto-update on. Claude Code updates a plugin only
when auto-update is on for its marketplace; it is off for every
marketplace outside Anthropic's own, and a marketplace has no field to
turn it on
(Claude Code docs).
"Install in Claude Code" now leads with the
~/.claude/settings.jsonentries —merget-queueunderextraKnownMarketplaceswith"autoUpdate": true, andmerget@merget-queueunderenabledPlugins— merged into the file's existing settings, which install the plugin at the next session start and keep it current. The/plugincommands follow as the alternative, with how to turn auto-update on afterwards (/plugin→ Marketplaces →merget-queue→ Enable auto-update, or the same entry). New "For a team": the same entries in a repository's.claude/settings.json, applied once each teammate trusts the folder, and managed settings for an organization. "Updating" says when a new version arrives with auto-update on, and how to update without it. - Skill
merget-setup, new last step: in Claude Code, offer to turn on auto-update formerget-queue, so new skills and fixes arrive without asking. Only on the human's yes, and only when it is not on already, the agent sets"autoUpdate": trueon thatextraKnownMarketplacesentry in~/.claude/settings.json(adding the entry when there is none), keeps every other setting and the entry'ssource, checks the file still parses, and says it takes effect from the next session.
0.3.0 — 2026-10-05
Needs the Merget release that serves the fourteen operating tools and the
write permissions (sema:org.read, sema:repos.write, sema:queue.write);
the member list (sema_org_get with include_members) also needs the
release of Merget's account service that answers it to an agent. The twelve
read tools are unchanged.
- New skill
merget-setup: the first run, fromsema_statusto a repository Merget works on — handing the human the dashboard page where they connect GitHub (the next stepsema_statusnames), re-checking (sema_status,sema_installation_sync), enabling a first repository withsema_repo_update, and choosing its mode from the readiness verdict ofsema_repo_settings_get. Permissions are chosen on the Merget sign-in page and changed under Settings › Agents; oninsufficient_scope,agent_scope_disabled,session_requiredand the other refusals the agent asks the human and never retries. References:setup-states.md(every setup state and next step, and who acts),tools.md. - New skill
merget-operate: repository settings (policyas a JSON merge patch checked againstpolicy_schema; Merget-managed engine limits are not settable), the queue's actions and their guards (confirm before a land, merge anyway or a cancel), runs, analytics, the organization's settings and members (read-only), installations (re-check), a repository's validation secrets (prefer the human pasting a value in the dashboard over passing it through the transcript) and the docs, and what stays human-only. References:tools.md,policy.md,queue.md. - Agents never act as an organization owner: an agent's role is member in
every organization, whoever its user is, and no permission changes that.
The skills hand every owner step to the human, in Merget's dashboard —
connecting GitHub, pausing and resuming merges, renaming the organization
and its LLM budget, adding and removing members, organization-wide
validation secrets and turning strict protection off — and no agent
grants, receives or transfers the owner role. With deleting an
organization or an account, every agent-access control and the browser
steps, that is
merget-operate's human-only list, andsession_requiredis the refusal that marks it.agent_relay_unavailable(503) andagent_relay_refused(502) concern the member list only: Merget could not ask its account service for it on the agent's behalf — Merget's fault, never a permission to ask the human for. - An organization is named to the human by its display name (
display_namefromsema_statusorsema_org_get), and by its slug only when it has none; the slug (u-7d9b0c3ein the examples) is only theorgargument and the URL segment, and choosing among several organizations is asked by name, adding the slug to those whose names match ignoring case. On a successful result the name is taken fromstructuredContent(display_name,consented_org_name,next_step.org_name,sema_installation_sync'sorg_name); a refusal has none, so there it is the decoded JSON of theorg_nameororganizationsdetail line, which prints text, list and object details as JSON in a code span. It is never taken from the`Name` (`slug`)label Merget's headings and messages write, the name in a code span of its own, and the human never sees those backticks. The agent says the name as plain text, its markdown characters escaped, never as a link or markup, and calls a name that reads like a URL, an address or instructions the organization's name. Thedescriptionof thecreate_organization,reauthorize,enable_agentsandallow_agent_permissionssteps is written to the agent, somerget-setuphas it tell the human what it says in its own words, naming the organization byorg_name, and giveurl, instead of passing the description on as it stands.consented_org_name,next_step.org_name,org_nameonagent_scope_disabled, on the organization'sagent_access_disabledand onsema_installation_sync's answer, andorganizationson the multi-organizationinvalid_argumentneed the Merget release that serves them, as do the code-spanned names and details;display_nameitself is served today. - Refusals: every tools reference describes an MCP refusal's text as it
is,
error <code> (HTTP <status>): <message>plus onekey: valueline per detail, and has the agent read the values from those lines — a bare number, boolean or null, or JSON in a code span that it decodes. A refusal carries nostructuredContent, and_meta["sema.error"], the same body as plain JSON, reaches the model only in a client that exposes it (Claude Code passes only the text). Themerget-graphandmerget-prreferences said the text was the body itself. merget-pr:sema whoamistays in the safe set, which now says it is not purely local: it may refresh a stored token at the sign-in service, and to name the token's organization it callsGET /v1/meon the configured API (SEMA_API_URL, else the API the lastsema loginstored, else the default) only when the token was issued for that same API and holdssema:org.read— amongsema login's default scopes from thesemarelease that names the organization. Otherwise it prints the slug and makes no/v1/merequest; a token is never sent to a host it was not issued for..mcp.json: IDE titles for the fourteen operating tools,sema_statustosema_docs.sema_graph_intentdescribed as what it returns: the pull request's title, Merget's brief of its latest finished run and the intents recorded per finding, for apr:<n>:headorpr:<n>:baserev (or a pull request's head sha); never its description, commit messages or prompts.merget-prandmerget-graph: a missing scope is turned on under Settings › Agents or by authorizing again,agent_scope_disabledis named, and merging, re-running and queue changes point atmerget-operateinstead of reading as unavailable.- README: the one-line setup prompt; what agents can and cannot do, in
place of 0.2.1's sentence that both skills only read; the six
permissions, which the consent page now offers as one checkbox each, all
ticked, for you to untick, and which you change later under
Settings › Agents; the organization's permission cap and the repository
access level that changes need;
/reload-pluginsamong the install commands;codex mcp addfor Codex; and removing and re-adding a connection that stopped working, in each client, such as one made before the 2026-09-29 sign-in move. - Plugin description: twenty-six tools, no longer twelve read-only ones.
The marketplace gains a description of its own (
metadata.description), soclaude plugin validate --strictpasses.
0.2.1 — 2026-10-05
- README: Claude Code signs in through the browser. After installing, run
/mcpand authenticate the Merget server: Claude Code opens Merget's sign-in service (https://auth.merget.ai) and its consent page. Removed thecargo install/sema login --legacy/ header-helper setup and the note about browser sign-in to come. - Upgrading from 0.2.0: remove the server that setup added, or any
mergetserver added by hand (claude mcp remove merget, which finds its scope), and delete its helper (~/.merget/mcp-headers.sh, or%USERPROFILE%\.merget\mcp-headers.ps1). A server you add yourself at the plugin's address takes precedence over the plugin's, soplugin:merget:mergetdoes not connect while it is there. For Codex, Cursor or any other client set up from 0.2.0 with theSEMA_TOKENbearer, delete what sends it (Codex'sbearer_token_env_varline, Cursor'sheadersentry) before signing in. - README, new: what the consent page shows; that a client asking for no
particular scope is offered every permission its registration allows,
plus
offline_accesswhen it can use a refresh token, and so stays signed in; signing in again (/mcp→ Clear authentication, after revoking the client to choose another organization or add a scope) and updating the plugin; claude.ai and Claude Desktop, Codex, Cursor, VS Code and OpenCode, each through its own OAuth sign-in, with a bearer token inSEMA_TOKENfor a client without one (sema loginonce, thenSEMA_TOKEN= sema token print, which never prints back a token already exported). Codex reads skills from~/.agents/skills/, and thesema graphexample takes--at file:line. - Skills: this plugin's MCP server is
merget, which/mcplists asplugin:merget:merget, so its tools aremcp__plugin_merget_merget__<name>;mcp__merget__<name>is the form only for a server added by hand asmerget.merget-pr,merget-graphandreferences/tools.mdstill saidmcp__sema__<name>through asemaserver, including in the sign-in-again advice forinsufficient_scope. - Skill
merget-pr: the verdictconflicts, for when Merget serves it — a repository inadvisorymode whose pull request git could not merge (a textual conflict Merget did not resolve, or a run that endedconflicts). It is never clean, and its findings are still counted beside it; the skill says so, with the sentence to use and the wording to avoid. A verdict status the skill does not list is never reported as clean. - Skill
merget-pr: a conflict is said by what it is with, which its finding's message names: with the target, git cannot merge the pull request as it stands; only with a pull request ahead in the queue, GitHub shows no conflict yet and there is nothing to do until that one merges. New classes in the vocabulary and in the classification order as the document applies it:conflict(layer 0, a file git could not merge;lifecycleresolvedwhen Merget resolved it) and, once Merget serves the review reading,review— what the pull request alone breaks against its predicted base, classed by its ownblockingflag ahead of the precise rule, which now reads "precise, whatever the layer" as the document's does. The schema gainsverdict.conflict_count,verdict.review_count,verdict.inheritedandrun.inherited(breaks inherited from a pull request ahead: that one's, never counted here), the conflict and review counts andfindings[].scope; the advisory sentence names review findings; finding kinds are the served ones (broken-reference,interference-dataflow, …). - README: the consent page for a client with a published identity, which
Claude Code signs in with — the page names the host that publishes it
(
claude.ai, which "calls it “Claude Code”"), adds that any app on this computer can ask in that host's name, and shows the identity's address as the Client ID (https://claude.ai/oauth/claude-code-client-metadata); a Claude Code that registered before keeps itsdcr_…registration until its authentication is cleared. What the page shows when Merget remembers an approval given or last used in the last 90 days (Continue as before?, Continuing as before…, Stop and review). Clearing authentication also when Merget's sign-in page says the app isn't registered (adcr_…registration lapses after two and a half to three months without use), andclaude mcp logout plugin:merget:mergetfor when/mcpoffers no Clear authentication; either way Claude Code signs the connection out at Merget too.
0.2.0 — 2026-09-10
- Renamed to Merget, the product's name;
semawas an internal codename. The plugin ismerget, the marketplace ismerget-queue(the namemergetis taken by the Merget VCS plugin marketplace), and the skills aremerget-prandmerget-graph. Tool ids (sema_pr_findings,sema_graph_*), thesemaCLI and theSEMA_TOKENenvironment variable keep their names until the API renames them in a versioned release. - Moved to this standalone repository, so installing the plugin no longer clones the product repository.
- README: sign-in through the
semaCLI with a header helper that refreshes the token, Codex and Cursor configuration, and what changes when browser sign-in ships.
0.1.0 — 2026-09-09
First release, as the sema plugin inside the product repository.
.mcp.json: the remote MCP connection tohttps://sema.merget.ai/mcp(type: http) with IDE titles for the twelve tools.- Skill
merget-pr: reads and interprets a pull request's findings document (sema_pr_findings,sema_pr_runs,sema_run_findings,sema_queue_status) — the classification rules (only precise Layer-1 findings block; Layer 2 is always advisory; advisory mode "would block in queue mode"; shadowed findings wait for the merge conflict), the verdict sentences, the lifecycle across runs, and the stop-and-ask list. References:findings-schema.md(every field of the document, the runs list, the queue block, the error table),interpretation.md. - Skill
merget-graph: the closed graph tool set (sema_graph_symbols,sema_graph_callers,sema_graph_callees,sema_graph_def_use,sema_graph_slice,sema_graph_diff,sema_graph_finding,sema_graph_intent) with the anchor → slice → widen protocol, provenance caveats, budgets (max_tokens2000 default, clamped to 8000;truncatedmeans narrow, not retry) and the error table. References:tools.md(arguments, result shapes, examples),rev-grammar.md(<sha>,pr:<n>:head|base|merge,branch:<name>).