Win-10-MCP-Server---Simple-persistant-logging

Win-10-MCP-Server---Simple-persistant-logging

**摘要:** Win-10-MCP-Server 通过创建持久的硬盘日志来增强 MCP Server 的日志记录,确保数据完整性,包括备份、错误处理和带时间戳的操作。

概述

这个工具通过修改 MCP Server 文件系统模块,增强了日志记录功能,确保:

  • 文件操作日志持久保存到硬盘
  • 自动创建文件备份
  • 详细的操作记录和错误跟踪

安装步骤

1. 创建日志记录模块

在项目根目录创建 logger.mjs

// logger.mjs
import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const LOG_DIR = path.join(__dirname, "logs");

// 确保日志目录存在
async function ensureLogDir() {
    try {
        await fs.mkdir(LOG_DIR, { recursive: true });
    } catch (err) {
        console.error("无法创建日志目录:", err);
    }
}

ensureLogDir();
const LOG_FILE = path.join(LOG_DIR, "KAN_server.log");

// 日志记录函数
export async function logToFile(level, message) {
    const timestamp = new Date().toISOString();
    const line = `[${level.toUpperCase()}] ${timestamp} - ${message}\n`;

    try {
        await fs.appendFile(LOG_FILE, line);
    } catch (err) {
        console.error("无法写入日志文件:", err);
    }
}

2. 修改 MCP Server 文件系统模块

找到 index.js 文件路径(Windows 10):

C:\Users\[用户名]\AppData\Roaming\npm\node_modules@modelcontextprotocol\server-filesystem\dist

3. 更新 write_file 处理函数

index.js 中添加或修改 handleOperation 函数中的 write_file 案例:

case "write_file": {
    try {
        // 1. 解析参数
        const parsed = WriteFileArgsSchema.safeParse(args);
        if (!parsed.success) {
            throw new Error(`write_file的无效参数: ${parsed.error}`);
        }

        // 2. 验证路径
        const validPath = await validatePath(parsed.data.path);
        let backupName = null;

        // 3. 如果文件存在则创建备份
        try {
            await fs.access(validPath);
            const now = new Date();
            const dateString = `${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}${String(now.getFullYear()).slice(-2)}_${String(now.getHours()).padStart(2, '0')}_${String(now.getMinutes()).padStart(2, '0')}`;
            
            const dirName = path.dirname(validPath);
            const baseName = path.basename(validPath);
            backupName = `${baseName}.${dateString}__CLDBak`;
            const backupPath = path.join(dirName, backupName);

            await fs.rename(validPath, backupPath);
            await logToFile("INFO", `在${backupPath}处创建了备份`);
        } catch (err) {
            if (err.code !== 'ENOENT') {
                await logToFile("ERROR", `备份文件时错误: ${err.message}`);
                throw err;
            }
            await logToFile("INFO", `在${validPath}处没有现有文件。未创建备份。`);
        }

        // 4. 写入新内容
        await fs.writeFile(validPath, parsed.data.content, "utf-8");
        await logToFile("INFO", `成功写入${validPath}`);

        // 5. 准备响应
        let responseText = `成功写入${parsed.data.path}`;
        if (backupName) {
            responseText += `\nKAN: 备份已保存到${backupName}`;
        }

        return {
            content: [{
                type: "text",
                text: responseText,
            }],
        };
    } catch (error) {
        await logToFile("ERROR", `write_file操作失败: ${error.message}`);
        throw error;
    }
}

功能特点

  • 自动备份:每次文件修改前创建带时间戳的备份
  • 详细日志:记录所有操作,包括成功和失败的文件操作
  • 安全验证:验证文件路径,防止未授权访问
  • 用户通知:在 Claude 界面中显示备份文件名

解决的问题

此修改解决了 Claude 可能无法完全完成文件写入操作的问题,防止原始文件在不完整写入时被破坏,方便用户通过差异比较工具验证变更。