mcpField
K
knock

knock

本地服务
github.com开发工具31 天前更新

关于 knock

knock 为代码仓库建立索引,向编码 Agent 提供简明代码图、精确行号,以及源文件变更后可标记为过期的记录。它适合需要调查陌生代码、追溯决策或在会话间保留发现的开发者。

主要功能

  1. 01按行号映射相关代码
  2. 02打开符号并查看调用关系
  3. 03保存供后续会话使用的发现
  4. 04源文件变更时标记记录过期
  5. 05增量索引已更改文件

适用场景

  1. 01修改前了解大型代码库
  2. 02追溯实现方案的决策依据
  3. 03复用先前调试会话的发现
  4. 04无需通读文件即可定位相关函数

MCP 相关

knock 以 MCP 服务形式运行,向编码 Agent 提供代码映射、源码读取和记忆工具。精简的 `map` 工具集包含 `map`、`open` 和 `remember`。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"hasangilani-knock": {
"command": "uvx",
"args": [
"knock-mcp"
]
}
}
}
启动命令uvx knock-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiknock-mcp0.2.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

🚪 knock

让你的 AI 编码 Agent 记住你的代码库。

别再每次会话都花钱让 Agent 重新读取相同的文件。先敲一下,再只读重要内容。

PyPI tests License: Apache-2.0 Python 3.10+ MCP server 100% local No API key needed

并排对比:在 Saleor(4,776 个文件)中进行相同的调查。仅使用 Claude Code:子 Agent 调用了 30 次工具,模型耗时 3 分 22 秒,花费 $0.49。使用 knock 的 Claude Code:调用 13 次工具,耗时 1 分 16 秒,花费 $0.25。两种方式的答案都正确。

在 Saleor 上进行的两次真实 Claude Code 会话(内容经过删节):两侧均展示三次运行中成本的中位数。不同运行和代码库的结果会有所差异;在一个小型且熟悉的代码库中,差异处于噪声范围内。完整数据:docs/benchmark.md。

📝 数据背后的故事:我记录了 87 次 Claude Code 会话,想弄清钱都花在哪里了


🤔 一张表说清问题

每次与编码 Agent 开启新对话,它都会失忆。要回答 “X 在哪里?” 或 “我们如何部署?”,它会用 grep 搜索、打开大文件并阅读……而下一次会话又会从头再来。

😩 不使用 knock😎 使用 knock
第一步用 grep 搜索、打开整个文件,或启动子 Agent 进行探索调用一次 map:以骨架形式展示相关代码,并提供精确的行范围
Agent 读取的文本每个问题约 27,000–118,000 个字符每个问题约 4,300 个字符
找到“为什么要这样做?”只有打开正确的文档才找得到回答会附带决策及其原因
记住昨天的 Bug 排查❌✅ Agent 使用 remember 保存发现
知道笔记何时过时—✅ 每个回答都会标明 fresh 或 stale

在留出基准测试中,每项任务的字符数中位数(针对性 grep 和 grep 并阅读的基线与 knock 对比)。字符数更少 ≠ 账单等比例减少;请参阅 FAQ。

⚡ 快速开始

只需设置一次 knock,之后照常使用你的 AI Agent 即可。 Agent 会在后台与 knock 通信;你无需在日常使用中运行 knock 命令。

1️⃣ 将其连接到 Claude Code(每个项目只需一次)

在你要处理的项目中运行:

claude mcp add knock -- uvx knock-mcp serve --repo . --toolset map

这里使用 uv,它会为你下载并运行 knock。没有 uv?运行 pipx install knock-mcp(或 pip install knock-mcp),然后运行 claude mcp add knock -- knock serve --repo . --toolset map。

--toolset map 会为 Agent 提供三个工具(map、open、remember),下方结果中的测试也使用了这种配置。省略此参数即可使用原来的八个工具。

就这么简单。下次你在该项目中打开 Claude Code 时,knock 会读取项目并自动生成笔记。小型项目只需几秒,约 5,000 个文件的项目需要一两分钟;之后,它只会重新读取发生更改的文件。

提示

将此行添加到项目的 CLAUDE.md,让 Agent 在适合时使用 knock: "在探索仓库之前(解答如何/为什么的问题、排查不明确的 bug、处理跨模块更改、查找无法通过一次搜索找到的代码),请根据你的任务调用 knock 的 map 工具。对于一次 grep 就能定位的小改动,可以跳过。使用 remember 保存不明显的发现。"

