Unified local + multi-provider git MCP server with a per-agent audit trail as a first-class feature.
Every tool call is tagged with the caller agent (AGENT_ID), written to a structured JSONL audit log, and write operations emit agent-bus events. Local git operations run entirely through gitpython — no subprocess, no injection risk.
| Tool | What it covers | Gap |
|---|---|---|
cyanheads/git-mcp-server (TS) |
28 local git tools | No remote providers, no agent attribution, no audit trail |
poly-git-mcp |
GitHub + GitLab + Gitea | Wraps CLI tools — fragile, no audit, no agent ID |
| Official GitHub MCP | GitHub only | No local git, no Gitea/GitLab |
| Official Gitea MCP | Gitea only | No local git, no GitHub/GitLab |
githost-mcp fills the gap: local git + multi-provider remote via native APIs + per-agent structured audit trail.
git_status, git_diff, git_log, git_show, git_branch, git_checkout, git_add, git_commit, git_push, git_pull, git_tag
github_create_release, github_get_release, github_list_releases, github_workflow_list, github_workflow_status, github_pr_list, github_pr_comments
gitea_create_release, gitea_get_release, gitea_list_releases, gitea_pr_list
gitlab_create_release, gitlab_get_release, gitlab_list_releases, gitlab_mr_list
release — coordinated multi-target release: git tag → GitHub/Gitea/GitLab release → PyPI → npm, with rollback on failure
pypi_publish, npm_publish
woodpecker_trigger, woodpecker_status
audit_log_query — query the JSONL audit log by agent, tool, repo, or time range
Every tool call writes a JSONL entry before returning:
{
"ts": "2026-05-27T09:14:23.000Z",
"agent_id": "sysadmin",
"tool": "git_push",
"provider": "local",
"repo": "/home/ted/repos/personal/signoz-mcp",
"params": {"remote": "origin", "branch": "main"},
"result": "ok",
"duration_ms": 312,
"hmac": "a3f8..."
}Each entry is HMAC-SHA256 signed with AUDIT_SIGNING_KEY. The audit_log_query tool verifies every returned entry and includes tamper_detected: true on any entry that fails.
Example — what did the sysadmin agent push last week?
audit_log_query(agent_id="sysadmin", tool="git_push", since="2026-05-20")Write tools (git_add, git_commit, git_push, git_tag, git_checkout, git_branch create/delete, release) reject any path not under ALLOWED_REPO_ROOTS. Read tools accept any readable path. When ALLOWED_REPO_ROOTS is not set, write operations are disabled by default — fail closed, not open.
All local git operations use gitpython (Python library), not subprocess. This eliminates command injection risk via crafted repo_path or branch values.
Token values never appear in:
- JSONL audit entries (credential filter applied before write)
- structlog output (processor filter bound to logger)
- tool return values (masked before return)
- exception messages (caught at provider layer and re-raised without token value)
Each provider has its own env vars — a compromised GitHub token does not expose Gitea or GitLab credentials.
AUDIT_SIGNING_KEY (required) is a server-side secret set in the launcher. Each JSONL entry includes hmac: HMAC-SHA256(canonical_json, key). The audit_log_query tool verifies every returned entry. This is symmetric (same key signs and verifies) — it proves the file wasn't edited after write, not that the agent identity is genuine. Agent identity proof is the scoped-mcp layer's job.
AGENT_ID=dev # agent attribution — set per launcher
AUDIT_SIGNING_KEY=<32-byte-hex> # generate: python3 -c "import secrets; print(secrets.token_hex(32))"
ALLOWED_REPO_ROOTS=/home/user/repos/personal,/home/user/repos/workGITHUB_TOKEN=<PAT with repo scope>
GITHUB_OWNER=YourOrgGITEA_URL=https://gitea.example.com
GITEA_TOKEN=<PAT>
GITEA_OWNER=youruserGITLAB_URL=https://gitlab.com
GITLAB_TOKEN=<PAT>PYPI_TOKEN=<API token>
NPM_TOKEN=<automation token>LOG_FILE=/opt/appdata/githost-mcp/logs/githost-mcp.log
AUDIT_LOG_FILE=/opt/appdata/githost-mcp/audit/githost.jsonl# OTEL (SigNoz, Honeycomb, Grafana Tempo, Jaeger, Datadog — same env var)
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# Loki
LOKI_URL=http://localhost:3100
# Prometheus scrape endpoint
METRICS_PORT=9185
# NATS
NATS_URL=nats://localhost:4222pip install githost-mcp
# With observability extras
pip install "githost-mcp[observability]"#!/bin/bash
# run-githost-mcp-dev.sh
export AGENT_ID="dev"
export ALLOWED_REPO_ROOTS="/home/ted/repos/personal,/home/ted/repos/work"
export AUDIT_SIGNING_KEY="$(cat /run/secrets/githost_audit_key)"
export GITHUB_TOKEN="$(cat /run/secrets/github_token)"
export GITEA_TOKEN="$(cat /run/secrets/gitea_token)"
export LOG_FILE="/opt/appdata/githost-mcp/logs/githost-mcp.log"
export AUDIT_LOG_FILE="/opt/appdata/githost-mcp/audit/githost.jsonl"
exec /opt/agents/dev/venv/bin/python3 -m githost_mcp.server