ESC
开源 2 分钟阅读

knowledge-base:支持 MCP API 调用的个人/团队知识库

开源项目 knowledge-base 发布第一阶段最小可用版本,基于 FastAPI + SQLite 构建个人/团队文件知识库,支持嵌套文件夹、多格式文档上传与浏览器本地预览、回收站、审计日志等功能,并提供只读 MCP 服务,支持 stdio 与 Streamable HTTP 传输,便于 AI agent 通过 MCP Token 安全检索知识库内容。

来源:GitHub

知识库第一阶段(Phase 1)

本仓库包含第一阶段的最小可用文件知识库。

当前技术栈

  • 后端:FastAPI
  • 数据库:SQLite
  • 文件存储:本地文件系统
  • 任务队列:为后续阶段预留的占位

PostgreSQL 和对象存储为后续迁移预留。当前版本无需 Docker、MinIO 或运行中的数据库服务。

本地开发

  1. 将根目录的环境变量模板复制为 backend/.env:
Copy-Item ..\.env.example .env
  1. 安装依赖:
cd backend
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
  1. 初始化 SQLite 数据库:
python -m app.db.init_db
  1. 运行后端:
uvicorn app.main:app --reload

验证

在 backend 目录下:

set PYTHONPATH=.
python -m pytest

PowerShell:

$env:PYTHONPATH = "."
python -m pytest

初始化或重建 SQLite 表:

python -m app.db.init_db

运行时文件生成于 backend/data/ 目录下:

  • knowledge_base.db:SQLite 数据库
  • storage/:上传的文件和生成的 Markdown 文件

现有的 Docker Compose 文件为后续 PostgreSQL 和对象存储迁移预留,当前阶段不需要。

服务的启动、重启、停止和状态命令由 scripts/ 目录下独立的 PowerShell 控制文件提供。

当前功能范围

  • 管理员创建用户、登录和 JWT 认证
  • 公开知识库
  • 带面包屑导航的嵌套文件夹
  • 按文件夹范围的文档列表与上传
  • 仅限所有者的文件夹重命名与空文件夹删除 API
  • 单文件与批量上传
  • 支持上传 PDF、文本/Markdown/HTML、图片、PowerPoint、Word 和 Excel 文件
  • 文档元数据与标签
  • 原始文件预览与下载
  • 应用内阅读器,支持文本、Markdown、PDF、DOCX、XLSX、PPTX 和图片
  • 使用基于 Vue 的预览组件在浏览器本地预览 PDF、DOCX、XLS/XLSX 和 Markdown,PPTX 由内置的 pptx-renderer 渲染
  • 尽最大努力对旧版 DOC、XLS 和 PPT 文件进行文本提取
  • 仅限所有者的文档编辑
  • 仅限所有者的软删除与恢复
  • 回收站列表
  • SQLite 数据库初始化
  • 带路径穿越防护的本地文件系统存储
  • 仅管理员可用的用户管理和审计日志页面
  • 按用户的 MCP Token 过期策略,包括持久化长期 Token
  • 应用内上传进度、安全的 HTML 预览、文档所有者/上传者元数据,以及管理员 MCP 调用日志
  • 文档和文件夹的跨范围复制,包括递归文件夹复制和物理本地存储复制

运维配置通过 .env.example、backend/app/core/config.py 和 scripts/ 下的脚本控制。本仓库还包含只读 REST API、OpenAPI 端点、MCP 集成,以及 skills/knowledge-base/ 下的 knowledge-base Skill。

API 示例

登录并获取 token:

$body = @{
  username = "demo"
  password = "password-123"
} | ConvertTo-Json

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/api/v1/auth/login `
  -ContentType "application/json" `
  -Body $body

上传文档:

$token = "<access_token>"
$knowledgeBaseId = 1

curl.exe `
  -X POST `
  "http://127.0.0.1:8000/api/v1/documents/upload" `
  -H "Authorization: Bearer $token" `
  -F "knowledge_base_id=$knowledgeBaseId" `
  -F "tags=制度,测试" `
  -F "file=@D:\path\to\guide.txt"

