Skip to content
Conduit

mcp server

Feishu-SuperSearch

飞书本地联邦检索:文档、消息、妙记、任务与可追溯 AI Evidence 问答

BlueSkyXN/Feishu-SuperSearchcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 23, 2026

SuperFeishuSearch

CI Security Release GitHub Release

SuperFeishuSearch 是一个面向飞书对象的、确定性的联邦检索程序。它将文档、消息、群、联系人、妙记、会议、日程、任务、邮件、Base 与 Sheets 的分散能力统一为一个可编程的 Retrieval Kernel:

  • Search:并发搜索多个全局来源,统一候选、去重并融合排序
  • Query:任务、Base、Sheets 等结构化或对象内查询
  • Fetch:按稳定 ObjectRef 补齐正文、上下文、原生摘要、结构或附件
  • Expand:有界展开会议→妙记、消息→文档、妙记→任务等关系
  • Continue:复用 session/cursor 继续特定来源分页
  • Resolve:将人员名称等解析为稳定对象引用
  • RetrievalPlan:执行有预算、有状态、可重试的有界 DAG

Planner、LLM、SKILL、MCP 与 Web 位于内核外层。内核本身不依赖 LLM,所以可单独运行、测试、录制和回放。

文档导航

仓库协作见 CONTRIBUTING.md,安全报告与部署边界见 SECURITY.md。

1. 已实现范围

Retrieval Kernel
├── Provider Registry + source/operation 路由
├── Search / Query / Fetch / Expand / Continue / Resolve
├── 并发 fan-out、总预算、超时、取消、有限重试、部分失败
├── Provider-specific source_queries
├── Canonical ID、精确去重、Weighted RRF、来源配额
├── 两阶段自适应分页
├── Projection / Late Materialization
├── 分组 Batch Fetch / cache / context-aware singleflight
├── RetrievalSession + SQLite 默认持久化 + JSON 兼容迁移
└── 有界 RetrievalPlan DAG、节点状态机、ready/retry heap

Adapters
├── lark-cli:11 个来源
├── direct OpenAPI:docs / messages / people / minutes
├── mock:完整离线演示数据
├── executable JSON-RPC Provider
└── Provider 交互 record/replay

Planners
├── rules:规则路由、query 压缩、按来源 query
├── default:固定 Search→Fetch
├── external command:可接独立 Planner
└── 可选 OpenAI-compatible AI Planner / Rerank / Answerer

Entrypoints
├── CLI
├── HTTP API + SSE
├── Web UI
├── MCP stdio server
└── Go HTTP Client SDK

2. 免编译安装

普通用户不需要 Go、Node.js、SQLite 或本地编译。打开 GitHub Releases,下载与系统对应的资产:

系统资产
macOS Apple SiliconSuperFeishuSearch-1.0.3-darwin-arm64.tar.gz
macOS IntelSuperFeishuSearch-1.0.3-darwin-amd64.tar.gz
Linux x86-64SuperFeishuSearch-1.0.3-linux-amd64.tar.gz
Linux ARM64SuperFeishuSearch-1.0.3-linux-arm64.tar.gz
Windows x86-64SuperFeishuSearch-1.0.3-windows-amd64.zip
Windows ARM64SuperFeishuSearch-1.0.3-windows-arm64.zip

macOS/Linux:

tar -xzf SuperFeishuSearch-1.0.3-<os>-<arch>.tar.gz
cd SuperFeishuSearch-1.0.3-<os>-<arch>
./sfs version

Windows PowerShell:

Expand-Archive .\SuperFeishuSearch-1.0.3-windows-amd64.zip
cd .\SuperFeishuSearch-1.0.3-windows-amd64
.\sfs.exe version

SHA256SUMS 覆盖 8 个压缩资产。Release workflow 会验证精确资产集合、校验和、六平台 GOOS/GOARCH、CGO_ENABLED=0、trimpath、嵌入版本/commit、源码包与 Git tracked tree 一致性、源码包在无 .git 环境下完整执行 make verify,以及 Linux amd64 离线 smoke。

3. 完整离线预览

发布包自带 config.demo.json,不需要飞书账号、Token 或 AI Key:

./sfs --config config.demo.json serve

