1Panel MCP Server

by ruibaby
Verified
import axios from "axios"; import crypto from "crypto"; import FormData from "form-data"; import fs from "fs-extra"; import path from "path"; class OnePanelAPI { constructor(config) { this.baseURL = config.baseURL || "http://your-1panel-ip:port/api/v1"; this.apiKey = config.apiKey; this.languageCode = config.languageCode || "zh"; } getAuthHeaders() { const timestamp = Math.floor(Date.now() / 1000).toString(); const content = `1panel${this.apiKey}${timestamp}`; const token = crypto.createHash("md5").update(content).digest("hex"); return { "1Panel-Token": token, "1Panel-Timestamp": timestamp, "Accept-Language": this.languageCode, }; } async createWebsite(siteConfig) { try { const headers = this.getAuthHeaders(); const requestBody = { primaryDomain: siteConfig.domain, type: "static", alias: siteConfig.domain, remark: "", appType: "installed", webSiteGroupId: 2, otherDomains: "", proxy: "", appinstall: { appId: 0, name: "", appDetailId: 0, params: {}, version: "", appkey: "", advanced: false, cpuQuota: 0, memoryLimit: 0, memoryUnit: "MB", containerName: "", allowPort: false, }, IPV6: false, enableFtp: false, ftpUser: "", ftpPassword: "", proxyType: "tcp", port: 9000, proxyProtocol: "http://", proxyAddress: "", runtimeType: "php", }; const response = await axios.post( `${this.baseURL}/websites`, requestBody, { headers } ); console.log(response.data + "-------------"); const website = await this.getWebsiteDetail(siteConfig.domain); return website; } catch (error) { throw new Error(`Create website failed: ${error.message}`); } } async getWebsiteDetail(domain) { try { const headers = this.getAuthHeaders(); const { data } = await axios.post( `${this.baseURL}/websites/search`, { name: "", page: 1, pageSize: 10, orderBy: "created_at", order: "null", websiteGroupId: 0, }, { headers, } ); const websites = data.data.items; const website = websites.find((w) => w.primaryDomain === domain); return website; } catch (error) { console.error("Get website detail failed:", error); throw new Error(`Get website detail failed: ${error.message}`); } } async uploadSingleFile(filePath, targetDir) { try { const formData = new FormData(); formData.append("file", fs.createReadStream(filePath)); formData.append("path", targetDir); formData.append("overwrite", "True"); const headers = this.getAuthHeaders(); const response = await axios.post( `${this.baseURL}/files/upload`, formData, { headers: { ...headers, ...formData.getHeaders(), }, } ); return response.data.data || { message: "Upload success" }; } catch (error) { console.error(`Upload file failed: ${filePath}`, error); throw new Error(`Upload file failed: ${filePath} - ${error.message}`); } } async uploadDirectory(sourceDir, targetDir, basePath) { if (!targetDir.endsWith("/")) { targetDir += "/"; } basePath = basePath || sourceDir; const results = []; const files = await fs.readdir(sourceDir); console.log( `Start uploading directory ${sourceDir} to ${targetDir}, ${files.length} files/directories` ); for (const file of files) { const sourcePath = path.join(sourceDir, file); const stats = await fs.stat(sourcePath); if (stats.isDirectory()) { console.log(`Found subdirectory: ${file}, uploading recursively...`); const subResults = await this.uploadDirectory( sourcePath, targetDir, basePath ); results.push(...subResults); } else { const relativePath = path.relative(basePath, sourceDir); let uploadTargetDir = targetDir; if (relativePath) { uploadTargetDir = path.join(targetDir, relativePath); } console.log(`Upload file: ${file} to directory ${uploadTargetDir}`); try { const result = await this.uploadSingleFile( sourcePath, uploadTargetDir ); results.push({ file, result, success: true }); } catch (error) { console.error(`Upload file ${file} failed:`, error.message); results.push({ file, error: error.message, success: false }); } } } return results; } async uploadStaticFiles(domain, sourceDirPath) { try { const siteDetail = await this.getWebsiteDetail(domain); if (!siteDetail.sitePath) { throw new Error("Cannot get website physical path"); } const sitePath = siteDetail.sitePath; console.log(`Website physical path: ${sitePath}`); if (!fs.existsSync(sourceDirPath)) { throw new Error(`Source directory does not exist: ${sourceDirPath}`); } const targetPath = path.join(sitePath, "index"); console.log(`Start uploading directory ${sourceDirPath} to website directory ${targetPath}`); const results = await this.uploadDirectory( sourceDirPath, targetPath, sourceDirPath ); const successCount = results.filter((r) => r.success).length; const failCount = results.filter((r) => !r.success).length; console.log( `Upload completed: ${results.length} files, ${successCount} success, ${failCount} failed` ); return { totalFiles: results.length, successCount, failCount, details: results, }; } catch (error) { console.error("Upload file failed:", error); throw new Error(`Upload file failed: ${error.message}`); } } } export default OnePanelAPI;