GitIntel
by hoangsonww
README.md
# GitIntel - A Git Intelligence MCP Server for AI Agents

















**Git Intelligence MCP Server** - deep repository analytics computed locally from your commit history.
Surfaces the same insights that tools like CodeScene and GitPrime charge for: hotspots, temporal coupling, knowledge maps, churn analysis, complexity trends, risk scoring, and more. Everything runs locally. No external APIs, no data leaves your machine.
This is a **locally-built MCP server**. It is not published to npm. You clone, build, and register it with your MCP client & AI agents (Claude Code, Codex, etc.).
```
You: "Analyze this repo -- show me hotspots, risk, and who knows the auth module best."
Claude: [calls hotspots, risk_assessment, knowledge_map in parallel, returns formatted analysis]
```
---
## Architecture
GitIntel is a standalone MCP server that exposes a suite of tools and resources for analyzing git repositories. It communicates with any MCP client (Claude Code, Codex, etc.) over stdio using JSON-RPC.
```mermaid
graph LR
A[MCP Client<br/>Claude Code / Codex] <-->|stdio<br/>JSON-RPC| B[mcp-git-intel<br/>MCP Server]
B -->|execFile| C[Git CLI]
C --> D[Repository<br/>.git]
B --> E[Analysis Engine<br/>scoring, formatting]
```
All communication happens over **stdio** using the Model Context Protocol. The server calls Git via `execFile` (never `exec`) to prevent shell injection. All operations are **strictly read-only**.
---
## Tools
12 analysis tools, each returning formatted tables, score bars, and actionable recommendations -- not raw git output.
```mermaid
graph TD
subgraph "Change Analysis"
H[hotspots<br/>Change frequency]
CH[churn<br/>Write/rewrite ratio]
CT[complexity_trend<br/>Complexity over time]
end
subgraph "Dependency Analysis"
CO[coupling<br/>Temporal coupling]
end
subgraph "Team Analysis"
KM[knowledge_map<br/>Who knows what]
CS[contributor_stats<br/>Team dynamics]
CP[commit_patterns<br/>Work patterns]
end
subgraph "Risk & Release"
RA[risk_assessment<br/>Change risk scoring]
RN[release_notes<br/>Changelog generation]
BR[branch_risk<br/>Branch health]
end
subgraph "Code Archaeology"
FH[file_history<br/>File evolution]
CA[code_age<br/>Staleness map]
end
```
| Tool | What it does | Key insight |
|------|-------------|-------------|
| `hotspots` | Files that change most frequently | Top 4% of files by change frequency contain 50%+ of bugs |
| `churn` | Code written then rewritten (additions vs deletions) | Churn ratio near 1.0 = code rewritten as fast as it's written |
| `coupling` | Files that always change together | Hidden dependencies not visible in imports |
| `knowledge_map` | Who knows a file/directory best, weighted by recency | Find the right reviewer, spot knowledge silos |
| `complexity_trend` | How a file's complexity evolves over time | Catch files growing out of control |
| `risk_assessment` | Risk score (0-100) for uncommitted or committed changes | Combines hotspot history, size, sensitivity, spread |
| `release_notes` | Structured changelog from conventional commits | Groups by type, extracts breaking changes and PR refs |
| `contributor_stats` | Team dynamics, collaboration graph, knowledge silos | Workload distribution, onboarding planning |
| `file_history` | Full commit history of a single file with rename tracking | Trace why a file looks the way it does |
| `code_age` | Age map showing when each file was last modified | Find dead code, abandoned features, stable infrastructure |
| `commit_patterns` | Day-of-week, hour-of-day, commit size distributions | Spot weekend work, late-night hotfixes, oversized commits |
| `branch_risk` | Branch staleness, divergence, and merge risk analysis | Branch hygiene, cleanup candidates, merge planning |
## Data Pipeline
Each tool transforms raw git output through a multi-stage pipeline:
```mermaid
graph LR
A["Git CLI<br/>raw output"] -->|parse| B["Structured Data<br/>LogEntry[], stats"]
B -->|score| C["Scored Results<br/>normalized 0-100"]
C -->|format| D["Formatted Output<br/>tables, bars, text"]
D -->|wrap| E["MCP Response<br/>CallToolResult"]
```
## Resources
Resources are pre-computed summaries or feeds that can be read directly without arguments. Useful for quick snapshots or embedding into prompts.
| Resource URI | Description |
|-------------|-------------|
| `git://repo/summary` | Repository snapshot: branch, last commit, total commits, active contributors, top languages, age, remote |
| `git://repo/activity` | Recent 50-commit activity feed with stats |
---
## Installation
This server is **not published to npm**. You must clone, build, and register it locally.
### Prerequisites
- **Node.js** >= 18
- **Git** >= 2.20
### Build from source
```bash
git clone https://github.com/hoangsonww/GitIntel-MCP-Server.git
cd GitIntel-MCP-Server
npm install
npm run build
```
### Register with Claude Code
> [!IMPORTANT]
> **Important**: For best results, always open Claude Code inside a git repository directory. The server auto-detects the repo from your working directory. If you open Claude Code from a non-repo folder (e.g. your home directory), you will need to pass `repo_path` to every tool call manually.
**Quick registration (analyzes cwd by default):**
```bash
claude mcp add git-intel -- node /absolute/path/to/mcp-server/dist/index.js
```
**With a specific repository:**
```bash
claude mcp add git-intel -- node /absolute/path/to/mcp-server/dist/index.js /path/to/your/repo
```
### Register with any MCP client (manual JSON)
Add to your MCP client's configuration file (e.g. `~/.claude.json` for Claude Code global config):
```json
{
"mcpServers": {
"git-intel": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"],
"env": {}
}
}
}
```
**With a pinned default repository** (optional — useful if you always analyze the same repo):
```json
{
"mcpServers": {
"git-intel": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"],
"env": {
"GIT_INTEL_REPO": "/path/to/your/repo"
}
}
}
}
```
> [!TIP]
> **Tip**: The `~` home directory expansion works in the repo path argument (e.g. `~/projects/my-repo`).
>
> **Also**: When registered globally (in `~/.claude.json`), the server auto-detects the git repo in your current working directory. No `GIT_INTEL_REPO` needed — just open Claude Code inside any git repo.
---
## Configuration
### Default Repository Resolution
The server determines which git repository to use as the **default** using this priority order:
| Priority | Method | Example |
|----------|--------|---------|
| 1 | CLI argument | `node dist/index.js /path/to/repo` |
| 2 | Environment variable | `GIT_INTEL_REPO=/path/to/repo` |
| 3 | Current working directory | Falls back to `process.cwd()` |
The `~` prefix is expanded to the user's home directory in all path inputs.
### Per-Tool `repo_path` Override
Every tool accepts an optional **`repo_path`** parameter that overrides the default repository for that specific call. This allows analyzing any repository on disk without reconfiguring the server:
```json
{ "repo_path": "C:/Users/you/other-project", "days": 90 }
```
### Resilient Startup (No-Crash Mode)
The server **never crashes** on startup, even when launched from a non-git directory. Instead:
1. If a git repository is found, it becomes the default for all tools.
2. If **no git repository** is found, the server starts anyway with no default repo. Tools require the `repo_path` parameter to specify which repo to analyze.
3. Resources (`git://repo/summary`, `git://repo/activity`) return informative messages directing the user to open Claude Code inside a git repo or use `repo_path`.
```mermaid
flowchart TD
Start["Server starts"] --> CheckRepo{"Is cwd a\ngit repo?"}
CheckRepo -->|Yes| Default["Set as default repo\nAll tools work immediately"]
CheckRepo -->|No| NoDefault["Start with no default\nTools require repo_path"]
Default --> Ready["Server ready\n12 tools, 2 resources"]
NoDefault --> Ready
Ready --> Call{"Tool called"}
Call --> HasArg{"repo_path\nprovided?"}
HasArg -->|Yes| UseArg["Use repo_path"]
HasArg -->|No| HasDefault{"Default repo\navailable?"}
HasDefault -->|Yes| UseDefault["Use default repo"]
HasDefault -->|No| Error["Return helpful error:\n'Open Claude Code in a git repo\nor pass repo_path'"]
UseArg --> Execute["Execute git analysis"]
UseDefault --> Execute
```
This design means the server works as a **global MCP server** in Claude Code — it connects successfully regardless of which project directory you open.
---
## Usage Examples
Once registered, the tools are available through natural language. You do not call them directly -- the AI client decides which tools to invoke based on your prompt.
**Find bug-prone files:**
> "Show me the change hotspots in the last 60 days"
**Analyze code stability:**
> "What's the churn analysis for the src/api directory over the last quarter?"
**Find hidden dependencies:**
> "Which files are temporally coupled with src/auth/login.ts?"
**Find the right reviewer:**
> "Who knows the src/api directory best?"
**Track complexity growth:**
> "Show me the complexity trend for src/services/payment.ts"
**Assess change risk before merging:**
> "What's the risk assessment for the uncommitted changes?"
> "Assess the risk of changes between main and feature-branch"
**Generate release notes:**
> "Generate release notes from v1.0.0 to HEAD"
**Understand team dynamics:**
> "Show me contributor statistics for the last 6 months"
> "Who are the top collaborators and where are the knowledge silos?"
**Trace a file's evolution:**
> "Show me the full history of src/auth/login.ts"
**Find stale or abandoned code:**
> "What are the oldest files in the src/ directory?"
> "Show me code age analysis for the project"
**Analyze work patterns:**
> "What are the commit patterns for the last 3 months?"
> "When does the team usually commit?"
**Branch hygiene:**
> "Which branches are stale or highly diverged?"
> "Show me branch risk analysis against main"
**Full repo analysis:**
> "Using git-intel, give me a comprehensive analysis of this repository"
See [`docs/EXAMPLES.md`](docs/EXAMPLES.md) for a complete real-world transcript of a full repo analysis session.
---
## Development
```mermaid
graph LR
subgraph "Development"
Dev["npm run dev<br/>tsx auto-reload"]
CLI["npm run cli<br/>Interactive REPL"]
end
subgraph "Testing"
Unit["npm test<br/>Vitest unit tests"]
Smoke["npm run smoke<br/>Full integration"]
end
subgraph "Quality"
Lint["npm run lint<br/>tsc --noEmit"]
Fmt["npm run format<br/>Prettier"]
end
subgraph "Ship"
Build["npm run build<br/>TypeScript → dist/"]
end
Dev --> Unit --> Lint --> Build
CLI --> Smoke
```
```bash
npm run dev # Run server with tsx (auto-reload, uses cwd as repo)
npm run cli # Interactive REPL for testing tools and resources
npm run smoke # Automated smoke test -- runs every tool and resource
npm test # Run unit tests (vitest)
npm run test:watch # Watch mode
npm run lint # Type check (tsc --noEmit)
npm run build # Compile TypeScript to dist/
```
### CLI REPL
The interactive CLI (`npm run cli`) spawns the MCP server as a child process, connects as a real MCP client over stdio, and provides a REPL for calling tools and reading resources.
```mermaid
sequenceDiagram
participant User as Developer
participant CLI as cli.ts (MCP Client)
participant Server as index.ts (MCP Server)
participant Git as Git CLI
User->>CLI: npm run cli [repo_path]
CLI->>Server: Spawn via StdioClientTransport
Server-->>CLI: Connected (JSON-RPC over stdio)
CLI->>User: git-intel> prompt
User->>CLI: call hotspots {"days": 60}
CLI->>Server: callTool("hotspots", {days: 60})
Server->>Git: git log --since=...
Git-->>Server: raw output
Server-->>CLI: formatted analysis
CLI->>User: Display result + elapsed time
User->>CLI: read git://repo/summary
CLI->>Server: readResource("git://repo/summary")
Server-->>CLI: repo snapshot
CLI->>User: Display result
User->>CLI: exit
CLI->>Server: close()
```
**Start the CLI:**
```bash
npm run cli # Uses current directory as repo
npm run cli ~/projects/myapp # Analyze a specific repo
```
**Available commands:**
| Command | Description |
|---------|-------------|
| `tools` | List all registered tools with parameters |
| `resources` | List all registered resources |
| `call <tool> [json]` | Call a tool with optional JSON arguments |
| `read <uri>` | Read a resource by URI |
| `help` | Show help |
| `exit` / `quit` / `q` | Quit the CLI |
**Example session:**
```
git-intel> tools
Available tools (12):
hotspots Identify files that change most frequently...
params: repo_path, days, limit, path_filter
churn Analyze code churn...
params: repo_path, days, limit, path_filter
...
git-intel> call hotspots {"days": 60, "limit": 5}
Calling hotspots...
(42ms)
## Change Hotspots (last 60 days)
File Changes Authors Last Changed Heat
-------------------- ------- ------- ------------ ---------------
src/index.ts 12 2 2026-03-08 [██████████] 100
src/tools/risk.ts 8 1 2026-03-07 [██████░░░░] 67
...
git-intel> call knowledge_map {"path": "src/auth"}
Calling knowledge_map...
(38ms)
## Knowledge Map: src/auth (last 365 days)
...
git-intel> call risk_assessment
Calling risk_assessment...
(125ms)
## Risk Assessment: uncommitted changes
...
git-intel> read git://repo/summary
Reading git://repo/summary...
(15ms)
Branch: master
Last commit: c4934239 by dav nguyxn on 2026-03-09
...
git-intel> exit
Bye.
```
See [`docs/CLI.md`](docs/CLI.md) for the full CLI reference.
> [!TIP]
> This is useful for manual testing and debugging without needing to go through an AI client.
### Smoke Test
`npm run smoke` connects to the server and calls every tool and every resource against the current repo, printing all results. Useful for verifying nothing is broken after changes.
---
## Security Model
```mermaid
graph LR
Input["User / AI Input"] --> V1["validatePathFilter()<br/>Blocks .. and abs paths"]
Input --> V2["validateRef()<br/>Strict char whitelist"]
V1 --> Safe["Sanitized Args<br/>(string array)"]
V2 --> Safe
Safe --> ExecFile["execFile()<br/>No shell involved"]
ExecFile --> Git["Git CLI<br/>read-only commands only"]
Git --> Repo[".git<br/>No writes ever"]
subgraph "Environment Hardening"
E1["GIT_TERMINAL_PROMPT=0"]
E2["GIT_PAGER=''"]
E3["LC_ALL=C"]
E4["30s timeout"]
E5["50MB buffer limit"]
end
ExecFile -.-> E1 & E2 & E3 & E4 & E5
```
| Concern | Mitigation |
|---------|------------|
| Shell injection | All git commands use `execFile` (array args, no shell interpolation) |
| Path traversal | `validatePathFilter()` blocks `..` and absolute paths |
| Ref injection | `validateRef()` validates git refs against a strict character whitelist |
| Write operations | Strictly read-only. No tool modifies the repository in any way |
| Network access | No external network calls. All data is local |
| Git safety | `GIT_TERMINAL_PROMPT=0` prevents interactive prompts; `GIT_PAGER=''` disables pagers |
| Timeouts | 30-second default timeout on all git commands |
| Buffer limits | 50MB max buffer to prevent memory exhaustion |
We take security seriously. This server is designed to be safe to run on any machine with access to git repositories. Here are the key mitigations for potential attack vectors:
| Concern | Mitigation |
|------------------|--------------------------------------------------------------------------------------|
| Shell injection | All git commands use `execFile` (array args, no shell interpolation) |
| Path traversal | `validatePathFilter()` blocks `..` and absolute paths |
| Ref injection | `validateRef()` validates git refs against a strict character whitelist |
| Write operations | Strictly read-only. No tool modifies the repository in any way |
| Network access | No external network calls. All data is local |
| Git safety | `GIT_TERMINAL_PROMPT=0` prevents interactive prompts; `GIT_PAGER=''` disables pagers |
| Timeouts | 30-second default timeout on all git commands |
| Buffer limits | 50MB max buffer to prevent memory exhaustion |
---
## Project Structure
The code is organized into clear modules for git interaction, analysis tools, resources, and utilities. The entry point (`index.ts`) sets up the MCP server and registers all tools and resources.
```
src/
index.ts Entry point, server setup, tool/resource registration (resilient startup)
cli.ts Interactive REPL for testing
smoke-test.ts Automated smoke test
git/
executor.ts Safe git command runner (execFile, timeouts, env)
parser.ts Git output parsers (log, numstat, conventional commits)
repo.ts Repo validation, path/ref sanitization
tools/
hotspots.ts Change frequency analysis
churn.ts Code churn (additions vs deletions)
coupling.ts Temporal coupling detection
knowledge-map.ts Knowledge scoring per author
complexity.ts Complexity trend over time
risk.ts Multi-factor risk assessment
release-notes.ts Changelog from conventional commits
contributors.ts Contributor analytics and collaboration
file-history.ts Single-file evolution with rename tracking
code-age.ts File staleness and age distribution
commit-patterns.ts Work pattern analytics (time, size)
branch-risk.ts Branch staleness and divergence detection
resources/
summary.ts Repository snapshot resource (graceful degradation)
activity.ts Recent commit activity feed (graceful degradation)
util/
scoring.ts Normalization, recency decay, coupling, risk scoring
formatting.ts Tables, score bars, text output helpers
resolve-repo.ts Per-call repo resolution with fallback chain and error messages
```
---
## Further Documentation
This README provides a high-level overview. For deeper technical details, see:
- **[`ARCHITECTURE.md`](ARCHITECTURE.md)** -- Deep technical architecture, design decisions, module dependencies
- **[`docs/TOOLS.md`](docs/TOOLS.md)** -- Detailed reference for every tool (schemas, examples, interpretation)
- **[`docs/CLI.md`](docs/CLI.md)** -- Full CLI reference with all commands, parameters, and examples
- **[`docs/EXAMPLES.md`](docs/EXAMPLES.md)** -- Real-world usage transcript showing a full repo analysis session
## License
MIT. See [LICENSE](LICENSE) for details.
## Author
Created by [Son Nguyen](https://sonnguyenhoang.com) in 2026. Contributions are welcome! See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for guidelines.
TDQS
A4.4/5.0
Scored across 12 tools
Disambiguation5/5
Each tool targets a distinct aspect of git analytics such as churn, coupling, contributor stats, and code age, with no functional overlap.
Naming Consistency5/5
All tool names are descriptive nouns or noun compounds in lowercase snake_case, following a consistent pattern (e.g., knowledge_map, commit_patterns).
Tool Count5/5
12 tools is well-scoped for a git intelligence server, covering analysis, risk, history, and collaboration without being overwhelming.
Completeness5/5
The toolset comprehensively covers code metrics, change patterns, ownership, risk, and history, with no obvious gaps for typical git analysis tasks.
Maintenance
ActivityInactive
ResponsivenessNo issues