generated from personal-projects/leo-claude-mktplace
Implement Gitea issue operations tools with the following features: - gitea_list_issues: List issues with filters (state, labels, milestone) - gitea_get_issue: Get single issue by number - gitea_create_issue: Create new issue with title, body, labels, milestone - gitea_update_issue: Update issue state, title, body, labels, assignees Files added: - src/gitea_mcp/tools/issues.py: Issue operation tool handlers Files modified: - src/gitea_mcp/server.py: Register issue tools in MCP server - src/gitea_mcp/tools/__init__.py: Export issue tool functions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
153 lines
4.3 KiB
Python
153 lines
4.3 KiB
Python
"""MCP server implementation for Gitea API integration."""
|
|
|
|
import asyncio
|
|
import argparse
|
|
from mcp.server import Server
|
|
from mcp.server.stdio import stdio_server
|
|
from mcp.types import Tool, TextContent
|
|
|
|
from . import __version__
|
|
from .auth import AuthConfig
|
|
from .client import GiteaClient, GiteaClientError
|
|
from .tools import get_issue_tools, handle_issue_tool
|
|
|
|
|
|
# Global client instance
|
|
gitea_client: GiteaClient | None = None
|
|
|
|
|
|
async def serve() -> None:
|
|
"""Run the MCP server."""
|
|
server = Server("gitea-mcp")
|
|
|
|
# Initialize authentication config
|
|
try:
|
|
config = AuthConfig()
|
|
except ValueError as e:
|
|
print(f"Configuration error: {e}")
|
|
raise
|
|
|
|
# Initialize Gitea client
|
|
global gitea_client
|
|
gitea_client = GiteaClient(config)
|
|
|
|
@server.list_tools()
|
|
async def list_tools() -> list[Tool]:
|
|
"""List available MCP tools.
|
|
|
|
Returns:
|
|
list: Available tools including issue operations.
|
|
"""
|
|
# Get issue tools
|
|
tools = get_issue_tools()
|
|
|
|
# Placeholder for future tools (PR tools, etc.)
|
|
tools.extend([
|
|
Tool(
|
|
name="list_repositories",
|
|
description="List repositories in an organization (coming soon)",
|
|
inputSchema={
|
|
"type": "object",
|
|
"properties": {
|
|
"org": {
|
|
"type": "string",
|
|
"description": "Organization name",
|
|
}
|
|
},
|
|
"required": ["org"],
|
|
},
|
|
),
|
|
Tool(
|
|
name="create_pull_request",
|
|
description="Create a new pull request (coming soon)",
|
|
inputSchema={
|
|
"type": "object",
|
|
"properties": {
|
|
"owner": {
|
|
"type": "string",
|
|
"description": "Repository owner",
|
|
},
|
|
"repo": {
|
|
"type": "string",
|
|
"description": "Repository name",
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"description": "Pull request title",
|
|
},
|
|
"head": {
|
|
"type": "string",
|
|
"description": "Source branch",
|
|
},
|
|
"base": {
|
|
"type": "string",
|
|
"description": "Target branch",
|
|
},
|
|
},
|
|
"required": ["owner", "repo", "title", "head", "base"],
|
|
},
|
|
),
|
|
])
|
|
|
|
return tools
|
|
|
|
@server.call_tool()
|
|
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
"""Handle tool calls.
|
|
|
|
Args:
|
|
name: Tool name.
|
|
arguments: Tool arguments.
|
|
|
|
Returns:
|
|
list: Tool response.
|
|
"""
|
|
# Handle issue tools
|
|
if name.startswith("gitea_") and any(
|
|
name.endswith(suffix) for suffix in ["_issues", "_issue"]
|
|
):
|
|
return await handle_issue_tool(name, arguments, gitea_client)
|
|
|
|
# Placeholder for other tools
|
|
return [
|
|
TextContent(
|
|
type="text",
|
|
text=f"Tool '{name}' is not yet implemented.",
|
|
)
|
|
]
|
|
|
|
# Run the server using stdio transport
|
|
async with stdio_server() as (read_stream, write_stream):
|
|
await server.run(
|
|
read_stream,
|
|
write_stream,
|
|
server.create_initialization_options(),
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
"""Main entry point with CLI argument parsing."""
|
|
parser = argparse.ArgumentParser(
|
|
description="Gitea MCP Server - MCP server for Gitea API integration"
|
|
)
|
|
parser.add_argument(
|
|
"--version",
|
|
action="version",
|
|
version=f"gitea-mcp {__version__}",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Run the server
|
|
try:
|
|
asyncio.run(serve())
|
|
except KeyboardInterrupt:
|
|
print("\nServer stopped by user")
|
|
except Exception as e:
|
|
print(f"Server error: {e}")
|
|
raise
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|