Windows 使用 .\sfs.exe --config config.demo.json serve。浏览器打开 http://127.0.0.1:3765,可以实际预览:

Search / Continue
Research / Evidence
Ask / Claim / Citation
对象正文预览
来源状态与 Doctor
Session 历史
桌面、移动端、浅色和深色界面

Demo 使用 Mock Provider 和确定性 Demo Answerer。它用于预览完整交互与数据契约,不代表模型回答,也不代表真实租户权限已通过。

命令行 Mock 搜索:

sfs --backend mock search "A 项目 延期" \
  --sources docs,messages,minutes,meetings,tasks

按来源传入不同的实际检索词,同时保留原始问题用于全局融合:

sfs --backend mock search "A 项目为什么延期,谁做了决定" \
  --sources docs,messages,minutes \
  --source-queries-json '{"docs":"A 项目 延期","messages":"A 项目 延期 决定","minutes":"A 项目"}'

执行 Search→Fetch→Evidence:

sfs --backend mock research "A 项目延期原因和未完成任务" \
  --sources docs,messages,minutes,meetings,tasks \
  --fetch-top 6

执行声明式计划:

sfs --backend mock plan examples/plan-search-fetch.json
sfs --backend mock --output ndjson plan examples/plan-search-fetch.json --events

启动 Web 与 HTTP API:

sfs --config config.demo.json serve

浏览器打开 http://127.0.0.1:3765。

4. 真实飞书后端

4.1 lark-cli 模式

确保本机可执行:

lark-cli --version
lark-cli doctor

SuperFeishuSearch 不复制或接管 lark-cli OAuth;它将 --profile、--as user|bot 传给子进程,并继承当前 profile 的 scope 与对象可见范围。

./sfs --backend larkcli --profile work --as user \
  search "上线" --sources docs,messages,minutes

探测已注册 Provider:

./sfs --backend larkcli --profile work --as user doctor

某个来源权限不足、超时或不可用时,其他来源仍可返回,结果会标记 partial=true 并保留每来源状态。

当前本机真实只读验证并非 11 来源全通过:docs、messages、chats、people、minutes、meetings、tasks 共 7 个来源成功;calendar、mail 返回 missing_scope;Base、Sheets 因缺少已知测试对象尚未完成验收。11 来源 fixture 基线不能替代这一真实矩阵。

最终工作树还重新验证了妙记 summary/structure/content Fetch:minutes[].artifacts 的嵌套结构和 transcript 文件均成功物化,子进程临时目录清理后仓库原有 minutes/ 状态未发生变化。

4.2 direct OpenAPI 高频来源

内置 direct OpenAPI Adapter 覆盖:

docs      Search / Fetch
messages  Search / Fetch Context / Expand Relations
people    Search / Resolve
minutes   Search / Fetch Summary/Structure/Content

SDK 调用需要应用 app_id 和 user access token。Token 只从 open_api.token_env 指定的环境变量读取,默认是 FEISHU_USER_ACCESS_TOKEN:

export SFS_OPENAPI_APP_ID='cli_xxx'
export FEISHU_USER_ACCESS_TOKEN='u-...'
./sfs --backend openapi --as user search "周报" --sources docs

也可通过 operation 级路由指定某个操作的后端:

export SFS_OPENAPI_APP_ID='cli_xxx'
export FEISHU_USER_ACCESS_TOKEN='u-...'
./sfs --config examples/config-openapi-route.json --profile work --as user \
  research "A 项目延期原因" --sources docs,messages,minutes

对应路由:

{
  "providers": {
    "routes": {
      "docs": {
        "search": "openapi.docs",
        "fetch": "larkcli.docs"
      }
    }
  }
}

这种路由粒度是 source + operation,不要求整个来源只能绑定一个后端。

direct OpenAPI 使用固定版本的官方 oapi-sdk-go/v3 实现文档搜索、消息搜索/读取、人员搜索和妙记 Search/Get/Artifacts;docs_ai Fetch 因 SDK 没有等价 XML/citation binding,保留受限 HTTP fallback。当前只完成了本机 httptest 请求、分页、大小限制和错误映射验证;由于没有同时可用的 App ID 与 Token,尚未执行真实租户 OpenAPI 验收。

