OKF Wiki MCP Server
Enables browsing, searching, and expanding a knowledge base of markdown nodes with YAML frontmatter from within a chat, supporting document ingest and generative HTML widgets.
README
OKF Wiki — MCP App
A living knowledge base served as an MCP App: the wiki renders as an interactive UI inside any MCP Apps host, the model reads and expands it through tools, and every interaction — a slider explored, an insight saved, a rule distilled — leaves the wiki smarter than it found it.
The content is an OKF wiki (Organizational Knowledge Framework): a directory of markdown nodes with YAML frontmatter that binds playbook text to UI behavior. The wiki directory is a runtime input — the server re-reads it on every tool call, so ingested or hand-edited nodes are live immediately, with no rebuild or restart.
Origin: this combines two earlier experiments — the Level 2/3 generative-UI architecture from gen-ui-wiki-playground and the MCP Apps plumbing (single-file UI, host shim, runtime design tokens) from mcp-apps-demo-engine.
The three levels of generative UI, MCP Apps edition
| Level | What it means | How this app does it |
|---|---|---|
| 1 — Static | Readable playbook text | Markdown rendered client-side (marked), widget source blocks stripped |
| 2 — Adaptive parameters | UI controls generated from data | Sliders from frontmatter variables; outcomes computed by declarative frontmatter rules the app merely interprets |
| 3 — Generative components | Bespoke per-node UI created at runtime | Ingest stores a self-contained ```html widget → served inside the tool result → rendered in a sandboxed sub-iframe with the app's theme variables injected |
The Level 3 translation is the interesting constraint: an MCP App is one sandboxed single-file resource — no dev server, no JSX compilation, no network. So a widget's source form is self-contained HTML (markup + inline style + inline script, no imports, no external requests).
The compounded-learning loop
explore sliders → save finding → distill into rule → sliders teach the next reader
↑ │
└──────────── gaps panel recommends what to explore ─────┘
- Findings write back. An insight discovered at the sliders is one click from permanent: it lands in the node's frontmatter with date + settings provenance and renders for every future reader.
- Findings become rules. Level 2 heuristics are data, not code: nodes carry declarative
rules(whenslider-settings match → outcomes + note; most specific rule wins). A "Distill findings into rules" button asks the model to promote insights viarecord_rule— validated against the node's actual variable space so unfireable rules are rejected. - The wiki detects its own gaps — ranks and explains them. Dangling relations, unported widgets, unexplored variable sets, and unlinked nodes are scored by leverage (a gap on a node referenced by 2 others outranks a leaf) and rendered as expandable cards: what the topic covers, why it matters, the specifics, and what closing it will do. Every card has a ready-to-send prompt behind an "Ask assistant" button.
- Growth is visible.
wiki/log.mdrecords every ingest, update, finding, rule, and link, rendered as a "How this wiki grew" timeline. - The chat knows what you're looking at. The app pushes compact state (current node, slider settings, outcomes, findings/rules counts) via
ui/update-model-contexton navigation and slider moves.
Tools
| Tool | Callable by | Purpose |
|---|---|---|
open_wiki |
model (renders UI) | Overview of all nodes + gaps + timeline; optionally opens a node by id |
get_node |
app only | Sidebar navigation via app.callServerTool |
ingest_document |
model | Add/update a playbook: classifies type, extracts variables/metrics, installs an ```html widget. Re-ingest preserves findings, rules, and relations |
record_finding |
model + app | Persist an insight with the slider settings it was observed under |
record_rule |
model + app | Add a declarative Level 2 heuristic (when → outcomes + note) |
link_nodes |
model + app | Add a typed relation between nodes |
All tool results include a plain-text/markdown fallback, so UI-less hosts still get useful answers.
Quick start (local, no host required)
npm install && npm run build
npm run serve:http # Terminal 1: MCP server on :3001
npm run shim # Terminal 2: reference host on :4180
# open http://localhost:4180/host-shim.html
The ~100-line shim does what a real host does — fetches the UI via resources/read, completes the MCP Apps handshake, proxies tool calls — and logs every message the app sends upward, including the context-sync and hand-back traffic.
For development with UI rebuild-on-change: npm run dev.
Connect to a real MCP Apps host
Streamable HTTP (server on http://localhost:3001/mcp):
npm run serve:http
# e.g. Claude Code:
claude mcp add --transport http okf-wiki http://localhost:3001/mcp
stdio:
{
"mcpServers": {
"okf-wiki": {
"command": "node",
"args": ["/path/to/okf-wiki-mcp-app/dist/main.js", "--stdio"]
}
}
}
Then ask the host's assistant to "open the wiki" — the open_wiki tool renders the app.
Bring your own wiki
The bundled wiki/ is demo content. To serve a different (e.g. live, generated) wiki, point WIKI_ROOT at any directory with this layout:
my-wiki-root/
├── wiki/ # the OKF nodes (*.md) + log.md ← required
├── raw/ # source documents (ingest writes here)
└── widgets/ # Level 3 widgets, <widgetId>.html
WIKI_ROOT=/path/to/my-wiki-root npm run serve:http
Everything the app writes (findings, rules, relations, ingests, log) goes to that directory, so a git-tracked wiki gets reviewable diffs of what the assistant and users learned. PORT overrides the HTTP port (default 3001).
OKF node format
One markdown file per node in wiki/, YAML frontmatter + playbook body:
---
type: pattern-analysis # concept | pattern-analysis | sector-deepdive
subtype: tactical # pattern-analysis only: strategic | tactical
id: my-node-id # unique slug; must match how others relate to it
title: "Human-Readable Title"
created: "2026-07-10"
source_files:
- "raw/my-node-id.md"
variables: # optional → Level 2 sliders
task_complexity: [Low, Medium, High]
metrics: # optional → baseline outcome cards
efficiency_gain: "Shown when no rule matches"
rules: # optional → declarative Level 2 heuristics
- when: { task_complexity: High }
outcomes:
efficiency_gain: { value: "12% (escalation overhead)", status: warning }
note: "High complexity needs human escalation."
- when: {} # empty when = baseline rule
outcomes:
efficiency_gain: { value: "34%", status: success }
findings: # accumulated insights (written by the app)
- date: "2026-07-10"
text: "High complexity erodes the efficiency gain."
settings: { task_complexity: High }
relations: # typed edges to other node ids
- type: depends-on
id: some-other-node-id
widgetId: Widget_my_node_id # optional → widgets/Widget_my_node_id.html
---
# Human-Readable Title
Playbook markdown here…
Notes:
- Rules match when all
whenentries equal the current slider values; the most specific matching rule (most entries) wins.statusissuccess | warning | danger. - Widgets (
widgets/<widgetId>.html) must be self-contained: markup + inline<style>+ inline<script>, no imports, no external requests. They render in a sandboxed iframe that receives the app's CSS custom properties (--color-accent,--color-background-primary, …), so use those with fallbacks for automatic theming. wiki/log.mdlines have the form## [YYYY-MM-DD] action | ID: node-id | Title: …— the app appendsingest,update,finding,rule, andlinkentries and renders them as the growth timeline.wiki/index.mdandwiki/log.mdare not treated as nodes.
Ingesting via the model
Ask the connected assistant to call ingest_document with a markdown document. It will classify the type, extract Level 2 variables from - **Name**: A / B / C bullet lines, and install a Level 3 widget from a fenced ```html block. Legacy ```jsx blocks are skipped with a note — this runtime cannot compile JSX.
Styling
DESIGN.md (design.md spec) is a runtime input like the wiki: its tokens compile to a CSS-variable override block injected into the served UI resource on every resources/read. Swap the file (samples in designs/), re-render, new brand — no rebuild. Host-provided style variables still win.
Repo layout
server.ts MCP tools + UI resource registration (DESIGN.md injection)
main.ts transport bootstrap (Streamable HTTP / stdio)
wiki.ts wiki store: parsing, gaps, timeline, ingest, findings/rules/links
design.ts DESIGN.md → CSS variables compiler
mcp-app.html app shell
src/mcp-app.ts the single-file wiki browser (Vite + vite-plugin-singlefile)
src/*.css app styles on host/design-token CSS variables
tools/host-shim.html minimal reference host for local testing
wiki/ raw/ widgets/ demo OKF content (replaceable via WIKI_ROOT)
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。