Content
# MCP Git Tools
Git tools implementation for the Model Context Protocol (MCP).
[中文文档](README_CN.md)
## Features
This library provides a set of Git operations that can be called through the Model Context Protocol:
- `git_status` - Get the status of a repository
- `git_branches` - List branch information
- `git_log` - Get commit history with flexible filtering options (by time, author, branch, count)
- `git_commit` - Create a new commit
- `git_pull` - Pull changes from remote
- `git_push` - Push changes to remote
- `git_diff` - View file differences
- `git_add` - Add file contents to the staging area
- `git_reset` - Reset the staging area or working tree to a specified state
- `git_worktree_list` - List all worktrees
- `git_worktree_add` - Create a new worktree
- `git_worktree_remove` - Remove a worktree
- `git_worktree_prune` - Prune expired worktree files
## Installation
```bash
# Clone the repository
git clone https://gitcode.com/lileeei/mcp-git-tools.git
# Navigate to the directory
cd mcp-git-tools
# Build
cargo build --release
```
## Usage
### Run as a standalone server
```bash
cargo run --release --bin mcp-git-server
```
This starts an MCP server that interacts with clients through standard input/output.
### Test with MCP Inspector
1. Build the server:
```bash
cargo build --release
```
2. Start the server:
```bash
./target/release/mcp-git-server
```
3. Use MCP Inspector to test the tools:
- Download MCP Inspector: https://github.com/modelcontextprotocol/inspector
- Click "Add a server"
- Enter: `/path/to/mcp-git-server/target/release/mcp-git-server`
- Click "Add"
- Test each tool using the Inspector interface
## Architecture
This project uses the modern RMCP SDK (v0.14.0) with a clean architecture:
### Core Components
**GitToolsHandler**
- Central handler struct for all Git operations
- Implements `ServerHandler` trait from RMCP SDK
- Contains methods for each Git operation
**ServerHandler Implementation**
- `get_info()` - Provides server metadata and capabilities
- `list_tools()` - Lists all available tools with their schemas
- `call_tool()` - Routes tool calls to appropriate handler methods
### Tool Implementation Pattern
Each tool is implemented as a method on `GitToolsHandler`:
```rust
impl GitToolsHandler {
#[tool(description = "Get the status of a git repository")]
pub async fn git_status(
&self,
repo_path: String,
) -> Result<CallToolResult> {
// Implementation
}
}
```
### Parameter Handling
All tool parameters use derive macros for automatic schema generation:
```rust
#[derive(serde::Deserialize, schemars::JsonSchema)]
struct GitStatusParams {
repo_path: String,
}
```
This provides:
- Automatic JSON schema generation
- Type-safe parameter parsing
- No manual serialization/deserialization code
### Transport
Uses RMCP's `stdio()` transport for standard input/output communication.
## Tool Details
### git_status
Get the status of a repository.
**Parameters:**
- `repo_path` - Path to the Git repository
**Returns:**
```json
{
"status": ["M file1.txt", "?? file2.txt"],
"is_clean": false
}
```
### git_branches
List all branches.
**Parameters:**
- `repo_path` - Path to the Git repository
**Returns:**
```json
{
"branches": ["* main", "develop", "feature/new-feature"],
"current": "main"
}
```
### git_log
Get commit history with flexible filtering options.
**Parameters:**
- `repo_path` - Path to Git repository
- `max_count` - (optional) Maximum number of commits to return
- `branch` - (optional) Branch name
- `since` - (optional) Start date (e.g., "2023-01-01", "1 week ago", "yesterday")
- `until` - (optional) End date (e.g., "2023-01-31", "today")
- `author` - (optional) Filter by specific author (matches name or email)
**Returns:**
```json
{
"commits": [
{
"hash": "abcd1234",
"author": "User Name",
"author_date": "Mon Aug 1 10:00:00 2023 +0800",
"message_title": "Initial commit"
}
]
}
```
**Examples:**
- Get recent 10 commits: `{"repo_path": ".", "max_count": 10}`
- Get commits from last week: `{"repo_path": ".", "since": "1 week ago"}`
- Get commits by author: `{"repo_path": ".", "author": "John"}`
- Get commits from a time range: `{"repo_path": ".", "since": "2023-01-01", "until": "2023-12-31"}`
### git_commit
Create a new commit.
**Parameters:**
- `repo_path` - Path to the Git repository
- `message` - Commit message
- `all` - (optional) Whether to automatically stage modified files
**Returns:**
```json
{
"success": true,
"hash": "abcd1234",
"message": "feat: Add new feature",
"output": "[main abcd1234] feat: Add new feature\n 1 file changed, 10 insertions(+), 2 deletions(-)"
}
```
### git_pull
Pull changes from remote.
**Parameters:**
- `repo_path` - Path to the Git repository
- `remote` - (optional) Remote name, defaults to "origin"
- `branch` - (optional) Branch name
**Returns:**
```json
{
"success": true,
"remote": "origin",
"output": "Updating abcd1234..efgh5678\nFast-forward\n file1.txt | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)"
}
```
### git_push
Push changes to remote.
**Parameters:**
- `repo_path` - Path to the Git repository
- `remote` - (optional) Remote name, defaults to "origin"
- `branch` - (optional) Branch name
- `force` - (optional) Whether to force push
**Returns:**
```json
{
"success": true,
"remote": "origin",
"output": "To github.com:user/repo.git\n abcd1234..efgh5678 main -> main"
}
```
### git_diff
View file differences.
**Parameters:**
- `repo_path` - Path to the Git repository
- `path` - (optional) Path to file or directory
- `staged` - (optional) Whether to show staged changes
- `commit` - (optional) Commit to compare against
**Returns:**
```json
{
"changes": "diff --git a/file.txt b/file.txt\nindex 1234567..abcdefg 100644\n--- a/file.txt\n+++ b/file.txt\n@@ -1,3 +1,4 @@\n Line 1\nLine 2\nLine 3\n+New line\nLine 4"
}
```
### git_add
Add file contents to the staging area.
**Parameters:**
- `repo_path` - Path to the Git repository
- `path` - Path(s) to add, or patterns to match. Use '.' for all files.
- `update` - (optional) Whether to update, rather than add
- `all` - (optional) Whether to add all changes, including untracked files
**Returns:**
```json
{
"success": true,
"message": "Files staged successfully",
"status": ["M file1.txt", "A file2.txt"]
}
```
### git_reset
Reset the staging area or working tree to a specified state.
**Parameters:**
- `repo_path` - Path to the Git repository
- `path` - Path(s) to reset, or patterns to match. Use '.' for all files.
- `hard` - (optional) Whether to perform a hard reset (WARNING: discards all local changes)
- `target` - (optional) The commit or branch to reset to (defaults to HEAD)
**Returns:**
```json
{
"success": true,
"message": "Files unstaged successfully",
"status": ["?? file1.txt", "?? file2.txt"]
}
```
### git_worktree_list
List all worktrees in a repository.
**Parameters:**
- `repo_path` - Path to the Git repository
**Returns:**
```json
{
"worktrees": [
{
"id": "worktree-name",
"path": "/path/to/worktree",
"locked": false,
"lock_reason": null
}
]
}
```
### git_worktree_add
Create a new worktree.
**Parameters:**
- `repo_path` - Path to the Git repository
- `path` - Path for the new worktree
- `branch` - (optional) Branch name to create
- `commit_ref` - (optional) Commit reference to check out
- `checkout` - (optional) Whether to check out files, defaults to true
**Returns:**
```json
{
"success": true,
"path": "/path/to/new/worktree",
"branch": "feature-branch",
"output": "Preparing worktree (checking out 'feature-branch')"
}
```
### git_worktree_remove
Remove a worktree.
**Parameters:**
- `repo_path` - Path to the Git repository
- `path` - Path to the worktree to remove
- `force` - (optional) Force removal even if worktree is dirty
**Returns:**
```json
{
"success": true,
"path": "/path/to/worktree",
"force": false,
"output": "Removing worktrees/feature-branch"
}
```
### git_worktree_prune
Prune working tree files in $GIT_DIR/worktrees.
**Parameters:**
- `repo_path` - Path to the Git repository
- `verbose` - (optional) Report all removals
- `dry_run` - (optional) Do not remove, show only
**Returns:**
```json
{
"success": true,
"verbose": false,
"dry_run": false,
"output": "Pruning worktrees/feature-branch"
}
```
## Development
### Project Structure
```
mcp-git-tools/
├── Cargo.toml # Dependencies and project configuration
├── src/
│ ├── lib.rs # Core library with GitToolsHandler
│ └── bin/
│ └── server.rs # Server entry point
├── tests/
│ └── lib_tests.rs # Unit tests
```
### Building
```bash
# Debug build
cargo build
# Release build
cargo build --release
# Run tests
cargo test
# Run server
cargo run --release --bin mcp-git-server
```
### Adding New Tools
To add a new Git tool:
1. Add the parameter struct in `src/lib.rs`:
```rust
#[derive(serde::Deserialize, schemars::JsonSchema)]
struct GitMyToolParams {
repo_path: String,
// other parameters...
}
```
2. Add the method in the `GitToolsHandler` impl block:
```rust
#[tool(description = "Description of your tool")]
pub async fn git_my_tool(
&self,
repo_path: String,
// other parameters...
) -> Result<CallToolResult> {
// Implementation
}
```
3. Update the `list_tools()` method to include your new tool in the returned list
## Dependencies
- `rmcp` v0.14.0 - The official RMCP SDK
- `tokio` - Async runtime
- `serde` - Serialization framework
- `serde_json` - JSON implementation
- `anyhow` - Error handling
- `tracing` - Logging framework
- `tempfile` - Testing utilities
## License
MIT License
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.