自动生成的 API 文档可在 /docs 访问。

浏览器本地文档预览

前端使用 vue3-office-preview 处理 DOCX、PPTX、XLS 和 XLSX,@vue3-office/vue-pdf 处理 PDF,@deot/docs-markdown 处理 Markdown。文件通过经过认证的 API 拉取到浏览器内存并在本地渲染。此预览路径无需 LibreOffice、ONLYOFFICE、Docker 或 Python SDK。

原始文件仍保存在本地存储中。Markdown 提取以及旧版 .doc、.xls 和 .ppt 的回退处理仍由后端完成。

文件夹 API

在知识库下创建文件夹:

$body = @{
  knowledge_base_id = 1
  name = "实验方案"
} | ConvertTo-Json

Invoke-RestMethod `
  -Method Post `
  -Uri http://127.0.0.1:8000/api/v1/folders `
  -Headers @{ Authorization = "Bearer $token" } `
  -ContentType "application/json" `
  -Body $body

在 multipart 表单中添加 folder_id 即可上传到文件夹。网页会针对当前选中的文件夹自动完成此操作。

知识库选择器默认为「全部」。在此模式下,页面显示所有公开知识库中的文件夹和根级文档。新建文件夹会被分配到对话框中选定的知识库;从「全部」上传时,除非选择了某个文件夹,否则使用第一个可用的知识库。

MCP 只读服务

项目包含一个面向 agent 的独立 MCP 服务。它与 FastAPI 应用共享同一个 SQLite 数据库、本地文件系统存储、JWT 密钥和文档阅读器。支持本地 stdio 和远程 Streamable HTTP 传输。第一阶段暴露只读工具:

  • list_knowledge_bases
  • list_documents
  • search_knowledge
  • get_document
  • get_document_metadata

MCP 进程不暴露上传、移动、删除或文件夹管理操作。它使用来自 KB_MCP_TOKEN 的 JWT 身份,因此 agent 无法看到对应用户无权阅读的文档。

对于本地 stdio 客户端,可以省略 KB_MCP_TOKEN。此时 agent 必须使用用户的用户名和密码调用一次 authenticate 工具;短期会话仅保留在 MCP 进程内存中。

在 PowerShell 中一次性创建 MCP 环境:

cd backend
python -m venv .mcp-venv
.\.mcp-venv\Scripts\python.exe -m pip install -r requirements-mcp.txt

设置与 API 相同的数据库和存储配置,然后将登录获得的 access_token 放入 KB_MCP_TOKEN:

$env:PYTHONPATH = "."
$env:KB_MCP_TOKEN = "<access_token>"
.\.mcp-venv\Scripts\python.exe -m app.mcp_server

该进程通过 stdin/stdout 通信 MCP 协议。不要在服务中添加普通的 print() 输出;诊断信息必须输出到 stderr,以保持协议有效。

远程 Streamable HTTP 模式:

$env:PYTHONPATH = "."
$env:MCP_TRANSPORT = "streamable-http"
$env:MCP_HOST = "0.0.0.0"
$env:MCP_PORT = "8020"
$env:MCP_PATH = "/mcp"
$env:MCP_STATELESS_HTTP = "true"
.\.mcp-venv\Scripts\python.exe -m app.mcp_server

配置 HTTPS 反向代理后,远程端点为 https://your-domain/mcp。远程客户端必须发送 Authorization: Bearer <access_token>。远程客户端需配置与 API 连接相同的端点和受保护的 Bearer 凭证。

浏览器页面 /mcp-token.html 读取当前登录账号并请求 MCP Token,无需读取或存储账号密码。管理员页面 /admin.html 由管理员角色保护,允许修改用户状态、角色、密码和 MCP Token 过期策略。

运行本地协议冒烟测试:

$env:PYTHONPATH = "."
.\.mcp-venv\Scripts\python.exe scripts\mcp_stdio_smoke.py