feishu-kb-mcp
# feishu-kb-agent
[](https://github.com/ZornZL/feishu-kb-agent/actions/workflows/ci.yml)
[](LICENSE)
**用 DeepSeek(DeepSeek Harness / 任意 MCP 客户端)管理你的个人飞书知识库。**
不是「让 AI 随便改文档」,而是把知识库当成一个有规则的系统:写入可审计、重复会被拦、删除必须过人。
> 一切设计只服务四件事:**可检索、可回指、可重建、可增改查**。
> 做不到这四件事的功能,一律不做。
---
## 它解决什么问题
飞书知识库有三个硬约束,直接决定了「AI 该怎么操作它」:
| 约束 | 后果 | 本项目的做法 |
|---|---|---|
| wiki 是严格树,一个节点一个父节点 | 一条内容不能有两个「家」 | 树只管存放与权限;分类靠定位头与地图页 |
| 平台搜索是黑盒,且不覆盖个人版全部内容 | 检索不可控 | 本地 SQLite FTS5 索引(中文二元组 + 标题加权) |
| docx 没有公开的版本 API | 「只追加」无法只靠飞书实现 | 每次写入前把正文镜像存本地台账,可回滚 |
所以这个项目不是把四个 API 包一层,而是补上飞书缺的三样东西:**索引、规则、审计**。
## 能力
模型通过 MCP 看到 12 个强类型工具:
| 工具 | 作用 | 关键约束 |
|---|---|---|
| `kb_status` | 连接、索引、待办状态 | — |
| `kb_search` | 全库检索,返回片段与链接 | 标题权重 ×10,中文二元组 |
| `kb_read` | 实时读取正文与定位头 | 永远读飞书,不读缓存 |
| `kb_outline` | 目录树 | 只读,用于「我都记了什么」 |
| `kb_create` | 新建页面 | **幂等**:同内容/同标题不重复建 |
| `kb_append` | 末尾追加 | 只追加,不改原文;重复段落自动跳过 |
| `kb_replace_text` | 字面替换 | 唯一会改原文的工具;先存镜像 |
| `kb_rename` | 改标题 | 旧标题保留为检索别名,链接不变 |
| `kb_move` | 移动节点 | `node_token` 不变,禁止移进自己的子孙 |
| `kb_propose_delete` | 发起删除提案 | **模型没有删除能力**,只能提案 |
| `kb_sync` | 同步索引 | 增量优先,`full` 可重建 |
| `kb_audit` | 体检与结构建议 | 重复页、空页、深度/宽度、目录阈值 |
人用的命令行补齐了模型不该有的能力:`init`、`doctor`、`login`、`delete --confirm`、`restore`、`export`、`eval`。
## 3 分钟跑起来
```bash
# 1) 安装(任选其一)
uv tool install git+https://github.com/ZornZL/feishu-kb-agent
# 或
pipx install git+https://github.com/ZornZL/feishu-kb-agent
```
```bash
# 2) 初始化:填飞书自建应用的 App ID / Secret 和知识库入口页链接
feishu-kb init
# 3) 体检:逐项验证权限,失败会直接告诉你去点哪里
feishu-kb doctor
# 4) 建索引
feishu-kb sync
```
飞书应用怎么建、要开哪些权限、怎么把应用加进知识库:见 **[飞书配置](docs/FEISHU-SETUP.md)**。
权限通了之后,跑一次真实验收(会创建一页测试页,默认只生成删除提案、不删除):
```bash
python scripts/acceptance.py
```
它依次验证:实时连通 → 同步 → 创建 → 立即可检索 → 追加 → 读回 → 定位头 → 删除提案。
想用「自己的飞书账号」而不是应用身份(更接近“每个人用自己的账号登录”):
```bash
feishu-kb init --auth-mode user
feishu-kb login
```
## 接进 DeepSeek Harness
在 `~/.dsh/cordis.patch.yml` 里加一条(Windows 把 `command` 换成 `feishu-kb-mcp.exe` 的绝对路径):
```yaml
- insert:
- id: feishu-kb
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: feishu_kb
transport: stdio
command: feishu-kb-mcp
args: []
```
重启 Harness,工具会以 `mcp__feishu_kb__kb_search` 这样的名字出现。完整说明与排错见 **[DSH 接入](docs/DSH-SETUP.md)**。
## 为什么这样设计
### 写入只追加,不覆盖
飞书没有版本 API,整篇覆盖等于「把历史删了再写一份」:审计断裂、样式丢失、并发时互相踩。
所以 `kb_append` 是默认写入方式,`kb_replace_text` 只用于纠错,且写入前会把原文镜像进本地台账(`feishu-kb restore` 可回滚)。
### 删除是人的权力,不是模型的能力
```text
模型 kb_propose_delete → 一次性提案号(24h 过期)
↓ 人在本机
feishu-kb delete --confirm <提案号> → 再输入 DELETE → 删除 + 墓碑
```
工具面里没有 `delete`,不是靠提示词约束模型,而是**能力边界**。
### 目录要「长」出来
不按学科建目录,只按用途建;同类页面 ≥5 才建议建,长期 <3 页建议并。
`kb_audit` 会按阈值给建议,而不是自动搬树——结构调整必须有人拍板。
完整规则判定(哪些吸收、哪些剔除、为什么):**[规则取舍](docs/RULES-ADOPTION.md)**。
CRUD 的完整契约与失败模式:**[CRUD 设计](docs/CRUD-DESIGN.md)**。
## 文档
| 文档 | 内容 |
|---|---|
| [飞书配置](docs/FEISHU-SETUP.md) | 建应用、开权限、发布版本、把应用加进知识库 |
| [DSH 接入](docs/DSH-SETUP.md) | MCP 配置、验证、排错 |
| [规则取舍](docs/RULES-ADOPTION.md) | 两份参考文档里哪些规则吸收、哪些剔除 |
| [CRUD 设计](docs/CRUD-DESIGN.md) | 增删改查的契约、幂等、失败模式 |
| [架构](docs/ARCHITECTURE.md) | 分层、数据流、不变量、选型理由 |
| [演进](docs/EVOLUTION.md) | 知识库变大后,先改什么、后加什么 |
## 分享给别人用
这是**一人一库**的工具,不是多人共用一个知识库的 SaaS:
- 每个人 clone 后填**自己的**飞书应用凭据与知识库链接;
- 配置与索引只存在本机 `~/.feishu-kb/`,不进 Git;
- 用 `user` 模式时,权限就是这个人自己的,不需要把应用加成知识库成员;
- 不做中央服务器,也就没有「谁的密钥放在服务端」的问题。
## 项目结构
```text
feishu_kb/
config.py 配置解析(env / .env / ~/.feishu-kb)
client.py 飞书 HTTP 客户端(令牌缓存、重试、错误翻译)
wiki.py 知识空间节点:树、建、改名、移动、删
docx.py 文档块 ↔ Markdown
rules.py 定位头、命名、查重、目录阈值
store.py SQLite 索引 + 修订台账 + 删除提案
service.py 业务操作(供 MCP 与 CLI 共用)
auth.py 飞书账号 OAuth(user_access_token)
mcp_server.py MCP stdio 服务器
cli.py 命令行
tests/ 单元测试 + 假飞书端到端 + MCP 握手
docs/ 飞书配置、DSH 接入、规则取舍、CRUD 设计
```
## 已知限制
- 只索引与编辑 `docx`;表格、思维导图、多维表格只能给链接。
- 图片/附件不进索引(飞书 docx 的 image 块没有可检索文本)。
- 中文检索用二元组,不做同义词扩展;专有名词全称/缩写要各写一次。
- 单机单进程假设:没有多人并发写同一页的冲突合并。
- 飞书接口限流约 100 次/分钟,首次全量同步大库会慢。
## Roadmap
- [ ] 引用回指:回答时返回 `(node_token, block_id, 片段)`,支持点击定位
- [ ] 关系提议队列:`supports / contradicts / refines` 先提案后落库
- [ ] `kb_audit` 的趋势报告(周环比)
- [ ] 图片 OCR 与图注生成
- [ ] 可选的本地向量召回(SQLite 扩展,零服务)
## License
MIT
TDQS
Scored across 12 tools
Each tool targets a distinct resource+action: search vs read vs outline for retrieval, create/append/replace_text/rename/move for different write operations, plus status, sync, audit, and a guarded delete proposal. The descriptions make the boundaries between the write tools (append at end vs literal text replacement) explicit, so an agent can reliably choose.
All tools share a consistent kb_ prefix and snake_case, mostly following a verb_noun pattern (kb_search, kb_read, kb_create, kb_move, kb_propose_delete). Two tools are noun-style (kb_status, kb_outline), a minor deviation from the verb convention but still readable and predictable.
12 tools is well within the ideal 3-15 range and each maps to a clear responsibility: discovery, reading, authoring, restructuring, maintenance, and safe deletion. Nothing appears redundant or bloated for a knowledge-base server.
The surface covers the full lifecycle: search/read/outline for retrieval, create/append/replace/rename/move for updates, guarded delete via proposal, plus sync and audit for maintenance. Minor gaps exist, such as no explicit version-history or batch-read operation, but core workflows are fully supported.