Skip to main content
Glama
thecodacus

OKF Knowledge Agent MCP Server

by thecodacus

understory 🌱

不断生长的记忆。

位于你的智能体之下的一层:一种自连线的纯 Markdown 记忆。你的智能体学到的每一条事实都会被整理为一个 Markdown 概念,交叉链接进一个活的知识图谱,并由智能体自身维护其健康——可搜索、可 diff、完全归你所有。在本地模型上运行效果很好。

Bundle 遵循 Open Knowledge Format (OKF) v0.1 spec —— 带 YAML frontmatter 的纯 Markdown 文件,人类可读、可在 git 中 diff、可跨工具移植。

三种接入方式,同一个智能体:

  • MCP server —— 通过 stdio 或 streamable HTTP 提供 memory_query / memory_add / memory_update / memory_status / memory_maintain 工具。每次调用都会驱动一个内部 LLM 智能体,其系统提示词中包含 OKF 规范。

  • Web UI —— 浏览 bundle(目录树、概念查看器、更新日志、一致性徽章),以 Obsidian 风格的力导向图查看记忆(拖拽/平移/缩放,按类型着色,按连接数决定大小,孤立概念以红色圆环标出,点击打开),并与同一个智能体聊天来测试它。工具调用会内联渲染,让你能观察它的工作过程。

  • 查询路径回放 —— 每次智能体运行(查询/变更/聊天)都会将其遍历过程(搜索 → 读取 → 写入)以紧凑记法记录下来,持久化在 <bundle>/.traces/ 下。图视图会列出最近的运行;选中一次运行后,会以编号的有向跳转在图上回放路径——已访问的概念带圆环,搜索命中用点线标出,其余全部淡化。

  • CLI —— pnpm agent:query "..." / pnpm agent:mutate "..." 冒烟测试入口。

设计原则:一致性由代码强制保证,而非提示词。 确定性的 bundle 层会校验 frontmatter(type 必填)、重新生成 index.md 文件、追加 log.md 条目(最新的在前,规范 §7),并将所有路径沙箱化到 bundle 根目录。LLM 决定要改什么;代码保证结果是一个符合规范的 bundle。

快速开始(Docker)

无需克隆——镜像已公开。将其保存为 docker-compose.yml

services:
  understory:
    image: ghcr.io/thecodacus/understory:latest
    ports:
      - "3800:3800"
    # Lets the container reach a llama.cpp server running on the host via
    # http://host.docker.internal:8080/v1 (see "Local llama.cpp" below).
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      # Your memory lives here as plain markdown — a named volume, or point
      # a bind mount (e.g. ./my-memory:/bundle) at any OKF bundle.
      - understory-memory:/bundle
    environment:
      BUNDLE_ROOT: /bundle
      LLM_API_BASE_URL: ${LLM_API_BASE_URL}
      LLM_API_KEY: ${LLM_API_KEY}
      LLM_API_FORMAT: openai
      LLM_MODEL: ${LLM_MODEL:-}
      # Optional fallback
      LLM_FALLBACK_API_BASE_URL: ${LLM_FALLBACK_API_BASE_URL:-}
      LLM_FALLBACK_API_KEY: ${LLM_FALLBACK_API_KEY:-}
      LLM_FALLBACK_API_FORMAT: ${LLM_FALLBACK_API_FORMAT:-openai}
      LLM_FALLBACK_MODEL: ${LLM_FALLBACK_MODEL:-}
    restart: unless-stopped

volumes:
  understory-memory:
docker compose up -d

选择提供商

通用提供商系统支持任何兼容 OpenAI 或兼容 Anthropic 的 API。 设置 LLM_API_BASE_URL + LLM_API_KEY + LLM_MODEL,并让 LLM_PROVIDER 保持未设置。

DeepSeek:

LLM_API_BASE_URL=https://api.deepseek.com/v1 LLM_API_KEY=sk-... LLM_MODEL=deepseek-chat

OpenAI:

LLM_API_BASE_URL=https://api.openai.com/v1 LLM_API_KEY=sk-... LLM_MODEL=gpt-4o

Anthropic (Claude):

LLM_API_BASE_URL=https://api.anthropic.com/v1 LLM_API_KEY=sk-ant-... LLM_API_FORMAT=anthropic LLM_MODEL=claude-sonnet-5