4.3 后端选择

auto      两者都可用时选择 hybrid;仅一个可用时选择对应真实后端;都不可用则直接报错
larkcli   全部使用内置 lark-cli Provider
openapi   仅注册当前已实现的直接 OpenAPI Provider
mock      离线演示 Provider
hybrid    高频来源 direct OpenAPI,其他来源 lark-cli;绝不注册或回退 Mock
replay    从录制 fixture 离线重放

5. 内置来源

来源Search / Query 主路径Fetch / Expand
docsdrive +search;或 direct Search v2docs +fetch;或 direct docs_ai Fetch
messagesim +messages-search;或 direct Search消息详情/上下文;消息→文档/群关系
chatsim +chat-search群详情
peoplecontact +search-user;或 direct Search用户详情;Resolve
minutesminutes +search;或 direct Searchsummary/todo/chapter/transcript
meetingsvc +search会议详情;meeting→minute
calendarcalendar +search-event已知 calendar/event 后读取
taskstask +search;结构化 Query任务详情
mailmail +triage邮件正文/上下文
base不参加默认全局 Searchbase +record-search 对象内 Query
sheets不参加默认全局 Searchsheets +cells-search 对象内 Query

lark-cli Adapter 使用 exec.CommandContext 参数数组,不经过 shell;限制 stdout/stderr,支持取消和超时,兼容显式 {ok,data,error} envelope 与 raw OpenAPI JSON。

docs 的 Drive Search 可能返回 Sheet、Base 或普通 File。它们会被标记为 sheet、base、attachment,不声明可 Fetch Projection,也不能直接走面向 Docx Markdown 的 docs +fetch:Base 应改用 query --source base,Sheets 应改用 query --source sheets;普通 File 当前仅保留搜索候选元数据。详见 lark-cli 兼容策略。

6. CLI

全局参数必须位于命令之前:

--config PATH
--backend auto|larkcli|openapi|mock|hybrid|replay
--session-dir PATH
--database PATH
--output pretty|json|ndjson
--profile NAME
--as auto|user|bot
--listen ADDRESS
--record-dir PATH
--replay-dir PATH

6.1 Search

sfs search "A 项目 延期" \
  --sources docs,messages,minutes \
  --after 14d \
  --strategy balanced \
  --limit 40 \
  --per-source 8 \
  --pages 2

输出包含:

  • session_id
  • 统一 Candidate[]
  • 每来源状态、页数、耗时和错误
  • continuation cursor
  • budget 与统计
  • projection / available_projection

6.2 Continue

sfs continue --session rs_xxx --sources messages,docs --pages 1

6.3 Query

任务:

sfs query --source tasks --filter '{"query":"A 项目","completed":false}'

Base:

sfs query --source base \
  --container-id app_token/table_id \
  --container-kind base_table \
  --filter '{"keyword":"延期","search_field":"项目名称"}'

Sheets:

sfs query --source sheets \
  --container-id spreadsheet_token \
  --container-kind sheet \
  --filter '{"find":"延期","sheet_id":"sheet_xxx"}'

6.4 Fetch

从 Search session 读取对象:

sfs fetch --session rs_xxx \
  --id feishu:scope:minute:obc_xxx \
  --projection summary,structure,relations

多个 ID:

sfs fetch --session rs_xxx --id ID1 --id ID2 --projection content,context

Fetch 会合并重复对象和 Projection、扣除 session 已缓存 Projection、按 Provider 能力分批,并对并发相同请求做 singleflight。

6.5 Expand

sfs expand --session rs_xxx \
  --id feishu:scope:meeting:m_xxx \
  --relations meeting.has_minute \
  --depth 2

默认最大深度 1,程序上限为 2;使用 visited set 防止关系环。

6.6 Resolve

sfs --as user resolve "张三" --source people --limit 10

6.7 RetrievalPlan

sfs plan examples/plan-search-fetch.json
sfs --output ndjson plan examples/plan-search-fetch.json --events

支持节点:

resolve search query fetch expand merge dedup rank limit project map_fetch

执行器包含 DAG 校验、200 节点上限、节点状态机、ready max-heap、retry min-heap、共享预算和有限指数退避。它不执行任意 shell,也不允许无界循环。

