Skip to main content
Glama

MCPDemo - Visual SQL Chat Platform

by Ayi456
OssUploader.ts5.66 kB
/** * 阿里云 OSS 上传工具 */ import OSS from 'ali-oss'; import path from 'path'; export interface OSSConfig { accessKeyId: string; accessKeySecret: string; bucket: string; endpoint: string; } export interface UploadResult { url: string; ossPath: string; fileName: string; size: number; } export class OSSUploader { private client: OSS; private bucket: string; private endpoint: string; constructor(config: OSSConfig) { this.validateConfig(config); this.bucket = config.bucket; this.endpoint = config.endpoint; this.client = new OSS({ accessKeyId: config.accessKeyId, accessKeySecret: config.accessKeySecret, bucket: config.bucket, endpoint: config.endpoint, }); } private validateConfig(config: OSSConfig): void { if (!config.accessKeyId) { throw new Error('OSS AccessKeyId 不能为空'); } if (!config.accessKeySecret) { throw new Error('OSS AccessKeySecret 不能为空'); } if (!config.bucket) { throw new Error('OSS Bucket 不能为空'); } if (!config.endpoint) { throw new Error('OSS Endpoint 不能为空'); } } async generateSignedUrl(objectKey: string, expiresSeconds: number = 86400): Promise<string> { try { if (!objectKey) { throw new Error('objectKey 不能为空'); } if (expiresSeconds <= 0 || expiresSeconds > 24 * 60 * 60) { throw new Error('过期时间必须在 1 秒到 24 小时之间'); } const signedUrl = this.client.signatureUrl(objectKey, { expires: expiresSeconds, method: 'GET', }); console.log(`为OSS对象 ${objectKey} 生成签名URL,有效期 ${expiresSeconds} 秒`); return signedUrl; } catch (error) { console.error(`为OSS对象 ${objectKey} 生成签名URL失败:`, error); throw new Error(`无法获取文件访问URL: ${error instanceof Error ? error.message : '未知错误'}`); } } /** * 上传 HTML 内容到 OSS */ async uploadHTML(htmlContent: string, fileName?: string): Promise<UploadResult> { try { // 生成文件名 const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const finalFileName = fileName || `visualization-${timestamp}.html`; // 构建 OSS 路径 const ossPath = `mcp-visualizations/${finalFileName}`; // 上传到 OSS(公共读权限) const result = await this.client.put(ossPath, Buffer.from(htmlContent, 'utf8'), { mime: 'text/html', headers: { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'public, max-age=3600', // 1小时缓存 'Content-Disposition': 'inline; filename="chart.html"', // 强制浏览器内联显示 }, }); // 生成公开访问 URL const publicUrl = `https://${this.bucket}.${this.endpoint}/${ossPath}`; return { url: publicUrl, ossPath: ossPath, fileName: finalFileName, size: Buffer.from(htmlContent, 'utf8').length }; } catch (error) { console.error('OSS 上传失败:', error); throw new Error(`OSS 上传失败: ${error instanceof Error ? error.message : '未知错误'}`); } } /** * 上传文件到 OSS */ async uploadFile(filePath: string, ossPath?: string): Promise<UploadResult> { try { const fileName = path.basename(filePath); const finalOssPath = ossPath || `mcp-files/${fileName}`; const result = await this.client.put(finalOssPath, filePath, { headers: { 'x-oss-object-acl': 'public-read', // 设置文件为公开可读 }, }); // 生成公开访问 URL const publicUrl = `https://${this.bucket}.${this.endpoint}/${finalOssPath}`; // 获取文件大小 const fs = await import('fs'); const stats = fs.statSync(filePath); return { url: publicUrl, ossPath: finalOssPath, fileName: fileName, size: stats.size }; } catch (error) { console.error('OSS 文件上传失败:', error); throw new Error(`OSS 文件上传失败: ${error instanceof Error ? error.message : '未知错误'}`); } } /** * 检查文件是否存在 */ async fileExists(ossPath: string): Promise<boolean> { try { await this.client.head(ossPath); return true; } catch (error) { return false; } } /** * 获取文件信息 */ async getFileInfo(ossPath: string): Promise<any> { try { const result = await this.client.head(ossPath); return result; } catch (error) { throw new Error(`获取文件信息失败: ${error instanceof Error ? error.message : '未知错误'}`); } } } // 创建全局 OSS 上传器实例 let ossUploader: OSSUploader | null = null; /** * 初始化 OSS 上传器 */ export function initOSSUploader(config: OSSConfig): void { ossUploader = new OSSUploader(config); } /** * 获取 OSS 上传器实例 */ export function getOSSUploader(): OSSUploader { if (!ossUploader) { throw new Error('OSS 上传器未初始化,请先调用 initOSSUploader()'); } return ossUploader; } /** * 检查 OSS 上传器是否已初始化 */ export function isOSSUploaderInitialized(): boolean { return ossUploader !== null; } /** * 便捷函数:生成签名URL(直接使用全局实例) */ export async function generateSignedUrl(objectKey: string, expiresSeconds: number = 86400): Promise<string> { const uploader = getOSSUploader(); return uploader.generateSignedUrl(objectKey, expiresSeconds); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ayi456/visual-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server