package operation import ( "fmt" "net/http" "gitea.com/gitea/gitea-mcp/operation/issue" "gitea.com/gitea/gitea-mcp/operation/pull" "gitea.com/gitea/gitea-mcp/operation/repo" "gitea.com/gitea/gitea-mcp/operation/search" "gitea.com/gitea/gitea-mcp/operation/user" "gitea.com/gitea/gitea-mcp/operation/version" "gitea.com/gitea/gitea-mcp/pkg/flag" "gitea.com/gitea/gitea-mcp/pkg/log" "github.com/mark3labs/mcp-go/server" ) var mcpServer *server.MCPServer func RegisterTool(s *server.MCPServer) { // User Tool s.AddTools(user.Tool.Tools()...) // Repo Tool s.AddTools(repo.Tool.Tools()...) // Issue Tool s.AddTools(issue.Tool.Tools()...) // Pull Tool s.AddTools(pull.Tool.Tools()...) // Search Tool s.AddTools(search.Tool.Tools()...) // Version Tool s.AddTools(version.Tool.Tools()...) s.DeleteTools("") } func Run() error { mcpServer = newMCPServer(flag.Version) RegisterTool(mcpServer) addr := fmt.Sprintf("127.0.0.1:%d", flag.Port) switch flag.Mode { case "stdio": if err := server.ServeStdio(mcpServer); err != nil { return err } case "sse": sseServer := server.NewSSEServer(mcpServer) log.Infof("Gitea MCP Server running:") log.Infof(" sse: http://%s/", addr) if err := sseServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil { return err } case "http": httpServer := server.NewStreamableHTTPServer(mcpServer) log.Infof("Gitea MCP Server running:") log.Infof(" http: http://%s/", addr) if err := httpServer.Start(fmt.Sprintf(":%d", flag.Port)); err != nil { return err } case "network": // Network mode: serve both HTTP and SSE on same port with different URLs log.Infof("Network mode: Creating streamable HTTP server...") streamableServer := server.NewStreamableHTTPServer(mcpServer) log.Infof("Network mode: Created streamable HTTP server") log.Infof("Network mode: Creating SSE server...") sseServer := server.NewSSEServer(mcpServer, server.WithSSEEndpoint("/sse"), server.WithMessageEndpoint("/message"), ) log.Infof("Network mode: Created SSE server") // Create custom HTTP mux log.Infof("Network mode: Creating HTTP mux...") mux := http.NewServeMux() mux.Handle("/mcp", streamableServer) mux.Handle("/", sseServer) log.Infof("Network mode: Configured HTTP routes") // Start single HTTP server log.Infof("Gitea MCP Server running in network mode:") log.Infof(" http: http://%s/mcp", addr) log.Infof(" sse: http://%s/sse", addr) err := http.ListenAndServe(fmt.Sprintf(":%d", flag.Port), mux) log.Errorf("Network mode: ListenAndServe returned with error: %v", err) return err default: return fmt.Errorf("invalid transport type: %s. Must be 'stdio', 'sse', 'http' or 'network'", flag.Mode) } return nil } func newMCPServer(version string) *server.MCPServer { return server.NewMCPServer( "Gitea MCP Server", version, server.WithToolCapabilities(true), server.WithLogging(), server.WithRecovery(), ) }