1. 项目概述:一个为 Cursor 编辑器注入记忆的 MCP 服务器

如果你和我一样,深度依赖 Cursor 作为主力代码编辑器,并且每天都在和它的 AI 伙伴(无论是 Claude 还是 GPT)进行高频对话,那你一定遇到过这个痛点: 对话历史是“健忘”的 。每次开启一个新聊天,或者项目重启,AI 助手就像一张白纸,完全不记得我们之前讨论过的项目架构、刚刚定下的命名规范,甚至是几分钟前才解决的某个棘手的 Bug。这意味着我们不得不反复粘贴上下文、重新解释背景,效率大打折扣。

S2thend/cursor-history-mcp 这个项目,就是为了根治这个“健忘症”而生的。它是一个 MCP(Model Context Protocol)服务器 ,专门为 Cursor 编辑器设计。简单来说,它就像给你的 Cursor AI 助手装上了一块“外置硬盘”,能够自动、智能地保存和管理你与 AI 的所有对话历史、项目上下文,并在你需要时,精准地将相关记忆“喂”给 AI,让它瞬间“想起”一切。

这个工具的核心价值在于,它将一次性的、孤立的 AI 对话,转变成了一个持续积累、可被检索的 项目知识库 。对于需要长期维护复杂项目、或与 AI 进行深度结对编程的开发者而言,这不仅仅是效率工具,更是工作流的一次质变。接下来,我将带你深入拆解它的设计思路、实现细节,并分享我将其集成到日常开发中的实战经验与避坑指南。

2. 核心设计思路与 MCP 协议解析

2.1 为什么是 MCP?协议选型的深层考量

在深入代码之前,我们必须先理解 MCP(Model Context Protocol) 是什么,以及为什么它是解决 Cursor 上下文记忆问题的最佳载体。

MCP 是由 Anthropic 提出的一种开放协议,其核心目标是 标准化 AI 模型与外部工具、数据源之间的通信方式 。你可以把它想象成 AI 世界的“USB 协议”或“HTTP 协议”。在 MCP 架构下,AI 模型(如 Claude)是“客户端”,而各种提供特定能力(如读取文件、搜索网络、查询数据库)的服务则是“服务器”。客户端通过标准的 MCP 请求,可以调用服务器提供的各种“工具”(Tools)和“资源”(Resources)。

对于 cursor-history-mcp 这个项目,选择基于 MCP 构建,是经过深思熟虑的:

  1. 非侵入性与未来兼容性 :MCP 是 Cursor(以及未来其他支持 MCP 的编辑器/IDE)官方支持和倡导的扩展方式。通过实现一个 MCP 服务器,我们无需修改 Cursor 编辑器或 AI 模型本身的任何代码。这保证了工具的稳定性,也意味着只要 Cursor 持续支持 MCP,这个工具就能一直工作下去。
  2. 能力标准化与聚焦 :MCP 协议明确定义了服务器能提供什么(工具和资源)。 cursor-history-mcp 的核心能力非常聚焦:提供“历史对话”这个资源。AI 模型通过标准的 MCP read_resource 调用,就能获取到格式化后的历史记录。这种设计清晰地将“记忆存储与检索”这个复杂功能,封装成了一个标准的、可被 AI 理解的服务。
  3. 灵活的上下文管理 :MCP 允许服务器动态地告诉客户端“我现在有哪些资源可用”。这意味着 cursor-history-mcp 可以根据当前项目、时间或用户指令,智能地决定提供哪一段历史、以何种摘要形式提供,从而在有限的上下文窗口内,实现价值最大化。

注意 :虽然 MCP 由 Anthropic 提出,但它是一个开放协议。这意味着 cursor-history-mcp 理论上也能服务于其他实现了 MCP 客户端的 AI 工具,这为项目的长期价值提供了更多可能性。

2.2 项目架构与数据流设计

