.
This commit is contained in:
156
src/aegis_gitea_mcp/mcp_protocol.py
Normal file
156
src/aegis_gitea_mcp/mcp_protocol.py
Normal file
@@ -0,0 +1,156 @@
|
||||
"""MCP protocol implementation for AegisGitea."""
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class MCPTool(BaseModel):
|
||||
"""MCP tool definition."""
|
||||
|
||||
name: str = Field(..., description="Unique tool identifier")
|
||||
description: str = Field(..., description="Human-readable tool description")
|
||||
input_schema: Dict[str, Any] = Field(..., description="JSON Schema for tool input")
|
||||
|
||||
|
||||
class MCPToolCallRequest(BaseModel):
|
||||
"""Request to invoke an MCP tool."""
|
||||
|
||||
tool: str = Field(..., description="Name of the tool to invoke")
|
||||
arguments: Dict[str, Any] = Field(default_factory=dict, description="Tool arguments")
|
||||
correlation_id: Optional[str] = Field(None, description="Request correlation ID")
|
||||
|
||||
|
||||
class MCPToolCallResponse(BaseModel):
|
||||
"""Response from an MCP tool invocation."""
|
||||
|
||||
success: bool = Field(..., description="Whether the tool call succeeded")
|
||||
result: Optional[Any] = Field(None, description="Tool result data")
|
||||
error: Optional[str] = Field(None, description="Error message if failed")
|
||||
correlation_id: str = Field(..., description="Request correlation ID")
|
||||
|
||||
|
||||
class MCPListToolsResponse(BaseModel):
|
||||
"""Response listing available MCP tools."""
|
||||
|
||||
tools: List[MCPTool] = Field(..., description="List of available tools")
|
||||
|
||||
|
||||
# Tool definitions for AegisGitea MCP
|
||||
|
||||
TOOL_LIST_REPOSITORIES = MCPTool(
|
||||
name="list_repositories",
|
||||
description="List all repositories visible to the AI bot user. "
|
||||
"Only repositories where the bot has explicit read access will be returned. "
|
||||
"This respects Gitea's dynamic authorization model.",
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": [],
|
||||
},
|
||||
)
|
||||
|
||||
TOOL_GET_REPOSITORY_INFO = MCPTool(
|
||||
name="get_repository_info",
|
||||
description="Get detailed information about a specific repository, "
|
||||
"including description, default branch, language, and metadata. "
|
||||
"Requires the bot user to have read access.",
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"owner": {
|
||||
"type": "string",
|
||||
"description": "Repository owner username or organization",
|
||||
},
|
||||
"repo": {
|
||||
"type": "string",
|
||||
"description": "Repository name",
|
||||
},
|
||||
},
|
||||
"required": ["owner", "repo"],
|
||||
},
|
||||
)
|
||||
|
||||
TOOL_GET_FILE_TREE = MCPTool(
|
||||
name="get_file_tree",
|
||||
description="Get the file tree structure for a repository at a specific ref. "
|
||||
"Returns a list of files and directories. "
|
||||
"Non-recursive by default for safety (max depth: 1 level).",
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"owner": {
|
||||
"type": "string",
|
||||
"description": "Repository owner username or organization",
|
||||
},
|
||||
"repo": {
|
||||
"type": "string",
|
||||
"description": "Repository name",
|
||||
},
|
||||
"ref": {
|
||||
"type": "string",
|
||||
"description": "Branch, tag, or commit SHA (defaults to 'main')",
|
||||
"default": "main",
|
||||
},
|
||||
"recursive": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to recursively fetch entire tree (use with caution)",
|
||||
"default": False,
|
||||
},
|
||||
},
|
||||
"required": ["owner", "repo"],
|
||||
},
|
||||
)
|
||||
|
||||
TOOL_GET_FILE_CONTENTS = MCPTool(
|
||||
name="get_file_contents",
|
||||
description="Read the contents of a specific file in a repository. "
|
||||
"File size is limited to 1MB by default for safety. "
|
||||
"Returns base64-encoded content for binary files.",
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"owner": {
|
||||
"type": "string",
|
||||
"description": "Repository owner username or organization",
|
||||
},
|
||||
"repo": {
|
||||
"type": "string",
|
||||
"description": "Repository name",
|
||||
},
|
||||
"filepath": {
|
||||
"type": "string",
|
||||
"description": "Path to file within repository (e.g., 'src/main.py')",
|
||||
},
|
||||
"ref": {
|
||||
"type": "string",
|
||||
"description": "Branch, tag, or commit SHA (defaults to 'main')",
|
||||
"default": "main",
|
||||
},
|
||||
},
|
||||
"required": ["owner", "repo", "filepath"],
|
||||
},
|
||||
)
|
||||
|
||||
# Registry of all available tools
|
||||
AVAILABLE_TOOLS: List[MCPTool] = [
|
||||
TOOL_LIST_REPOSITORIES,
|
||||
TOOL_GET_REPOSITORY_INFO,
|
||||
TOOL_GET_FILE_TREE,
|
||||
TOOL_GET_FILE_CONTENTS,
|
||||
]
|
||||
|
||||
|
||||
def get_tool_by_name(tool_name: str) -> Optional[MCPTool]:
|
||||
"""Get tool definition by name.
|
||||
|
||||
Args:
|
||||
tool_name: Name of the tool to retrieve
|
||||
|
||||
Returns:
|
||||
Tool definition or None if not found
|
||||
"""
|
||||
for tool in AVAILABLE_TOOLS:
|
||||
if tool.name == tool_name:
|
||||
return tool
|
||||
return None
|
||||
Reference in New Issue
Block a user