6.8 Research / Ask

research 是确定性的 Search→Fetch→Evidence 流程,不调用 Answerer:

sfs --backend mock research "A 项目为什么延期" --fetch-top 6

ask 会先执行同一检索与证据流程,再由启用的 Answerer 仅依据 Evidence Pack 生成带 citation 的答案:

SFS_AI_API_KEY='...' sfs --config ~/.sfs/config.json \
  ask "A 项目为什么延期" --sources docs,messages,minutes --fetch-top 8

AI 默认关闭;Answerer 不可用时 ask 返回 unsupported,Search/Research 不受影响。模型运行中失败时返回确定性证据摘要并标记 partial=true。

启用 OpenAI-compatible AI 表示允许程序把 Planner 所需的查询/能力、Rerank 的候选标题与摘要,以及 Answerer 的 Evidence Pack 发送到配置的 base_url。不要对无权处理业务正文的模型服务启用这些功能。离线 provider=demo 不发送网络请求,并且只能与 backend=mock 一起使用。

6.9 Session

sfs sessions list
sfs sessions get rs_xxx
sfs sessions rm rs_xxx
sfs migrate sessions --from ~/.sfs/sessions --to ~/.sfs/sfs.db

新安装默认使用 ~/.sfs/sfs.db。旧 JSON Session 可幂等导入 SQLite;迁移成功前不会删除或改写源文件。Session ID 会校验格式;复用 session 时还会校验 identity scope。

7. Planner

7.1 内置规则 Planner

默认 planner.type=rules:

  • 根据问题中的任务、会议、邮件、人员等线索选择来源
  • 对长问题进行有限压缩
  • 为具有短 query 限制的来源生成 source_queries
  • 在 deep 模式生成有界 map_fetch

固定 Planner:

{"planner":{"type":"default"}}

7.2 外部命令 / LLM Planner

外部 Planner 从 stdin 读取:

{
  "request": {},
  "capabilities": {},
  "output_schema": "retrieval-plan/v1"
}

并向 stdout 只写一个 RetrievalPlan JSON。接入示例:

sfs --config examples/config-external-planner.json \
  research "A 项目延期原因和待办" --fetch-top 6

或命令行覆盖:

sfs --backend mock research "A 项目延期原因" \
  --planner command \
  --planner-command python3 \
  --planner-args-json '["examples/external-planner.py"]' \
  --planner-timeout 10s

Planner 只生成计划;预算、节点上限、重试、Provider 能力和数据访问仍由 Kernel 控制。

内建 AI Planner 对首次输出和最多一次修复输出都执行同一份 retrieval-plan/v1 严格校验;仍不合法时回退 Rules Planner,并在 Plan metadata 中记录原因。

8. 外部 Provider

独立进程通过 one-shot JSON-RPC 2.0 over stdio 实现:

health search query fetch expand resolve

运行示例:

sfs --config examples/config-external-provider.json \
  search "External Provider" --sources docs

协议:api/provider-protocol.schema.json。示例实现:examples/external-provider.py。

每次调用启动一个隔离进程;stdout 只能输出 JSON-RPC 响应。宿主严格校验 envelope、方法、descriptor、ObjectRef、Projection、分页一致性和输出大小。

9. Record / Replay

录制 Provider 层输入输出:

rm -rf .tmp/replay
sfs --backend mock --record-dir .tmp/replay \
  search "A 项目 延期" --sources docs,messages,minutes

离线回放相同检索:

sfs --replay-dir .tmp/replay \
  search "A 项目 延期" --sources docs,messages,minutes

Replay key 会去掉临时 session_id,但保留 identity scope 与业务请求,因此可跨进程复现,同时不会把不同身份范围混在一起。

10. HTTP API 与 Web

sfs serve --listen 127.0.0.1:3765

主要接口:

GET    /v1/health
GET    /v1/capabilities?probe=true
POST   /v1/search
POST   /v1/search/continue
POST   /v1/query
POST   /v1/fetch
POST   /v1/expand
POST   /v1/resolve
POST   /v1/plans:execute
POST   /v1/research
POST   /v1/ask
GET    /v1/sessions
GET    /v1/sessions/{id}
DELETE /v1/sessions/{id}
curl -s http://127.0.0.1:3765/v1/search \
  -H 'Content-Type: application/json' \
  -d '{
    "query":"A 项目 延期",
    "source_queries":{"minutes":"A 项目"},
    "sources":["docs","messages","minutes"],
    "identity":{"mode":"user"},
    "limit":30
  }'

Plan SSE:

curl -N http://127.0.0.1:3765/v1/plans:execute \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  --data-binary @examples/plan-search-fetch.json

OpenAPI 3.1 契约:api/openapi.yaml。

11. MCP

sfs --backend larkcli --profile work --as user mcp

工具:

feishu_search
feishu_continue
feishu_query
feishu_fetch
feishu_expand
feishu_resolve
feishu_research
feishu_ask
feishu_get_session
feishu_capabilities

Agent 推荐流程:

feishu_search
→ 查看 Candidate 的 projection / available_projection
→ 对 3–8 个高价值对象调用 feishu_fetch
→ 必要时 feishu_expand / feishu_continue
→ 基于 Artifact/Evidence 输出带来源答案

SKILL:skills/super-feishu-search/SKILL.md。

12. Go API

内核:

snap, err := app.Engine.Search(ctx, kernel.SearchRequest{
    Query:         "A 项目 延期",
    SourceQueries: map[kernel.SourceID]string{kernel.SourceMinutes: "A 项目"},
    Sources:       []kernel.SourceID{kernel.SourceDocs, kernel.SourceMessages},
    Identity:      kernel.Identity{Mode: kernel.IdentityUser},
})

HTTP Client:

c := client.New("http://127.0.0.1:3765")
snap, err := c.Search(ctx, kernel.SearchRequest{Query: "A 项目 延期"})

13. Projection 与对象模型

Candidate 是轻量命中,Artifact 是 Fetch 后的物化对象。Projection:

head snippet summary structure content context relations attachments

例如妙记搜索只得到 head/snippet,随后可请求 summary/relations;消息 shortcut 若已经返回正文和会话上下文,Candidate 会声明已有 content/context,避免重复读取。

核心对象:

ObjectRef    稳定引用:scope/kind/native/canonical/provider/source
Candidate    搜索候选、原生排名、融合分数、Projection
Artifact     正文块、原生摘要、元数据、附件、关系
Relation     from/type/to/confidence/provenance
Session      候选、Artifact、cursor、来源运行、预算、事件

14. 搜索算法

默认融合为 Weighted Reciprocal Rank Fusion:

score = Σ source_weight / (k0 + native_rank)

再叠加有限的确定性信号:标题/短语命中、多来源发现与时效。各飞书来源的原生 score 不直接互相比大小。

分页采用有界 adaptive 策略:首轮并发;只对仍有 cursor 且仍可能影响结果的来源继续,始终受 max_pages_per_source、max_calls、deadline 与 byte budget 约束。

15. 配置与环境变量

复制配置:

cp config.example.json ~/.sfs/config.json
sfs --config ~/.sfs/config.json doctor

主要环境变量:

SFS_BACKEND
SFS_LARKCLI
SFS_SESSION_DIR
SFS_STORAGE_TYPE
SFS_STORAGE_PATH
SFS_STORAGE_TTL
SFS_LISTEN
SFS_CONCURRENCY
SFS_OPENAPI_ENABLED
SFS_OPENAPI_BASE_URL
SFS_OPENAPI_APP_ID
SFS_OPENAPI_TOKEN
SFS_OPENAPI_TOKEN_ENV
SFS_OPENAPI_USER_OPEN_ID
SFS_OPENAPI_TIMEOUT
SFS_REPLAY_MODE
SFS_REPLAY_DIR
SFS_PLANNER
SFS_PLANNER_COMMAND
SFS_PLANNER_TIMEOUT
SFS_AI_ENABLED
SFS_AI_BASE_URL
SFS_AI_API_KEY_ENV
SFS_AI_MODEL

飞书 Token 和 AI API Key 不允许写入配置文件,只通过配置指定的环境变量名读取;不得写入日志、Session、fixture 或发布包。

