An MCP server that exposes tools for GPG-signed commits and SSH-authenticated git operations. It delegates to the user's local gpg-agent and ssh-agent via the controlling TTY, so no key material is ever exposed to the AI client.
All tools run git as a subprocess with the full user environment and stdin connected to the TTY:
git_commit— runsgit commit -S, delegating signing togpg-agent.git_push— runsgit push, delegating authentication tossh-agent.git_force_push— runsgit push --force-with-lease(or--force), as a separate tool so the AI client must request it explicitly.git_pull— runsgit pull, delegating authentication tossh-agent.git_rebase— runsgit rebase -S, re-signing all rewritten commits viagpg-agent.git_rebase_continue— continues an in-progress rebase with GPG signing enforced.git_rebase_abort— aborts an in-progress rebase, restoring the original branch state.git_checkout— switches branches, creates new branches, or checks out tags.
Stdout and stderr are captured and returned to Claude as the tool result.
- Go 1.25+
gitinPATH- GPG configured for commit signing (
git config user.signingkey) ssh-agentrunning with your key loaded (for push/pull over SSH)
go install github.com/iwarapter/gpg-commit-mcp@latestOr build from source:
git clone https://github.com/iwarapter/gpg-commit-mcp
cd gpg-commit-mcp
go build -o gpg-commit-mcp .claude mcp add gpg-commit $(go env GOPATH)/bin/gpg-commit-mcpOr if built from source, use the full path to the binary:
claude mcp add gpg-commit /path/to/gpg-commit-mcp| Parameter | Type | Required | Description |
|---|---|---|---|
message |
string | yes | Commit message |
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
Prerequisites: changes must already be staged with git add before calling the tool.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
remote |
string | no | Remote name or URL (defaults to origin) |
branch |
string | no | Branch to push (defaults to the remote's configured upstream) |
Force-pushes to a remote. This is a separate tool from git_push so the AI client must call it explicitly, giving the user a distinct approval prompt.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
remote |
string | no | Remote name or URL (defaults to origin) |
branch |
string | no | Branch to push (defaults to the remote's configured upstream) |
force |
bool | no | Use --force instead of --force-with-lease (default: false) |
--force-with-lease is the default — it refuses to push if the remote has advanced since your last fetch, protecting against accidentally overwriting others' commits. Set force: true only when you need the unconditional override.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
remote |
string | no | Remote name (defaults to origin) |
branch |
string | no | Branch to pull (defaults to the current branch's upstream) |
rebase |
bool | no | Rebase local commits on top of the fetched branch instead of merging |
Non-interactive rebase. All rewritten commits are GPG-signed via -S.
| Parameter | Type | Required | Description |
|---|---|---|---|
upstream |
string | yes | Branch or commit to rebase onto |
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
onto |
string | no | New base commit for a three-way rebase (--onto <onto>) |
If the rebase hits a conflict, resolve it manually then call git_rebase_continue, or call git_rebase_abort to restore the original state.
Continues an in-progress rebase after conflicts have been resolved. The continuation commit is GPG-signed.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
Aborts an in-progress rebase and restores the branch to its pre-rebase state.
| Parameter | Type | Required | Description |
|---|---|---|---|
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
Switches to a branch, creates a new branch, or checks out a tag. Checking out a tag results in a detached HEAD.
| Parameter | Type | Required | Description |
|---|---|---|---|
target |
string | yes | Branch name, tag, or commit to check out |
repo_dir |
string | no | Path to git repository (defaults to current working directory) |
create |
bool | no | Create a new branch with the given name (-b) |
Stage your changes first, then ask Claude:
"Commit the staged changes with the message 'Fix null pointer in auth handler'"
Claude will call git_commit and GPG will sign the commit using your local gpg-agent.
To push:
"Push the changes to origin"
To rebase your feature branch onto main:
"Rebase the current branch onto main"
Claude will call git_rebase, re-signing all rewritten commits with your GPG key.
To switch branches:
"Check out the feature/auth branch"
"Create and switch to a new branch called feature/payments"
"Check out the v2.1.0 tag"
Add the following to ~/.claude/CLAUDE.md (create it if it doesn't exist):
## Git operations
When asked to commit changes, always use the `git_commit` MCP tool (server: `gpg-commit`)
instead of running `git commit` via the Bash tool. This ensures commits are GPG-signed
via the local gpg-agent.
When asked to push, use `git_push`. For force-push operations, use `git_force_push`.
For rebase, use `git_rebase` (and `git_rebase_continue`/`git_rebase_abort` as needed).
For branch switching, use `git_checkout`.
Only fall back to plain `git` via Bash if the `gpg-commit` MCP server is not connected.Claude Code loads this file globally at the start of every session.
git log --show-signature -1
git verify-commit HEAD