Skip to main content
Glama

Office MCP Server

by walkingzzzy
SessionManager.ts4.71 kB
import fs from 'fs-extra'; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; import config from '../config'; import logger from '../utils/logger'; export interface DocumentSession { sessionId: string; documentType: 'word' | 'excel' | 'powerpoint'; tempDir: string; currentFile: string; backupFile: string; metadata: Record<string, any>; createdAt: number; lastActivity: number; } export class SessionManager { private sessions = new Map<string, DocumentSession>(); private cleanupInterval: NodeJS.Timeout; constructor() { // 确保临时目录存在 fs.ensureDirSync(config.tempDir); // 启动清理定时器 this.cleanupInterval = setInterval(() => { this.cleanupExpiredSessions(); }, 5 * 60 * 1000); // 每5分钟清理一次 } /** * 创建新会话 */ async createSession(documentType: 'word' | 'excel' | 'powerpoint'): Promise<DocumentSession> { const sessionId = uuidv4(); const sessionDir = path.join(config.tempDir, `session-${sessionId}`); // 创建会话目录 await fs.ensureDir(sessionDir); const session: DocumentSession = { sessionId, documentType, tempDir: sessionDir, currentFile: path.join(sessionDir, `current.${this.getFileExtension(documentType)}`), backupFile: path.join(sessionDir, `backup.${this.getFileExtension(documentType)}`), metadata: {}, createdAt: Date.now(), lastActivity: Date.now() }; this.sessions.set(sessionId, session); logger.info('创建文档会话', { sessionId, documentType }); return session; } /** * 获取会话 */ getSession(sessionId: string): DocumentSession | undefined { const session = this.sessions.get(sessionId); if (session) { session.lastActivity = Date.now(); } return session; } /** * 保存文档到会话 */ async saveDocumentToSession(sessionId: string, documentData: Buffer): Promise<string> { const session = this.getSession(sessionId); if (!session) { throw new Error(`会话不存在: ${sessionId}`); } // 备份当前文件 if (await fs.pathExists(session.currentFile)) { await fs.copy(session.currentFile, session.backupFile); } // 保存新文档 await fs.writeFile(session.currentFile, documentData); session.lastActivity = Date.now(); logger.info('保存文档到会话', { sessionId, fileSize: documentData.length }); return session.currentFile; } /** * 从会话读取文档 */ async readDocumentFromSession(sessionId: string): Promise<Buffer> { const session = this.getSession(sessionId); if (!session) { throw new Error(`会话不存在: ${sessionId}`); } if (!(await fs.pathExists(session.currentFile))) { throw new Error(`会话文档不存在: ${sessionId}`); } const documentData = await fs.readFile(session.currentFile); session.lastActivity = Date.now(); return documentData; } /** * 更新会话元数据 */ updateSessionMetadata(sessionId: string, metadata: Record<string, any>): void { const session = this.getSession(sessionId); if (session) { session.metadata = { ...session.metadata, ...metadata }; session.lastActivity = Date.now(); } } /** * 删除会话 */ async deleteSession(sessionId: string): Promise<void> { const session = this.sessions.get(sessionId); if (session) { // 删除临时文件 await fs.remove(session.tempDir); this.sessions.delete(sessionId); logger.info('删除文档会话', { sessionId }); } } /** * 获取所有活跃会话 */ getActiveSessions(): DocumentSession[] { return Array.from(this.sessions.values()); } /** * 清理过期会话 */ private async cleanupExpiredSessions(): Promise<void> { const now = Date.now(); const maxAge = 60 * 60 * 1000; // 1小时 const expiredSessions = Array.from(this.sessions.entries()) .filter(([_, session]) => now - session.lastActivity > maxAge); for (const [sessionId, _] of expiredSessions) { await this.deleteSession(sessionId); } if (expiredSessions.length > 0) { logger.info('清理过期会话', { count: expiredSessions.length }); } } private getFileExtension(documentType: string): string { switch (documentType) { case 'word': return 'docx'; case 'excel': return 'xlsx'; case 'powerpoint': return 'pptx'; default: return 'bin'; } } /** * 关闭会话管理器 */ close(): void { if (this.cleanupInterval) { clearInterval(this.cleanupInterval); } } } export default new SessionManager();

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/walkingzzzy/office-mcp'

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