Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
551777f
Enhance Git server with repository path security and improved configu…
sparesparrow Feb 16, 2025
879a168
Merge branch 'main' into bug-604
sparesparrow Mar 14, 2025
189c512
Merge branch 'modelcontextprotocol:main' into bug-604
sparesparrow Mar 14, 2025
6f21d6e
Merge branch 'main' into bug-604
sparesparrow Mar 24, 2025
1e8312a
Merge main into bug-604: Resolve conflicts and integrate security imp…
olaservo Jul 8, 2025
6c8ff9b
Fix pyright failures
olaservo Jul 8, 2025
51fc1d7
Merge branch 'main' into bug-604
olaservo Jul 8, 2025
0e4243e
Remove unnecessary async
olaservo Jul 10, 2025
cc74e99
Merge branch 'bug-604' of https://github.com/sparesparrow/mcp-servers…
olaservo Jul 10, 2025
cb54172
Update sdk version and lock file
olaservo Jul 10, 2025
e045250
Merge branch 'main' into bug-604
cliffhall Jul 15, 2025
87aaebb
Merge remote-tracking branch 'upstream/main' into bug-604
Jul 20, 2025
a038f03
Added section Testing to src/git/README.md.
Jul 20, 2025
bfb4feb
Merge branch 'main' into bug-604
sparesparrow Jul 22, 2025
58c92a7
Merge branch 'main' into bug-604
sparesparrow Jul 30, 2025
a494504
Merge branch 'main' into bug-604
cliffhall Aug 1, 2025
4c192ae
Remove out-of-specification notifications/stderr sending
evalstate Aug 2, 2025
b43ecf8
1) Update README to contain basic build/run instructions. Remove lega…
evalstate Aug 2, 2025
3a297d8
Revert "1) Update README to contain basic build/run instructions. Rem…
evalstate Aug 2, 2025
496e8eb
1) Update README to contain basic build/run instructions. Remove lega…
evalstate Aug 2, 2025
c1a3833
make test insensitive to default branch name, update README
evalstate Aug 2, 2025
e45c34e
Merge branch 'fix/mcp-git-tests' of https://github.com/modelcontextpr…
evalstate Aug 2, 2025
6538527
upgrade libraries to latest
evalstate Aug 2, 2025
8400604
type checking error fixes
evalstate Aug 2, 2025
3958f00
Merge remote-tracking branch 'origin/fix/mcp-git-tests' into pr/spare…
evalstate Aug 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions src/everything/everything.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,18 +209,6 @@ export const createServer = () => {
}, 20000);


// Set up update interval for stderr messages
stdErrUpdateInterval = setInterval(() => {
const shortTimestamp = new Date().toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
});
server.notification({
method: "notifications/stderr",
params: { content: `${shortTimestamp}: A stderr message` },
});
}, 30000);