16. 验证边界

自动化验证覆盖:

  • Projection、ObjectRef 与 JSON 契约
  • Canonical 去重、Weighted RRF、来源配额
  • 多源 Search、source_queries、分页、Continue
  • Batch Fetch、cache、并发 singleflight、共享预算
  • 两跳 Expand 与关系过滤
  • RetrievalPlan DAG、状态机、重试 heap、跨节点共享预算
  • SQLite/JSON Session 持久化、TTL、重启恢复、并发与幂等迁移
  • lark-cli 版本、命令面、关键 flag、参数/profile 传播、envelope 与 raw JSON 兼容
  • direct OpenAPI 官方 SDK 请求、分页、响应大小限制和错误映射
  • Research/Ask 的服务端 SSE 阶段、RetrievalEvent、唯一 result/error 终态和 Web 流解析
  • AI JSON Schema、Planner 修复/回退、Rerank 降级、Citation 完整性
  • Provider record/replay 与 operation route
  • rules/default/external Planner
  • HTTP/Web、MCP、Go Client

真实飞书 live 调用无法由 Mock/单元测试替代。当前 lark-cli 真实验证只有 7 个来源成功,calendar/mail 被 missing_scope 阻塞,Base/Sheets 缺测试对象;direct OpenAPI 因没有同时可用的 App ID 与 user access token 未做真实验收。是否能读到具体对象,最终取决于用户 Token、应用 scope、租户配置、对象权限及目标 lark-cli 版本。

17. GitHub Actions CI/CD 与开发者验证

仓库内置:

  • CI:PR 与 main exact-head 的格式、Vet、单元/竞态测试、coverage、文档、Mock、Web、Playwright、平台原生构建和 Docker;
  • Security:每个 PR、main、merge queue 和每周定时的 NPM audit、Govulncheck 与 CodeQL;
  • Release:只接受属于 main 的稳定 vX.Y.Z Tag,自动构建六平台二进制、源码包和 SHA-256;workflow 拒绝覆盖已存在的同名 Release,但未启用 GitHub 平台级 immutable;
  • Live Smoke:仅允许 main,在受保护 Environment 与受控 self-hosted runner 上执行真实租户只读验收;
  • Dependabot:Go Module、NPM、GitHub Actions 与 Docker 更新;
  • Issue/PR Template、安全策略、贡献指南和发布脚本。

正式交付事实以 Actions 中具体 commit 的终态和 Releases 中实际资产为准。pending、cancelled、不同 SHA 或本地测试都不能替代 exact-head 成功记录。

源码贡献者需要 Go 1.25+、Node.js 22.22.2+(或 24.15.0+/26+)、Python 3、Ruby、ShellCheck 和 Chromium。维护者本地入口:

make verify
make coverage
make web-install
make web-test
make http-smoke

普通使用者不需要执行这些命令,也不需要运行 make package;正式二进制只从 GitHub Release 下载。

详细说明见 docs/GITHUB_ACTIONS.md 和 docs/RELEASING.md。

18. 目录

adapter/       lark-cli、OpenAPI、mock、exec Provider、replay
api/           OpenAPI 3.1 与 JSON Schema
client/        Go HTTP Client
cmd/sfs/       主程序
examples/      Plan、配置、外部 Planner/Provider
internal/      Engine、Budget、Fusion、Session、Plan Executor、Research
kernel/        公共领域模型和接口
planner/       rules、default、external-command
provider/      Registry 与 source/operation 路由
skills/        Agent SKILL
synthesis/     Candidate/Artifact/Evidence Pack
transport/     CLI、HTTP、MCP
web/           React/TypeScript/Vite Web 唯一源码

完整设计:docs/SuperFeishuSearch_完整技术设计_v1.md。实现状态:docs/IMPLEMENTATION_STATUS.md。

仓库整体采用 GPL-3.0;来源材料及正式运行时依赖的许可证、版本与归属保存在 LICENSES/ 与 THIRD_PARTY_NOTICES.md。make license-check 会拒绝未登记的 Go 运行时模块、Web 生产依赖、版本漂移或许可证文件变更,GitHub Release 运行包携带完整 LICENSES/ 目录。

↑↓ navigate openesc close