在我们的录制中,knock 在大型代码库的调查中节省了成本,但会给快速编辑增加少量成本,因此这一行很重要。

2️⃣ 照常工作

向 Agent 提出你平时会问的问题。以下是幕后发生的变化:

你输入的内容Agent 的操作
"为登录端点添加速率限制"先询问 knock,获取登录处理程序的 file:line、中间件约定和测试配置,然后只打开相关代码行
"为什么我们使用 Postgres 而不是 Mongo?"从文档或 ADR 中获取决策及其原因,并附上来源链接
"测试因 Redis 错误而失败,有什么头绪吗?"找到之前会话保存的发现:"登录测试需要运行 Redis"
(弄清楚某件事之后)使用 remember 保存,这样明天的会话就已经知道了

无需维护:代码更改时,knock 会更新笔记,并标记可能已过时的内容。

🖥️ 可选:在终端中自行使用 knock

你不一定需要使用这些命令,但它们很实用。

命令使用场景
knock map "where are expired checkouts cleaned up?"查看 Agent 获取的同一份代码地图
knock open SomeClass.method查看某个符号的精确代码,以及它的调用方和被调用方
knock context "how do we deploy?"自行提问,例如熟悉不熟悉的仓库时
knock search "rate limit"查找 knock 对某个主题的了解
knock status检查笔记的新旧程度以及 knock 了解多少
knock index .立即更新笔记;通常由 Agent 为你完成
knock index . --full大规模重构后从头重建所有内容
knock forget . --yes删除 knock 为此项目保存的所有内容

想让 knock 忽略某些文件?将它们列在 .knockignore 文件中(格式与 .gitignore 相同)。

👥 为整个团队设置

将 .mcp.json 文件提交到仓库,每位队友的 Claude Code 都会自动加载 knock(每个人都需要安装 knock):

{
  "mcpServers": {
    "knock": { "command": "knock", "args": ["serve", "--repo", ".", "--toolset", "map"] }
  }
}

每个人的笔记都保存在各自的设备上。目前还不支持在团队成员之间共享发现(参见下方的 Status)。

## 🧠 工作原理
flowchart LR
    A["📁 Your repo<br/>code · docs · configs · git log"] -->|"knock index<br/>(only changed files)"| B["🗂️ Notes<br/>each one points to<br/>file + lines + hash"]
    B --> C[("💾 SQLite<br/>on your machine")]
    C -->|"map"| D["🤖 Your agent"]
    D -->|"open / Read<br/>(verify the real lines)"| A
    D -->|"remember<br/>(save what it learned)"| C
  1. **索引:**knock 会读取你的代码库,但不会在其中运行任何内容。它会写下简短的笔记:每个模块定义了什么、文档中如何说明设置和部署、你使用了哪些工具和依赖项、做出决策的原因,以及哪些近期提交修复了错误。
  2. **提问:**你的 Agent 提出问题,并获得简短的排序结果,其中包含 file:line 指针,而不必读取整个文件。
  3. **验证:**编辑前,Agent 只读取所需的代码行。原始文件始终是唯一可信来源。
  4. 记忆:Agent 会保存学到的内容。如果这些文件之后发生变化,knock 会将笔记标记为过时,以免有人误信过期信息。

🧰 Agent 能获取的内容

使用 --toolset map(推荐):

工具功能
map🗺️**需要探索时使用。**以骨架形式提供与任务相关的代码:函数签名、准确的行范围、每个函数使用和捕获的内容、调用者;以及背后的历史和相关文档。对于变更请求,则提供更精简的版本,指出需要阅读的准确范围和可复用的现有代码。
open📄显示函数或类的准确代码行(带行号)及其调用者和被调用者、指定的行范围,或文件的骨架
remember✍️为后续会话保存发现;引用的文件发生变化时会自动标记
原始的 8 工具集(不使用 --toolset map 时的默认配置)
工具功能
get_context🔎**需要探索时从这里开始。**提供与任务相关的排序结果包:笔记、带 file:line 的函数、值得打开的文件、相关提交,以及坦诚列出的“关于 X 没有已知信息”空缺
search_knowledge📚搜索笔记,可按类别(架构、决策、工作流……)或文件夹筛选
get_knowledge🧾查看一条笔记及其完整溯源信息:来源、时间,以及当前是否仍有效
get_source📄读取文件中的实际代码行,并对机密信息进行隐藏。仅限 knock 已索引的文件
record_knowledge✍️保存发现;自动合并重复内容,并标记矛盾
update_knowledge_status✅将笔记标记为已验证或错误
get_repository_status🩺查看索引的新鲜度,以及数量和统计信息
refresh_repository🔄重新索引已更改的文件(只需几毫秒,不会调用 AI)
👀 查看真实会话示例(8 工具集,Flask)

