Skip to main content
Glama
yywdandan

Memory Bank MCP Server

by yywdandan

archive_generate_summary

Generate summary reports for projects by specifying project ID, report title, and sections to include, using the MCP server for multi-project document management.

Instructions

生成项目总结报告

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
includeSectionsNo包含的章节
projectIdYes项目ID
titleNo报告标题

Implementation Reference

  • Main handler function for archive_generate_summary tool. Generates a project summary report by aggregating content from project documents (projectbrief, progress, reflections, tasks), extracts relevant sections, counts completed tasks, and creates a new summary markdown document.
    export const archiveGenerateSummary = async (projectId: string, title?: string, includeSections?: string[]) => {
      try {
        // 检查项目是否存在
        const project = await projectStorage.getById(projectId);
        if (!project) throw new Error('项目不存在');
        
        // 获取项目文档
        const docs = await documentStorage.getByProjectId(projectId);
        
        // 默认章节
        const defaultSections = ['overview', 'achievements', 'challenges', 'lessons'];
        const sections = includeSections || defaultSections;
        
        // 收集项目信息
        const projectBrief = docs.find(d => d.type === 'projectbrief');
        const progressDoc = docs.find(d => d.type === 'progress');
        const reflectionsDoc = docs.find(d => d.type === 'reflections');
        const tasksDoc = docs.find(d => d.type === 'tasks');
        
        // 生成报告标题
        const reportTitle = title || `${project.name} - 项目总结报告`;
        const reportDate = new Date().toISOString().split('T')[0];
        
        // 初始化报告内容
        let reportContent = `# ${reportTitle}\n\n**生成日期**: ${reportDate}\n\n`;
        
        // 添加概述部分
        if (sections.includes('overview') && projectBrief) {
          reportContent += '## 项目概述\n\n';
          
          // 提取项目目标
          const goalMatch = projectBrief.content.match(/##\s+项目目标\s+([^#]+)/);
          if (goalMatch) {
            reportContent += goalMatch[1].trim() + '\n\n';
          }
        }
        
        // 添加成就部分
        if (sections.includes('achievements') && progressDoc) {
          reportContent += '## 项目成就\n\n';
          
          // 提取已完成的工作
          const achievementMatch = progressDoc.content.match(/##\s+已完成的工作\s+([^#]+)/);
          if (achievementMatch) {
            reportContent += achievementMatch[1].trim() + '\n\n';
          }
          
          // 统计完成的任务数量
          if (tasksDoc) {
            const completedTasksCount = (tasksDoc.content.match(/- \[x\]/g) || []).length;
            reportContent += `共完成 ${completedTasksCount} 个任务。\n\n`;
          }
        }
        
        // 添加挑战部分
        if (sections.includes('challenges') && reflectionsDoc) {
          reportContent += '## 项目挑战\n\n';
          
          // 从反思文档中提取挑战信息
          const challenges = extractChallengesFromReflections(reflectionsDoc.content);
          if (challenges.length > 0) {
            reportContent += challenges.join('\n') + '\n\n';
          } else {
            reportContent += '未记录项目挑战。\n\n';
          }
        }
        
        // 添加经验教训部分
        if (sections.includes('lessons') && reflectionsDoc) {
          reportContent += '## 经验教训\n\n';
          
          // 从反思文档中提取经验教训
          const lessons = extractLessonsFromReflections(reflectionsDoc.content);
          if (lessons.length > 0) {
            reportContent += lessons.join('\n') + '\n\n';
          } else {
            reportContent += '未记录经验教训。\n\n';
          }
        }
        
        // 创建总结报告文档
        const reportFileName = `${project.name.replace(/\s+/g, '_')}_summary_${reportDate}.md`;
        const summaryDoc = await documentStorage.create(
          projectId,
          reportFileName,
          reportContent,
          'summary'
        );
        
        return {
          status: 'success',
          message: '项目总结报告已生成',
          summary: {
            id: summaryDoc.id,
            title: reportTitle,
            fileName: reportFileName,
            sections: sections,
            createdAt: new Date().toISOString()
          }
        };
      } catch (error) {
        console.error('生成项目总结报告错误:', error);
        throw new Error('生成项目总结报告失败');
      }
    };
  • Registration in the tool call switch statement: handles incoming calls to 'archive_generate_summary' by invoking tools.archiveGenerateSummary with parsed arguments.
    case 'archive_generate_summary': {
      if (!args.projectId) {
        throw new McpError(ErrorCode.InvalidParams, '项目ID不能为空');
      }
      return this.formatResponse(await tools.archiveGenerateSummary(
        args.projectId as string,
        args.title as string | undefined,
        args.includeSections as string[] | undefined
      ));
    }
  • Tool registration in listTools response: defines the tool name, description, and input schema for 'archive_generate_summary'.
    name: 'archive_generate_summary',
    description: '生成项目总结报告',
    inputSchema: {
      type: 'object',
      properties: {
        projectId: {
          type: 'string',
          description: '项目ID',
        },
        title: {
          type: 'string',
          description: '报告标题',
        },
        includeSections: {
          type: 'array',
          items: {
            type: 'string'
          },
          description: '包含的章节',
        },
      },
      required: ['projectId'],
    }
  • Input schema definition for the tool, specifying required projectId and optional title/includeSections.
    inputSchema: {
      type: 'object',
      properties: {
        projectId: {
          type: 'string',
          description: '项目ID',
        },
        title: {
          type: 'string',
          description: '报告标题',
        },
        includeSections: {
          type: 'array',
          items: {
            type: 'string'
          },
          description: '包含的章节',
        },
      },
      required: ['projectId'],
    }
  • Helper functions extractChallengesFromReflections and extractLessonsFromReflections: parse reflections document to extract challenge and lesson bullet points using regex, used in the summary generation.
    function extractChallengesFromReflections(content: string): string[] {
      const challenges = [];
      
      // 从反思文档中提取挑战部分
      const challengeSections = content.match(/##\s+问题|##\s+挑战[^#]*?(?=##|$)/g);
      
      if (challengeSections) {
        for (const section of challengeSections) {
          const lines = section.split('\n');
          // 跳过标题行
          for (let i = 1; i < lines.length; i++) {
            const line = lines[i].trim();
            if (line.startsWith('-') || line.startsWith('*')) {
              challenges.push(line);
            }
          }
        }
      }
      
      return challenges;
    }
    
    /**
     * 从反思文档中提取经验教训
     */
    function extractLessonsFromReflections(content: string): string[] {
      const lessons = [];
      
      // 从反思文档中提取经验教训部分
      const lessonSections = content.match(/##\s+经验|##\s+教训|##\s+经验教训|##\s+改进[^#]*?(?=##|$)/g);
      
      if (lessonSections) {
        for (const section of lessonSections) {
          const lines = section.split('\n');
          // 跳过标题行
          for (let i = 1; i < lines.length; i++) {
            const line = lines[i].trim();
            if (line.startsWith('-') || line.startsWith('*')) {
              lessons.push(line);
            }
          }
        }
      }
      
      return lessons;
    }

Latest Blog Posts

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/yywdandan/memory-bank-mcp-server'

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