内容
# okf-mcp
`okf-mcp` 是一个与项目无关的开放知识格式命令行工具、图形索引、生成器运行器、MCP 标准输入/输出服务器和可选的 HTTP 编写 API。
它使用带有 YAML 前置信息的 Markdown 文件目录, 将非保留的 Markdown 文件视为 OKF 概念,并通过命令行命令以及用于结构化搜索、验证、图形导航和基于提案的编写的 MCP 资源和工具公开这些概念。
核心故意没有运行时依赖项,没有数据库,也没有嵌入。本地捆绑模式不会进行网络调用。 可选的远程捆绑可以在配置后从 GitHub 拉取公共 Markdown 概念。生成器插件和接受的编写提案是写入路径,并且仅在配置的项目目录下写入。
## 安装和运行
从此存储库:
```bash
git clone https://github.com/mfdaves/okf-mcp.git
cd okf-mcp
npm test
node bin/okf-mcp.js --bundle ./okf/bundles/app --inspect
node bin/okf-mcp.js --bundle app=./okf/bundles/app
```
`--bundle` 接受路径或 `id=path`。允许多个 `--bundle` 标志。
`--remote-bundle` 接受 `id=https://github.com/<owner>/<repo>/tree/<ref>/<path>`。它从 GitHub 树中拉取公共 Markdown 文件,并将它们索引为只读捆绑。
`--inspect` 打印一个紧凑的图形摘要然后退出。没有 `--inspect` 和没有显式命令,进程启动一个 stdio MCP 服务器。
该软件包还公开了一个 `okf` 二进制文件在安装时。
## 项目配置
对于与项目无关的使用,在存储库根目录下创建 `okf.project.yaml`:
```yaml
project: Example
bundles:
- id: app
root: okf/bundles/app
include: ["**/*.md"]
exclude: ["archive/**"]
- id: data
root: okf/bundles/data
relationTypes:
- deployed_by
remoteBundles:
- id: shared
url: https://github.com/example/okf-atlas/tree/main/bundles/shared
include: ["public/**"]
exclude: ["drafts/**"]
plugins:
- name: docs
type: filesystem
root: docs
output: okf/bundles/app/generated/docs
bundle: app
```
运行项目命令:
```bash
node bin/okf-mcp.js --project okf.project.yaml validate
node bin/okf-mcp.js --project okf.project.yaml search "orders"
node bin/okf-mcp.js --project okf.project.yaml graph mermaid
node bin/okf-mcp.js --project okf.project.yaml generate
node bin/okf-mcp.js --project okf.project.yaml mcp
OKF_WRITE_TOKEN=change-me node bin/okf-mcp.js --project okf.project.yaml serve
node bin/okf-mcp.js --remote-bundle shared=https://github.com/example/okf-atlas/tree/main/bundles/shared --inspect
```
命令:
- `mcp`
- `validate`
- `graph [json|dot|mermaid]`
- `search <query>`
- `concept <uri>`
- `neighbors <uri>`
- `paths <from> <to>`
- `generate`
- `serve`
`serve` 选项:
- `--host <host>`:绑定主机,默认为 `127.0.0.1`
- `--port <port>`:绑定端口,默认为 `8765`
- `--write-token <token>`:写入端点的 bearer token;默认为 `OKF_WRITE_TOKEN`
- `--proposal-root <path>`:提案 JSON 目录;默认为项目根目录下的 `.okf-proposals`
## MCP 客户端配置
MCP 客户端配置示例:
```json
{
"mcpServers": {
"okf": {
"command": "node",
"args": [
"/absolute/path/to/okf-mcp/bin/okf-mcp.js",
"--bundle",
"app=/absolute/path/to/repo/okf/bundles/app"
]
}
}
}
```
具有创作工具的项目配置模式:
```json
{
"mcpServers": {
"okf": {
"command": "node",
"args": [
"/absolute/path/to/okf-mcp/bin/okf-mcp.js",
"--project",
"/absolute/path/to/repo/okf.project.yaml",
"mcp"
]
}
}
}
```
## 概念格式
服务器为每个 Markdown 文档公开一个资源:
```text
okf://<bundle-id>/<relative-path>
```
资源使用 `text/markdown`。保留的 `index.md` 和 `log.md` 文件是资源,但它们不是概念文档。
概念文件可以使用派生自路径的 URI 或设置稳定的 `id`:
```markdown
---
id: okf://app/routes/order-status
type: API Route
title: Order Status Route
description: Serves order status state.
aliases: [order-status]
tags: [api, orders]
relations:
- type: consumes
target: okf://data/tables/order_status
- type: configured_by
target: repo://src/routes/order-status.js
---
# Order Status Route
```
`okf://` 关系目标必须解析为已知的概念。非 OKF 目标(例如 `repo://`)被视为外部不透明引用。
## 工具
- `list_bundles`
- `list_concepts`
- `get_concept`
- `search_concepts`
- `list_types`
- `list_tags`
- `list_relation_types`
- `load_remote_bundle`
- `list_remote_bundles`
- `okf_validate_concept`
- `okf_suggest_concept_path`
- `okf_propose_concept`
- `okf_list_proposals`
- `okf_get_proposal`
- `okf_accept_proposal`
- `okf_reject_proposal`
- `get_graph`
- `get_neighbors`
- `get_subgraph`
- `find_paths`
- `graph_summary`
- `validate_bundle`
- `validate_project`
- `export_graph`
大多数 MCP 工具在当前索引上是只读的。`load_remote_bundle` 仅通过拉取公共 GitHub 树来改变服务器的内存索引;它不写入文件。
`okf_*` 编写工具是基于提案的。当服务器使用 `--project` 启动时启用它们,因为项目配置标识了可写的本地捆绑。提出概念只写入提案记录。接受提案将 Markdown 概念写入配置的捆绑根目录,并刷新内存索引。
## 编写概念
通过 MCP 工具和 HTTP API 可以进行概念编写。客户端永远不需要直接访问本地文件。
MCP 提案流程:
```json
{
"name": "okf_propose_concept",
"arguments": {
"bundle": "app",
"path": "tools/create-order.md",
"frontmatter": {
"type": "MCP Tool",
"title": "Create Order",
"relations": [
{
"type": "related_to",
"target": "okf://app/workflows/order-creation"
}
]
},
"body": "# Create Order\n\nCreates an order through the application MCP tool.",
"message": "Document create_order for agents."
}
}
```
然后使用返回的 `proposal.id` 调用 `okf_accept_proposal`。
安全规则:
- 概念路径必须是在可写捆绑内安全相对 `.md` 路径
- 缺失的子目录仅在接受提案时创建
- `index.md` 和 `log.md` 不能作为概念编写
- 拒绝重复路径和重复 `okf://` ID
- 无效 ID、无效关系类型和损坏的内部 OKF 关系会失败验证
- 允许外部关系目标(例如 `repo://...`)
## HTTP API
启动 HTTP 服务器:
```bash
OKF_WRITE_TOKEN=change-me node bin/okf-mcp.js --project okf.project.yaml serve --host 127.0.0.1 --port 8765
```
读取/验证端点:
- `GET /health`
- `GET /v1/bundles`
- `POST /v1/concepts/validate`
- `POST /v1/concepts/suggest-path`
- `GET /v1/proposals`
- `GET /v1/proposals/:id`
修改端点需要 `Authorization: Bearer <OKF_WRITE_TOKEN>`:
- `POST /v1/proposals`
- `POST /v1/proposals/:id/accept`
- `POST /v1/proposals/:id/reject`
默认文件支持的提案存储在项目根目录下的 `.okf-proposals` 下。接受的提案将 Markdown 概念写入配置的捆绑根目录。
`POST /v1/concepts/validate` 和 `POST /v1/concepts/suggest-path` 不会持久化任何内容。`POST /v1/proposals` 仅持久化提案记录。只有 `POST /v1/proposals/:id/accept` 写入概念 Markdown 文件。
## 远程捆绑
远程捆绑允许一个项目使用另一个存储库发布的概念,而无需在本地克隆或采购它们。
支持的源:
- 公共 GitHub 存储库树 URL:`https://github.com/<owner>/<repo>/tree/<ref>/<path>`
远程加载:
- 仅索引 `.md` 文件
- 忽略非 Markdown 文件
- 将每个远程捆绑保留在其配置的捆绑 ID 下
- 支持 `include` 和 `exclude` 过滤器
- 解析远程捆绑路径内的 Markdown 链接
- 强制执行文件数量和字节限制
- 不从远程存储库执行代码
CLI 示例:
```bash
node bin/okf-mcp.js --remote-bundle shared=https://github.com/example/okf-atlas/tree/main/bundles/shared --inspect
node bin/okf-mcp.js --project okf.project.yaml --remote-bundle vendor=https://github.com/example/vendor-okf/tree/main/bundles/catalog validate
```
MCP 运行时加载:
```json
{
"name": "load_remote_bundle",
"arguments": {
"id": "shared",
"url": "https://github.com/example/okf-atlas/tree/main/bundles/shared",
"include": ["public/**"]
}
}
```
使用 `list_remote_bundles` 检查已加载的内容。
## 结构化搜索
`search_concepts` 接受:
- `query`
- `bundle`
- `types`
- `tagsAny`
- `tagsAll`
- `pathPrefix`
- `frontmatter`
- `linkedTo`
- `linkedFrom`
- `relationType`
- `orphanOnly`
- `limit`
- `offset`
标签和类型不区分大小写。任意的前置信息筛选器支持精确的标量匹配和数组包含匹配。
示例:
```json
{
"query": "catalog",
"types": ["API Route"],
"tagsAll": ["api", "orders"],
"limit": 10
}
```
## 图形行为
Markdown 链接在 OKF 文档之间成为 `markdown_link` 边。前置信息 `relations` 成为类型化的 `relation` 边。
图形工具返回紧凑的 JSON:
```json
{
"nodes": [
{
"id": "okf://app/routes/order-status",
"bundle": "app",
"path": "routes/order-status.md",
"type": "API Route",
"title": "Order Status Route",
"tags": ["api", "orders"],
"description": "Serves order status state."
}
],
"edges": [],
"warnings": []
}
```
首先使用 `graph_summary` 获取紧凑的概览,使用 `get_neighbors` 进行本地遍历,使用 `get_subgraph` 进行种子概念的有界扩展。`export_graph` 支持 `json`、`dot` 和 `mermaid`。当不透明的外部目标应作为图形节点出现时,将 `includeExternal: true` 传递给图形工具。
默认关系类型:
- `depends_on`
- `produces`
- `consumes`
- `persists_to`
- `materializes_to`
- `configured_by`
- `checked_by`
- `owned_by`
- `supersedes`
- `related_to`
在 `okf.project.yaml` 中使用 `relationTypes` 添加项目特定的关系类型。
`bundles` 和 `plugins` 中的项目路径必须是相对于包含 `okf.project.yaml` 的目录的相对路径。拒绝绝对路径和 `../` 转义。
捆绑的 `include` 和 `exclude` 过滤器使用简单的路径模式:
- 精确的文件路径,例如 `services/order-status.md`
- 目录前缀,例如 `archive/`
- 一个路径段的 `*`
- 任意嵌套路径的 `**`
## 验证
`validate_bundle` 和 `validate_project` 报告:
- 无效或不支持的 YAML 前置信息
- 概念文件上缺少前置信息
- 概念文件上缺少非空 `type`
- 重复的 OKF URI
- 损坏的内部 Markdown 链接
- 无效的关系类型
- 丢失的关系目标
- 损坏的 `okf://` 关系目标
- 重复的捆绑 ID
- 无效或转义的项目路径
- 解析到配置的捆绑根目录之外的链接
- 丢失的捆绑根目录
服务器继续为部分捆绑提供有效的概念。
## 生成器插件
在 `okf.project.yaml` 中配置生成器插件,并使用 `generate` 运行。
内置插件:
- `filesystem`:为每个匹配的源文件创建一个概念。默认为 Markdown 文件。
- `json-spec`:为每个 JSON 文件创建一个概念,并在存在目标表时发出 `persists_to` 关系。
生成的输出是常规的 Markdown/YAML OKF,并由与手工创作概念相同的索引器验证。
## 限制
- YAML 解析器故意支持 OKF 概念元数据使用的简单前置信息形状:标量键、内联数组、块数组和对象数组。
- MCP 服务器直接实现资源和工具所需的 stdio JSON-RPC 方法,而不是使用 SDK,因此高级 SDK 便利功能不在考虑范围内。
- 没有文件监视器。在外部文件更改后重新启动服务器。通过 MCP 编写接受的概念会立即刷新 MCP 服务器索引。
- HTTP API 是一个轻量级的内置服务器,而不是一个完整的托管多租户服务。