Token导航 LogoToken导航

MCP Server · 运维云端

Win 10 MCP Server Simple Persistant Logging

一个用于在文件写入时自动创建备份并记录日志的持久化日志系统,适用于防止文件覆盖和数据丢失的场景。

未说明官方级别未说明来源级核验工具 0
持久化存储JavaScriptClaude日志记录Claude Desktop

快速开始

公开资料没有提供安装命令,按仓库或官方文档接入。
作者 / 组织
trevorwilkerson
提供方
trevorwilkerson

工具数量

0

来源目录标注

资源数量

0

来源目录标注

提示词数量

0

来源目录标注

GitHub Star

0

仓库热度

收录来源

1 个

MCP World

选型结论

Win 10 MCP Server Simple Persistant Logging 属于运维云端类 MCP Server,公开资料标注 0 个工具,通过传输方式未标注接入,适配 Claude Desktop、Claude,没有现成的安装命令;接入前先确认权限范围。

分类

运维云端

传输方式

未说明

认证方式

无需认证

部署方式

公开资料未说明

安装与配置

公开目录没有给出安装命令,需要按仓库 README安装;下面按同类条目的通用流程说明。

公开命令不是通用的启动方式,拼不出可靠配置示例;请在客户端 MCP 配置里按官方文档填写 command 和 args。

上手步骤

  1. 1

    先确认运行方式

    公开资料没有标注传输方式,先看仓库 README,确认是本地进程还是远程地址。

  2. 2

    获取服务

    公开目录没有给出安装命令,按仓库 README里的步骤安装或获取服务。

  3. 3

    写入客户端配置

    在客户端的 MCP 配置里填启动命令和参数,保存后完全退出客户端再打开,让新配置生效。

  4. 4

    验证是否可用

    连接成功后客户端会列出 0 个工具,随便调一个只读工具确认能返回结果。

接入前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

公开资料仍需确认:安装命令

详细介绍

Win-10-MCP-Server——简单持久的日志记录

虽然MCP Inspector显示了MCP服务器的所有通信,但我希望日志能保存在HDD上。 具体来说,因为我修改了index.js中“服务器文件系统/dist”中的“写入文件”案例

问题:Claude变得非常懒惰,可能无法编写它正在处理的整个文件。

例如,它可以写标题,然后说 \[其余代码保持不变…\]

现在我的文件被覆盖了。..

我做了两件事:

  1. 每次调用write_file工具时,我都会复制一个带有日期时间戳的目标文件(如果存在)。
  2. 记录文件名并将其发送回(返回语句)Claude Desktop App,以便用户看到备份文件名。

然后,我手动使用diff工具来验证发生了什么变化。…稍后修复克劳德的错误

这里是代理的绝佳用例。…提示,提示。.

1.创建 logger.mjs

创建一个名为的新文件 logger.mjs 在项目根目录中:

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

// Determine the directory of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Define logs directory relative to the logger.mjs file
const LOG_DIR = path.join(__dirname, "logs");

// Ensure the logs directory exists
async function ensureLogDir() {
    try {
        await fs.mkdir(LOG_DIR, { recursive: true });
    } catch (err) {
        console.error("Failed to create logs directory:", err);
    }
}

ensureLogDir();

// Define log file path
const LOG_FILE = path.join(LOG_DIR, "KAN_server.log");

/**
 * Logs a message to the log file with the specified level.
 *
 * @param {string} level - The severity level of the log (e.g., INFO, ERROR).
 * @param {string} message - The message to 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) {
        // If writing fails, log to console.error without disrupting the main flow
        console.error("Failed to write to log file:", err);
    }

}

// Temporary verification (commented out to prevent interference)
// console.log("Logging to:", LOG_FILE); // Do not use, as it can interfere with JSON responses

添加index.js

我更改了我的index.js 它可以在以下目录中找到(Win10): C: \\用户\\TrevorW\\AppData\\Roaming\\npm\\node_modules@modelcontextprotocol\\服务器文件系统\\dist

3.实施 write_file 案例

修改 write_file 操作,确保它处理文件写入和备份创建,并记录所有相关信息。

// index.js

// ...imports and schema definitions...

/**
 * Validates the provided file path to prevent unauthorized access.
 *
 * @param {string} filePath - The file path to validate.
 * @returns {Promise} - The validated and normalized file path.
 * @throws Will throw an error if the path is invalid.
 */
async function validatePath(filePath) {
    // Normalize the path to prevent directory traversal
    const normalizedPath = path.normalize(filePath);

    // Define allowed base directories
    const allowedBase = path.resolve(process.cwd(), "Control_Charts");

    // Ensure the normalized path starts with the allowed base directory
    if (!normalizedPath.startsWith(allowedBase)) {
        throw new Error("Invalid file path. Access denied.");
    }

    // Additional validations can be added here (e.g., file extension checks)

    return normalizedPath;
}

/**
 * Handles various operations based on the provided operation name and arguments.
 *
 * @param {string} operation - The name of the operation to perform.
 * @param {object} args - The arguments required for the operation.
 * @returns {Promise} - The response object to send back.
 */
