**feat(git-ops): enhance MCP server with Git provider updates and SSRF protection**
- Added `mcp-git-ops` service to `docker-compose.dev.yml` with health checks and configurations. - Integrated SSRF protection in repository URL validation for enhanced security. - Expanded `pyproject.toml` mypy settings and adjusted code to meet stricter type checking. - Improved workspace management and GitWrapper operations with error handling refinements. - Updated input validation, branching, and repository operations to align with new error structure. - Shut down thread pool executor gracefully during server cleanup.
This commit is contained in:
@@ -257,7 +257,9 @@ class WorkspaceInfo:
|
||||
"last_accessed": self.last_accessed.isoformat(),
|
||||
"size_bytes": self.size_bytes,
|
||||
"lock_holder": self.lock_holder,
|
||||
"lock_expires": self.lock_expires.isoformat() if self.lock_expires else None,
|
||||
"lock_expires": self.lock_expires.isoformat()
|
||||
if self.lock_expires
|
||||
else None,
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +272,9 @@ class CloneRequest(BaseModel):
|
||||
project_id: str = Field(..., description="Project ID for scoping")
|
||||
agent_id: str = Field(..., description="Agent ID making the request")
|
||||
repo_url: str = Field(..., description="Repository URL to clone")
|
||||
branch: str | None = Field(default=None, description="Branch to checkout after clone")
|
||||
branch: str | None = Field(
|
||||
default=None, description="Branch to checkout after clone"
|
||||
)
|
||||
depth: int | None = Field(
|
||||
default=None, ge=1, description="Shallow clone depth (None = full clone)"
|
||||
)
|
||||
@@ -407,7 +411,9 @@ class PushRequest(BaseModel):
|
||||
|
||||
project_id: str = Field(..., description="Project ID for scoping")
|
||||
agent_id: str = Field(..., description="Agent ID making the request")
|
||||
branch: str | None = Field(default=None, description="Branch to push (None = current)")
|
||||
branch: str | None = Field(
|
||||
default=None, description="Branch to push (None = current)"
|
||||
)
|
||||
remote: str = Field(default="origin", description="Remote name")
|
||||
force: bool = Field(default=False, description="Force push")
|
||||
set_upstream: bool = Field(default=True, description="Set upstream tracking")
|
||||
@@ -428,7 +434,9 @@ class PullRequest(BaseModel):
|
||||
|
||||
project_id: str = Field(..., description="Project ID for scoping")
|
||||
agent_id: str = Field(..., description="Agent ID making the request")
|
||||
branch: str | None = Field(default=None, description="Branch to pull (None = current)")
|
||||
branch: str | None = Field(
|
||||
default=None, description="Branch to pull (None = current)"
|
||||
)
|
||||
remote: str = Field(default="origin", description="Remote name")
|
||||
rebase: bool = Field(default=False, description="Rebase instead of merge")
|
||||
|
||||
@@ -451,7 +459,9 @@ class DiffRequest(BaseModel):
|
||||
|
||||
project_id: str = Field(..., description="Project ID for scoping")
|
||||
agent_id: str = Field(..., description="Agent ID making the request")
|
||||
base: str | None = Field(default=None, description="Base reference (None = working tree)")
|
||||
base: str | None = Field(
|
||||
default=None, description="Base reference (None = working tree)"
|
||||
)
|
||||
head: str | None = Field(default=None, description="Head reference (None = HEAD)")
|
||||
files: list[str] | None = Field(default=None, description="Specific files to diff")
|
||||
context_lines: int = Field(default=3, ge=0, description="Context lines")
|
||||
@@ -463,9 +473,7 @@ class DiffResult(BaseModel):
|
||||
project_id: str = Field(..., description="Project ID")
|
||||
base: str | None = Field(default=None, description="Base reference")
|
||||
head: str | None = Field(default=None, description="Head reference")
|
||||
files: list[dict[str, Any]] = Field(
|
||||
default_factory=list, description="File diffs"
|
||||
)
|
||||
files: list[dict[str, Any]] = Field(default_factory=list, description="File diffs")
|
||||
total_additions: int = Field(default=0, description="Total lines added")
|
||||
total_deletions: int = Field(default=0, description="Total lines removed")
|
||||
files_changed: int = Field(default=0, description="Number of files changed")
|
||||
@@ -549,9 +557,7 @@ class ListPRsResult(BaseModel):
|
||||
"""Result of listing pull requests."""
|
||||
|
||||
success: bool = Field(..., description="Whether list succeeded")
|
||||
pull_requests: list[dict[str, Any]] = Field(
|
||||
default_factory=list, description="PRs"
|
||||
)
|
||||
pull_requests: list[dict[str, Any]] = Field(default_factory=list, description="PRs")
|
||||
total_count: int = Field(default=0, description="Total matching PRs")
|
||||
error: str | None = Field(default=None, description="Error message if failed")
|
||||
|
||||
@@ -578,7 +584,9 @@ class MergePRResult(BaseModel):
|
||||
|
||||
success: bool = Field(..., description="Whether merge succeeded")
|
||||
merge_commit_sha: str | None = Field(default=None, description="Merge commit SHA")
|
||||
branch_deleted: bool = Field(default=False, description="Whether branch was deleted")
|
||||
branch_deleted: bool = Field(
|
||||
default=False, description="Whether branch was deleted"
|
||||
)
|
||||
error: str | None = Field(default=None, description="Error message if failed")
|
||||
|
||||
|
||||
@@ -626,7 +634,9 @@ class LockWorkspaceRequest(BaseModel):
|
||||
|
||||
project_id: str = Field(..., description="Project ID")
|
||||
agent_id: str = Field(..., description="Agent ID requesting lock")
|
||||
timeout: int = Field(default=300, ge=10, le=3600, description="Lock timeout seconds")
|
||||
timeout: int = Field(
|
||||
default=300, ge=10, le=3600, description="Lock timeout seconds"
|
||||
)
|
||||
|
||||
|
||||
class LockWorkspaceResult(BaseModel):
|
||||
@@ -634,7 +644,9 @@ class LockWorkspaceResult(BaseModel):
|
||||
|
||||
success: bool = Field(..., description="Whether lock acquired")
|
||||
lock_holder: str | None = Field(default=None, description="Current lock holder")
|
||||
lock_expires: str | None = Field(default=None, description="Lock expiry ISO timestamp")
|
||||
lock_expires: str | None = Field(
|
||||
default=None, description="Lock expiry ISO timestamp"
|
||||
)
|
||||
error: str | None = Field(default=None, description="Error message if failed")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user