OKF Knowledge Agent MCP Server
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-chatOpenAI:
LLM_API_BASE_URL=https://api.openai.com/v1 LLM_API_KEY=sk-... LLM_MODEL=gpt-4oAnthropic (Claude):
LLM_API_BASE_URL=https://api.anthropic.com/v1 LLM_API_KEY=sk-ant-... LLM_API_FORMAT=anthropic LLM_MODEL=claude-sonnet-5Groq:
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 UI → http://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 | 说明 |
| OKF bundle 层(零 LLM)+ 智能体(Vercel AI SDK 工具循环:search/read/list/write/patch/delete)+ 提供商注册表 |
| Express:MCP streamable-HTTP 位于 |
| Vite + React + TS + Tailwind:bundle 浏览器 + 智能体聊天( |
提供商通过 LLM_API_BASE_URL、LLM_API_KEY、LLM_API_FORMAT(openai 或 anthropic)和 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 devMCP 注册(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 永远不会产生检查记忆的本能。因此,在会话开始时,服务器会通过两条到达模型的通道注入知识库内容的紧凑概览(目录、带类型和描述的概念、近期活动):
MCP initialize 的
instructions字段(像 Claude 这样的客户端会将其放入系统提示词),以及memory_query工具描述 —— 每个工具调用客户端都会加载的通用回退。
种子会在每个新会话中重新生成。在长生命周期(stdio)会话中执行 memory_add / memory_update 后,工具描述会通过 tools/list_changed 刷新,因此会话能看到自己的写入。带外编辑(手动编辑、其他客户端)会在下一个会话中被捕获。
图谱健康与维护
记忆是一个图谱,而不是一堆笔记,而图谱会腐烂:概念会变成孤立(没有任何链接指向它们),链接会断裂。有两种机制保持其健康:
写入时链接 —— 新知识要么丰富它所属的概念(现有实体的属性被修补进去,而不是单独归档),要么在它是一个独立实体时被创建并从相关概念反向链接。矛盾会在原地被取代,绝不会与旧值并存。
memory_maintain—— 一个确定性的 lint(孤立概念 + 断裂链接,在memory_status的graph下显示)驱动内部智能体将孤立概念接入相关概念并修复悬空链接。定期运行它以对抗漂移;当图谱已经健康时,它是一个空操作。
这一设计借鉴了 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.example。BUNDLE_ROOT 是必需的;GIT_AUTOCOMMIT=true 会为每次变更提交。
This server cannot be installed
Maintenance
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
Knowledge base MCP for AI agents on iknow.dev. Search, read, and maintain via OAuth.
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP 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).1014Apache 2.0
- AlicenseNot gradedqualityBmaintenanceA 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
- AlicenseNot gradedqualityBmaintenanceProvides LLM agents with a structured, queryable, local-first knowledge base with typed documents and full-text search via MCP.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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