Groq:

LLM_API_BASE_URL=https://api.groq.com/openai/v1 LLM_API_KEY=gsk_... LLM_MODEL=llama-3.3-70b-versatile

本地 llama.cpp:

LLM_API_BASE_URL=http://host.docker.internal:8080/v1 LLM_MODEL=

当 understory 在 Docker 中运行时,localhost 指的是容器本身,而不是宿主机——因此宿主机上的 llama-server 需要通过 host.docker.internal 访问(上面的 compose 文件已经通过 extra_hosts 映射了它)。在与 llama-server 同一台机器上从源码运行时,请使用 http://localhost:8080/v1

本地 llama.cpp 搭配 DeepSeek 回退:

LLM_API_BASE_URL=http://host.docker.internal:8080/v1 LLM_MODEL= \
LLM_FALLBACK_API_BASE_URL=https://api.deepseek.com/v1 LLM_FALLBACK_API_KEY=sk-... LLM_FALLBACK_MODEL=deepseek-chat

旧的 LLM_PROVIDER 以及各提供商专属的密钥环境变量仍然有效(向后兼容),但已弃用。

然后:

  • Web UIhttp://localhost:3800 —— 浏览记忆、查看图谱、与智能体聊天

  • MCP 端点http://localhost:3800/mcp(streamable HTTP)—— 在任何 MCP 客户端中注册:

    claude mcp add --transport http ustory http://localhost:3800/mcp
  • 你的智能体现在拥有 memory_query / memory_add / memory_update / memory_status / memory_maintain,并在每次会话开始时获得记忆的种子概览。

教它一点东西(memory_add:“我们只在周五部署,绝不在周一”),然后打开图谱,看着这个概念自动接入。使用 Portainer 部署?将 docker-compose.portainer.yml 用作仓库堆栈。

Related MCP server: Kremis

技术栈

pnpm monorepo:

Package

说明

packages/core

OKF bundle 层(零 LLM)+ 智能体(Vercel AI SDK 工具循环:search/read/list/write/patch/delete)+ 提供商注册表

packages/server

