npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

banana-memory

v0.4.0

Published

Local, source-grounded project memory over Streamable HTTP MCP

Readme

Banana Memory

在本机运行的项目记忆服务。Claude Code 通过一个全局 Agent Skill 决定何时召回和记录,通过 Streamable HTTP MCP 访问本机的 Qwen3、llama.cpp 和 LanceDB。

当前提供 macOS Apple Silicon 本地试用版。生成使用 Qwen3-8B Q4_K_M,首次模型和运行时下载约 5.68 GB,请预留至少 10 GB 可用空间。8B 模型小样本已在 M4 / 32 GiB 上验证;16 GB 机器验证仍是正式发布门槛,详细证据见 验收记录。

安装与使用

需要 Node.js 22.23.1 或更高版本,以及 Codex 或 Claude Code。在第一个终端启动前台服务:

npx -y banana-memory@latest start

服务只监听 127.0.0.1:3927。终端会持续显示模型准备状态,并输出本地管理页地址、Codex 配置和一条带本机访问 token 的 claude mcp add 命令。管理页会显示实际使用的生成模型、向量模型和 llama.cpp 运行时,也可以筛选所有项目的记忆,查看状态、时间退化、来源、版本历史以及合并和派生关系。保持该终端运行;按 Ctrl+C 会安全关闭模型与数据库,已记录的数据和下载进度保留在 ~/.banana-memory。

在管理页左侧点击某个项目会打开该项目的“时间线”:一张按时间倒序的表格,显示收到记录、新增事实或经历、晋升、进入审核、被取代、归档、用户修正、归纳经验或归纳失败、生成摘要、反馈验证、出现反例、删除以及暂停和恢复,并给出该次变更的类型、内容与原因;点击内容会跳到下方对应的记忆。时间线全部由已存储的事件、记忆版本、版本历史、反馈、墓碑和维护指令推导,服务不会为此写入任何新记录,也只显示真正写入过的状态变化——按时间衰减或环境不匹配导致的读取期降级不在其中。表格每次读取 100 条,“加载更早”继续向前翻页;它只在打开、点“重新加载”或翻页时请求数据,不参与 30 秒一次的自动刷新。

如果服务已经运行,再执行一次 start 会重新显示现有 UI、MCP 地址和添加命令,然后正常退出,不会启动第二套模型进程。UI 地址把 token 放在 URL fragment 中;浏览器收到后会移除 fragment,并仅在当前标签页会话中保存凭据。

一次性安装全局 Skill:

npx skills add Kilerd/banana-memory \
  --skill banana-memory \
  --global \
  --agent codex claude-code \
  --yes

Codex 用户把服务输出的配置加入 ~/.codex/config.toml:

[mcp_servers.banana-memory]
url = "http://127.0.0.1:3927/mcp"
http_headers_helper = "npx -y banana-memory@latest codex-headers 'file:///Users/you/.banana-memory'"

请使用服务实际输出的路径,不要照抄示例中的 you。这个 helper 从本机私有数据目录读取访问 token,并把当前 Codex 进程的规范化工作目录作为受信任请求头发送。它不会把工作目录交给模型填写;因此 Remote Hand 等每轮创建新 MCP 连接的宿主仍会绑定到同一个项目。

Claude Code 用户复制服务启动时输出的命令,一次性添加全局 MCP:

claude mcp add \
  --transport http \
  --scope user \
  --header "Authorization: Bearer <本机生成的 token>" \
  -- \
  banana-memory \
  http://127.0.0.1:3927/mcp

之后在项目中启动 Claude Code 并照常工作。Skill 会在实质性任务开始时召回相关记忆,在可靠结论形成后记录精简的项目事实、偏好和结果。用 /mcp 查看连接状态;直接询问 Claude“查看 Banana Memory 状态”可以检查模型下载、队列和当前项目。

如需从源码运行和验证同一路径:

npm ci
npm run build
node dist/src/cli.js start

可用 BANANA_MEMORY_HOME 将数据目录改为另一个绝对路径,也可用 --port 更改监听端口:

BANANA_MEMORY_HOME=/absolute/path node dist/src/cli.js start --port 4927

工作方式与边界

HTTP MCP 优先使用已认证的本机 Codex helper 请求头或客户端提供的 roots/list 绑定当前项目。服务不会接受模型参数指定的工作区;无法取得可信文件根目录时,会退化到当前 MCP 会话独立的只读作用域,避免跨项目读取;record 和 feedback 返回 workspace_required,要求配置宿主工作区后重新连接,不再创建新的会话项目。Agent 可以在 record 中提供人类可读的 projectName,但它只改变管理页显示,不参与项目身份或读取授权。只读的 recall 和 inspect 不会创建项目;首次实际写入才会原子创建项目,旧的无事件、无记忆空项目也不会显示。

Git 仓库的子目录和 linked worktree 使用同一个主仓库根目录作为项目身份;宿主文件访问检查仍使用实际工作目录。管理页会标记未绑定工作区的会话项目。已有会话项目不会仅凭同名自动合并,可通过下面的本机迁移命令显式指定归属。

