MCP server for LocalGitHub: a lightweight local Git hosting service. Exposes 12 repository and server control tools over stdio, enabling AI assistants to manage local Git repositories, perform backups, run CI/CD, and interact with the LGH daemon.
LGH MCP server demonstrates solid definition quality with consistent naming conventions, comprehensive descriptions, and visible input schemas. All 13 tools follow the verb_noun pattern (lgh_status, lgh_list, lgh_add, etc.). Descriptions are well-crafted (averaging ~250 chars) and explain WHAT the tool does, WHEN to use it, and prerequisites. Input parameters are typed and described. However, output schemas are not explicitly documented in the source, they are mentioned in descriptions ('Returns JSON with...') but formal schema definitions are not visible in the code provided. Tool annotations (readOnlyHint, destructiveHint) are declared in feature flags and descriptions but not verified in actual tool registration. Error handling is mentioned descriptively but not formalized with recovery guidance patterns.
Fetch the most recent N lines of the ActionD daemon's log file (~/.localgithub/logs/actiond.log). Returns raw log text. Fails gracefully if ActionD is not installed or has never run (log file does not exist). Use this to debug CI/CD issues when triggered_job_ids from lgh_up suggest a job was spawned but you need to see why it failed.
Register a local Git repository with the LGH local server. Creates a bare repository under the LGH repos dir and adds an "lgh" remote pointing at it to the source repo. Initializes a git repo first if the directory is not one yet; refuses with an error if the path does not exist, the name is already registered, or a bare repo already exists at the target path. Returns the repository name and its clone URL. Use lgh_up to push subsequent commits and lgh_remove to unregister.
Clone a repository from the LGH local server into a new working directory on this machine — the restore side of the backup loop and the inverse of lgh_up. Use it to recover a working copy after data loss or to materialize an existing backup on a new machine: find the exact registered name with lgh_list, make sure the server is up (lgh_status, otherwise lgh_serve_start), then clone. The name may carry a .git suffix. Refuses with a clear error when the name is not registered, the server is not running, or the destination directory already exists and is not empty — it never overwrites existing files. Returns JSON with name, clone_url, destination (absolute path), and the checked-out branch and HEAD commit.
Show the unified diff (patch) of all pending uncommitted changes in a local Git repository. Use it to review exactly what will be committed before calling lgh_up or lgh_save. Works only in git repositories; fails with a clear error if the directory is not one. Returns the raw git diff output (unified format, --no-color) as a string.
Output schemas not formally documented. Descriptions state 'Returns JSON with...' but no explicit JSON Schema definitions for responses are visible in source code. LLMs cannot reliably parse undocumented response structures.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) claimed in feature flags but not verified in actual tool registration code. Without explicit annotation in tool definitions, MCP clients cannot programmatically detect which tools are safe to retry, destructive, or read-only.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | <=2025-11-25 | v2 |
List every Git repository registered with the LGH local server, each with its name, source_path (local working dir), bare_path, clone_url (LGH server URL), and created_at. Reads only the local registry under ~/.localgithub; no network access. Use it to discover the clone_url of an existing backup or the exact registered name required by lgh_remove. Returns a JSON array, empty when nothing is registered.
Show the git commit history (reflog) of a local Git repository, most recent first. Useful for understanding what commits exist locally before calling lgh_up or for tracing the history of a cloned repo. Works only in git repositories; fails with a clear error if the directory is not one. Returns the raw git log output (oneline format) as a string.
Unregister a repository from LGH. Deletes the bare backup repository from the LGH repos dir and removes the "lgh" remote from the local working directory; the local working tree and its git history are never touched. Fails with an error if the name is not registered. Destructive: the LGH-side backup copy and its history are permanently deleted and only come back by re-registering (lgh_add) and pushing again (lgh_up). Use lgh_list first to find the exact registered name.
Create a local checkpoint: ensures a .gitignore exists, then git add + git commit (no push) to the local git history only. Does not touch the LGH server. Use it to checkpoint work mid-project before risky changes, or as a frequent save point when lgh_up (push + CI) is overkill. Never auto-registers or initializes; fails if the directory is not a git repo. Aborts when trash detection finds blocking issues unless force is set. Returns JSON with success, output, and commit hash.
Start the LGH HTTP server in background (daemon mode). Fails with a clear error if the server is already running (use lgh_serve_stop first) or if the port is already in use. Logs all output to ~/.localgithub/logs/server.log. Returns JSON with success, server address, PID, and next steps. After this returns, check lgh_status to confirm the server is accepting connections; most tools require the server to be running.
Stop the LGH HTTP server (kill the daemon). Fails with a clear error if the server is not running. Gracefully closes all active connections and cleans up the PID file. Returns JSON with success and a shutdown message.
Get a unified health snapshot of the LGH server and the ActionD daemon. Aggregates LGH running state, PID, listen address, registered repo count, repos dir, and read-only flag, plus the ActionD daemon's running state and PID (probed via its PID file). Takes no arguments and reads only local state, so it is safe to call at any time. Use this to answer "is LGH up?"; use lgh_log when you need the historical runtime events that led to the current state. Returns pretty-printed JSON with top-level "lgh" and "actiond" objects.
One-click backup: ensures a .gitignore exists, then git add + git commit + git push to the LGH local server (localhost, NOT GitHub/GitLab). Auto-registers the repo with LGH and initializes git if needed, so it also works on a fresh directory. Aborts with an error when trash detection finds blocking issues (large files, .env secrets) unless force is set. If ActionD is running, the result includes event_id and triggered_job_ids for the CI jobs spawned by this push; use the ActionD server's dev_cycle_run tool when you need full job tracing. Returns JSON with success, output, project_type, commit, and optional triggered_job_ids.
Dry-run preview of lgh_up without touching any state: nothing is committed, pushed, registered, or written. Reports whether the directory is a git repo, the pending changed files, LGH registration status (or the name it would auto-register as), and trash-detection results including whether lgh_up would fail and why. Call this before lgh_up whenever you are unsure what a backup would include; use lgh_diff when you want the actual patch content instead of the changed-file list. Returns a JSON object with dry_run=true.
Error handling lacks recovery guidance. Descriptions mention failure conditions ('Fails with an error if...') but do not provide actionable next steps. E.g., lgh_clone 'Refuses with a clear error when the name is not registered', should suggest 'Use lgh_list to find registered names.'
lgh_up and lgh_save use 'force' boolean parameter without clear enum/constraint documentation. Descriptions say 'force' but do not explain what will be forced or what the default behavior prevents. Risk: LLM may misuse force flag.
Optional parameters like 'dest' in lgh_clone and 'path' in lgh_diff/lgh_log/lgh_save default to 'current directory' or './<name>' but this is ambiguous in a remote/agent context. No explicit validation that paths are absolute or within safe boundaries mentioned.