内容
# okf-mcp
一款提供人工智能代理标准化 Open Knowledge Format(OKF)后端支持的 MCP 服务器:一个由纯 Markdown 文件组成的知识库,带有 YAML 前置信息,索引成一个链接图,并通过 MCP 资源和工具暴露,以便于搜索、遍历、验证和创作。
知识库本身就是一个目录(一个 bundle)。人类可以使用任何编辑器浏览和编辑它——包括直接作为 **Obsidian vault** 打开——而代理则通过 MCP 服务器工作。Obsidian 不是必需的:格式是纯 OKF v0.1 Markdown,任何 `.obsidian/` 目录都被索引器忽略。
- 没有数据库,没有嵌入;唯一的网络调用是针对您显式配置的可选只读远程 bundles。
- 按设计允许(spec §9):报告格式错误的文件,有效概念继续提供服务。
- 写路径保持 `index.md` 导航页面和 `log.md` 历史更新,以便人类视图在代理写入时保持可浏览。
## 快速入门
```bash
npm install
npm test
npm run dev -- --bundle acme=examples/acme inspect
```
启动 stdio MCP 服务器(默认命令):
```bash
npm run dev -- --bundle acme=examples/acme # 只读
npm run dev -- --bundle acme=examples/acme --writable # + 创作工具
```
或构建并运行编译后的二进制文件:
```bash
npm run build
node dist/cli.js --bundle /path/to/your/bundle
```
## MCP 客户端配置
该软件包发布到 npm,因此最简单的设置是通过 `npx` 运行:
```json
{
"mcpServers": {
"okf": {
"command": "npx",
"args": [
"-y", "@copperbox/okf-mcp",
"--bundle", "brain=/absolute/path/to/your/bundle",
"--writable"
]
}
}
}
```
或者,指向您自己构建的本地副本(`npm run build`):
```json
{
"mcpServers": {
"okf": {
"command": "node",
"args": [
"/absolute/path/to/okf-mcp/dist/cli.js",
"--bundle", "brain=/absolute/path/to/your/bundle",
"--writable"
]
}
}
}
```
`--bundle` 接受 `path` 或 `id=path`,并且是可重复的。省略 `--writable` 以获取只读服务器。
## 教会您的代理维护大脑
服务器故意不对何时捕获知识持意见:其内置指令教会连接的代理 OKF 约定和写入流程(`suggest_concept_path` → `write_concept`),但没有任何内容指示代理在普通工作的副作用下记录它所学到的内容。捕获策略属于您代理的自己的配置 — `CLAUDE.md`、`AGENTS.md` 或系统,您的客户端读取的任何一个。
服务器也不执行 git 同步。如果 bundle 是共享的——挂载到团队存储库的本地克隆——它只是在克隆的最后一次 `git pull` 时更新,并且通过 `write_concept` 写入的概念只有在异地提交和推送后才能被队友访问。保持共享 bundle 同步是您(或您的代理)的责任,因此它属于相同的固定指令。
如果您想要在工作时“大脑不断增长”的环境行为,则这样的固定指令就足够了——将其复制到您的代理配置中,并根据需要进行调整:
```markdown
## 知识捕获(OKF 大脑)
该项目在 `okf` MCP 服务器后面保持一个持久的知识库(“大脑”)。
- 在开始非琐碎工作之前,请检查大脑:使用 `graph_summary` 进行定位,然后使用 `search_concepts` 查找与任务相关的任何内容,并将找到的内容视为先前上下文。
- 当您获得持久的知识时——决策及其理由、陷阱、系统实际工作方式、值得保留的约定——请在完成之前记录它:调用 `suggest_concept_path` 选择位置,然后调用 `write_concept`。优先更新现有概念而不是创建近似重复的概念。
- 保持概念小且相互关联:每个概念一个想法,文档相对的 Markdown 链接(`../tables/orders.md`)到相关概念,并重用现有的类型和标签。
- 不要记录短暂信息(任务状态、一次性调试详细信息)——大脑用于一个月后仍应为真的知识。
- 如果大脑是共享的(团队存储库的克隆),服务器永远不会为您同步 git。在依赖它之前,请确保克隆是当前的 - 运行 `git pull` 在 bundle 存储库中,然后调用 `reload_bundles` 以使索引获取更改。对于 `--remote-bundle` 挂载,调用 `reload_bundles` 重新获取。
- 将持久知识写入共享大脑后,如果您有权限,请提交并推送它,或者提醒用户 - 在此之前,新知识对队友是不可见的。
```
这从一开始就有效:将 `--bundle` 指向一个空目录,并使用 `--writable`,第一个 `write_concept` 创建文件夹结构、导航索引和日志。
## 多 bundle 设置(组织大脑 + 项目大脑)
`--bundle` 和 `--remote-bundle` 是可重复的,因此一个服务器可以将共享的组织范围的大脑挂载到项目的 bundle 旁边。将组织大脑从本地克隆挂载到代理应该写入它:
```json
{
"mcpServers": {
"okf": {
"command": "npx",
"args": [
"-y", "@copperbox/okf-mcp",
"--bundle", "org=/absolute/path/to/org-brain-clone",
"--bundle", "project=/absolute/path/to/this-repo/brain",
"--writable"
]
}
}
}
```
如果只需要使用组织大脑,可以用只读 GitHub 树交换其挂载 - 无需保持克隆新鲜,并且 `reload_bundles` 重新获取它:`"--remote-bundle", "org=https://github.com/your-org/brain/tree/main/bundle"`。注意 `--writable` 是服务器范围的 - 每个本地挂载的 `--bundle` 都变为可写 - 因此 `--remote-bundle` 也是保持组织大脑对代理只读同时项目 bundle 保持可写的方法。
有两个路由行为使其可行:
- 聚合读取工具 - `search_concepts`、`list_concepts`、`list_types`、`list_tags`、`graph_summary`、`validate_bundle` - 在省略 `bundle` 参数时涵盖 **所有** bundle,因此一次搜索跨越两个大脑。
- 每个概念和写入工具(`get_concept`、`get_neighbors`、`write_concept`,...)需要再次显式 `bundle`,因此写入始终指定其目的地。
按范围分割知识:标准、环境架构和跨存储库系统映射属于组织 bundle;特定于某个存储库的决策和陷阱属于该存储库的项目 bundle。跨 bundle 的 Markdown 链接不是 OKF 的一部分(§5 链接在单个 bundle 内解析,因此指向另一个 bundle 的链接只是作为损坏的索引)- 要从项目概念引用组织概念,请在 `# Citations` 部分(spec §8)中使用组织 bundle 的规范 URL 引用它;当需要真正的图边时,请在项目 bundle 中添加一个 `references/` 下的小型存根概念,镜像组织概念,链接到存根,并让存根的引用指向源。当项目知识被证明是组织范围的时,`promote_concept` 将其移入组织 bundle,并在此旧路径上留下这样的引用存根,因此项目 bundle 的入站链接继续解析。
将路由指南追加到上面的 CLAUDE.md 代码片段:
```markdown
- 挂载了两个大脑:`org`(跨项目标准、环境架构、系统映射)和 `project`(此存储库的决策、陷阱、约定)。在开始工作之前,请搜索两者 - 省略 `bundle` 参数,以便 `search_concepts` 和 `graph_summary` 涵盖所有 bundle,或者分别查询每个 bundle。
- 按范围路由写入:特定于此存储库的知识进入 `project` bundle。适用于多个项目的知识 - 标准、共享基础设施、组织范围的架构 - 进入 `org` bundle;如果组织大脑是只读挂载的,请在项目 bundle 中记录它并标记为提升。
- 永远不要从一个 bundle 编写 Markdown 链接到另一个 bundle - 它们作为损坏的索引。在项目概念中,通过使用组织 bundle 的规范 URL 的 `# Citations` 条目,或者通过 `references/` 存根概念(当需要图边时)引用组织概念。
```
### 并置 bundle(vault 作为 monorepo)
一种常见的布局将多个 bundle 保留为一个根目录的 sibling 子目录 - 例如,作为单个 Obsidian vault 打开的存储库:
```
knowledge/ ← 存储库根目录,作为 Obsidian vault 打开
├── AGENTS.md ← 不属于任何 bundle
├── acme/ ← bundle "acme"
└── ops/ ← bundle "ops"
```
不要为每个子目录重复 `--bundle`,而是用一个标志挂载它们:
```bash
okf-mcp --colocated-bundles /path/to/knowledge
```
根目录的 **直接子目录** 的每个目录,如果至少包含一个 Markdown 文件,则作为其自己的 bundle 挂载,文件夹名称作为其 bundle id(与 `--bundle <path>` 使用的默认 id 规则相同)。点目录(`.obsidian`、`.git`)被跳过,根目录下的松散文件(`README.md`、`AGENTS.md`)不属于任何 bundle。该标志是可重复的,与 `--bundle` / `--remote-bundle` 结合使用;发现的 id 与另一个挂载的 id 冲突时,会出现启动错误,命名并置根目录。除了节省标志, `--colocated-bundles` *声明* sibling 布局(在每个发现的 bundle 配置的 `colocatedRoot` 上),因此可以区分并置 sibling 的功能,并区分独立挂载的 bundle。位于并置 bundle 之间的相对 `../sibling/...` 链接导出 [跨 bundle 图边](#cross-bundle-awareness),解析引用,由 `validate` 检查,并在 [`pack`](#cli) 中重写为 sibling 的规范 URL。
当根目录包含许多 bundle,但当前项目只需要几个时, `--only <folder,folder,...>` 是 scoped 挂载的出口:
```bash
okf-mcp --colocated-bundles /path/to/knowledge --only acme,ops
```
只有命名的子文件夹被挂载;根目录中的其他所有内容都完全被忽略 - 未被发现,不被列出 - 这保持启动轻量,并防止不相关的 bundle 稀释搜索结果,类型/标签词汇和 `graph_summary` 扫描。 不存在的名称作为子目录(或存在但不包含 Markdown)是一个启动错误,而不是静默跳过, 而且不带 `--colocated-bundles` 的 `--only` 也会出错。
当根目录作为一个存储库发布时,每个 bundle 的规范 URL 是机械的 - 存储库的树 URL 加上文件夹名称 - 因此一个标志声明它们全部用于 [跨 bundle 感知](#cross-bundle-awareness):
```bash
okf-mcp --colocated-bundles /path/to/knowledge \
--canonical-url https://github.com/acme/knowledge/tree/main
```
每个并置 bundle 派生 `canonicalUrl = <rootUrl>/<folder>`(此处为 `…/tree/main/acme`、`…/tree/main/ops`),并且派生的 URL 具有与显式声明的 URL 相同的树/blob/raw 前缀扩展。裸 URL 在恰好配置了一个并置根目录时有效;有多个时,请命名根目录: `--canonical-url /path/to/knowledge=<url>`。显式每个 bundle 的 `--canonical-url id=<url>` 仍然覆盖派生的值。非 GitHub 根 URL 也有效 - 文件夹名称附加到字面前缀。消费者仍然可以直接从其子目录树 URL 挂载单个 bundle( `--remote-bundle acme=https://github.com/acme/knowledge/tree/main/acme` ) - 或通过一个 URL 挂载整个发布的根目录,使用 [`--colocated-remote-bundles`](#consuming-a-published-colocated-root-by-one-url).
#### 延迟挂载:发现所有,加载时访问
并置根目录可能包含许多给定项目从未触及的 bundle,因此 MCP 服务器(`mcp`,默认命令)延迟挂载并置 bundle:启动时,每个子目录的成本仅为其发现 - 文件夹名称以及根目录 `index.md` 的前置信息读取以获取 `description` - 并且仅在任何工具命名它时才解析和索引 bundle(`bundle` 参数,`okf://` 资源读取,`reload_bundles <id>` 等)。语义选择如下,确保没有任何内容被静默截断:
- `list_bundles` 列出每个 bundle,带有 `loaded` 标记;未加载的 bundle 带有其名称和描述,以便代理可以查看存在什么并选择要加载的内容。
- 无参数扫描(`search_concepts`、`list_concepts`、`list_types`、`list_tags`、`graph_summary`、`validate_bundle`)仅涵盖 **已加载** 的 bundle,并且工具结果附带一个注释,指出被排除的已发现 bundle 的名称 - 不相关的 bundle 停止污染结果,而不会被视为完整覆盖。
- `resources/list` 仅用其根目录 `index.md` 表示未加载的 bundle(带有已发现的描述);读取它会加载 bundle,然后其文档会单独列出。
- [跨 bundle 派生](#cross-bundle-awareness) 仅看到已加载的 sibling:`../sibling/...` 链接到未加载的 bundle 不会派生边,其引用分类为 `missing`,直到 sibling 加载(访问它会使边出现);`validate` 的悬空链接警告同样对未加载的 sibling 保持沉默。
- 无参数 `reload_bundles` 仅重载已加载的 bundle(未加载的 bundle 没有过时的索引);命名未加载的 bundle 会加载它。 `--watch` 监视已加载的 bundle,并在延迟 bundle 加载后立即开始监视。
- `--only` 组合:过滤掉的子文件夹甚至不会被发现。
一次性 CLI 命令(`inspect`、`validate`、`search` 等)按设计扫描每个 bundle,因此它们像以前一样急切地加载并置 bundle。远程挂载始终是急切的 - 远程根目录是一次获取,其文件夹名称在获取之前是未知的。
#### 根目录 `AGENTS.md`:bundle 指南
如果并置根目录包含一个 `AGENTS.md`(确切的名称),其内容会在 MCP 服务器指令下追加到一个 `Bundle guide (from AGENTS.md):` 分隔符后,因此每个会话都知道哪些 bundle 存在以及哪些 bundle 适用于什么样的工作 - 并传递显式的 `bundle` 参数而不是扫描所有内容。将它写成一个短注册表,供代理决定在哪里查找:每行或两行每个 bundle,涵盖的内容,何时查找。它兼作 Obsidian 中可读的 vault 根目录注释,并在存储库中旅行。
指令在每个会话中加载到代理的上下文中,因此指南是预算的:超过 4000 个字符后,服务器会记录警告并注入一个截断的指南,并指向 `get_bundle_guide`(以及完整的文件)。保持它精简。
该指南也可以通过 `get_bundle_guide` 工具按需获取,该工具在挂载并置根目录(本地或远程)时注册 - 包括在会话中途,通过 `tools/list_changed`,当 `load_colocated_remote_bundles` 挂载第一个时。它返回每个根目录的 `AGENTS.md`(本地根目录从磁盘读取,因此外部编辑显示出来;远程根目录返回使用挂载获取的指南)以及每个 bundle 的一行 `description`,用于一个根目录(`root` 参数:本地路径或远程 URL)或省略时所有已挂载的根目录。基本指令告诉代理在探索之前调用它,因此指南在会话的任何时候都可访问 - 不仅在初始化握手。
## 远程 bundle(知识交换)
OKF 的第三个目标是在系统之间交换知识。您可以索引在另一个存储库中发布的 bundle,而无需克隆它,直接从公共的 GitHub 树:
```bash
npm run dev -- \
--remote-bundle okf=https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf \
inspect
```
`--remote-bundle id=url` 是可重复的,接受 `https://github.com/<owner>/<repo>/tree/<ref>/<path>` URL(不支持包含 `/` 的引用),或通过扩展名检测到的 `.tar.gz` / `.tgz` / `.zip` 存档 - 任何 http(s) URL,或本地存档路径。运行时可以通过 `load_remote_bundle` 工具(`{ id, url, include?, exclude?, canonicalUrl? }`,bundle 相对路径的 glob 过滤器)提供相同的内容,该工具仅更改内存索引;`list_remote_bundles` 列出已加载的内容,带有树或存档 URL 作为源。
### 通过一个 URL 使用发布的 colocated 根
一个作为单个仓库发布的 [colocated 根](#colocated-bundles-vault-as-monorepo) 可以整体安装 — 每个子文件夹成为其自己的只读包 — 而不是在每个子目录树 URL 上重复使用 `--remote-bundle`:
```bash
okf-mcp --colocated-remote-bundles https://github.com/acme/knowledge/tree/main inspect
```
与本地 `--colocated-bundles` 相同的发现规则适用:每个包含 markdown 的立即子目录作为一个包安装,文件夹名称作为其 ID(与另一个安装发生冲突时命名根目录),跳过点目录, loose 根文件不属于任何包。安装的包声明根 URL 作为其共享的 colocated 根,因此发布的仓库中的相对 `../sibling/...` 链接导出 [跨包边缘](#cross-bundle-awareness) 之间的远程兄弟节点 — 一个通过 URL 安装的仓库保持与本地克隆的连贯性,无需重写步骤。树安装自动导出每个包的规范 URL 为 `<treeUrl>/<folder>` (树/blob/raw 表单全部匹配);`.tar.gz`/`.tgz`/`.zip` 根(任何 http(s) URL,或本地路径;条目按包装目录后的第一个路径段分区)没有每个文件的 URL,因此它们仅从显式的根 `canonicalUrl` 导出规范 URL。标志是可重复的,`--only <folder,folder,...>` 限制安装到命名子文件夹,类似于本地根目录,并且 500 文件 / 10 MiB 天花板适用于整个根目录 — 而不是每个包 — 因此安装根目录的成本永远不会超过安装一个大包的成本。
根目录 `AGENTS.md` 随安装一起提供:CLI 提取它并将其作为 [包指南](#root-agentsmd-the-bundle-guide) 附加到服务器指令中,与本地 colocated 根目录相同。运行时对应的工具是 `load_colocated_remote_bundles` 工具(`{ url, only?, include?, exclude?, canonicalUrl? }`)— MCP 指令在初始化时固定,因此该工具返回其结果(`agentsGuide`)中的 `AGENTS.md` 内容,而不是注册 `get_bundle_guide` (通过 `tools/list_changed` 公告,以便在会话的其余部分保持指南的可检索性),并且代理仍然接收指南。重新加载任何安装的包都会重新提取整个根目录,跟踪上游出现或消失的子文件夹。
远程包是严格只读和沙盒化的:
- 仅 `.md` 文件被索引(GitHub 树通过内容 API;`GITHUB_TOKEN` 用于速率限制,设置时从未发送到非 GitHub 主机),绑定到每个包 500 个文件 / 10 MiB;存档下载另外限制在 10 MiB 压缩。
- 具有路径遍历(`..`,绝对路径)的存档条目被拒绝;包装所有文件的一个顶级目录(在 GitHub 源 tarballs 中)被剥离;不支持 zip64 存档。
- 远程内容被解析为 markdown,从不执行,从不写入磁盘。
- 所有创作工具拒绝只读包,并且 `regenerate_indexes` / `index` 命令跳过它们。
- `reload_bundles` 重新提取它们,报告与本地包相同的添加/删除/更改增量。
### 跨包感知
OKF §5 故意没有跨包链接语法,但是服务器知道每个安装包的规范位置,并且可以从规范数据中导出跨包关系。当一个概念的 §8 引用目标,外部链接或前置 `resource` URL 指向另一个安装包的规范位置下时,图工具记录一个导出的 `kind: "cross-bundle"` 边到该概念 — 只读的,无需文档中的新语法。
[Colocated 包](#colocated-bundles-vault-as-monorepo) 在没有 URL 的情况下获得相同的处理:一个普通的相对链接,如 `[orders](../acme/tables/orders.md)` — 当 colocated 根目录作为一个保险库打开时,Obsidian 原生解析 — 当其第一个路径段命名一个安装的兄弟节点(一个声明相同的 colocated 根目录的包)并且其余部分解析到其概念之一(`.md` 可选,如正文链接)时,导出一个 `kind: "cross-bundle"` 边。通过此类链接分类的引用为 `concept` 而不是 `missing`,并且当 `../` 链接指向安装的兄弟节点中它不具有的概念时,`validate` 发出警告(悬空);链接到未安装的文件夹或 loose 根文件保持沉默 — 声明 colocation,但从磁盘推断 colocation。
`promote_concept` 发出确切的此类链接:在 colocated 兄弟节点之间,引用桩引用规范副本的相对路径(例如,从一个目录深的桩 `../../org/standards/naming.md`)而不是 `okf://` URI — 并且即使目标具有规范 URL,也倾向于相对形式,因为磁盘保险库 UX 是 colocation 的重点,并且打包时发布重写相对链接为规范 URL。桩的前置 `resource` 保持规范的 `/okf://` URI(规范 §4.1 需要一个可解析的 URI)。非 colocated 提升继续引用规范位置。
- GitHub 树安装自动获取其规范位置(树,blob 和 raw.githubusercontent.com 表单的树 URL 全部匹配)。
- 本地克隆和存档没有固有的 URL:使用 `--canonical-url id=<url>` (或 `load_remote_bundle` 上的 `canonicalUrl`)赋予它们一个,例如共享包的发布的 GitHub 树 URL,以便引用它的引用即使在从本地检出安装时也能解析。
- 作为一个仓库发布的 [colocated 包](#colocated-bundles-vault-as-monorepo) 只需要一个根级别的 `--canonical-url <rootUrl>`:每个包导出 `<rootUrl>/<folder>`,并且显式的包级标志覆盖。
`graph_summary` 报告 `crossBundleEdges`;`get_neighbors` 和 `find_path` 在调用时遍历导出的边 `crossBundle: true` (节点 ID 变为 `bundle:concept` 并且携带目标包);`export_graph` 在 `crossBundle: true` 时导出一个命名空间的多包图,导出边以虚线形式在 `dot`/`mermaid` 中渲染。
## 包(你的“OKF 大脑”)
一个包是一个 Markdown 概念文档的目录树,每个 OKF v0.1:
```
brain/
├── index.md # 生成的导航(保留,渐进披露)
├── log.md # 生成的更新历史(保留,最新的优先)
├── tables/
│ ├── index.md
│ └── orders.md # 一个概念:前置 + markdown 正文
└── playbooks/
└── freshness.md
```
每个非保留的 `.md` 文件都是一个概念。前置仅需要 `type`;`title`、`description`、`resource`、`tags` 和 `timestamp` 是推荐的,未知的键被保留。当省略 `title` 时,显示名称(索引条目,MCP 资源名称,搜索/列表命中)从文件名导出 §4.1 — `customer-order-history.md` 变成“客户订单历史” — 并且搜索/列表命中携带 `titleDerived: true` 以便代理可以区分导出的标题和作者的标题。包根 `index.md` 可以在其前置中声明一个 `okf_version` (规范 §11):`list_bundles` 和 `graph_summary` 报告它,并且 `validate_bundle` 警告 — 而不失败 — 当它命名一个比服务器支持的新主版本时。相同的前置可以声明一个 `description` — 一个关于包用途的一行,用于告知代理是否查看它(例如 `description: "Payments-team runbooks and schema notes"`):`list_bundles` 和 `list_remote_bundles` 报告它,根 `index.md` MCP 资源携带它,并且像其余根前置一样,它在索引再生中存活。概念 ID 是不带 `.md` 的文件路径(`tables/orders`)。关系是普通的 markdown 链接 — 文档相对 (`./customers.md`、`../tables/orders.md`;推荐:它们在图,GitHub 和 Obsidian 中解析相同,无论包在仓库中处于何种位置)或包绝对 (`/tables/orders.md`,从包根解析;接受但不鼓励 — GitHub 从 *仓库* 根解析一个前导 `/`,因此当包是仓库子文件夹时,这些渲染会损坏)— 并且变成图中的有向边。损坏的链接是警告,而不是错误。
写入再生每个 `index.md` 作为生成的工件,例外是两个人类策划的情况(规范 §6 支持具有有意义的章节分组的手工策划索引)。一个 `index.md`,其前置声明 `generated: false` 被视为手工策划并且永远不会被重写 — `regenerate_indexes` 报告它被跳过,并且删除留下其目录原样。而包根 `index.md` 的前置始终在再生后存活:声明的 `okf_version` 和任何扩展键都被保留;仅当不存在时,才会标记 `okf_version`。
要在 Obsidian 中查看大脑,请将包目录作为一个保险库打开(文件 → 打开文件夹作为保险库)。生成的 `index.md` 文件同时作为导航页面,标准的 markdown 链接按原样工作。
## MCP 接口
资源:每个文档的 `text/markdown` 资源,在 `okf://<bundle>/<path>`。
服务器还声明 MCP 服务器级指令 — 一个关于 OKF 约定的简短入门指南(概念 ID,链接形式,保留文件,读写工具流)客户端将这些指令注入到代理的上下文中。只有当服务器以 `--writable` 运行,创作指南才会被包含。
两个入口点工具,`search_concepts` 和 `get_concept`,在其 `_meta` 中声明 `anthropic/alwaysLoad`,因此当工具集加载按需时,客户端保持其模式可见。
读取工具:
| 工具 | 用途 |
|---|---|
| `list_bundles` | 配置的包,包含概念计数,只读标志,每个包声明的 `description`,以及 [延迟安装](#lazy-mounting-discover-all-load-on-first-access) 的 colocated 包的 `loaded` 标记 |
| `get_bundle_guide` | 每个 colocated 根的 [`AGENTS.md` 指南](#root-agentsmd-the-bundle-guide) 以及每个包的一行 `description`;仅在安装了 colocated 根时注册(动态,在第一次运行时安装) |
| `reload_bundles` | 重新读取包(磁盘,远程树或存档)以获取外部编辑;报告添加/删除/更改的概念。无参数形式涵盖加载的包;命名未加载的发现包会加载它 |
| `load_remote_bundle` | 从公共 GitHub 树 URL 或 `.tar.gz`/`.tgz`/`.zip` 存档中索引一个只读包,仅在内存中 |
| `load_colocated_remote_bundles` | 通过 URL 安装发布的 colocated 根 — 每个子文件夹成为其自己的只读包 — 在结果中返回根 `AGENTS.md` 指南 |
| `list_remote_bundles` | 当前加载的远程包,及其源 URL 和声明的 `description` |
| `list_concepts` | 概念元数据(包括设置 `resource` URI 时),按前缀/类型过滤 |
| `get_concept` | 一个完整的文档:前置、正文、输出链接和 `sections` 标题列表;传递 `section` 以获取单个正文部分 |
| `get_citations` | 概念的编号 `# Citations` 条目(规范 §8),每个分类为 `external` / `concept` / `missing`;重复的 `# Citations` 部分被合并,因此一个意外的空重复项无法掩盖条目 |
| `read_document` | 任何包文档的原始 markdown 文件路径,包括保留的 `index.md` / `log.md`;缺少的 `index.md` 由前置合成(规范 §6,标记 `synthesized: true`)— 远程包发布的没有索引文件的入口点 |
| `search_concepts` | 文本查询 + 类型/标签/路径/链接/孤儿过滤器,分页;精确 `resource` 过滤器将资产 URI 映射到其概念;命中包括匹配位置、正文片段和封闭节标题 |
| `list_types` | 不同的概念 `type` 值及其使用计数 |
| `list_tags` | 不同的标签值及其使用计数 |
| `suggest_concept_path` | 一个新概念应该存在的位置,按相同类型(和相同标签)的概念已经存在的位置排名 |
| `graph_summary` | 紧凑的概述:计数,类型,标签,孤儿,导出的 `crossBundleEdges` |
| `get_neighbors` | 围绕概念的有界扩展(`in`/`out`/`both`,深度);`crossBundle: true` 跟随导出的边进入其他安装的包 |
| `find_path` | 两个概念之间的最短有向链接路径;`crossBundle: true` 接受 `bundle:concept` ID 并跨包 |
| `export_graph` | 图为 `json`,`dot` 或 `mermaid`;`crossBundle: true` 导出所有安装的包为一个命名空间图,带有虚线导出边 |
| `concept_history` | 概念文件的 Git 提交历史,按最新优先顺序,跟踪重命名 |
| `concept_diff` | 概念文件的统一 Git 差异与引用(默认:其最新更改) |
| `validate_bundle` | OKF v0.1 一致性错误 + 软警告(损坏的链接,包绝对前导 `/` 链接,悬空的 `../` 链接进入 colocated 兄弟节点,格式错误的推荐前置字段,格式错误或未解析的引用,重复的顶级标题,`index.md` / `log.md` 结构检查);带有安全机械修复名称的警告它们的 `okf-mcp repair` 修复程序 ID |
`concept_history` 和 `concept_diff` 需要包生活在 git 工作树中;在非 git 包上,它们返回一个 `not a git repository` 结果而不是失败。
写入工具(仅限 `--writable`):
| 工具 | 用途 |
|---|---|
| `write_concept` | 创建/更新概念(默认为写入时间 `timestamp`),追加 `log.md` 条目,重新生成 `index.md` 文件。按顺序排列的 `# Citations` 条目(`1. [text](target)`)被规范化为规范 §8 `[n] [text](target)` 形式 |
| `update_concept` | 部分更新:浅前置修补和/或用头部替换一个正文部分 — 所有其他内容,包括 YAML 注释和格式,都原样保留。 `timestamp` 刷新到写入时间(如 `write_concept`)(如果没有 `timestamp` 的概念会在其规范顺序槽中获得一个)除非修补程序命名它,否则 `keepTimestamp: true` 固定它。正文内容可以包括头部 — 领先的重复被剥离,永远不会重复 — 并且 `# Citations` 条目像 `write_concept` 一样规范化;日志 + 索引 |
| `delete_concept` | 删除概念(可选,如果存在传入链接则拒绝),记录它,重新生成索引 |
| `rename_concept` | 将概念移动到新路径,重写跨包的传入链接,记录它,重新生成索引 |
| `promote_concept` | 将概念移动到另一个可写的包(显式 `toPath`,或 `suggest_concept_path` 样式放置),在旧路径上留下一个引用桩,指向提升的副本(在 colocated 兄弟节点之间为相对 `../<bundle>/<path>` 链接,否则为规范位置)— 或 `stub: false` 仅报告悬空的传入链接;日志和重新索引两个包 |
| `append_log_entry` | 在包根的 `log.md` — 或通过 `directory` 的每个目录 — 中记录更改叙述条目,无需触摸任何概念 |
| `regenerate_indexes` | 从前置重写 `index.md` 导航,报告它跳过的手动策划索引(`generated: false`) |
写入约束为包内安全相对 `.md` 路径;拒绝保留文件名(`index.md`,`log.md`)和点目录作为概念路径。
## CLI
```
okf-mcp --bundle [id=]<路径> [--colocated-bundles <根目录> [--only <a,b,c>]]
[--remote-bundle id=<网址>] [--colocated-remote-bundles <网址>]
[--canonical-url [id=]<网址>] [--writable] [--watch] [命令]
mcp 启动标准输入/输出MCP服务器(默认)
inspect 打印每个捆绑包图的摘要
validate 报告一致性错误和警告(如果有错误则退出1)
search <查询> 搜索概念
concept <id> 以JSON格式打印一个概念文档
graph [格式] [捆绑包]
导出链接图(json | dot | mermaid | html)
index 重新生成index.md文件(需要--writable)
pack [捆绑包] 以可分发存档形式发布捆绑包
repair [捆绑包] 检测并自动修复已知的捆绑包缺陷类别
(默认情况下为干预运行;--write应用)
```
`graph` 以指定的格式导出链接图。如果有多个捆绑包挂载且没有指定捆绑包参数,则所有捆绑包导出为一个合并图 - 节点ID命名为`bundle:concept`,并包含派生的[跨捆绑包边](#cross-bundle-awareness),在`dot`/`mermaid`中以虚线表示 - 因此,`--colocated-bundles`根目录导出整个图。指定一个捆绑包以将导出范围限定为该捆绑包(未限定的节点ID,与单个捆绑包输出相同)。`--include-external`添加外部链接目标作为不透明节点;派生跨捆绑包边的网址不会重复作为节点。`--out <文件>`将导出写入文件而不是标准输出。
`html`格式将图渲染为**一个自包含的交互式页面** - 嵌入数据和一个小的手动滚动力模拟在`<canvas>`上,无需CDN或网络访问 - 因此该文件可以在任何浏览器打开时共享和查看:
```bash
okf-mcp --colocated-bundles /path/to/vault graph html --out graph.html
```
节点按*社区*着色,并带有图例(点击条目以聚焦该社区:其他一切都变淡 - 边缘在任一端点内部时保持完整强度 - 点击条目再次,或背景,清除焦点):合并的多捆绑包导出按**捆绑包**分组 - 每个捆绑包读取为一个集群,捆绑包之间的跨捆绑包边缘在它们之间强调(明亮的虚金色,比捆绑包内的链接更宽更不透明)- 而单个捆绑包按概念**类型**分组,除非`--community folder`(概念ID的第一个路径段;顶级概念分组为`(root)`)或`--community tag`(第一个frontmatter标签;如果不存在,则为`(untagged)`)覆盖。由于捆绑包分组在合并图中始终获胜,因此`--community`在合并图中被拒绝 - 指定一个捆绑包来使用它。每个边缘都有一个目标的指向箭头,颜色与边缘匹配。节点半径随度数缩放,悬停显示id/标题/描述/标签,点击节点突出其邻居,搜索框通过id/标题/标签中的不区分大小写的子字符串过滤(非匹配节点变淡;只有两个端点都匹配时,边缘才会保持明亮),视图支持节点拖动,滚轮缩放和平移;外部节点(`--include-external`)渲染为哑巴方形。标题和描述嵌入`<`转义,因此文档中的`</script>`不能破坏页面。
`pack` 以`.tar.gz`(或`.zip`,通过`--out`扩展名)形式导出一个挂载的捆绑包,以便与无法访问其git远程的系统进行交换 - 这是`--remote-bundle`的对应项,它加载此类存档。`index.md`文件从打包的概念集中重新生成内存,因此存档是自我描述的,带有捆绑包根目录的声明frontmatter(包括`okf_version`)保留和手动策划的索引(`generated: false`)原样传递;源捆绑包永远不会被写入,因此`pack`不需要`--writable`,只读远程捆绑包也可以重新导出。重复的`--include`/`--exclude`通配符选择概念和日志,其语义与`load_remote_bundle`使用的相同(重新生成的索引始终发出,仅描述已打包的内容):
```bash
okf-mcp --bundle brain=/path/to/bundle pack --out brain.tar.gz --exclude 'drafts/**'
```
相对`../<sibling>/...`链接到[同位](#colocated-bundles-vault-as-monorepo)兄弟姐妹仅在共享布局保持时才有意义,因此存档副本携带兄弟姐妹的规范概念网址(其blob表单用于GitHub规范网址) - 一个spec §8引用表单,在任何地方解析;只有链接目标更改,每个其他字节原样传输,源文件保持不变。解析链接的兄弟姐妹没有规范网址(显式或从根级`--canonical-url`派生)失败打包而不是发送死链接。
`repair` 在挂载的捆绑包(或一个命名捆绑包)上运行一个**命名自动修复程序注册表** - 一个捆绑包医生,用于处理已经在磁盘上的文档中发现的缺陷类别,每个缺陷类别都将检测与机械、安全基于拼接的重写配对(人类格式化和未知frontmatter在触摸的跨度之外幸存)。它默认情况下进行干运行,打印每个修复程序,每个文件的发现作为JSON,带有`fixed`/`skipped`计数;`--write`应用安全重写,追加一个`log.md`条目,总结扫描(修复程序ID + 文件计数),并重新生成索引,与作者工具的记账相匹配。发现如果重写无法被证明安全,则会报告而不是猜测,读取-仅远程捆绑包将被跳过,`validate`警告如果有安全自动修复程序会命名其修复程序ID。`--list`打印注册表;对于此命令,`--only`命名修复程序,而不是同位子文件夹:
```bash
okf-mcp --bundle ./kb repair # 干运行:报告发现
okf-mcp --bundle ./kb repair --write # 应用所有修复程序
okf-mcp --bundle ./kb repair --only citation-format --write
okf-mcp repair --list # 显示修复程序注册表
```
初始修复程序: **`citation-format`** 规范化有序列表引用条目(`1. [text](target)`,`1) ...`)在`# Citations`标题下到spec §8 `[n] [text](target)`表单 - 写入路径应用的相同转换,因此修复和写入时间预防不会漂移; **`duplicate-citation-headings`** 通过删除空重复项(损坏模式,其中空第一个副本掩盖了来自第一个匹配读取器的每个条目)合并重复的`# Citations`部分,报告每个具有内容的重复项以进行手动合并; **`okf-uri-to-canonical`** 重写`okf://<bundle>/<path>`引用目标和frontmatter `resource` URI - 目标捆绑包没有规范网址时的回退表单`promote_concept`写入 - 到捆绑包的规范网址,一旦配置完成,报告URI的捆绑包未挂载或仍然没有; **`absolute-links-to-relative`** 重写捆绑包绝对(前导`/`)链接目标到文档相对表单 - GitHub从存储库根目录解析前导`/`链接,因此绝对表单在捆绑包作为存储库子文件夹发布时中断,而两个表单规范化为图内的相同捆绑包相对路径(损坏的链接保持同样损坏,因此每个发现都是安全可修复的)。
`--colocated-bundles <根目录>`(可重复)将共享根目录的每个直接子目录挂载为其自己的捆绑包;`--only <文件夹,文件夹,...>`限制挂载到命名的子文件夹 - 参见[同位捆绑包](#colocated-bundles-vault-as-monorepo)。`--colocated-remote-bundles <网址>`(可重复)对发布的根目录执行相同的操作 - GitHub树网址或`.tar.gz`/`.tgz`/`.zip`存档 - 将每个子文件夹挂载为只读捆绑包;参见[通过一个网址消费发布的同位根目录](#consuming-a-published-colocated-root-by-one-url)。
`--canonical-url id=url`(可重复)声明一个捆绑包的发布的规范网址用于[跨捆绑包感知](#cross-bundle-awareness);使用同位根目录的路径作为ID - 或一个裸网址,当恰好配置了一个同位根目录 - 根目录下的每个捆绑包派生`<url>/<文件夹>`,显式每个捆绑包标志优先。
`--watch`(仅限mcp)自动重新加载本地捆绑包,当磁盘上的`.md`文件更改时,延迟触发一个重新加载;`.obsidian/`和其他点目录被忽略。远程捆绑包仍然只能通过`reload_bundles`工具重新加载。在不支持递归`fs.watch`的地方,服务器以stderr日志记录一个注释并继续运行而不监视。
## 开发
```bash
npm run typecheck # 对src + tests执行tsc
npm test # 通过tsx执行node:test
npm run build # 生成dist/
```
源代码布局:`frontmatter.ts` / `parser.ts`(文档解析,链接提取和正文部分),`bundle.ts` / `store.ts`(加载和内存索引),`remote.ts`(来自公共GitHub树和tar.gz/zip存档的只读捆绑包),`pack.ts`(`pack`命令的存档写入器),`repair.ts`(`repair`命令的自动修复程序注册表),`canonical.ts`(派生的跨捆绑包边的规范网址匹配),`graph.ts` / `search.ts`(遍历,结构化搜索和词汇列表),`visualize.ts`(`graph html`自包含的力导向导出),`validate.ts`(一致性),`git.ts`(通过捆绑包的git仓库的历史记录/差异),`suggest.ts`(概念放置建议),`authoring.ts`(唯一的写入路径),`watch.ts`(`--watch`文件监视器),`server.ts`(MCP线路),`cli.ts`(入口点)。
没有`--watch`就没有文件监视器:在服务器外部编辑捆绑包文件后调用`reload_bundles`(例如在Obsidian中)。通过`write_concept`编写的概念会立即刷新索引。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器