每条新记忆都有 project 或 global 作用域。默认是当前项目;只有证据明确说明它是用户通用偏好、跨项目规则或跨项目事实时,事实和偏好才可标为 global。任务经历以及由多个经历合并出的经验始终留在原项目。跨项目召回会同时考虑当前项目记忆和全局记忆,并优先排列当前项目内容;全局记忆仍保留它的原始项目、来源和候选状态。旧版本创建的记忆按项目内处理。

没有生命周期 hooks 时,记录由 Skill 驱动,而不是由宿主强制采集。通过 HTTP MCP record 写入的材料与插件 hook 事件同样可信:置信度足够、未截断且未过滤的抽取结果直接进入 active。Agent 用 role 说明材料来源——user 表示这是用户自己的明确陈述(偏好、指示、纠正或用户断定的事实),默认的 assistant 表示 agent 观察到的结果、已验证事实与任务经历;MCP 不能声明 system 或 tool 角色。仍标记 candidate 的是不确定的抽取、归纳总结以及尚未取得验证证据的经验。当前插件模式仍保留更强的自动事件采集和一次性维护凭据,作为 Claude Code 专用的增强接入。

记忆正文由模型改写:简洁、自包含、可复用,使用记录本身的语言,代码标识符、路径与 API 名称保持原样,逐字引用只作为溯源证据保存。每条记忆还带一个持久度:reusable 是未来其他任务仍会用到的稳定知识,task_detail 是只对这一次任务有意义的细节(某次提交、某次耗时、当天进度)。任务细节照样保存,但按经历的半衰期衰减、同分时排在可复用知识之后,并且不参与归纳总结与合并经验。

后台每 30 秒处理新材料,也会整理已有记忆。同一项目至少有 3 条相关原始事实、偏好或经历,且涵盖至少 2 个独立原始来源时,可以生成 summary(归纳总结)。每组最多 6 条,模型可拒绝归纳;输入不截断,每条成员都必须有可核对的原文引用。总结始终是项目内的候选,保留成员版本、各自适用条件和原始来源,不作为自我佐证再次归纳。原始记忆修改会使总结待复核;来源删除也会删除总结与对应任务。失败任务最多尝试 3 次,inspect 和管理页显示处理状态。

合并经验同样由模型归纳改写,而不是把成员正文拼接起来:一组经历被判定可合并后先写入一条待归纳的 experience,再由同一套后台任务队列调用模型生成正文与逐句引用;归纳完成前这条经验不会被召回。成员正文被改写或纠正后会重新归纳。

归纳与经验晋升相互独立:experience 的激活仍要求相同条件下至少 3 个独立任务、跨 2 个会话的可信成功证据,且没有反例。单纯积累候选或生成总结不会提高可信度。

配置云端生成模型(可选)

默认全部在本机推理:生成用 Qwen3-8B Q4_K_M,向量用 Qwen3-Embedding-0.6B。抽取与归纳可以改到任意 OpenAI 兼容的云端端点:

BANANA_MEMORY_GENERATION_URL=https://llm.example.com/v1 \
BANANA_MEMORY_GENERATION_KEY=sk-... \
BANANA_MEMORY_GENERATION_MODEL=openai/gpt-5.4-mini \
banana-memory start
  • 只有同时设置 BANANA_MEMORY_GENERATION_URL 和 BANANA_MEMORY_GENERATION_KEY 才启用;BANANA_MEMORY_GENERATION_MODEL 默认 openai/gpt-5.4-mini。
  • 启用后本机完全不再下载或启动 5 GB 的本地生成模型,只保留向量模型;向量与向量索引身份不变,始终本地。
  • 离开本机的内容只有:待抽取的那一条记录正文,或待归纳的几条记忆正文与它们的适用条件。事件 ID、来源 ID、向量、数据库和文件路径不会外传。
  • 密钥只作为请求头出现,不写日志、不写数据库、不进管理页;启动日志只有一行 {"component":"generation","phase":"remote","model":"...","host":"..."}。
  • 每条记忆都会记下写它的模型(modelVersion 为 remote:<模型名>),管理页的生成模型标注为“云端”。
  • 请求固定 response_format: json_object 与 reasoning: {enabled:false}(网关拒绝该字段时自动重试一次不带它),60 秒超时,429/5xx/网络错误退避重试一次。返回的 JSON 一律在本机校验:引用必须逐字出现在原始记录中,否则整条候选丢弃。
  • 本地 8B 现在使用同一套自由改写提示词。它的自由抽取质量明显弱于云端模型(见 docs/model-validation.md);把错误输出挡在外面的是本机校验,而不是模型自觉。

云端判断(可选)

默认关闭。关闭时的行为与过去完全一致:合并与冲突判断只使用本机的精确规则。