Express:MCP streamable-HTTP 位于 /mcp,stdio 二进制,REST 浏览 API 位于 /api/*,流式聊天位于 /api/chat,托管 Web 构建产物

packages/web

Vite + React + TS + Tailwind:bundle 浏览器 + 智能体聊天(useChat

提供商通过 LLM_API_BASE_URLLLM_API_KEYLLM_API_FORMATopenaianthropic)和 LLM_MODEL 配置。任何兼容 OpenAI 的端点(DeepSeek、OpenAI、Groq、OpenRouter、llama.cpp 等)都可以使用 LLM_API_FORMAT=openai;兼容 Anthropic 的端点使用 LLM_API_FORMAT=anthropic。可选的回退使用对应的 LLM_FALLBACK_* 变量。

llama.cpp

# on the inference box — --jinja enables OpenAI-style tool calling
llama-server -m model.gguf --jinja --host 0.0.0.0 --port 8080

# here — no model id needed, it's discovered for llama-server-like local endpoints
LLM_API_BASE_URL=http://inference-box:8080/v1 LLM_API_FORMAT=openai LLM_MODEL= \
BUNDLE_ROOT=./sample-bundle node packages/server/dist/index.js

在 llama-swap 后面也能工作:发现过程会优先选择当前已加载的模型,这样查询就不会触发长达数分钟的模型切换。使用 LLM_MODEL= 固定特定模型。

从源码运行

pnpm install
pnpm build
cp .env.example .env   # add your API key

BUNDLE_ROOT=./sample-bundle \
LLM_API_BASE_URL=https://api.deepseek.com/v1 \
LLM_API_KEY=sk-... \
LLM_API_FORMAT=openai \
LLM_MODEL=deepseek-chat \
node packages/server/dist/index.js
# → http://localhost:3800  (web UI + /api + /mcp)

或者自己构建容器:docker compose up --build(仓库中的 docker-compose.yml 会从源码构建并挂载 ./sample-bundle)。

开发模式(服务器在 :3800,Vite HMR 在 :5180 并带代理):

BUNDLE_ROOT=./sample-bundle pnpm --filter @understory/server dev
pnpm --filter @understory/web dev

MCP 注册(Claude Code / Desktop)

claude mcp add ustory \
  -e BUNDLE_ROOT=/path/to/your/bundle \
  -e LLM_API_BASE_URL=https://api.deepseek.com/v1 \
  -e LLM_API_KEY=sk-... \
  -e LLM_API_FORMAT=openai \
  -e LLM_MODEL=deepseek-chat \
  -- node /path/to/understory/packages/server/dist/mcp/stdio.js

或者将 HTTP MCP 客户端指向 http://host:3800/mcp

认证

默认情况下服务器是开放的——在 localhost 或可信 LAN 上没问题。在将其暴露到任何其他地方之前,请设置 AUTH_TOKEN

AUTH_TOKEN=$(openssl rand -hex 24)

设置后,/mcp/api 需要 Authorization: Bearer <token>(Web UI 仍然可访问,并会提示输入 token)。使用请求头注册已认证的 MCP 客户端:

claude mcp add --transport http ustory http://host:3800/mcp \
  --header "Authorization: Bearer <token>"

stdio 传输不需要 token——它是由客户端生成的本地进程。

种子记忆

一个只看到四个光秃秃的工具名称的客户端 LLM 永远不会产生检查记忆的本能。因此,在会话开始时,服务器会通过两条到达模型的通道注入知识库内容的紧凑概览(目录、带类型和描述的概念、近期活动):

  1. MCP initialize 的 instructions 字段(像 Claude 这样的客户端会将其放入系统提示词),以及

  2. memory_query 工具描述 —— 每个工具调用客户端都会加载的通用回退。

种子会在每个新会话中重新生成。在长生命周期(stdio)会话中执行 memory_add / memory_update 后,工具描述会通过 tools/list_changed 刷新,因此会话能看到自己的写入。带外编辑(手动编辑、其他客户端)会在下一个会话中被捕获。

图谱健康与维护

记忆是一个图谱,而不是一堆笔记,而图谱会腐烂:概念会变成孤立(没有任何链接指向它们),链接会断裂。有两种机制保持其健康:

  • 写入时链接 —— 新知识要么丰富它所属的概念(现有实体的属性被修补进去,而不是单独归档),要么在它是一个独立实体时被创建从相关概念反向链接。矛盾会在原地被取代,绝不会与旧值并存。

  • memory_maintain —— 一个确定性的 lint(孤立概念 + 断裂链接,在 memory_statusgraph 下显示)驱动内部智能体将孤立概念接入相关概念并修复悬空链接。定期运行它以对抗漂移;当图谱已经健康时,它是一个空操作。

这一设计借鉴了 Karpathy 的 LLM Wiki 中的模式(index.md + log.md、创建与丰富之争、针对孤立的 lint)。在规模需要之前,暂缓实现该模式中的:显式页面类型 schema,以及混合 FTS5+embedding 搜索(search.ts 中的朴素扫描在概念数量为数千时仍然够用)。

测试

pnpm test                                  # core: 18 tests (spec §5/§6/§7/§9, sandbox, search, concurrency)
pnpm --filter @understory/server exec tsx scripts/mcp-smoke.mts   # MCP stdio round-trip (needs SMOKE_BUNDLE + an API key)

环境变量

参见 .env.exampleBUNDLE_ROOT 是必需的;GIT_AUTOCOMMIT=true 会为每次变更提交。

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    A Knowledge Graph MCP server optimized for LLM context efficiency through compact JSON and SQLite persistence. It enables full graph management including node/edge CRUD operations, full-text search, and subgraph traversal.
  • A
    license
    A
    quality
    A
    maintenance
    MCP server exposing a deterministic, local knowledge graph over stdio. Zero LLM calls in the bridge; answers are classified as Fact, Inference, or Unknown and persisted in redb (ACID, BLAKE3-hashed).
    10
    14
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    A local OKF-compatible knowledge engine for AI agents. Enables capturing agent conversations, hybrid semantic+keyword search, MCP serving to agents, interactive graph visualization, and OKF bundle export.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides LLM agents with a structured, queryable, local-first knowledge base with typed documents and full-text search via MCP.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/thecodacus/understory'

If you have feedback or need assistance with the MCP directory API, please join our Discord server