在 Flask 项目中,Agent 收到的指令是:“轮换 SECRET_KEY 后,使用旧密钥签名的 SECRET_KEY_FALLBACKS 中的会话会被拒绝”。

  1. get_context 返回约 7.7 KB 内容,包括:
    • src/flask/sessions.py:317:SecureCookieSessionInterface.get_signing_serializer
    • tests/test_basic.py:374:test_session_secret_key_fallbacks
    • 相关提交 fb54159861 secret key rotation: fix key list ordering 和 e13373f838 enable secret key rotation
    • 关于会话和密钥的文档章节
  2. get_source("src/flask/sessions.py", symbol="get_signing_serializer") 返回约 80 行相关代码,而不是整个文件。
  3. record_knowledge 保存发现:
    {"category": "debugging",
     "content": "get_signing_serializer builds the key list as SECRET_KEY_FALLBACKS followed by SECRET_KEY; ordering was fixed in fb54159.",
     "sources": [{"path": "src/flask/sessions.py", "start_line": 317, "end_line": 335}]}
    
    下一次会话可立即获取这条信息。如果 sessions.py 发生变化,这条笔记就会被标记为过时。
## 📊 它真的有帮助吗?

通过可复现的基准测试进行测量:每个仓库包含 12 项工程任务,涵盖架构、查找功能、部署、Bug 调查、设计原理和遵循约定。

留出仓库(full-stack-fastapi-template;knock 从未针对它进行调优):

方法找到所需事实阅读字符数工具调用次数
🐢 grep + 读取 3 个文件9 / 121,215,57072
🐇 定向 grep + 读取片段7 / 12328,20660
🚪 knock10 / 1288,96217
更多数据,以及细节说明
  • Flask(开发期间使用过,因此结果偏乐观):knock 为 12/12,耗费 92K 个字符;基准方法为 7/12,分别耗费 2.1M 和 247K 个字符。
  • **速度:**约 200 个文件的仓库可在 0.3–0.6 秒内完成索引;没有变更时,重新索引耗时约 30 毫秒。
  • **测量内容:**事实是否传达给了 Agent,而不是 Agent 随后是否解决了任务。基准方法是对 Agent 行为的模拟。
  • 在真实的 Claude Code 会话中(每种情况运行 3 次),结果取决于仓库和任务:
    • Flask(规模小且广为人知):在 Bug 调查中,knock 的成本与基准方法持平;在简单编辑中,成本略高,因为额外步骤的开销超过了单次搜索。
    • Saleor(4,776 个文件,在测试前几天刚发布),使用精简的 map 工具集:在一项涉及多个模块的调查中,knock 将成本中位数从 $0.49 降至 $0.29,将模型耗时从 170 秒降至 78 秒,而且每次 knock 运行的成本都更低。在后续编辑中,单次正则表达式搜索就能找到目标文件,knock 的成本更高($0.14 vs $0.08)。
    • 最新版本(增加了编辑模式和“简单编辑时跳过 knock”的指导),在完整的“调查后编辑”场景中:Saleor 两天的成本中位数从 $0.70 降至 $0.43(−39%)。Flask 的成本为 $0.31 vs $0.27,处于每次运行的波动范围内。Claude 遵循了指导:所有调查都使用 knock,所有 Flask 编辑都跳过了它。
    • 波动性检查(Saleor 调查每侧运行 8 次):成本中位数 $0.42 → $0.25(−40%),两侧均为 8/8 次回答正确,结果波动幅度约减半。不使用 knock 时,Claude 在 8 次运行中有 5 次委派给子 Agent;使用 knock 时,一次也没有。
    • 完整情况,包括效果变差的版本:我记录了 87 次 Claude Code 会话……。
    • 详情和注意事项见 docs/benchmark.md。
  • **尚未测量:**使用在线模型时实际计费的 Token 数量。测试框架已就绪(benchmarks/agent_bench.py),但运行需要消耗 API 额度。
  • **knock 未能找到的内容:**措辞不匹配(“linters” vs “lint”),以及它目前尚未索引的模块级变量。

