Skip to main content
Glama

log_conversation

Log AI conversations by recording user requests, execution plans, and summaries in structured format for searchable history and project continuity.

Instructions

记录AI对话 - 所有会话都要记录

使用规范: • userRequest: 用户原始需求+上传文件说明 • aiTodoList: 你的执行计划清单(即使只是查看也要列出) • aiSummary: 你的操作总结(3-5句话,包括解释、分析等) • fileOperations: 文件操作总结,格式:"动作 文件路径 - 说明"(可为空) • title: 对话标题(可选) • tags: 标签数组(可选)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
userRequestYes用户原始需求 + 上传文件说明
aiTodoListYesAI的执行计划清单(即使只是查看也要列出)
aiSummaryYesAI的操作总结(3-5句话,包括解释、分析等)
fileOperationsNo文件操作总结,格式:"动作 文件路径 - 说明"(可为空)
titleNo对话标题(可选)
tagsNo标签数组(可选)
projectNo项目名(可选,自动检测)

Implementation Reference

  • The logConversation method implements the core tool logic: validates parameters, auto-detects project, generates conversation entry, appends to daily Markdown log file, and returns formatted success or error response.
    async logConversation(params: unknown): Promise<{ content: Array<{ type: string; text: string }> }> {
      try {
        const validatedParams = validateLogConversation(params);
        const {
          userRequest,
          aiTodoList,
          aiSummary,
          fileOperations,
          title,
          tags,
          platform
        } = validatedParams;
    
        // Auto-detect project from current working directory
        const projectInfo = await this.fileManager.getProjectInfo();
        const projectName = projectInfo.name;
    
        await this.fileManager.initializeProject();
    
        const now = new Date();
        // Use zero-padded date format for better sorting (2025-08-07 instead of 2025-8-7)
        const year = now.getFullYear();
        const month = String(now.getMonth() + 1).padStart(2, '0');
        const day = String(now.getDate()).padStart(2, '0');
        const dateStr = `${year}-${month}-${day}`;
        const conversationEntry: ConversationEntry = {
          id: randomUUID(),
          timestamp: now.toISOString(),
          project: projectName,
          platform: platform || CONSTANTS.PLATFORMS.UNKNOWN,
          userRequest: userRequest.trim(),
          aiTodoList: aiTodoList || [],
          aiSummary: aiSummary.trim(),
          fileOperations: fileOperations || [],
          title: title?.trim() || undefined,
          tags: tags || []
        };
    
        const dailyLogPath = await this.fileManager.getDailyLogPath(projectName, dateStr);
        let existingContent = await this.fileManager.readFile(dailyLogPath);
        
        // Calculate conversation number
        const existingConversationCount = (existingContent.match(/## 对话/g) || []).length;
        const conversationNumber = existingConversationCount + 1;
        
        // Generate the conversation markdown
        const conversationMarkdown = MarkdownFormatter.formatConversationEntry(conversationEntry, conversationNumber);
        
        if (!existingContent) {
          // New file: create header + new conversation
          const header = MarkdownFormatter.formatDailyLogHeader(projectName, dateStr, projectInfo.root);
          const finalContent = header + conversationMarkdown;
          await this.fileManager.writeFile(dailyLogPath, finalContent);
        } else {
          // Existing file: just append new conversation
          const finalContent = existingContent + conversationMarkdown;
          await this.fileManager.writeFile(dailyLogPath, finalContent);
        }
    
        return {
          content: [
            {
              type: 'text',
              text: `✅ 对话已成功记录到项目 "${projectName}"!\n\n` +
                    `📁 文件位置: ${dailyLogPath}\n` +
                    `💻 项目目录: ${projectInfo.root || '未检测到项目'}\n` +
                    `🕒 时间: ${now.toLocaleString('zh-CN')}\n` +
                    `🏷️ 标签: ${(tags && tags.length > 0) ? tags.join(', ') : '无'}\n` +
                    `⚡ 执行任务: ${aiTodoList?.length || 0}\n` +
                    `📂 文件操作: ${fileOperations?.length || 0}\n` +
                    `📝 对话编号: 对话${conversationNumber}`
            }
          ]
        };
      } catch (error) {
        const errorMessage = error instanceof ValidationError 
          ? `参数验证失败: ${error.message}`
          : error instanceof FileOperationError
          ? `文件操作失败: ${error.message} (文件: ${error.filePath})`
          : `记录对话时出错: ${String(error)}`;
        
        return {
          content: [
            {
              type: 'text',
              text: `❌ ${errorMessage}`
            }
          ]
        };
      }
    }
  • Zod schema for validating input parameters of the log_conversation tool, including transformation for defaults.
    export const LogConversationSchema = z.object({
      project: z.string().optional(),  // 项目名称(可选,自动检测)
      userRequest: z.string().min(1, '用户需求不能为空'),
      aiTodoList: z.array(z.string()).min(1, 'AI执行计划不能为空'),
      aiSummary: z.string().min(1, 'AI总结不能为空'),
      fileOperations: z.array(z.string()).optional(),
      title: z.string().optional(),
      tags: z.array(z.string()).optional(),
      platform: z.string().default(CONSTANTS.PLATFORMS.CLAUDE_CODE)
    }).transform((data) => ({
      ...data,
      tags: data.tags || [],
      fileOperations: data.fileOperations || [],
      platform: data.platform || CONSTANTS.PLATFORMS.CLAUDE_CODE
    }));
  • src/index.ts:38-78 (registration)
    MCP tool registration: defines the 'log_conversation' tool specification including name, description, and input schema in the ListTools response.
    {
      name: 'log_conversation',
      description: '记录AI对话 - 所有会话都要记录\n\n使用规范:\n• userRequest: 用户原始需求+上传文件说明\n• aiTodoList: 你的执行计划清单(即使只是查看也要列出)\n• aiSummary: 你的操作总结(3-5句话,包括解释、分析等)\n• fileOperations: 文件操作总结,格式:"动作 文件路径 - 说明"(可为空)\n• title: 对话标题(可选)\n• tags: 标签数组(可选)',
      inputSchema: {
        type: 'object',
        properties: {
          userRequest: {
            type: 'string',
            description: '用户原始需求 + 上传文件说明'
          },
          aiTodoList: {
            type: 'array',
            items: { type: 'string' },
            description: 'AI的执行计划清单(即使只是查看也要列出)'
          },
          aiSummary: {
            type: 'string',
            description: 'AI的操作总结(3-5句话,包括解释、分析等)'
          },
          fileOperations: {
            type: 'array',
            items: { type: 'string' },
            description: '文件操作总结,格式:"动作 文件路径 - 说明"(可为空)'
          },
          title: {
            type: 'string',
            description: '对话标题(可选)'
          },
          tags: {
            type: 'array',
            items: { type: 'string' },
            description: '标签数组(可选)'
          },
          project: {
            type: 'string',
            description: '项目名(可选,自动检测)'
          }
        },
        required: ['userRequest', 'aiTodoList', 'aiSummary']
      }
    },
  • src/index.ts:161-162 (registration)
    Dispatch handler in CallToolRequest that routes 'log_conversation' calls to the ConversationLogger instance.
    case 'log_conversation':
      return await this.conversationLogger.logConversation(args || {});
  • Validator function for log_conversation parameters using the Zod schema, throws error on invalid input.
    export const validateLogConversation = (data: unknown): LogConversationParams => {
      const result = LogConversationSchema.safeParse(data);
      if (!result.success) {
        const errorMessages = result.error.errors.map(err => `${err.path.join('.')}: ${err.message}`).join('; ');
        throw new Error(`${CONSTANTS.ERROR_MESSAGES.INVALID_PARAMETERS}: ${errorMessages}`);
      }
      return result.data as LogConversationParams;
    };

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/fablefang/ai-conversation-logger-mcp'

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