理解了 MCP 的基础,我们来看 cursor-history-mcp 是如何具体工作的。它的架构可以概括为“ 监听-存储-处理-提供 ”四个环节。

  1. 监听环节 :服务器需要实时获取 Cursor 中 AI 对话的内容。这通常通过监听 Cursor 产生的特定日志文件、或利用 Cursor 可能提供的 API(如果未来开放)来实现。项目需要解决如何可靠、低延迟地捕获到完整的对话流(包括用户提问和 AI 回复)。
  2. 存储环节 :捕获到的原始对话数据需要被持久化。这里涉及到存储选型:
    • 本地文件存储(如 SQLite) :优点是零依赖、部署简单、速度快。 cursor-history-mcp 很可能采用这种方式,将历史数据以结构化的形式(例如按项目、会话、时间戳)保存在用户本地的一个数据库中。
    • 向量数据库(可选进阶) :如果未来要实现基于语义的智能检索(例如“帮我找到上次讨论用户登录模块的对话”),那么引入像 ChromaDB LanceDB 这样的轻量级向量数据库,将对话内容转换为向量存储,会是更强大的方案。
  3. 处理环节 :原始对话日志可能是杂乱的文本。服务器需要对其进行清洗、结构化,并可能生成摘要。例如,将一次完整的 Q&A 识别为一个“对话轮次”,并提取关键实体(如提到的文件名、函数名、错误代码)。这一步是提升后续检索精度的关键。
  4. 提供环节(MCP 服务器核心) :当 Cursor 的 AI 模型需要上下文时,它会通过 MCP 向本服务器发起请求。服务器根据请求参数(可能隐含了当前文件路径、项目信息),从存储中检索出最相关的历史对话片段,按照 MCP 资源的标准格式(通常是包含 text json 内容的响应体)返回。

整个数据流形成了一个闭环:AI 对话产生历史,历史被保存和加工,加工后的历史在需要时又被注入到新的 AI 对话中,从而提升新对话的质量。

3. 核心功能拆解与实现要点

3.1 对话历史的捕获与解析

这是项目最基础,也最可能出问题的环节。Cursor 本身并未公开官方的实时对话流 API,因此开发者需要一些“巧劲”。

常见实现方案与取舍:

  • 方案A:监听日志文件 :Cursor 在运行过程中可能会在特定目录(如 ~/Library/Logs/Cursor/ %APPDATA%/Cursor/logs/ )生成日志文件。这些日志可能包含对话内容。需要编写一个文件监听器(如使用 Node.js 的 chokidar 库),实时跟踪日志文件的追加内容,并通过正则表达式或特定标记来解析出对话。
    • 优点 :实现相对直接,不依赖网络。
    • 缺点 :高度依赖 Cursor 的日志格式,一旦 Cursor 更新导致日志格式变化,解析器就可能失效,稳定性风险高。且日志可能包含敏感信息,需要谨慎处理。
  • 方案B:模拟或拦截网络请求 :Cursor 与后端 AI 服务(如 Anthropic, OpenAI)的通信是通过网络请求完成的。理论上可以设置一个本地代理,拦截这些请求和响应来获取对话内容。
    • 优点 :获取的数据结构清晰、完整。
    • 缺点 :实现复杂,涉及 HTTPS 解密(可能需要安装自签名证书),对用户来说配置门槛高,且可能引发安全软件告警。
  • 方案C:利用 Cursor 的扩展能力(如果存在) :持续关注 Cursor 官方是否提供插件或扩展 API。这是最理想、最稳定的方式,但目前可能还不存在。

实操心得与避坑指南:

从我尝试类似项目的经验来看, 方案A(监听日志)是目前可行性最高的起点 ,但必须做好防御性编程。

  1. 健壮的日志解析 :不要写死正则表达式。应该先收集不同场景下(正常对话、代码编辑、错误状态)的大量日志样本,找出对话内容的稳定模式(例如,是否以 [USER] [ASSISTANT] 这样的标记开头)。解析代码要有足够的容错性,匹配失败时记录警告而非直接崩溃。
  2. 处理日志轮转与切割 :日志文件可能会在达到一定大小后被轮转(重命名并新建一个)。你的监听器必须能处理 rename create 事件,确保监听不中断。
  3. 性能与缓冲区 :日志写入可能很快,特别是当 AI 流式输出时。避免在每次文件变化事件中都进行完整的读取和解析。应该实现一个小的去抖(debounce)机制和缓冲区,累积一小段时间内的变化再统一处理,以减少 IO 压力。
  4. 隐私安全 :明确告知用户该工具会读取并存储对话日志。考虑提供选项,允许用户排除某些包含敏感信息的项目或会话不被记录。存储时,是否需要对内容进行简单的脱敏处理(如自动遮盖可能的密钥模式)?