async function handleOperation(operation, args) {
    switch (operation) {
        case "write_file": {
            try {
                // 1. Parse incoming arguments
                const parsed = WriteFileArgsSchema.safeParse(args);
                if (!parsed.success) {
                    throw new Error(`Invalid arguments for write_file: ${parsed.error}`);
                }

                // 2. Validate the path
                const validPath = await validatePath(parsed.data.path);

                let backupName = null; // Initialize backupName to track if a backup is created

                // 3. Backup existing file if it exists
                try {
                    await fs.access(validPath); // Throws if file doesn't exist

                    // Build date/time string in MMDDYY_HH_MM format
                    const now = new Date();
                    const mm = String(now.getMonth() + 1).padStart(2, '0');
                    const dd = String(now.getDate()).padStart(2, '0');
                    const yy = String(now.getFullYear()).slice(-2);
                    const hh = String(now.getHours()).padStart(2, '0');
                    const mn = String(now.getMinutes()).padStart(2, '0');
                    const dateString = `${mm}${dd}${yy}_${hh}_${mn}`;

                    // Build backup file path
                    const dirName = path.dirname(validPath);
                    const baseName = path.basename(validPath);
                    backupName = `${baseName}.${dateString}__CLDBak`; // Assign to backupName
                    const backupPath = path.join(dirName, backupName);

                    // Rename original file to create backup
                    await fs.rename(validPath, backupPath);

                    // Log the backup creation
                    await logToFile("INFO", `Backup created at ${backupPath}`);
                } catch (err) {
                    if (err.code !== 'ENOENT') { // ENOENT: File does not exist
                        // Log unexpected errors during backup
                        await logToFile("ERROR", `Error accessing or backing up file: ${err.message}`);
                        throw err; // Re-throw unexpected errors
                    }
                    // File doesn't exist; proceed without backup
                    await logToFile("INFO", `No existing file at ${validPath}. No backup created.`);
                }

                // 4. Write the new content
                await fs.writeFile(validPath, parsed.data.content, "utf-8");
                await logToFile("INFO", `Successfully wrote to ${validPath}`);

                // 5. Prepare the response
                let responseText = `Successfully wrote to ${parsed.data.path}`;
                if (backupName) {
                    responseText += `\nKAN: Backup saved to ${backupName}`;
                }

                //  THIS IS THE KEY TO MAKE CLAUDE DESKTOP HAPPY
                //  The response HAS TO BE in JSON, or will bitch at you
                const response = {
                    content: [{
                        type: "text",
                        text: responseText,
                    }],
                };

                // 6. Return the response without any additional logging
                return response;
            } catch (error) {
                // Log the error details
                await logToFile("ERROR", `write_file operation failed: ${error.message}`);
                throw error; // Ensure the error is propagated appropriately
            }
        }

        // ... handle other cases ...      //  Example of the lazyness I am dealing with here ....

        default:
            throw new Error(`Unknown operation: ${operation}`);
    }
}

如果你已经做到了这一点,你可能会说,嘿,Trevor,为什么不使用类似IDE的游标来添加此功能呢。

我的答案是:三个月后我们会有光标吗?在Windows 10完全进入语音模式之前,我可能会学到一些东西。...

工具与能力

工具数量

0

资源数量

0

提示词数量

0

能力标签

文件备份JavaScript本地部署日志记录数据安全持久化存储文件管理

支持客户端

Claude DesktopClaude

数量来自来源目录的标注,具体工具清单以官方文档为准。

典型使用场景

看服务状态

查询容器、日志和监控指标,定位异常。

执行部署变更

在权限范围内触发发布、回滚和环境切换。

核对资源用量

汇总用量,找出闲置和超额的部分。

选择建议

值得选的地方

  • 只提供 0 个工具,职责集中,接入后不容易误操作。
  • 已经适配 Claude Desktop、Claude,换客户端不用重新研究配置。
  • 公开说明写得比较完整,接入前能看清能力边界。

先想清楚的地方

  • 公开资料没有可直接复制的安装命令,第一次接入要自己找入口。
  • 公开摘要偏短,具体能力和限制要回到仓库确认。
  • 第三方目录整理,版本更新和行为细节以官方仓库为准。

更适合

  • 需要在运维云端场景里让模型直接调用外部能力的人。
  • 已经在用 Claude Desktop 的用户,接入路径最短。
  • 愿意照着官方文档一步步配环境的人。

不太适合

  • 希望一条命令就装好、不想看文档的人。
  • 需要厂商级 SLA 和技术支持的生产环境。

同类对比

5 个同类
MCP Server工具数传输方式安装命令收录来源最后核验
Win 10 MCP Server Simple Persistant Logging

MCP World · 本页

0未说明未标注1 个2026-05-17
Ui Tars Desktop 8a825770

MCP World

0stdio有1 个2026-05-17
Elie222 MCP

MCP World

0未说明未标注1 个2026-05-17
Arizeai Phoenix MCP

MCP World

0stdio有3 个2026-05-17
Unity MCP 87ee506e

MCP World

42HTTP有2 个2026-05-17

按同分类和工具数量挑出最接近的几条,字段以各自详情页为准。

常见问题

5 条

Win 10 MCP Server Simple Persistant Logging 怎么安装?

公开目录没有给出可以直接复制的安装命令,需要按仓库 README里的步骤安装;装好后写进客户端的 MCP 配置再重启。

Win 10 MCP Server Simple Persistant Logging 怎么在 Claude Desktop、Cursor 里配置?

它是传输方式未标注,客户端配置里要写启动命令和参数,运行环境是 未标注;保存后完全退出客户端再打开,配置才会生效。

Win 10 MCP Server Simple Persistant Logging 收费吗?

本站只整理公开资料,不代收费用,也没有标注具体价格。是否收费取决于服务本身和背后的接口额度,正式使用前按官方说明确认。

Win 10 MCP Server Simple Persistant Logging 需要 API Key 吗?

公开资料标注为无需认证,装好就能连;如果实际调用时报鉴权错误,按官方文档补上凭据。

Win 10 MCP Server Simple Persistant Logging 支持哪些客户端?

公开资料标注支持 Claude Desktop、Claude;其他客户端只要能配置 MCP Server,也能用同样的命令或地址接入。

来源信息

继续浏览同类 MCP