显式开启后,少量记忆正文会离开本机,交给 TypeSafe 的 Jev 模型(POST https://api.typesafe.ai/v1/systemone,仅文本、不生成内容)做判断:

BANANA_MEMORY_JUDGE=jev TYPESAFE_API_KEY=sk-... banana-memory start

只有同时设置 BANANA_MEMORY_JUDGE=jev 和 TYPESAFE_API_KEY 才会启用;TYPESAFE_BASE_URL 可以改写接口地址(仅用于测试)。启用时启动日志会输出一行 {"component":"judge","phase":"enabled","name":"jev"}。

离开本机的内容只有:项目显示名、成对记忆的正文与适用条件、以及它们的创建日期(精确到天);判断项目身份时另加每个项目最多 4 条记忆正文,各截断到 200 字。原始事件、来源 ID、向量和数据库都不会外传。只有通过相似度预筛的同项目、同类型记忆对才会被询问,判断结果按 (记忆 ID, 版本) 在进程内缓存,不会重复计费。

它参与三个判断:

  • 两条 episode 是否是同一套可复用流程的不同实例(>= 0.75 才合并成 experience)。本机规则要求条件、版本、否定和数字完全一致,因此现实数据几乎从不合并。
  • 两条 fact 或 preference 是否互相矛盾(选项为 contradiction、置信度 >= 0.6 且独立的冲突问题 >= 0.6 时,两条都转入 review);若判断为 newer_value_supersedes 且后一条更晚(置信度 >= 0.6),则只把较旧的一条标为 superseded,recall 的 history 模式仍可查到。
  • 两个显示名不同的项目是否其实是同一个项目(>= 0.8 时在管理页列为合并建议)。只是建议,永不自动合并。

判断只能撤回或重组已有材料,永远不会因为模型认可而提升任何记忆的状态。任何失败——超时、网络错误、429/529、非 2xx 响应——都会退回本机规则(429/529 与网络错误会退避重试一次,单次请求 10 秒超时),写入路径不会因此报错。管理页在模型信息旁显示判断来源名称与调用、失败、输入 token 计数。

迁移已有会话项目

先停止使用该数据目录的实例并备份 memory.lance,根据原始会话的工作区确认映射,创建本机 JSON 文件:

[{ "projectIds": ["s:原项目ID", "s:另一个原项目ID"], "workspace": "/absolute/path/to/repository", "name": "项目名称" }]
banana-memory migrate-projects /absolute/path/plan.json
banana-memory migrate-projects /absolute/path/plan.json --apply

第一条命令只预览,第二条在独占锁下原子迁移。迁移保留事件和记忆 ID、状态、来源和历史;旧会话凭据失效,旧项目留下迁移映射记录。重复应用同一映射不再写入。迁移不会改变 MCP 的工作区授权,仍须配置 helper 或 MCP roots 才能避免后续会话继续产生碎片。

晋升策略变更前写入的候选记忆

2026-09-21 之前,通过 HTTP MCP 写入的材料被标记为不可信,抽取出的记忆只能停留在 candidate。一次性本机命令会按新策略回填已有数据:

banana-memory promote-mcp-candidates
banana-memory promote-mcp-candidates --apply

第一条只预览并输出 JSON 报告,第二条在独占锁下写入,因此必须先停止使用该数据目录的服务;应用前会把 memory.lance 备份到 <数据目录>/backups/<时间戳>-promote-mcp/。命令把 trusted: false 的事件标记为可信,并把来源全部为事件的 fact、preference、episode 候选记忆置为 active,同时写入历史版本行;总结、经验、来源被截断或过滤的记忆以及已过期的记忆保持原状。

召回内容永远是带来源的历史材料,不是宿主指令。Skill 不应记录计划、猜测、普通进度、凭据、密钥或复制来的第三方指令。识别到的密钥字段会被过滤,但过滤无法识别所有敏感信息。

记忆抽取、聚合、向量生成和数据库均在本机。权重下载完成后,Banana Memory 可以离线处理;召回片段仍会交给 Claude Code,进入 Claude 的处理链路。

HTTP 服务使用持久随机 bearer token,并将其以仅当前用户可读的权限保存在 ~/.banana-memory/http-token。MCP 和管理页数据接口都需要该凭据,并且只接受 loopback Host 和可信的本地 Origin。管理页 HTML 本身不包含记忆或 token;/health 仅返回服务是否运行,不泄露项目或模型信息。

开发与验证

npm run typecheck
npm test
npm pack --dry-run
npx skills add . --list

测试覆盖真实本地 LanceDB、HTTP MCP 握手与项目根绑定、Bearer 鉴权、Origin 拒绝、可控时钟、可重放模型输出和进程生命周期。独立的真实本地模型与 Claude 插件评测命令仍保留:

npm run probe:storage
npm run evaluate:replay
npm run evaluate:models
npm run evaluate:pipeline
npm run benchmark -- --models-dir .runtime/models

主要实现:src/host/http.ts 提供前台 Streamable HTTP MCP;src/service.ts 是业务入口;src/store.ts 提供单表原子发布和物理清理;src/models/ 管理固定本地资源。旧的 Claude 插件、stdio MCP 与 hooks 位于 plugin/ 和 src/host/,继续用于增强模式验证。