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;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. '生成' (generate) implies a creation/write operation, but the description doesn't specify if this requires specific permissions, whether it's idempotent, what format the output takes (e.g., text, PDF), or if it has side effects like updating project status. It lacks details on rate limits, error handling, or response behavior, leaving significant gaps for a tool that likely produces reports.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence ('生成项目总结报告') that is front-loaded and wastes no words. It's appropriately sized for a simple tool, though it could benefit from more detail given the lack of annotations and output schema. Every word earns its place, but it might be too concise for full clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (a report-generation tool with 3 parameters), no annotations, and no output schema, the description is incomplete. It doesn't explain what the tool returns (e.g., a text summary, a file ID), behavioral traits, or usage context. For a tool that likely involves data processing and output creation, more information is needed to guide an AI agent effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all parameters ('projectId', 'title', 'includeSections') documented in the schema. The description adds no additional meaning beyond the schema, such as explaining what 'includeSections' might contain (e.g., typical report sections) or how 'title' is used. Since the schema does the heavy lifting, the baseline score of 3 is appropriate, but the description doesn't compensate or enhance understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description '生成项目总结报告' (Generate project summary report) states a clear verb ('生成' - generate) and resource ('项目总结报告' - project summary report), but it's somewhat vague about what exactly constitutes a 'summary report' and doesn't differentiate from sibling tools like 'archive_export_project' or 'reflect_create' that might also produce project-related outputs. It avoids tautology since it doesn't just restate the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing an existing project), exclusions, or comparisons to siblings like 'archive_export_project' (which might export data) or 'reflect_create' (which might create reflections). Usage is implied only by the tool name and description, with no explicit context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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