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 可能无法完全完成文件写入操作的问题,防止原始文件在不完整写入时被破坏,方便用户通过差异比较工具验证变更。