// Helper method to request sampling from client
const requestSampling = async (
Expand Down
2 changes: 1 addition & 1 deletion src/git/.python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.10
3.13
64 changes: 33 additions & 31 deletions src/git/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ A Model Context Protocol server for Git repository interaction and automation. T

Please note that mcp-server-git is currently in early development. The functionality and available tools are subject to change and expansion as we continue to develop and improve the server.

### Repository Path Security

When running the server with the `--repository` flag, all Git operations are restricted to that specific repository path, regardless of any `repo_path` values provided in tool calls. This provides an important security boundary:

- The server will reject any attempts to access paths outside the configured repository
- All tool operations that accept a `repo_path` parameter will ignore it and use the configured repository instead
- Path traversal attempts (e.g., using `../`) are blocked
- If no repository is configured, the server requires explicit repository paths for each operation

This makes it safe to expose the server to untrusted clients while maintaining control over which repositories they can access.

### Tools

1. `git_status`
Expand Down Expand Up @@ -68,7 +79,7 @@ Please note that mcp-server-git is currently in early development. The functiona
- Inputs:
- `repo_path` (string): Path to Git repository
- `branch_name` (string): Name of the new branch
- `start_point` (string, optional): Starting point for the new branch
- `base_branch` (string, optional): Starting point (branch name or commit hash) for the new branch. Defaults to the current active branch.
- Returns: Confirmation of branch creation
10. `git_checkout`
- Switches branches
Expand Down Expand Up @@ -285,13 +296,29 @@ help you debug any issues.

## Development

If you are doing local development, there are two ways to test your changes:
### Building

1. Run the MCP inspector to test your changes. See [Debugging](#debugging) for run instructions.
[`uv`](https://docs.astral.sh/uv/) is used for development.

Start by creating a fresh virtual environment:

```bash
uv venv
source .venv/bin/activate
```
To run the tests, type `uv run pytest`, to run the server from source use `uv run src/mcp_server_git/`.

2. Test using the Claude desktop app. Add the following to your `claude_desktop_config.json`:
To build, type `uv build`. You can then now run `mcp-server-git` command directly. Open with the inspector using `npx @modelcontextprotocol/inspector@latest mcp-server-git`.

### Docker
To specify the Python version type `uv python pin <version>` (useful if you want to use a more recent version than the default).

To create the Docker container use

```bash
docker build -t mcp/git .
```

An example showing how to run via the Docker container is below:

```json
{
Expand All @@ -310,34 +337,9 @@ If you are doing local development, there are two ways to test your changes:
}
}
}
```

### UVX
```json
{
"mcpServers": {
"git": {
"command": "uv",
"args": [
"--directory",
"/<path to mcp-servers>/mcp-servers/src/git",
"run",
"mcp-server-git"
]
}
}
}
```

## Build

Docker build:

```bash
cd src/git
docker build -t mcp/git .
```

## License

This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.

10 changes: 5 additions & 5 deletions src/git/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "mcp-server-git"
version = "0.6.2"
description = "A Model Context Protocol server providing tools to read, search, and manipulate Git repositories programmatically via LLMs"
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.13"
authors = [{ name = "Anthropic, PBC." }]
maintainers = [{ name = "David Soria Parra", email = "davidsp@anthropic.com" }]
keywords = ["git", "mcp", "llm", "automation"]
Expand All @@ -16,10 +16,10 @@ classifiers = [
"Programming Language :: Python :: 3.10",
]
dependencies = [
"click>=8.1.7",
"gitpython>=3.1.43",
"mcp>=1.0.0",
"pydantic>=2.0.0",
"click>=8.2.2",
"gitpython>=3.1.45",
"mcp>=1.12.3",
"pydantic>=2.11.7",
]

[project.scripts]
Expand Down
40 changes: 30 additions & 10 deletions src/git/src/mcp_server_git/__init__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
import asyncio
import click
from pathlib import Path
import logging
from pathlib import Path
import sys
import signal
from .server import serve

def handle_sigint():
for task in asyncio.all_tasks():
task.cancel()

@click.command()
@click.option("--repository", "-r", type=Path, help="Git repository path")
@click.option("-v", "--verbose", count=True)
def main(repository: Path | None, verbose: bool) -> None:
@click.option(
"--repository",
type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
help="Path to Git repository to operate on",
)
@click.option("-v", "--verbose", count=True, default=0)
def main(repository: Path | None, verbose: int = 0) -> None:
"""MCP Git Server - Git functionality for MCP"""
import asyncio

logging_level = logging.WARN
if verbose == 1:
logging_level = logging.INFO
elif verbose >= 2:
elif verbose > 1:
logging_level = logging.DEBUG

logging.basicConfig(level=logging_level, stream=sys.stderr)
asyncio.run(serve(repository))
logging.basicConfig(level=logging_level)

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

# Set up signal handlers
loop.add_signal_handler(signal.SIGINT, handle_sigint)
loop.add_signal_handler(signal.SIGTERM, handle_sigint)

try:
loop.run_until_complete(serve(repository))
except asyncio.CancelledError:
logging.info("Server shutdown initiated")
finally:
loop.close()

if __name__ == "__main__":
main()
Loading