mcp-convention-gate
Gates git commits by blocking them until required reviews are registered, using MCP tools to create review sessions, register gate results, and check whether a commit is allowed.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-convention-gate Create a gate session for the login flow, register code-review pass, and check commit status."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-convention-gate
Enforce your process by construction — not by prompt. No review, no commit.

An MCP server + git pre-commit hook that refuses a commit until a required review is registered. It enforces the step outside the model's prompt and discretion — so an AI coding agent can't skip it, no matter what the instructions say.
The problem
Rules written as text — convention files, scoped instructions, even the system prompt — don't make an AI coding agent perform a costly, skippable step. In a controlled study across nine models, a "review before commit" rule was skipped in 135 of 135 trials, at every instruction layer. The identical rule, enforced by a gate that refuses the commit, is obeyed 0 of 135 non-compliant — by construction.
Related MCP server: Cross Repo Ops MCP
Requirements
Node.js ≥ 18 — uses the built-in test runner and modern APIs.
git — the enforcement layer is a git
pre-commithook.An MCP-capable agent/client — VS Code + Copilot, Claude Desktop, Cursor, or any client that speaks MCP over stdio — to register reviews in-loop. (The git hook still enforces even without one.)
Quickstart
In your repo:
npx mcp-convention-gate initThis installs a pre-commit hook, a .gate-config.json (which reviews are required), and an MCP server entry
(.vscode/mcp.json). From then on:
Your AI agent registers each completed review through the MCP tools (
create_gate_session,register_gate), checksgate_statusuntilcommit_allowedistrue, then runs the realgit commititself — no MCP call authorizes it, thepre-commithook enforces automatically at that point.Any commit — from the agent or from a terminal — is blocked until the required reviews are registered.
Call
guarded_commitonly after that commit succeeds, purely to log it to the session's audit trail. Calling it before committing marks the session committed, and the hook will then block the commit you were about to make — see theguarded_commitrow below.
npx mcp-convention-gate status # show current gate status
npx mcp-convention-gate check # run the pre-commit check manuallyHow it works
Two enforcement layers, both fail-closed:
Git hook level — a
pre-commithook blocksgit commitat the OS level, even from the terminal. This is the actual enforcement; nothing else needs to run for a commit to be blocked.MCP tool level —
gate_statusreports whethercommit_allowedistruebefore you commit;guarded_commitis an audit-log call for after a commit succeeds, not a gate you pass through to get one.
Pick which reviews are mandatory in .gate-config.json:
{
"enabled": true,
"required_gates": ["security-review", "tests", "docs"]
}The default required_gates is an opinionated nine-role review panel (spec-reviewer, architect,
code-reviewer, security-auditor, test-writer, qa-acceptance, debugger, docs-writer,
ux-evaluator) — that's a lot for a first commit. Most projects start lighter and grow into it; edit
required_gates to match your workflow, e.g. a single gate to begin:
{ "enabled": true, "required_gates": ["code-review"] }If
.gate-config.jsonis missing or fails to parse, the gate is treated as disabled (not enforced) — printed as aWARNINGto stderr, never silently. This favors not disrupting every commit repo-wide over silently enforcing from a file most contributors never touch directly; fix or restore the file to configure gates intentionally.
Session overrides are honored on both layers. If
create_gate_sessionsets its ownrequired_gates, the git hook enforces that session's list too (it checks a session's ownrequiredGatesbefore falling back to.gate-config.json) — not just the MCP tools. Omittingrequired_gatesat session creation falls back to.gate-config.jsonon both sides as well, so the common case (no override) stays in sync automatically. They can only diverge if you deliberately pass an ad hoc list tocreate_gate_sessionthat isn't reflected anywhere else you track — an intentional escalation, not a footgun.
MCP tools
The MCP server (server.js) exposes five tools over stdio. Your agent calls them in-loop; the TOOLS
definition in server.js is the source of truth.
Tool | Required args | Optional args | What it does |
|
|
| Opens a session for a task/sprint/PR and returns its |
|
|
| Records that one review completed. Only |
|
|
| Call this AFTER |
|
| — | Reports registered / missing / failed gates and whether a commit is allowed. |
| — |
| Lists sessions, most recent first, for auditing which tasks went through review. |
A findings entry is { severity: "critical"|"high"|"medium"|"low", description, file?, line? }.
Configuring other MCP clients
init writes a ready-to-use .vscode/mcp.json for VS Code. Other clients use the same launch command — node
running this package's server.js, with MCP_GATE_STORE_PATH pointed at your repo's .gate-store.json. The
exact server path is whatever init wrote into .vscode/mcp.json — copy it from there.
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"convention-gate": {
"command": "node",
"args": ["/absolute/path/to/mcp-convention-gate/server.js"],
"env": { "MCP_GATE_STORE_PATH": "/absolute/path/to/your/repo/.gate-store.json" }
}
}
}Cursor — add the same block to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global).
Any MCP client — launch node <server.js> over stdio and set MCP_GATE_STORE_PATH. The git hook enforces
independently of the client, so even a client that never reaches the server is still gated at commit time.
Why it works — advisory vs. enforced
A prompt is a preference the model weighs. "Run a review first" competes with the immediate task ("edit and commit"), so a cooperative, action-oriented agent follows the nearest instruction and treats the distant rule as optional. Nothing stops it skipping.
The gate is code that returns failure, not a request. The model can't decide to bypass it any more than it can decide a locked door is open. It's a "please knock" sign vs. a locked door — the prompt is the sign; the gate is the lock.
"Isn't this just…"
…a Claude Code hook? Those are vendor-locked and gate tool calls; they don't prove a process step happened, and don't work outside Claude. This is model-agnostic — any agent that speaks MCP + git.
…a
pre-commithook?pre-commitchecks file content (lint/format). This gates on process state ("was the review registered?") and exposes it to the agent over MCP so it can satisfy the gate in-loop.…a guardrail? Guardrails filter the model's words (safety / PII / jailbreak). This gates your process, not the model's words.
Coverage (honest caveat)
The gate governs every commit that passes through it. An agent could still commit via a path the gate does not
mediate (e.g. a raw shell call outside the hook, or git commit --no-verify). Making the guarded path the only
path is a deployment step; within its coverage, enforcement is by construction. See
SECURITY.md for the full trust model and the intentional bypass paths (GATE_BYPASS, MCP
override).
Uninstall
rm .git/hooks/pre-commit # remove the enforcement hook
rm .gate-config.json .gate-store.json # optional: remove gate config + runtime stateIf init backed up a previous hook it saved it as .git/hooks/pre-commit.backup — restore that if you had
one. Also delete the convention-gate entry from .vscode/mcp.json (and any other client config).
Background
Built on the study "Advisory, Not Enforceable: Text Cannot Gate Costly Process Steps in AI Coding Agents (But an Out-of-Band Mechanism Can)."
License
MIT © Dvir Shamay
Available Tools
5 toolscreate_gate_sessionA
Create a new gate session for a task/sprint/PR. Returns a session ID used for subsequent gate registrations and commit checks. If required_gates is omitted, defaults to this repo's .gate-config.json (falling back to the built-in 9-role set if that file is absent).
Inputs: description (required), required_gates.
gate_statusA
Check the current status of a gate session — which gates have been registered, which are missing, and whether commit is allowed.
Inputs: session_id (required).
guarded_commitA
AUDIT RECORD ONLY — call this AFTER git commit has already succeeded, never before. It does not perform or authorize the commit: on success it marks the session "committed" in the store, and the git pre-commit hook treats a committed session as used up. Calling this BEFORE running git commit will cause that following commit to be BLOCKED (the hook will see no eligible session). Correct flow: register_gate for every required role -> gate_status to confirm commit_allowed:true -> run the real git commit yourself -> optionally call guarded_commit afterward to log it.
Inputs: session_id (required), commit_message (required), override, override_reason.
list_sessionsA
List all gate sessions (most recent first). Useful for auditing which tasks went through full review.
Inputs: limit.
register_gateA
Register that a review gate has been completed. Called by each agent after finishing its review. The gate result (pass/fail/warn) and any findings are recorded.
Inputs: result (required), gate_name (required), session_id (required), agent, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Each tool targets a distinct phase of the gate workflow: session creation, gate registration, status inspection, commit logging, and listing. There is no meaningful overlap between tool purposes, and the guarded_commit description clearly differentiates it from actually running a commit.
create_gate_session, register_gate, and list_sessions follow a clean verb_noun pattern, but gate_status is a noun phrase and guarded_commit reads as an adjective_noun rather than an action. The naming is still readable and snake_case is consistent throughout, but the deviations are noticeable enough to lower the score.
Five tools is well-scoped for a focused gate-review workflow: create, register, check, log, and list. Each tool serves a necessary function in the lifecycle, and none feel redundant or ornamental.
The core workflow is covered end-to-end: session creation, gate registration, status verification, commit logging, and session listing. Minor gaps exist, such as no way to retrieve the detailed findings recorded during register_gate or to cancel/abort a session, but these do not block the primary gate-enforcement flow.
Maintenance
Related MCP Connectors
Freeze and unfreeze merges across a GitHub organization, with an audit trail.
ToolGuard paid gate decisions and attestation lookup. Customer API key required. Limited beta.
Git-native policy layer for AI agents: check_action verdicts against rules approved via PR.
Audit GitHub repos for malicious and supply-chain code before you depend on them.
Related MCP Servers
- AlicenseAqualityAmaintenanceA trust-first repository copilot to audit signed commit provenance, preview editor configuration safety, and manage Git hook rollouts.135Apache 2.0
- FlicenseBqualityCmaintenanceEnables secure, policy-controlled operations on local git repositories through MCP, including bounded reads, context-checked patches, allowlisted tasks, and guarded git operations.10-

Review Gateofficial
FlicenseAqualityBmaintenanceAI code review against your team's own rules from your repository, before the pull request: two tools, review_changes and get_team_rules. Closed-source binary distributed via GitHub Releases; published in the official MCP Registry as dev.reviewgate/reviewgate.2-- AlicenseNot gradedqualityBmaintenanceExtracts a repository's hidden contribution rules (assignment-first, claim-first, DCO, CLA, vouch requirements) from its docs into a machine-readable contribution-gates.json. Also lets clients check a committed gates file for drift and render a plain-language README badge snippet.73 npmMIT