Merge pull request #2757 from 0dd/security/git-server-optimization

Fix: Git Server Path Restriction
This commit is contained in:
Cliff Hall 2025-09-24 10:07:03 -04:00 • committed by GitHub
commit 582bc1d58f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 6 additions and 29 deletions

View file

@ -84,13 +84,8 @@ Please note that mcp-server-git is currently in early development. The functiona
- `repo_path` (string): Path to Git repository - `repo_path` (string): Path to Git repository
- `revision` (string): The revision (commit hash, branch name, tag) to show - `revision` (string): The revision (commit hash, branch name, tag) to show
- Returns: Contents of the specified commit - Returns: Contents of the specified commit
12. `git_init`
- Initializes a Git repository
- Inputs:
- `repo_path` (string): Path to directory to initialize git repo
- Returns: Confirmation of repository initialization
13. `git_branch` 12. `git_branch`
- List Git branches - List Git branches
- Inputs: - Inputs:
- `repo_path` (string): Path to the Git repository. - `repo_path` (string): Path to the Git repository.

View file

@ -70,8 +70,7 @@ class GitShow(BaseModel):
repo_path: str repo_path: str
revision: str revision: str
class GitInit(BaseModel):
repo_path: str
class GitBranch(BaseModel): class GitBranch(BaseModel):
repo_path: str = Field( repo_path: str = Field(
@ -104,7 +103,7 @@ class GitTools(str, Enum):
CREATE_BRANCH = "git_create_branch" CREATE_BRANCH = "git_create_branch"
CHECKOUT = "git_checkout" CHECKOUT = "git_checkout"
SHOW = "git_show" SHOW = "git_show"
INIT = "git_init"
BRANCH = "git_branch" BRANCH = "git_branch"
def git_status(repo: git.Repo) -> str: def git_status(repo: git.Repo) -> str:
@ -183,12 +182,7 @@ def git_checkout(repo: git.Repo, branch_name: str) -> str:
repo.git.checkout(branch_name) repo.git.checkout(branch_name)
return f"Switched to branch '{branch_name}'" return f"Switched to branch '{branch_name}'"
def git_init(repo_path: str) -> str:
try:
repo = git.Repo.init(path=repo_path, mkdir=True)
return f"Initialized empty Git repository in {repo.git_dir}"
except Exception as e:
return f"Error initializing repository: {str(e)}"
def git_show(repo: git.Repo, revision: str) -> str: def git_show(repo: git.Repo, revision: str) -> str:
commit = repo.commit(revision) commit = repo.commit(revision)
@ -308,11 +302,7 @@ async def serve(repository: Path | None) -> None:
description="Shows the contents of a commit", description="Shows the contents of a commit",
inputSchema=GitShow.model_json_schema(), inputSchema=GitShow.model_json_schema(),
), ),
Tool(
name=GitTools.INIT,
description="Initialize a new Git repository",
inputSchema=GitInit.model_json_schema(),
),
Tool( Tool(
name=GitTools.BRANCH, name=GitTools.BRANCH,
description="List Git branches", description="List Git branches",
@ -354,15 +344,7 @@ async def serve(repository: Path | None) -> None:
async def call_tool(name: str, arguments: dict) -> list[TextContent]: async def call_tool(name: str, arguments: dict) -> list[TextContent]:
repo_path = Path(arguments["repo_path"]) repo_path = Path(arguments["repo_path"])
# Handle git init separately since it doesn't require an existing repo # For all commands, we need an existing repo
if name == GitTools.INIT:
result = git_init(str(repo_path))
return [TextContent(
type="text",
text=result
)]
# For all other commands, we need an existing repo
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
match name: match name: