# markzither/bookstack-mcp-server-dotnet architecture

> Architecture diagram of the GitHub repository markzither/bookstack-mcp-server-dotnet, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/markzither/bookstack-mcp-server-dotnet
- Repository: https://github.com/markzither/bookstack-mcp-server-dotnet

## Overview

This repository is a .NET MCP server that exposes BookStack content and administration to AI clients, with optional semantic search backed by a periodically synchronized vector index. The main request path is an MCP client invoking a tool or resource handler, which uses the BookStack API client to retrieve or change BookStack data. Semantic search adds embedding, chunking, and vector storage; an admin task subsystem is also registered by the server. Several handlers and storage implementations are unsampled, so their internal links are omitted where evidence is unavailable.

Main entry points: [`src/BookStack.Mcp.Server/Program.cs`](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Program.cs) (MCP host), [`src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs`](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs) (Index synchronizer), [`src/BookStack.Mcp.Server.Data.Abstractions/IVectorStore.cs`](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Abstractions/IVectorStore.cs) (Vector store contract), [`src/BookStack.Mcp.Server.Evaluation/EvaluationRunner.cs`](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/EvaluationRunner.cs) (Evaluation runner)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["MCP server"]
  node_server["MCP host<br/>[Program.cs]"]
end

subgraph group_content["BookStack access"]
  node_content_handlers["Content tools<br/>[tools]"]
  node_resources["Content resources<br/>[resources]"]
  node_search_tool["Text search tool"]
  node_api_client["BookStack API client"]
  node_api_contract["API contract"]
  node_scope["Access scoping<br/>[ScopeFilter.cs]"]
end

subgraph group_indexing["Semantic search"]
  node_semantic_tool["Semantic search tool"]
  node_sync["Index synchronizer"]
  node_chunking["Text chunking"]
  node_embedding["Embedding provider"]
  node_vector_abstraction["Vector store contract<br/>[IVectorStore.cs]"]
  node_sqlite_store["SQLite vector store"]
  node_postgres_store["Postgres vector store<br/>[PgVectorStore.cs]"]
  node_vector_db[("Vector database")]
end

subgraph group_admin["Administration"]
  node_admin_handlers["Admin handlers<br/>[AdminHandlers.cs]"]
  node_admin_queue["Admin task queue<br/>[AdminTaskQueue.cs]"]
  node_admin_worker["Admin index worker"]
end

subgraph group_evaluation["Search evaluation"]
  node_eval_harness["Evaluation harness"]
  node_eval_runner["Evaluation runner"]
  node_eval_client["MCP HTTP client<br/>[McpHttpClient.cs]"]
  node_eval_metrics["Search metrics"]
  node_eval_report["Markdown report"]
end

node_assistant(("AI assistant"))
node_bookstack["BookStack instance"]

node_assistant -->|"invokes MCP"| node_server
node_server -.->|"exposes tools"| node_content_handlers
node_server -.->|"exposes resources"| node_resources
node_content_handlers -->|"calls API"| node_api_contract
node_resources -.->|"uses API"| node_api_contract
node_search_tool -->|"searches content"| node_api_contract
node_api_client -.->|"sends API requests"| node_bookstack
node_search_tool -->|"filters results"| node_scope
node_server -.->|"exposes tool"| node_semantic_tool
node_semantic_tool -->|"searches vectors"| node_vector_abstraction
node_server -->|"hosts service"| node_sync
node_sync -->|"fetches pages"| node_api_contract
node_sync -->|"chunks page text"| node_chunking
node_sync -->|"generates embeddings"| node_embedding
node_sync -->|"upserts vectors"| node_vector_abstraction
node_embedding -->|"registers store"| node_vector_abstraction
node_vector_abstraction -->|"implemented by"| node_sqlite_store
node_vector_abstraction -->|"implemented by"| node_postgres_store
node_sqlite_store -.->|"persists vectors"| node_vector_db
node_postgres_store -.->|"persists vectors"| node_vector_db
node_server -->|"registers admin"| node_admin_handlers
node_admin_handlers -.->|"queues tasks"| node_admin_queue
node_admin_worker -.->|"processes tasks"| node_admin_queue
node_eval_harness -.->|"runs evaluation"| node_eval_runner
node_eval_runner -.->|"sends MCP requests"| node_eval_client
node_eval_runner -.->|"calculates metrics"| node_eval_metrics
node_eval_runner -.->|"writes report"| node_eval_report

click node_server "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Program.cs"
click node_content_handlers "https://github.com/markzither/bookstack-mcp-server-dotnet/tree/main/src/BookStack.Mcp.Server/tools"
click node_resources "https://github.com/markzither/bookstack-mcp-server-dotnet/tree/main/src/BookStack.Mcp.Server/resources"
click node_search_tool "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/tools/search/SearchToolHandler.cs"
click node_api_client "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/api/BookStackApiClient.cs"
click node_api_contract "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/api/IBookStackApiClient.cs"
click node_scope "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/config/ScopeFilter.cs"
click node_semantic_tool "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/tools/semantic-search/SemanticSearchToolHandler.cs"
click node_sync "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs"
click node_chunking "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/MarkZither.Rag.Chunking/SlideWindowChunkingService.cs"
click node_embedding "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/api/VectorSearchServiceCollectionExtensions.cs"
click node_vector_abstraction "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Abstractions/IVectorStore.cs"
click node_sqlite_store "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Sqlite/SqliteVectorStoreImpl.cs"
click node_postgres_store "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Postgres/PgVectorStore.cs"
click node_admin_handlers "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Admin/AdminHandlers.cs"
click node_admin_queue "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Admin/AdminTaskQueue.cs"
click node_admin_worker "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Admin/AdminIndexWorkerService.cs"
click node_eval_harness "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/EvaluationHarness.cs"
click node_eval_runner "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/EvaluationRunner.cs"
click node_eval_client "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/McpHttpClient.cs"
click node_eval_metrics "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/MetricsCalculator.cs"
click node_eval_report "https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/MarkdownReportWriter.cs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server toneBlue
class node_content_handlers,node_resources,node_search_tool,node_api_client,node_api_contract,node_scope toneAmber
class node_semantic_tool,node_sync,node_chunking,node_embedding,node_vector_abstraction,node_sqlite_store,node_postgres_store,node_vector_db toneMint
class node_admin_handlers,node_admin_queue,node_admin_worker toneRose
class node_eval_harness,node_eval_runner,node_eval_client,node_eval_metrics,node_eval_report,node_assistant,node_bookstack toneIndigo
```

## Components

### MCP server

- [MCP host](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Program.cs): `src/BookStack.Mcp.Server/Program.cs`

### BookStack access

- [Content tools](https://github.com/markzither/bookstack-mcp-server-dotnet/tree/main/src/BookStack.Mcp.Server/tools): `src/BookStack.Mcp.Server/tools`
- [Content resources](https://github.com/markzither/bookstack-mcp-server-dotnet/tree/main/src/BookStack.Mcp.Server/resources): `src/BookStack.Mcp.Server/resources`
- [Text search tool](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/tools/search/SearchToolHandler.cs): `src/BookStack.Mcp.Server/tools/search/SearchToolHandler.cs`
- [BookStack API client](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/api/BookStackApiClient.cs): `src/BookStack.Mcp.Server/api/BookStackApiClient.cs`
- [API contract](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/api/IBookStackApiClient.cs): `src/BookStack.Mcp.Server/api/IBookStackApiClient.cs`
- [Access scoping](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/config/ScopeFilter.cs): `src/BookStack.Mcp.Server/config/ScopeFilter.cs`

### Semantic search

- [Semantic search tool](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/tools/semantic-search/SemanticSearchToolHandler.cs): `src/BookStack.Mcp.Server/tools/semantic-search/SemanticSearchToolHandler.cs`
- [Index synchronizer](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs): `src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs`
- [Text chunking](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/MarkZither.Rag.Chunking/SlideWindowChunkingService.cs): `src/MarkZither.Rag.Chunking/SlideWindowChunkingService.cs`
- [Embedding provider](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/api/VectorSearchServiceCollectionExtensions.cs): `src/BookStack.Mcp.Server/api/VectorSearchServiceCollectionExtensions.cs`
- [Vector store contract](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Abstractions/IVectorStore.cs): `src/BookStack.Mcp.Server.Data.Abstractions/IVectorStore.cs`
- [SQLite vector store](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Sqlite/SqliteVectorStoreImpl.cs): `src/BookStack.Mcp.Server.Data.Sqlite/SqliteVectorStoreImpl.cs`
- [Postgres vector store](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Data.Postgres/PgVectorStore.cs): `src/BookStack.Mcp.Server.Data.Postgres/PgVectorStore.cs`
- **Vector database**

### Administration

- [Admin handlers](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Admin/AdminHandlers.cs): `src/BookStack.Mcp.Server/Admin/AdminHandlers.cs`
- [Admin task queue](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Admin/AdminTaskQueue.cs): `src/BookStack.Mcp.Server/Admin/AdminTaskQueue.cs`
- [Admin index worker](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server/Admin/AdminIndexWorkerService.cs): `src/BookStack.Mcp.Server/Admin/AdminIndexWorkerService.cs`

### Search evaluation

- [Evaluation harness](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/EvaluationHarness.cs): `src/BookStack.Mcp.Server.Evaluation/EvaluationHarness.cs`
- [Evaluation runner](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/EvaluationRunner.cs): `src/BookStack.Mcp.Server.Evaluation/EvaluationRunner.cs`
- [MCP HTTP client](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/McpHttpClient.cs): `src/BookStack.Mcp.Server.Evaluation/McpHttpClient.cs`
- [Search metrics](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/MetricsCalculator.cs): `src/BookStack.Mcp.Server.Evaluation/MetricsCalculator.cs`
- [Markdown report](https://github.com/markzither/bookstack-mcp-server-dotnet/blob/main/src/BookStack.Mcp.Server.Evaluation/MarkdownReportWriter.cs): `src/BookStack.Mcp.Server.Evaluation/MarkdownReportWriter.cs`

### Other components

- **AI assistant**
- **BookStack instance**

## Connections

- AI assistant → MCP host: invokes MCP (evidence: `README.md`)
- MCP host → Content tools: exposes tools
- MCP host → Content resources: exposes resources
- Content tools → API contract: calls API (evidence: `src/BookStack.Mcp.Server/tools/books/BookToolHandler.cs`)
- Content resources → API contract: uses API (evidence: `src/BookStack.Mcp.Server/resources/search/SearchResourceHandler.cs`)
- Text search tool → API contract: searches content (evidence: `src/BookStack.Mcp.Server/tools/search/SearchToolHandler.cs`)
- BookStack API client → BookStack instance: sends API requests
- Text search tool → Access scoping: filters results (evidence: `src/BookStack.Mcp.Server/tools/search/SearchToolHandler.cs`)
- MCP host → Semantic search tool: exposes tool
- Semantic search tool → Vector store contract: searches vectors (evidence: `src/BookStack.Mcp.Server/tools/semantic-search/SemanticSearchToolHandler.cs`)
- MCP host → Index synchronizer: hosts service
- Index synchronizer → API contract: fetches pages (evidence: `src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs`)
- Index synchronizer → Text chunking: chunks page text (evidence: `src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs`)
- Index synchronizer → Embedding provider: generates embeddings (evidence: `src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs`)
- Index synchronizer → Vector store contract: upserts vectors (evidence: `src/BookStack.Mcp.Server/services/VectorIndexSyncService.cs`)
- Embedding provider → Vector store contract: registers store (evidence: `src/BookStack.Mcp.Server/api/VectorSearchServiceCollectionExtensions.cs`)
- Vector store contract → SQLite vector store: implemented by
- Vector store contract → Postgres vector store: implemented by (evidence: `src/BookStack.Mcp.Server.Data.Postgres/PostgresVectorStoreServiceCollectionExtensions.cs`)
- SQLite vector store → Vector database: persists vectors
- Postgres vector store → Vector database: persists vectors
- MCP host → Admin handlers: registers admin (evidence: `src/BookStack.Mcp.Server/Program.cs`)
- Admin handlers → Admin task queue: queues tasks
- Admin index worker → Admin task queue: processes tasks
- Evaluation harness → Evaluation runner: runs evaluation
- Evaluation runner → MCP HTTP client: sends MCP requests
- Evaluation runner → Search metrics: calculates metrics
- Evaluation runner → Markdown report: writes report
