内容
# bookstack-mcp-server-dotnet
[](https://github.com/MarkZither/bookstack-mcp-server-dotnet/actions/workflows/ci.yml)
[](https://marketplace.visualstudio.com/items?itemName=MarkZither.bookstack-mcp-server)
[](https://hub.docker.com/r/markzither/bookstack-mcp-server)
[](https://hub.docker.com/r/markzither/bookstack-mcp-server)
一款提供完整访问 BookStack 知识管理 API 的 Model Context Protocol(MCP)服务器,基于 .NET 10 构建。可为 AI 助手(如 GitHub Copilot、Claude 等)提供直接访问 BookStack 实例的能力。
灵感来自 <https://github.com/pnocera/bookstack-mcp-server>。
---
## 安装
### VS Code 扩展(推荐 - 无需 .NET 环境)
从 VS Code Marketplace 安装 - 服务器二进制文件已捆绑:
[](https://marketplace.visualstudio.com/items?itemName=MarkZither.bookstack-mcp-server)
然后设置三个设置(`Ctrl+,` → 搜索 `bookstack`):
| 设置 | 值 |
|---------|-------|
| `bookstack.url` | `https://your-bookstack/` |
| `bookstack.tokenId` | 您的 BookStack API token ID |
| `bookstack.tokenSecret` | 您的 BookStack API token 密钥 |
参见 [vscode-extension/README.md](vscode-extension/README.md) 以获取完整的配置参考。
### Docker(流式 HTTP 传输)
以容器形式运行服务器 - 适用于自托管的 AI 助手、Claude Desktop 或任何支持流式 HTTP MCP 的客户端。
```bash
docker run -d \
-e BOOKSTACK_BASE_URL=https://your-bookstack/ \
-e BOOKSTACK_TOKEN_SECRET=your-token-id:your-token-secret \
-e BOOKSTACK_MCP_TRANSPORT=http \
-e BOOKSTACK_MCP_HTTP_AUTH_TOKEN=change-me \
-p 3000:3000 \
ghcr.io/markzither/bookstack-mcp-server:latest
```
健康检查:`GET http://localhost:3000/health`
MCP 端点:`http://localhost:3000/mcp`(如果设置了 `BOOKSTACK_MCP_HTTP_AUTH_TOKEN`,则需要 Bearer token)
#### Docker Compose
提供了适用于常见配置的示例 compose 文件:
| 文件 | 描述 |
|------|-------------|
| [`docker-compose.yml`](docker-compose.yml) | HTTP 传输,无向量搜索(最简单) |
| [`docker-compose.sqlite.yml`](docker-compose.sqlite.yml) | SQLite 向量搜索 + Ollama 嵌入 |
| [`docker-compose.postgres.yml`](docker-compose.postgres.yml) | PostgreSQL + pgvector + Ollama(所有容器中) |
| [`docker-compose.postgres-external.yml`](docker-compose.postgres-external.yml) | PostgreSQL 外部连接字符串 + Ollama |
复制并编辑相关文件,然后:
```bash
cp docker-compose.yml docker-compose.override.yml
# 编辑 docker-compose.override.yml 以适应您的值
docker compose up -d
```
#### 环境变量
| 变量 | 必需 | 描述 |
|----------|----------|-------------|
| `BOOKSTACK_BASE_URL` | ✅ | 您的 BookStack 实例的完整 URL,例如 `https://demo.bookstackapp.com/` |
| `BOOKSTACK_TOKEN_SECRET` | ✅ | `tokenId:tokenSecret` 来自 BookStack → 设置 → API Tokens |
| `BOOKSTACK_MCP_TRANSPORT` | — | `stdio`(默认)\| `http` \| `both` |
| `BOOKSTACK_MCP_HTTP_PORT` | — | HTTP 监听端口(默认:`3000`) |
| `BOOKSTACK_MCP_HTTP_AUTH_TOKEN` | — | HTTP 端点身份验证的 Bearer token(推荐用于 HTTP 传输) |
| `BOOKSTACK_SCOPED_BOOKS` | — | 以逗号分隔的 book ID 或 slugs 以限制访问 |
| `BOOKSTACK_SCOPED_SHELVES` | — | 以逗号分隔的 shelf ID 或 slugs 以限制访问 |
| `ConnectionStrings__VectorDb` | — | 向量数据库的连接字符串(默认:`Data Source=bookstack-vectors.db`) |
| `VectorSearch__Enabled` | — | `true` 以启用语义搜索(默认:`false`) |
| `VectorSearch__Database` | — | `Sqlite`(默认)\| `Postgres` |
| `VectorSearch__EmbeddingProvider` | — | `Ollama`(默认)\| `AzureOpenAI` |
| `VectorSearch__Ollama__BaseUrl` | — | Ollama 基本 URL(默认:`http://localhost:11434`) |
| `VectorSearch__Ollama__Model` | — | Ollama 嵌入模型(默认:`qllama/bge-large-en-v1.5`)- 参见 [嵌入模型选择](#embedding-model-selection) |
| `VectorSearch__Ollama__QueryPrefix` | — | 查询字符串嵌入前的前缀。空字符串用于对称模型(`qllama/bge-large-en-v1.5`,`nomic-embed-text`);在使用 `mxbai-embed-large` 时设置为 `"Represent this sentence for searching relevant passages: "`。 |
| `VectorSearch__AzureOpenAI__Endpoint` | — | Azure OpenAI 端点(使用 AzureOpenAI 提供程序时) |
| `VectorSearch__AzureOpenAI__DeploymentName` | — | Azure OpenAI 部署名称 |
| `VectorSearch__AzureOpenAI__ApiKey` | — | Azure OpenAI API 密钥 |
| `VectorSearch__Sync__IntervalHours` | — | 同步嵌入的频率(默认:`24`) |
| `VectorSearch__Sync__BatchSize` | — | 每次同步批次的页面数(默认:`50`) |
### 嵌入模型选择
嵌入模型决定了向量的质量和维度。 21 种配置(3 种模型 × 7 种块大小)在 v2 黄金数据集(30 个查询,ASP.NET Core / .NET 开发人员知识)上进行了基准测试,得出最佳块配置(ChunkSize=256,ChunkOverlap=64):
| 模型 | 维度 | Recall@1 | Recall@3 | MRR | p50 延迟 |
|-------|-----------|---------|---------|-----|-------------|
| `qllama/bge-large-en-v1.5` | 1024 | **0.6667** | **0.9000** | **0.7856** | 228ms |
| `mxbai-embed-large` | 1024 | 0.5667 | 0.9333 | 0.7556 | 288ms |
| `nomic-embed-text` | 768 | 0.4333 | 0.8000 | 0.6067 | 93ms |
**默认**:`qllama/bge-large-en-v1.5` - 最佳 Recall@1(+10 pp 超过 mxbai)和 MRR。无需查询前缀(对称模型)。`nomic-embed-text` 约快 3 倍,但质量明显较低。
在启动服务器之前拉取默认模型:
```bash
ollama pull qllama/bge-large-en-v1.5
```
#### 更改嵌入模型
切换到具有**不同向量维度**的模型(例如 768 → 1024)需要:
1. 将 `VectorSearch__Ollama__Model`(或 `BOOKSTACK_VECTOR_OLLAMA_MODEL`)更新为新模型名称。
2. 删除或替换现有的向量数据库文件(`Data Source=bookstack-vectors.db`)- 架构不兼容。
3. 重启服务器;它将自动重新索引所有页面。
> **注意:** 向量维度编译到架构中。更改为具有**相同**维度的模型(例如两个 768 维模型)只需要更新模型名称和完整重新索引;无需更改架构。
### 本地开发(自托管 BookStack + F5 调试)
运行完整的本地栈 - BookStack、MariaDB 和 MCP 服务器 - 无需外部依赖。
**前提条件**:Docker Engine 20.10+,.NET 10 SDK,VS Code
```bash
git clone https://github.com/MarkZither/bookstack-mcp-server-dotnet.git
cd bookstack-mcp-server-dotnet
# 必需:创建本地 env 文件(gitignored - 永远不会提交)
cp .env.dev.example .env.dev
# 必需:生成 BookStack 应用程序密钥并追加到 .env.dev
docker run --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey \
| sed 's/^/APP_KEY=/' >> .env.dev
```
然后在 VS Code 中按 **F5**。预启动任务启动 BookStack 和 MariaDB,等待它们健康,然后使用调试器附加启动 MCP 服务器。
首次运行时,打开 <http://localhost:6875>,使用 `admin@admin.com` / `password` 登录,生成一个 API token(配置文件 → API Tokens → 添加 Token),并将 token ID 和密钥粘贴到 `.env.dev` 中。
参见 [docs/developer-guide.md](docs/developer-guide.md) 以获取完整的设置演练,包括 Ollama 集成和数据种子脚本。
### 从源代码构建
**前提条件**:[.NET 10 SDK](https://dotnet.microsoft.com/download)
```bash
git clone https://github.com/MarkZither/bookstack-mcp-server-dotnet.git
cd bookstack-mcp-server-dotnet
dotnet build
dotnet test
```
---
## 可用的 MCP 工具
### 内容
| 类别 | 操作 |
|----------|-----------|
| **书籍** | 列出,创建,读取,更新,删除,导出 |
| **章节** | 列出,创建,读取,更新,删除 |
| **页面** | 列出,创建,读取,更新,删除,导出 |
| **书架** | 列出,创建,读取,更新,删除 |
### 搜索
| 工具 | 描述 |
|------|-------------|
| **搜索** | 跨所有 BookStack 内容的全文搜索 |
| **语义搜索** | 使用 AI 嵌入的自然语言向量搜索(需要 `VectorSearch__Enabled=true`) |
### 管理
| 类别 | 操作 |
|----------|-----------|
| **用户** | 列出,创建,读取,更新,删除 |
| **角色** | 列出,创建,读取,更新,删除 |
| **附件** | 列出,创建,读取,更新,删除 |
| **图像** | 列出,读取,更新,删除 |
| **权限** | 读取和更新内容级权限 |
| **审计日志** | 列出审计日志条目 |
| **回收站** | 列出,恢复和永久删除项目 |
| **服务器信息** | 读取 BookStack 服务器版本和实例信息 |
---
## 向量搜索
语义搜索允许 AI 助手通过含义而不是确切的关键词来查找页面。默认情况下禁用此功能,需要:
1. 嵌入提供程序(Ollama with `qllama/bge-large-en-v1.5`,或 Azure OpenAI)
2. 向量数据库(SQLite with sqlite-vec,或 PostgreSQL with pgvector)
服务器在可配置的时间表上将页面内容同步到向量数据库(`VectorSearch__Sync__IntervalHours`)。
参见 [docker-compose.sqlite.yml](docker-compose.sqlite.yml) 和 [docker-compose.postgres.yml](docker-compose.postgres.yml) 文件以获取现成的示例。
### SQLite 数据库文件位置
使用 SQLite 提供程序时,数据库在可预测的每个用户位置创建:
| 平台 | 路径 |
|----------|------|
| Linux / macOS | `~/.local/share/bookstack-mcp/bookstack-vectors.db` |
| Windows | `%LOCALAPPDATA%\bookstack-mcp\bookstack-vectors.db` |
VS Code 管理面板(BookStack 状态栏 → 点击)显示了解决的路径,并允许您在文件管理器中显示它。
### 浏览 SQLite 数据库
`page_vectors` 表是 **sqlite-vec 虚拟表**(`vec0` 模块)。通用 SQLite 浏览器(DB Browser for SQLite,DBeaver 等)如果未首先加载 sqlite-vec 本地扩展,则无法打开文件 - 文件本身是标准 SQLite 数据库。
**您可以在没有扩展的情况下读取的内容:**
`sync_metadata` 表是一个普通的 EF Core 表,可以在任何浏览器中打开:
```bash
sqlite3 ~/.local/share/bookstack-mcp/bookstack-vectors.db "SELECT * FROM sync_metadata;"
```
**DB Browser for SQLite - 加载扩展:**
1. 查找 sqlite-vec 本地库与服务器二进制文件一起(例如在 `publish-local/` 或扩展二进制文件旁边):
```bash
find ~/.local/share/bookstack-mcp -name "*.so" 2>/dev/null
find "$(dirname $(which bookstack-mcp-server))" -name "*vec*" 2>/dev/null
```
2. 在 DB Browser for SQLite 中:**编辑 → 首选项 → 扩展 → 添加**,粘贴 `.so` / `.dll` 路径,单击确定。
3. 重新打开数据库 - `vec0` 虚拟表将被识别。
您也可以使用 **工具 → 加载扩展**(大多数版本中可用)以在单个会话中加载它。
---
## 作用域访问
将 MCP 服务器限制在特定的书籍或书架上,以限制 AI 可以看到和修改的内容:
```bash
# 通过环境变量(逗号分隔的 ID 或 slugs)
BOOKSTACK_SCOPED_BOOKS=architecture-decisions,runbooks
BOOKSTACK_SCOPED_SHELVES=engineering
```
```json
// 通过 VS Code 设置
{
"bookstack.scopedBooks": ["architecture-decisions", "runbooks"],
"bookstack.scopedShelves": ["engineering"]
}
```
---
## 传输
| 传输 | 用例 |
|-----------|----------|
| `stdio` | VS Code 扩展,Claude Desktop(默认) |
| `http` | Docker / 自托管,远程 AI 客户端 |
| `both` | 同时运行两者 |
HTTP 传输在 `/mcp` 处公开了一个流式 HTTP MCP 端点,在 `/health` 处进行健康检查。使用 `BOOKSTACK_MCP_HTTP_AUTH_TOKEN`(Bearer token)保护它。
---
## 开发
```bash
dotnet build # 还会自动安装 pre-commit 钩子(首次运行)
dotnet test --configuration Release
dotnet format # 在提交前修复任何格式问题
```
### Pre-commit 钩子
[husky.net](https://alirezanet.github.io/Husky.Net/) 强制执行代码格式化 - 跨平台 .NET git 钩子工具。
它通过任务运行器在每次 `git commit` 上运行 `dotnet format --verify-no-changes`,并在发现问题时阻止提交。
钩子在首次运行 `dotnet build` 或 `dotnet restore` 时**自动安装**。
[`Directory.Build.targets`](Directory.Build.targets) 通过 MSBuild 运行 `dotnet tool restore && dotnet husky install` - 无需手动设置。
| 平台 | 要求 |
|----------|-------------|
| Linux / macOS | 开箱即用 |
| Windows | 需要 [Git for Windows](https://git-scm.com/download/win) - Git 使用捆绑的 `sh.exe` 执行钩子脚本 |
要临时跳过钩子(例如,WIP 提交):设置 `HUSKY=0` 然后提交。
如果钩子阻止了您的提交,请运行 `dotnet format`,重新暂存更改的文件,然后再次提交。
参见 [docs/](docs/) 获取架构决策、功能规范和迁移指南。
## 贡献
- [GitHub 问题](https://github.com/MarkZither/bookstack-mcp-server-dotnet/issues)
- 欢迎拉取请求 - 请先为重大更改打开一个问题。