3.2 历史数据的存储与索引策略

数据捕获后,我们需要一个高效、可靠的方式来存储它。 cursor-history-mcp 作为一个本地优先的工具, SQLite 几乎是必然选择。

数据库表结构设计建议:

-- 会话表:代表一次连续的 Cursor 使用周期(可能对应一个项目窗口)
CREATE TABLE sessions (
    id TEXT PRIMARY KEY, -- UUID
    project_path TEXT, -- 项目根目录,用于关联历史
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 对话记录表:存储每一轮完整的 Q&A
CREATE TABLE messages (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    session_id TEXT,
    role TEXT CHECK(role IN ('user', 'assistant', 'system')),
    content TEXT, -- 完整的消息内容
    tokens INTEGER, -- 估算的token数,用于上下文窗口管理
    metadata TEXT, -- JSON字段,存储额外信息,如涉及的文件、语言、模型等
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
);

-- 索引表(可选,用于加速基于内容的检索)
CREATE TABLE message_embeddings (
    message_id INTEGER PRIMARY KEY,
    embedding BLOB, -- 存储文本的向量化表示
    FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
);

为什么这样设计?

  1. 会话(Session)抽象 :将对话按“项目窗口”或“时间窗口”组织,符合用户的心理模型。当用户在新项目中问 AI 时,服务器可以优先提供同一 project_path 下的历史会话,相关性最高。
  2. 元数据(Metadata)字段 :这是实现智能检索的关键。在解析消息时,可以运行一个简单的分析器,提取出消息中提到的文件路径(如 ./src/utils/api.js )、函数名、错误码、语言类型等,存入 metadata 的 JSON 中。这样,后续可以根据“当前打开的文件”快速找到相关的历史讨论。
  3. Token 计数 :AI 模型的上下文窗口是宝贵资源。记录每条消息的大致 token 数,可以帮助服务器在响应 MCP 请求时,做出更优的决策:是提供完整的最近 10 条对话,还是提供 3 天前一次重要讨论的摘要?

进阶考量:向量索引 对于“帮我找到关于用户认证逻辑的讨论”这类语义搜索需求,仅靠关键词匹配(元数据)是不够的。这就是 message_embeddings 表的用途。你可以使用一个本地运行的轻量级嵌入模型(如 all-MiniLM-L6-v2 ,通过 sentence-transformers 库),将消息内容转换为向量。当用户提出一个语义查询时,将查询语句也转换为向量,并在数据库中进行余弦相似度搜索,找到最相关的历史对话。这一步计算量稍大,可以作为可选的高级功能。

3.3 MCP 服务器端点的实现

这是项目作为 MCP 服务器的核心。你需要实现 MCP 协议规定的几个标准端点。这里我们聚焦于最关键的 resources read_resource

1. 声明可用的资源( resources

当 Cursor(MCP 客户端)初始化连接时,它会调用 tools/list resources/list 。你的服务器需要返回一个资源列表,告诉客户端“我这里有这些历史资源可供查询”。

// 服务器响应示例
{
  "resources": [
    {
      "uri": "cursor-history://session/recent",
      "name": "Recent conversation history",
      "description": "The most recent messages from the current project session.",
      "mimeType": "text/plain"
    },
    {
      "uri": "cursor-history://project/context",
      "name": "Project context summary",
      "description": "A summarized context of all conversations in the current project.",
      "mimeType": "application/json"
    },
    {
      "uri": "cursor-history://search?q={query}",
      "name": "Search history",
      "description": "Search through all past conversations.",
      "mimeType": "text/plain"
    }
  ]
}

关键点 uri 是资源的唯一标识符,也是客户端请求时的地址。你可以设计不同的 URI 模式来代表不同类型的查询(如最近记录、项目总结、搜索)。

2. 处理资源读取请求( read_resource

当 AI 模型需要历史上下文时,Cursor 会向你的服务器发送一个 read_resource 请求,其中包含它想获取的 uri

你的服务器需要:

  1. 解析 uri ,理解客户端的意图(是要最近记录,还是搜索某个关键词)。
  2. 根据 uri 参数和 当前上下文 (如客户端可能在请求中附带当前文件路径,这取决于 MCP 客户端的实现,有时需要服务器从其他途径获取),从 SQLite 数据库中执行相应的查询。
  3. 将查询结果格式化为 text/plain application/json 内容,并返回。
// 伪代码示例:处理 read_resource
async function handleReadResource(uri, currentProjectPath) {
  if (uri.startsWith('cursor-history://session/recent')) {
    const recentMessages = await db.getRecentMessages(currentProjectPath, 10); // 获取当前项目最近10条
    return {
      contents: [{
        type: 'text',
        text: formatMessagesAsText(recentMessages) // 将消息数组格式化为易读的文本
      }]
    };
  } else if (uri.startsWith('cursor-history://search')) {
    const query = new URL(uri).searchParams.get('q');
    const results = await db.semanticSearch(query, currentProjectPath);
    return {
      contents: [{
        type: 'text',
        text: formatSearchResults(results)
      }]
    };
  }
  // ... 处理其他 uri 模式
}

3. 上下文的动态注入 一个优秀的 cursor-history-mcp 服务器不应该被动等待调用。它可以更智能。例如,当检测到用户在新会话中打开了某个文件( main.ts ),服务器可以主动通过 MCP 的 notifications 或是在 resources/list 中动态添加一个资源,如 cursor-history://file/main.ts ,暗示 AI 客户端“这里有关于这个文件的历史讨论,你可以考虑读一下”。这需要服务器与编辑器有更深度的集成感知。

4. 部署、配置与 Cursor 集成实战

4.1 本地开发与运行环境搭建

假设项目使用 Node.js 开发(这是实现 MCP 服务器的常见选择),你需要确保环境就绪。

  1. 克隆项目与安装依赖
    git clone https://github.com/S2thend/cursor-history-mcp.git
    cd cursor-history-mcp
    npm install  # 或 pnpm install / yarn install
    
  2. 环境变量配置 :项目根目录下可能需要一个 .env 文件或配置文件(如 config.json )。
    # .env 示例
    CURSOR_LOG_PATH=~/Library/Logs/Cursor/Cursor.log
    DB_PATH=./data/history.db
    # 是否启用向量搜索(会增加内存和CPU占用)
    ENABLE_SEMANTIC_SEARCH=false
    # 本地嵌入模型路径(如果启用)
    EMBEDDING_MODEL_PATH=./models/all-MiniLM-L6-v2
    
    关键配置解析
    • CURSOR_LOG_PATH :这是最关键的路径,需要根据你的操作系统(macOS, Windows, Linux)和 Cursor 的安装位置准确配置。如果路径不对,服务器将“听”不到任何对话。
    • DB_PATH :指定 SQLite 数据库存放位置。建议放在项目 data 目录下,便于管理。
  3. 启动服务器 :通常项目会提供一个启动脚本。
    npm start
    # 或用于开发的热重载模式
    npm run dev
    
    启动后,服务器默认会在某个本地端口(如 3000 )监听,等待 Cursor 连接。

4.2 在 Cursor 中配置 MCP 服务器

这是将你的服务器与 Cursor AI 连接起来的关键一步。Cursor 的 MCP 配置通常在一个全局或项目级的配置文件中。

  1. 找到 Cursor 的 MCP 配置 :配置文件可能位于:

    • 全局配置 ~/.cursor/mcp.json (macOS/Linux) 或 %APPDATA%/Cursor/mcp.json (Windows)。
    • 项目级配置 :在项目根目录下的 .cursor/mcp.json 项目级配置优先级更高 ,这允许你为不同项目设置不同的历史策略。
  2. 编辑 MCP 配置文件 :在配置文件中添加你的服务器信息。

    // ~/.cursor/mcp.json 或 .cursor/mcp.json
    {
      "mcpServers": {
        "cursor-history": {
          "command": "node",
          "args": [
            "/ABSOLUTE/PATH/TO/YOUR/cursor-history-mcp/build/index.js" // 必须使用绝对路径!
          ],
          "env": {
            "CURSOR_LOG_PATH": "/Users/yourname/Library/Logs/Cursor/Cursor.log"
          }
        }
      }
    }
    

    重要细节

    • command :启动服务器的命令。如果你的服务器是 Node.js 脚本,就是 node 。如果是打包成的二进制文件,则指向该二进制文件。
    • args :传递给命令的参数,第一个通常是服务器入口文件的 绝对路径 。相对路径很可能导致 Cursor 启动失败。
    • env :可以在这里覆盖服务器所需的环境变量,这对于在不同机器上保持配置一致性很有用。
  3. 重启 Cursor :修改配置后,需要完全关闭并重新打开 Cursor,以确保新的 MCP 配置被加载。

4.3 验证与调试

配置完成后,如何确认一切工作正常?

  1. 检查 Cursor 连接 :在 Cursor 中打开 AI 聊天面板,有时在输入框附近会有微小的提示或图标,表明已连接的 MCP 服务器。更直接的方式是,在聊天中输入一个测试性问题,观察 AI 的回复是否透露出它“知道”了历史信息(但这需要历史数据已存在)。
  2. 查看服务器日志 :你的 cursor-history-mcp 服务器在运行时应该会输出日志。查看这些日志,确认:
    • 是否成功连接到 Cursor 日志文件。
    • 是否成功解析到了对话消息并存入数据库。
    • 是否收到了来自 Cursor 的 MCP 请求(如 read_resource )。
  3. 直接查询数据库 :使用 SQLite 客户端(如 sqlite3 命令行工具或 DB Browser for SQLite)打开项目生成的 .db 文件,查看 sessions messages 表中是否有数据。这是最直接的验证方式。
  4. 使用 MCP 调试工具 :Anthropic 提供了一些 MCP 调试工具,如 mcp-cli 。你可以用它手动连接到你的服务器,发送 list_resources read_resource 请求,模拟 Cursor 的行为,从而独立于编辑器调试你的服务器逻辑。

5. 高级用法、优化与问题排查

5.1 提升历史检索的相关性与效率

当历史数据积累到成千上万条时,如何快速、准确地找到对当前对话最有用的片段,成为挑战。

  1. 基于上下文的动态过滤

    • 项目隔离 :这是最基本的过滤。始终将当前编辑器的项目路径( project_path )作为检索的第一条件,避免其他项目的历史造成干扰。
    • 文件关联 :在 read_resource 请求中,尝试获取当前激活的编辑器标签页的文件路径。如果获取到,优先检索 metadata 字段中包含该文件路径的历史消息。这实现了“基于文件的上下文记忆”。
    • 时间衰减权重 :在综合排序时,给较近的历史记录更高的权重,因为最近的讨论往往与当前任务连续性更强。
  2. 摘要生成与压缩 :对于很久以前的长篇讨论,直接提供原始文本会占用大量 token。可以在后台运行一个摘要任务(使用本地轻量级 LLM 或高效的摘要算法),为每个会话或主题生成一个简短的摘要。当 AI 请求“项目上下文”时,返回这些摘要而非全文,能极大节省上下文窗口。

  3. 混合检索策略

    • 关键词匹配(快) :首先利用 metadata 中的文件名、函数名等进行快速筛选。
    • 语义搜索(准) :对于更模糊的查询,使用向量数据库进行语义相似度搜索。
    • 将两者的结果进行融合和重排序,兼顾速度和准确性。

5.2 隐私、安全与数据管理

这是一个处理用户对话数据的工具,必须严肃对待隐私和安全。

  1. 明确的数据所有权 :所有数据存储在用户本地,不上传任何云端。这应该在项目的 README 中明确声明,让用户安心。
  2. 提供管理功能
    • 查看与删除 :应该提供一个简单的命令行界面或图形化工具,让用户可以查看存储了哪些历史,并选择性删除某个会话或全部历史。
    • 导出/导入 :允许用户导出历史数据为 JSON 等格式,方便备份或在其他机器上恢复。
    • 全局开关 :在配置中提供选项,允许用户完全禁用历史记录功能。
  3. 敏感信息过滤(可选但建议) :在存储前,可以对内容进行简单的正则表达式扫描,尝试识别并遮盖(例如替换为 [KEY_REDACTED] )类似密码、API Key、令牌等常见敏感信息模式。但这需要谨慎处理,避免误伤正常代码。

5.3 常见问题与故障排除实录

以下是我在搭建和使用类似工具时遇到的一些典型问题及解决方法:

问题1:Cursor 启动后,AI 完全没有“记忆”,服务器日志显示无连接或请求。

  • 排查步骤
    1. 检查 MCP 配置路径 :确认 mcp.json 中的 args 路径是 绝对路径 ,并且指向正确的、已构建的入口文件(如 index.js )。这是最常见的错误。
    2. 检查服务器是否在运行 :在终端运行 ps aux | grep node (或 Windows 任务管理器),查看你的服务器进程是否存在。
    3. 检查 Cursor 日志 :查看 Cursor 自身的日志(可能与你的服务器监听的不是同一个文件),看是否有关于加载 MCP 服务器的错误信息。
    4. 验证服务器独立性 :使用 mcp-cli 或写一个简单的脚本,直接连接你的服务器端口,手动发送 list_resources 请求,看服务器是否能正常响应。这可以排除 Cursor 配置问题,聚焦于服务器本身。

问题2:服务器能运行,但数据库里没有数据,或数据不完整。

  • 排查步骤
    1. 确认日志路径 :检查 CURSOR_LOG_PATH 环境变量是否指向了 Cursor 实际 写入日志的位置。不同版本、不同安装方式的 Cursor,日志路径可能不同。
    2. 验证日志格式 :手动打开 Cursor 的日志文件,触发几次 AI 对话,观察新日志的格式。确保你的解析器正则表达式或解析逻辑能匹配最新的格式。
    3. 检查文件监听权限 :确保你的服务器进程有权限读取目标日志文件。
    4. 查看解析器日志 :增加服务器解析环节的调试日志,打印出它从日志文件中读取到的原始行,以及解析后的结果,看是在哪一步出现了问题。

问题3:历史记录被成功检索并提供了,但 AI 的回复似乎没有利用这些信息。

  • 原因分析 :这可能不是服务器的问题,而是 AI 模型(客户端)如何使用上下文的问题。MCP 服务器只负责“提供”资源,至于 AI 模型是否、以及如何将这些资源内容纳入其思考过程,是由模型自身策略决定的。
  • 应对策略
    1. 优化资源内容格式 :确保你返回的 text 内容是高度结构化、易读的。例如,使用清晰的标记如 [历史对话 - 2023-10-27] User: ... Assistant: ... ,帮助 AI 快速理解。
    2. 提供更精准的资源 :尝试改进你的检索逻辑,只返回与当前问题 最相关 的 1-2 段历史,而不是一大堆可能不相关的记录。过量的、低相关性的上下文反而会干扰 AI。
    3. 在用户提问中引导 :作为用户,你可以在提问时明确指令,例如:“参考我们之前关于用户认证的讨论(你应该能在上下文中找到),现在遇到一个新问题...”。这能更明确地提示 AI 去使用已有的上下文。

问题4:服务器运行一段时间后,性能下降或内存占用过高。

  • 优化方向
    1. 数据库索引 :确保 sessions(project_path) , messages(session_id, created_at) 等常用查询字段上建立了索引。
    2. 向量搜索优化 :如果启用了语义搜索,考虑将向量索引存储在磁盘上,而不是全部加载到内存。或者使用更高效的向量数据库。
    3. 定期清理旧数据 :实现一个简单的清理任务,例如自动删除 30 天前的会话记录,或者允许用户设置历史保留期限。
    4. 日志监听优化 :确保文件监听器不会产生内存泄漏,对于不再需要的旧日志文件句柄要及时关闭。

cursor-history-mcp 这类工具融入工作流,初期可能需要一点调试成本,但一旦稳定运行,它带来的效率提升是显著的。你不再需要反复向 AI 解释项目背景,AI 更像一个真正有连续记忆的结对编程伙伴。它的价值会随着项目时间的增长和对话历史的积累而不断放大。开始可能会关注技术实现,但最终你会忘记它的存在,因为它已经无缝地成为了你开发环境里一个理所当然的“增强功能”。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