MCP知识库服务器
](https://www.npmjs.com/package/mcp-kb-server)  ](https://www.npmjs.com/package/mcp-kb-server)
模型上下文协议(MCP)服务器,提供持久内存、知识库和项目摘要功能,具有自动项目检测和交互式仪表板。
运作原理
┌──────────────────────────────────────────────────────────────┐
│ AI Assistant (Kiro, Claude, etc.) │
│ │
│ "Remember we use JWT" "What do I know about auth?" │
│ "Init KB from my docs" "What changed since last summary?" │
└──────────────┬───────────────────────────┬───────────────────┘
│ MCP Protocol (stdio) │
▼ ▼
┌──────────────────────────────────────────────────────────────┐
│ mcp-kb-server │
│ │
│ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │
│ │ memory │ │ kb │ │ summary │ │dashboard │ │
│ │ .store │ │ .add │ │.project │ │.projects │ │
│ │ .search │ │ .search │ │ .delta │ └──────────┘ │
│ │ .list │ │ .init ★ │ └─────────┘ │
│ │ .delete │ └──────────┘ │
│ │ .update │ Auto-detect project_id from project_root │
│ └─────────┘ package.json → git remote → directory name │
│ │
│ ┌────────────────────┐ ┌─────────────────────┐ │
│ │ memory.sqlite │ │ kb.sqlite │ │
│ │ + memory_fts(FTS5)│ │ + kb_fts (FTS5) │ │
│ │ + wiki_links │ │ + kb_meta (scoping) │ │
│ │ + expires/TTL │ │ + sources + fts │ │
│ └────────────────────┘ └─────────────────────┘ │
└──────────────────────────────────────────────────────────────┘______________________________________________________________________
工作流图
1.请求流
每次工具调用都遵循从AI到数据库再到数据库的相同路径。
AI Assistant
│
│ JSON-RPC 2.0 over stdio
▼
server.js
│
├─ Joi validation ──── invalid ──► error -32602
│
├─ project_id resolution
│ project_root provided?
│ ├─ yes → detectProjectId()
│ │ ├─ package.json name
│ │ ├─ git remote URL
│ │ └─ directory basename
│ └─ no → use explicit project_id
│
├─ LRU query cache (read-only tools)
│ hit ──────────────────────► return cached result
│ miss ─┐
│ ▼
├─ tool handler (memory / kb / sources / wiki / summary)
│ │
│ ▼
│ better-sqlite3 (synchronous)
│ memory.sqlite ── kb.sqlite
│ │
│ ▼
│ cache invalidated (on mutations)
│
└─ JSON-RPC result ──────────────► AI Assistant______________________________________________________________________
2.项目初始化(kb.init)
在开始项目工作时运行一次,从现有文档中填充知识库。
Developer / AI
│
│ kb.init({ project_root: "/path/to/project" })
▼
Resolve project_id
│ package.json → git remote → directory name
▼
Expand glob patterns
│ default: ["**/*.md", "**/*.txt"]
│ skip: node_modules / .git / dist / build
▼
For each file
├─ already in KB? (matched by source path)
│ └─ yes + overwrite=false → skip
│
├─ read file content
│ └─ binary or empty → skip
│
└─ extract title
├─ first "# Heading" in content
└─ fallback: filename without extension
▼
Bulk INSERT (single SQLite transaction)
│ kb_fts ← title, content, source
│ kb_meta ← rowid, project_id
▼
Return { scanned, added, skipped, added_titles }______________________________________________________________________
3.内存生命周期
┌─────────────────────────────┐
│ AI Assistant │
└──┬──────────┬───────────┬───┘
│ │ │
store/update search delete
│ │ │
▼ ▼ ▼
┌────────────────────────────────────┐
│ memory.sqlite │
│ │
│ memory table │
│ ┌──────────────────────────────┐ │
│ │ id · project_id · scope │ │
│ │ content · tags · created_at │ │
│ │ updated_at · expires_at │ │
│ └──────────────────────────────┘ │
│ │ FTS5 sync │
│ memory_fts (BM25 ranked search) │
│ │
│ wiki_links (cross-references) │
└────────────────────────────────────┘
│
TTL purge
(auto on access, max 1×/60s/project)
│
▼
expired entries removed______________________________________________________________________
4.知识库流程
┌──────────────────────────────────┐
│ Input sources │
│ │
│ kb.init kb.add │
│ (bulk scan) (single doc) │
│ Dashboard Dashboard │
│ Import New Document │
└──────────┬───────────┬────────────┘
│ │
▼ ▼
┌──────────────────────────────────┐
│ kb.sqlite │
│ │
│ kb_fts ── title, content, source │
│ kb_meta ─ rowid → project_id │
└──────────────────────────────────┘
│
┌─────────────┼──────────────┐
│ │ │
kb.search dashboard wiki.link
(FTS5/BM25 (split-panel (cross-ref
+ Qdrant list+detail) to memory
optional) or source)
│
▼
AI Assistant______________________________________________________________________
5.总结和三角洲流量
summary.project summary.delta
────────────── ─────────────
project_root project_root
│ │
├─ auto-discover files ├─ run summary.project
│ README, ARCHITECTURE, │ (current snapshot)
│ .kiro/resources/*.md, etc. │
│ ├─ search memory for
├─ memory.search (recent) │ last "project-summary"
│ │ scope entry
├─ kb.search (relevant docs) │
│ └─ diff current vs stored
▼ │
combined snapshot text ▼
│ changed files / new memories /
│ (AI stores result via updated docs highlighted
│ memory.store scope=
│ "project-summary")
▼
searchable baseline for next delta______________________________________________________________________
6.仪表板架构
Browser HTTP Server (Node.js) SQLite
│ │ │
│ GET / │ │
│ ─────────────────────────► │ │
│ ◄── HTML (self-contained) ──│ │
│ │ │
│ GET /api/projects │ SELECT project_id, │
│ ─────────────────────────► │ COUNT(*) FROM memory ──► │
│ ◄── [{ project_id, total }] │ ◄─────────────────────── │
│ │ │
│ GET /api/kb │ SELECT kb_fts JOIN │
│ ?project_id=x&limit=30 │ kb_meta WHERE │
│ ─────────────────────────► │ project_id=x ──► │
│ ◄── { items, total } │ ◄────────────────────── │
│ │ │
│ (click item) │ │
│ GET /api/kb/:id ──► │ SELECT * FROM kb_fts ──► │
│ ◄── { title, content, … } │ ◄─────────────────────── │
│ │ │
│ GET /api/export/kb │ SELECT all docs for │
│ ?project_id=x ──► │ project → render .md ──► │
│ ◄── kb-x-2026-04-12.md │ ◄─────────────────────── │
│ │ │
│ POST /api/kb/import │ bulk INSERT kb_fts │
│ { project_id, docs[] } ──► │ + kb_meta (transaction)──►│
│ ◄── { ok, count } │ ◄─────────────────────── │______________________________________________________________________
7.Wiki链接和Lint
Entries (any type)
memory ──┐
kb ──┼──► wiki.link ──► wiki_links table
source ──┘ (source_id, source_type,
target_id, target_type,
relation, project_id)
│
┌───────────────┼───────────────┐
│ │ │
wiki.links wiki.lint wiki.export
(lookup by (health check) (dump to .md)
entry_id) │
│ ┌────┴────────────────┐
│ │ orphan_memory │
│ │ (no links at all) │
│ │ │
│ │ broken_links │
│ │ (source or target │
│ │ no longer exists) │
│ │ │
│ │ stale_sources │
│ │ (90+ days, no links) │
│ └──────────────────────┘
▼
{ outbound[], inbound[] }______________________________________________________________________
特性
🧠 内存管理
- 长期记忆:存储、搜索、列出、更新和删除特定于项目的内存条目
- 全文检索:FTS5通过BM25排名
use_fts标志,加上子字符串回退 - 标签筛选:按标签名称过滤记忆,结合文本查询
- 分页:
memory.list随着total_count,offset,has_more - TTL/到期:可选
expires_at在条目上,访问时自动清除 - 项目隔离:项目之间完全数据隔离
📚 知识库
- 文档存储:使用FTS5全文搜索添加和搜索文档
- 项目范围界定:
project_id在所有知识库操作上隔离每个项目的文档 - 批量初始化:
kb.init扫描项目目录并导入所有.md/.txt一次通话中的文件 - 向量搜索:可选的Qdrant集成用于语义搜索
- 来源追踪:跟踪文档来源和元数据
📂 源层
- 生吃:摄入
.md,.txt,.csv,.pdf文件通过source.ingest - FTS搜索:在摄入的源内容中进行全文搜索
- 项目隔离:每个项目范围内的来源
🔗 Wiki链接和Lint
- 交叉引用:
wiki.link在内存/KB/源条目之间创建类型化链接 - 链接查找:
wiki.links返回任何条目的入站和出站链接 - 健康检查:
wiki.lint检测孤立条目、断开的链接和过时的源 - 出口:
wiki.export将所有数据作为markdown文件转储到一个目录
📊 项目总结
- 快照生成:
summary.project将文件+内存+KB读入单个快照 - 三角洲概述:
summary.delta将当前状态与上次摘要进行比较 - 自动发现:查找指令文件(README、ARCHITECTURE、,
.kiro/resources/*.md等等)
🎨 交互式仪表板
- 拆分面板UI:KB、内存和源选项卡在左侧显示分页列表,在右侧显示详细视图——不再有无限的滚动转储
- 加载更多:所有列表以30个为一批分页
- 项目管理:直接从UI创建和删除项目
- 知识库管理:添加、编辑、删除、导入(JSON/
.md),并将KB文档导出为Markdown - 内存管理:查看和删除单个内存条目;全部导出为Markdown
- 源查看器:内联浏览和预览摄入的源文件
- 暗/亮模式、响应式布局、markdown渲染
🔒 安全
- 路径验证、不匹配检测、XSS保护、参数化SQL
安装
npm install -g mcp-kb-server或者直接与npx一起使用:
npx mcp-kb-server用法
配置MCP客户端
{
"mcpServers": {
"kb-server": {
"command": "npx",
"args": ["mcp-kb-server"],
"env": {}
}
}
}使用自定义数据目录:
{
"mcpServers": {
"kb-server": {
"command": "npx",
"args": ["mcp-kb-server"],
"env": {
"DATA_DIR": "/path/to/your/data",
"DASHBOARD_PORT": "4242"
}
}
}
}______________________________________________________________________
可用工具
内存工具
所有记忆工具都需要 project_root (推荐)或 project_id.
memory.store
{
"project_root": "/path/to/project",
"content": "We use JWT for auth — stateless, works with mobile",
"scope": "decisions",
"tags": ["auth", "jwt", "architecture"],
"expires_at": "2027-01-01T00:00:00Z"
}memory.search
{
"project_root": "/path/to/project",
"query": "authentication",
"tag": "decision",
"use_fts": true,
"limit": 10
}memory.list
{
"project_root": "/path/to/project",
"limit": 50,
"offset": 0,
"scope": "decisions"
}退货 { total_count, offset, limit, has_more, entries }.
memory.update
{
"project_root": "/path/to/project",
"id": "uuid",
"content": "Updated content",
"tags": ["updated", "auth"],
"expires_at": ""
}记住.删除
{
"project_root": "/path/to/project",
"id": "uuid"
}______________________________________________________________________
知识库工具
kb.add
{
"title": "API Reference",
"content": "## Endpoints\n...",
"source": "docs/api.md",
"project_id": "my-project"
}kb.search
{
"query": "authentication",
"project_id": "my-project",
"limit": 5
}kb.init ★ — 扫描项目并将所有文档批量导入知识库
{
"project_root": "/path/to/project",
"patterns": ["**/*.md", "docs/**/*.txt"],
"overwrite": false
}退货:
{
"project_id": "my-project",
"scanned": 42,
"added": 38,
"skipped": 4,
"added_titles": ["Getting Started", "API Reference", "..."],
"skipped_paths": ["CHANGELOG.md (empty or binary)", "..."]
}- 自动检测
project_id从project_root - 默认模式:
["**/*.md", "**/*.txt"] - 跳跃
node_modules,.git,dist,build自动地 - 先使用
# Heading作为标题,回退到文件名 - 跳过已导入的文件,除非
overwrite: true - 在单个SQLite事务中批量插入
______________________________________________________________________
源代码工具
信息来源 --摄取原始文件(md、txt、csv、pdf)
{
"project_root": "/path/to/project",
"filename": "spec.md",
"content": "...",
"file_type": "md"
}source.list / 来源搜索
{
"project_root": "/path/to/project",
"query": "authentication",
"limit": 20,
"offset": 0
}______________________________________________________________________
Wiki工具
wiki.link --在两个条目之间创建键入链接
{
"project_root": "/path/to/project",
"source_id": "mem-uuid",
"source_type": "memory",
"target_id": "kb-rowid",
"target_type": "kb",
"relation": "implements"
}wiki.links --查找条目的所有链接
{
"project_root": "/path/to/project",
"entry_id": "mem-uuid"
}wiki.lint --健康检查
{ "project_root": "/path/to/project" }退货 { orphan_memory, broken_links, stale_sources, summary }.
wiki.export --将所有内容导出为markdown文件
{
"project_root": "/path/to/project",
"output_dir": "./wiki-export"
}______________________________________________________________________
摘要工具
总结.项目
{
"project_root": "/path/to/project",
"auto_discover": true,
"include_memory": true,
"include_kb": true
}总结.德尔塔
{
"project_root": "/path/to/project",
"auto_discover": true
}______________________________________________________________________
仪表板工具
仪表板.项目 --启动仪表板服务器并返回URL
{ "limit": 10 }退货 { dashboard_url, file_path }.在浏览器中打开URL。
集 DASHBOARD_PORT=4242 在env中,服务器启动时自动启动。
______________________________________________________________________
仪表盘
仪表板是一个本地提供的自包含HTML应用程序。
KB选项卡
- 左侧面板:带搜索的分页文档列表(30/页)
- 右侧面板:带有编辑/删除操作的完整文档视图
- 工具栏:新建文档,导入(JSON或
.md),导出为Markdown
内存选项卡
- 左侧面板:显示范围+预览的分页条目列表
- 右侧面板:带删除按钮的完整降价内容
- 标题:将所有条目导出为Markdown
源选项卡
- 左侧面板:带搜索的分页文件列表
- 右侧面板:内联文件内容预览(无模态)
链接/Lint选项卡
- 链接:按条目ID查找交叉引用
- Lint:检测孤儿、断开的链接、过时的来源
项目管理
- 顶部栏中的项目选择器--切换所有选项卡
- “+”按钮创建新项目
- “删除项目”按钮清除当前项目的所有数据
导入格式(JSON)
[
{ "title": "Getting Started", "content": "## Overview\n...", "source": "docs/intro.md" },
{ "title": "API Reference", "content": "## Endpoints\n..." }
]导出格式(Markdown)
KB导出(kb-{project}-{date}.md):
# Knowledge Base — my-project
> Exported 2026-04-12T... · 38 documents
---
## Getting Started
**Source:** docs/intro.md
**ID:** 1
## Overview
...内存导出(memory-{project}-{date}.md):
# Memory — my-project
> Exported 2026-04-12T... · 12 entries
---
### [decisions] uuid-here
**Tags:** auth, jwt
**Created:** 2026-03-01T...
We use JWT for auth — stateless, works with mobile.______________________________________________________________________
自动项目检测
project_id 从以下位置自动检测 project_root 按照以下顺序:
package.jsonname领域- Git远程源URL(仓库名称)
- 目录基名称
所有ID都被净化为小写字母数字+连字符。
// Auto-detection
memory.store({ project_root: "/Users/me/my-app", content: "test" })
// → project_id: "my-app"______________________________________________________________________
环境变量
| 变量 | 默认值 | 用途 |
|---|---|---|
DATA_DIR | ./data | SQLite数据库位置 |
LOG_LEVEL | info | Winston日志级别 |
MAX_MEMORY_ENTRIES | 1000 | 每个项目的内存上限 |
MAX_KB_ENTRIES | 500 | 每个项目的KB上限 |
ENABLE_QDRANT | false | 启用矢量搜索 |
QDRANT_URL | http://localhost:6333 | Qdrant端点 |
VACUUM_INTERVAL | 86400000 | DB真空间隔(ms) |
DASHBOARD_PORT | -- | 开机时自动启动仪表板 |
______________________________________________________________________
项目结构
mcp-kb-server/
├── src/
│ ├── server.js # MCP entry point (JSON-RPC 2.0 over stdio)
│ ├── storage/db.js # SQLite schema + migrations
│ ├── tools/
│ │ ├── memory.js # memory.* tools
│ │ ├── kb.js # kb.add / kb.search / kb.init
│ │ ├── sources.js # source.ingest / list / search
│ │ ├── summary.js # summary.project
│ │ ├── summaryDelta.js # summary.delta
│ │ ├── wikiLinks.js # wiki.link / wiki.links
│ │ ├── wikiLint.js # wiki.lint
│ │ ├── wikiExport.js # wiki.export
│ │ └── dashboard.js # HTTP server + HTML dashboard
│ └── utils/
│ ├── projectId.js # Auto-detection logic
│ ├── fileDiscovery.js # Glob + file reading utilities
│ ├── config.js # Env config
│ ├── validation.js # Joi schemas
│ ├── performance.js # LRU cache + vacuum scheduler
│ └── errors.js # AppError / handleError
├── config/discovery.json # Auto-discovery glob patterns
├── data/ # SQLite databases (auto-created)
└── test/ # 84 tests (node --test)______________________________________________________________________
数据库模式
memory.sqlite
CREATE TABLE memory (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL DEFAULT 'legacy',
scope TEXT NOT NULL,
content TEXT NOT NULL,
tags TEXT,
created_at TEXT NOT NULL,
updated_at TEXT,
expires_at TEXT
);
CREATE VIRTUAL TABLE memory_fts USING fts5(content, tags);
CREATE TABLE wiki_links (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL,
source_id TEXT, source_type TEXT,
target_id TEXT, target_type TEXT,
relation TEXT, created_at TEXT
);kb.sqlite
CREATE VIRTUAL TABLE kb_fts USING fts5(title, content, source);
CREATE TABLE kb_meta (rowid INTEGER PRIMARY KEY, project_id TEXT);
CREATE TABLE sources (
id TEXT PRIMARY KEY, project_id TEXT,
slug TEXT, filename TEXT, file_type TEXT,
content TEXT, file_path TEXT,
ingested_at TEXT, size_bytes INTEGER
);
CREATE VIRTUAL TABLE sources_fts USING fts5(slug, content);______________________________________________________________________
发展
git clone https://github.com/dereknguyen269/mcp-kb-server.git
cd mcp-kb-server
npm install
npm test # runs all 84 tests运行单个测试文件:
NODE_ENV=test node --test test/memory.test.js______________________________________________________________________
安全
- 项目隔离:SQL级别
project_id对每个查询进行筛选 - 路径验证:阻止目录遍历
- XSS保护:仪表板中转义的所有用户内容HTML
- 参数化查询:无SQL注入表面
- 无外部资源:仪表板完全脱机工作
______________________________________________________________________
演出
- FTS5/BM25:按内存、KB和源对全文搜索进行排名
- LRU查询缓存:50个条目缓存,5分钟TTL,突变无效
- 节流吹扫:每个项目最多每60秒清理一次过期条目
- SQLite WAL:并发读取而不阻塞写入
- 大宗交易:
kb.init仪表板导入使用单一事务
______________________________________________________________________
错误代码
| 代码 | 含义 |
|---|---|
-32602 | 参数无效(缺少字段、路径错误) |
-32601 | 未找到方法 |
-32000 | 服务器/DB错误 |
______________________________________________________________________
版本历史
v1.2.0(当前)
- ✅
kb.init--在一次MCP调用中从文件系统批量导入项目文档 - ✅ 仪表板拆分面板UI——KB、内存、源的列表+详细信息
- ✅ 所有选项卡上的分页列表(30个/页,加载更多)
- ✅ 从JSON数组导入KB或
.md通过仪表板文件 - ✅ 将KB和内存导出为Markdown下载
- ✅ 从仪表板创建/删除项目
- ✅ 从仪表板中删除单个内存条目
- ✅ KB列表已筛选
project_id(正在显示所有项目) - ✅ 新文档正确地限定了当前项目的范围
- ✅ 84测试
v1.1.0版本
- ✅ memory.delete/memory.update/memory.list
- ✅ 基于标签的过滤,内存上的FTS5
- ✅ KB项目范围、TTL/到期、LRU缓存
- ✅ 源代码层(摄取md/txt/csv/pdf)
- ✅ Wiki链接、lint、导出工具
v1.0.0
- ✅ 自动检测project_id
- ✅ 交互式HTML仪表板(暗/亮)
- ✅ 知识库管理(添加/编辑/删除)
- ✅ 项目范围界定、路径验证
______________________________________________________________________
支持
- npm: https://www.npmjs.com/package/mcp-kb-server
- GitHub: https://github.com/dereknguyen269/mcp-kb-server
- 问题: https://github.com/dereknguyen269/mcp-kb-server/issues