完整方法:docs/benchmark.md。

🔒 你的代码仍由你掌控

  • 💻 所有内容均在本地:~/.knock 中的一个 SQLite 文件。无云端、无遥测、无网络调用(有测试确保这一点)。
  • 🙈 跳过机密信息:.env 文件、密钥和凭据绝不会被索引,代码中的 Token 或密码也会被脱敏。
  • 🧱 **不会执行任何内容:**knock 从不运行你的脚本、钩子或测试。它只读取内容。
  • 🚧 **读取范围受沙箱限制:**Agent 只能获取 knock 已索引的文件,无法访问 ../../anything。

重要

Agent 通过 knock 检索的任何内容都会进入 Agent 的上下文,就像它亲自读取了文件一样。请使用 .knockignore 文件排除敏感内容。详情:docs/security.md。

❓ 常见问题

这样能节省 Token 吗?

这是我们的目标,基准测试也显示,传递给 Agent 的文本大幅减少。但你的账单还包括系统提示词、推理和输出,而且提示词缓存已经能为重复输入打折。预期最大的收益来自探索型问题(“X 是如何工作的?”、“Y 在哪里?”、“我们该如何部署?”),而单纯编写代码的收益不大。无论如何,回答更快、能在多个会话间保留记忆都是优势。

我需要 API 密钥或付费模型吗?

不需要。索引和搜索完全基于确定性逻辑,并在本地运行。唯一会使用 API 的是可选的基准测试。

它支持哪些 Agent?

任何支持通过 stdio 使用 MCP 的 Agent。已验证:Claude Code(本页顶部的会话是 Claude 使用 knock 工具的真实录制)和官方 MCP Python SDK 客户端(测试套件中覆盖全部 8 个工具)。Cursor、Windsurf 等应该也能使用,但尚未测试。配置方法:docs/agents.md。

它能理解哪些语言和文件?

Python(通过语法树深入解析),以及 JavaScript/TypeScript、Go、Rust、Java、Kotlin、C#、Ruby、PHP、Swift、C/C++ 等。它还会读取 Markdown 和 reStructuredText 文档、ADR、package.json、pyproject.toml、go.mod、Cargo.toml、Dockerfile、Makefile、GitHub Actions、linter 配置和 git 历史。完整列表:docs/architecture.md。

如果文档有误或已经过时怎么办?

每条笔记都会标明来源(extracted from docs、recorded by an agent、git history)和新鲜度。Agent 可以将笔记标记为错误,在来源发生变化前,该笔记会保持隐藏。只需调用一次 get_source 就能查看真实文件。

这和“在我的代码仓库上做 RAG”有什么区别?

它不使用嵌入,也不使用向量数据库。knock 会存储可追溯到确切代码行的小型结构化事实,跟踪这些代码行的变化,并允许 Agent 添加它们学到的信息。它更像一个能自我维护的团队 Wiki,而不是搜索索引。

🗺️ 状态

knock 目前处于早期 MVP 阶段(v0.1)。当前已实现的功能和后续计划:

  • 增量式、可恢复的索引,遵循 .gitignore 并跳过机密信息
  • 带有来源、新鲜度和生命周期信息的结构化知识
  • 提供 8 个工具、缓存和本地指标的 MCP 服务
  • 使用保留测试代码仓库的可复现基准测试
  • 模型参与的 Token 和成本基准测试(测试框架已就绪)
  • 精简的 3 工具“代码地图”(--toolset map),已在 Flask 和 Saleor 的真实 Claude Code 会话中测量
  • 在更多大型代码仓库和私有代码库上进行测量
  • 改进同义词匹配,并索引模块级变量
  • 可选的 AI 辅助提取(需主动启用,并明确披露)
  • 在团队间共享知识

🤝 贡献

欢迎提交 Issue 和 PR。请从 CONTRIBUTING.md 开始。

.venv/bin/pip install -e '.[dev]' && .venv/bin/pytest

更多文档:架构 · 安全性 · Agent · 基准测试 · 故障排除

📜 许可证

Apache-2.0

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。