bookstack-mcp
MCP server for BookStack — 56 tools covering the full API + semantic vector search. Rust/tokio/axum, dual transport (SSE + Streamable HTTP), OAuth 2.1, pluggable DB (SQLite/PostgreSQL+pgvector).
Install / Use
claude mcp add bees-roadhouse -- npx -y github:bees-roadhouse/bookstack-mcpIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
AI & Machine LearningSupported Platforms
Skill content
View source on GitHubBookStack MCP Server
An MCP (Model Context Protocol) server that gives Claude full access to a BookStack instance. Built in Rust with tokio/axum as a Cargo workspace with pluggable database backends and optional semantic vector search.
Features
- Full CRUD on all core BookStack resources (shelves, books, chapters, pages, attachments)
- Full-text search with BookStack query operators
- Semantic vector search — natural language search across all content via embeddings (optional). Two modes on
semantic_search:standard(default, vector + keyword + Markov-blanket blend) andprecision(4-stage cascade — semantic → keyword → Markov-blanket → cross-encoder). An optionalrerank: boolflag layers a cross-encoder pass on top of the standard top-N (v0.13.0; replaces the pre-v0.13.0mode: "rerank"). Per-page access control enforced via BookStack's API on every result. - Settings UI (
/settings) — browser-based admin configuration page (token-gated via the same/authorizeflow). Surfaces only the global server fields the index worker needs (hive_shelf_id,user_journals_shelf_id). - Pluggable database — SQLite for simple deployments, PostgreSQL + pgvector for production
- Separate embedder — background embedding service with pluggable backends (local ONNX, Ollama, OpenAI, Voyage)
- Cross-encoder reranker (optional) — embedder exposes
POST /rerankwhenBSMCP_RERANK_PROVIDERis configured. Three providers:local(in-process ONNX cross-encoder via fastembed, defaultBAAI/bge-reranker-v2-m3),voyage(Voyage's/v1/rerank),openai(any OpenAI-shape rerank endpoint — covers Voyage/Jina/Cohere-via-shim/self-hosted). Off by default; consumed bysemantic_search'srerank: trueflag (refinement on the standard mode) +mode: "precision"(cascade), and bysearch_content'srerank: trueflag (v0.13.0). - Server-side markdown to HTML conversion — send markdown, server converts before sending to BookStack
- Staging upload flow — upload local images and attachments through a two-step staging endpoint without exposing local paths to the container (see below)
- OAuth 2.1 support — use as a Claude.ai or Claude Desktop custom connector without config files
- Encrypted token storage — OAuth tokens encrypted at rest with AES-256-GCM
- Dual transport — SSE (MCP 2024-11-05) and Streamable HTTP (MCP 2025-03-26)
- Dynamic structure discovery — AI automatically learns your BookStack hierarchy on connect
- Auto-migration — seamlessly migrate from SQLite to PostgreSQL on startup
- Multi-user support via per-session BookStack API tokens
- Multi-arch Docker images (amd64 + arm64)
Architecture
crates/
bsmcp-common/ Shared types, traits, config, chunking, vector utils
bsmcp-db-sqlite/ SQLite backend (rusqlite, bundled)
bsmcp-db-postgres/ PostgreSQL + pgvector backend (sqlx)
bsmcp-server/ MCP server binary (axum, no ONNX dependency)
bsmcp-embedder/ Embedder + reconciliation worker (single binary, role-selected via --role flag)
— local ONNX / Ollama / OpenAI / Voyage embedding, job queue worker, HTTP /embed + optional /rerank
— reconciliation worker: initial walk + webhook/cron delta walk on the index_jobs queue
docker/
Dockerfile.server Lightweight server image (~35MB)
Dockerfile.embedder Embedder + worker image with ONNX Runtime (~45MB)
docker-compose.yml PostgreSQL deployment (production)
docker-compose.sqlite.yml SQLite deployment (simple)
The MCP server handles all client-facing protocol, OAuth, and search. The embedder runs separately, polling a database-backed job queue to embed pages and serving a /embed HTTP endpoint for query-time embedding (and /rerank when a reranker provider is configured). The embedder supports four embedding backends: local ONNX models (fastembed), Ollama, OpenAI-compatible APIs, and Voyage. The reconciliation worker (same binary, run with --role=worker) owns the index_jobs queue — runs the initial full walk on cold start, then consumes webhook + cron jobs and the periodic delta walk. Run as two compose services (separate embedder + worker) or as one with --role=both.
Available Tools (59 BookStack + 3 semantic = 62)
| Category | Tools |
|----------|-------|
| Search | search_content |
| Semantic | semantic_search, reembed, embedding_status |
| Shelves | list_shelves, get_shelf, create_shelf, update_shelf, delete_shelf |
| Books | list_books, get_book, create_book, update_book, delete_book |
| Chapters | list_chapters, get_chapter, create_chapter, update_chapter, delete_chapter |
| Pages | list_pages, get_page, create_page, update_page, delete_page, edit_page, append_to_page, replace_section, insert_after |
| Move | move_page, move_chapter, move_book_to_shelf |
| Attachments | list_attachments, get_attachment, create_attachment, update_attachment, delete_attachment, upload_attachment |
| Staging | prepare_upload (used with upload_image / upload_attachment for local file uploads) |
| Exports | export_page, export_chapter, export_book (markdown, plaintext, html) |
| Comments | list_comments, get_comment, create_comment, update_comment, delete_comment |
| Recycle Bin | list_recycle_bin, restore_recycle_bin_item, destroy_recycle_bin_item |
| Users | list_users, get_user |
| Audit Log | list_audit_log |
| System | get_system_info |
| Images | list_images, get_image, upload_image, update_image, delete_image |
| Permissions | get_content_permissions, update_content_permissions |
| Roles | list_roles, get_role |
Semantic tools (semantic_search, reembed, embedding_status) only appear when BSMCP_SEMANTIC_SEARCH=true and an embedder is running. Without semantic search: 59 BookStack tools.
The server is a thin BookStack CRUD facade plus semantic-search enrichment, OAuth, audit, and the reconciliation worker. Personal-memory primitives (journals, identities, reminders) and the v0.8.0/v0.9.0 briefing surface were removed in v0.10.0; v0.11.0 added the optional cross-encoder reranker on the embedder side; v0.13.0 (current) refactors that reranker from a third semantic_search mode into a flag on both semantic_search and search_content (breaking — see the v0.12 → v0.13 migration below). See the migration notes below.
Setup
Prerequisites
- A BookStack instance with API access enabled
- A BookStack API token (created in your BookStack user profile under "API Tokens")
- Docker and Docker Compose (for container deployment)
Quick Start (PostgreSQL — recommended)
cp .env.example .env
# Edit .env with your BookStack URL, encryption key, and database password
docker compose -f docker/docker-compose.yml up -d
This starts four containers:
- bsmcp-postgres — PostgreSQL 17 with pgvector extension
- bsmcp-server — MCP server (port 8080)
- bsmcp-embedder — Background embedding service (
--role=embedder, default); also serves/rerankwhen a reranker is configured - bsmcp-worker — Reconciliation worker (same image as the embedder, started with
--role=worker): initial walk on cold start, webhook + cron job consumption, periodic delta walk
Quick Start (SQLite — simple)
cp .env.example .env
# Edit .env with your BookStack URL and encryption key
docker compose -f docker/docker-compose.sqlite.yml up -d
This starts three containers (server + embedder + worker) sharing a SQLite database file.
Run from source
The project distributes as multi-arch (linux/amd64 + linux/arm64) container images on GHCR — ghcr.io/bees-roadhouse/bsmcp-server and ghcr.io/bees-roadhouse/bsmcp-embedder. Native binaries for bsmcp-server only are attached to each GitHub Release for linux-x86_64, linux-aarch64, darwin-x86_64, darwin-aarch64, and windows-x86_64. The embedder is not distributed as a bare binary — it depends on ONNX Runtime (a per-platform C++ shared library), so running it outside Docker is awkward. Either run the published embedder container, or build from source:
# Server
cargo run --release -p bsmcp-server
# Embedder (separate terminal)
cargo run --release -p bsmcp-embedder
The server is pure Rust + bundled SQLite and builds cleanly on any target the Rust toolchain supports. The embedder depends on fastembed, which links ONNX Runtime; the crate downloads a matching prebuilt at build time for common targets, but cross-compiling or running on uncommon platforms may require installing ONNX Runtime separately. For most users, running the embedder from the published container avoids that complexity entirely.
Configuration
Server Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| BSMCP_BOOKSTACK_URL | Yes | - | Your BookStack instance URL |
| BSMCP_ENCRYPTION_KEY | Yes | - | 32+ char key for AES-256-GCM token encryption |
| BSMCP_DB_BACKEND | No | sqlite | Database backend: sqlite or postgres |
| BSMCP_DATABASE_URL | If postgres | - | PostgreSQL connection string |
| BSMCP_DB_PATH | No | /data/bookstack-mcp.db | SQLite database path |
| BSMCP_PUBLIC_DOMAIN | No | - | Public domain for OAuth redirects (e.g. mcp.example.com) |
| BSMCP_INTERNAL_DOMAIN | No | - | Internal/Docker-network domain |
| BSMCP_HOST | No | 0.0.0.0 | Bind address |
| BSMCP_PORT | No | 8080 | Bind port |
| BSMCP_INSTANCE_NAME | No | - | Instance name shown to AI |
| BSMCP_INSTANCE_DESC | No | - | Instance description shown to AI |
| BSMCP_SEMANTIC_SEARCH | No | false | Enable semantic search tools |
| BSMCP_EMBEDDER_URL | No | http://bsmcp-embedder:8081 | Embedder HTTP endpoint |
| BSMCP_WEBHOOK_SECRET | If semantic | - | BookStack webhook secret |
| BSMCP_ACCESS_TOKEN_TTL | No | 86400 | Access token TTL in seconds (24h) |
| BSMCP_REFRESH_TOKEN_TTL | No | 7776000 | Refresh token TTL in seconds (90d) |
| BSMCP_BACKUP_INTERVAL | No | - | Hours between backups (0 = disabled) |
| BSMCP_BACKUP_PATH | No | /data/backups | Backup directory |
| BSMCP_BOOKSTACK_RATE_LIMIT_PER_MIN | No | 180 | Per-process BookStack API request cap. Lower if multiple processes share a token and you see 429s. |
Embedder Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| BSMCP_EMBED_TOKEN_ID | Yes | - | BookStack API token ID for crawling |
| BSMCP_EMBED_TOKEN_SECRET | Yes | - | BookStack API token secret |
| BSMCP_EMBED_PROVIDER | No | local | Embedding backend: local (fastembed ONNX), ollama, openai (or OpenAI-compatible), voyage. See Embedding Providers for per-provider config. |
| BSMCP_EMBED_MODEL | No | (per provider) | Model name (see Embedding Providers) |
| BSMCP_EMBED_API_KEY | If openai | - | API key for OpenAI embedding provider |
| BSMCP_EMBED_API_URL | No | (per provider) | Base URL for Ollama or OpenAI-compatible endpoint |
| BSMCP_EMBED_DIMS | No | (auto) | Embedding dimensions (auto-detected for Ollama) |
| BSMCP_MODEL_PATH | No | /data/models | ONNX model cache directory (local provider only) |
| BSMCP_EMBED_CPUS | No | 0 (unlimited) | Docker CPU limit for embedder |
| BSMCP_EMBED_JOB_TIMEOUT | No | 14400 | Seconds before stuck jobs reset |
| BSMCP_EMBED_BATCH_SIZE | No | 32 | Chunks per embedding batch |
| BSMCP_EMBED_DELAY_MS | No | 50 | Delay between pages (API throttle) |
| `BSMCP_EM
Truncated for display — read the full file on GitHub.
Related Skills
caveman
107.1k🪨 why use many token when few token do trick. Viral skill + proxy for coding agents that cuts 65% of tokens by talking like a caveman.
claude-mem
94.4kPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More
Agent-Reach
84.2kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
Understand-Anything
83.5kGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.
