Zileo Docs
MCP server for indexing, semantic search, and generation of multi-format documents. Exposes 13 tools over JSON-RPC 2.0 so an LLM can search your local PDF, Excel, and Word files, and create or edit Excel and Word documents.
README
Zileo Docs
MCP (Model Context Protocol) server for indexing, semantic search, and generation of multi-format documents. Exposes 13 tools over JSON-RPC 2.0 so an LLM can search your local PDF, Excel, and Word files, and create or edit Excel and Word documents.
Developed by Assistance Micro Design
Built with Claude Code by Anthropic
Beta Warning
This project is in beta. Use at your own risk and review the trade-offs before relying on it.
| Risk | Description |
|---|---|
| API Costs | Every index_document call triggers Mistral embeddings (and OCR for image pages). Indexing large PDFs can generate non-trivial billing. |
| Breaking Changes | The MCP tool surface evolves between minor versions. Version 0.3.0 split search_documents into search_hybrid and search_semantic; expect similar adjustments before 1.0. |
| Security | Designed for personal local use behind Docker. The author declines responsibility if exposed to the public internet without an additional auth layer. |
| Instability | Schemas validated with extra="forbid" since 0.4.0 — clients sending unknown fields now receive VALIDATION_ERROR instead of silent acceptance. |
| No SLA | No guaranteed availability, no support contract. File issues via GitHub. |
Recommendation: Run behind a private network, set API_KEY, and pin the Docker image to a tagged version.
Description
Zileo Docs ingests heterogeneous office documents, extracts their content (native text or Mistral OCR), chunks the result while preserving Markdown structure, embeds each chunk with Mistral (1024-dim dense vectors plus BM25 sparse vectors), and stores them in Qdrant. An LLM connected over MCP can then search the indexed corpus, read full documents, and generate new Excel or Word files — all from natural-language tool calls.
Key Features
- 13 MCP tools over JSON-RPC 2.0 / HTTP (
POST /mcp) - Multi-format ingestion: PDF (native + OCR), Excel
.xlsx/.xls, Word.docx - Hybrid search (dense + BM25 RRF) with cosine relevance guard against off-domain results
- Semantic-only search with explicit
score_threshold - Excel and Word generation from structured input (data, formulas, styles, charts)
- Path traversal, formula-injection, and ZIP-bomb protections
- Per-endpoint rate limiting (
slowapi) and API-key authentication - Docker multi-stage image, non-root runtime, health-checked
Prerequisites
| Dependency | Purpose | Installation |
|---|---|---|
| Docker Engine >= 24 | Container runtime | https://docs.docker.com/engine/install/ |
| Docker Compose v2 | Service orchestration | Bundled with Docker Desktop or the docker compose CLI plugin |
| Mistral API key | Embeddings (1024d) + OCR | https://console.mistral.ai/ |
Build Requirements
Required only when developing outside Docker (the container ships everything else).
| Tool | Min version | Verify |
|---|---|---|
| Python | 3.11 | python3 --version # >= 3.11 |
| uv | 0.9 | uv --version # >= 0.9 |
Installation
git clone https://github.com/assistance-micro-design/zileo-docs.git
cd zileo-docs
cp .env.example .env
# Edit .env: set MISTRAL_API_KEY and DOCUMENTS_PATH
# Generate an API key to protect the server:
echo "API_KEY=$(openssl rand -hex 32)" >> .env
docker compose up -d
About
API_KEY— Protects/api/v1/*,/mcp, and/health. OutsideDEBUG=true, the server refuses to start with an empty key. See docs/mcp-client-setup.md for passing it to MCP clients.
Verify the server is up:
curl -H "X-API-Key: $API_KEY" http://localhost:8000/health
# {"status": "healthy", ...}
Tech Stack
| Layer | Technology |
|---|---|
| Language | Python 3.11+ |
| Web framework | FastAPI |
| MCP runtime | mcp SDK (JSON-RPC 2.0 over HTTP) |
| Dense embeddings | Mistral (mistral-embed, 1024 dim) |
| Sparse embeddings | fastembed (BM25) |
| Vector store | Qdrant 1.16.3 |
| OCR | Mistral OCR API |
| PDF extraction | PyMuPDF + pymupdf4llm |
| Excel I/O | openpyxl, xlrd |
| Word I/O | docx2python, python-docx |
| Packaging | uv + Hatchling |
| Runtime | Docker Compose (multi-stage, non-root) |
MCP Configuration
The MCP endpoint is POST /mcp (JSON-RPC 2.0 over HTTP).
Claude Desktop
Add to the Claude Desktop config:
| OS | Path |
|---|---|
| Linux | ~/.config/Claude/claude_desktop_config.json |
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"zileo-docs": {
"url": "http://localhost:8000/mcp",
"transport": "http",
"headers": {
"X-API-Key": "your_api_key_here"
}
}
}
}
Replace your_api_key_here with the API_KEY from .env. Restart Claude Desktop after editing.
Zileo Chat
In Zileo Chat, open Settings → MCP → Add server and fill in the form:
| Field | Value |
|---|---|
| Name | zileo-docs |
| Deployment method | HTTP |
| Arguments | the endpoint URL on the first line — http://localhost:8000/mcp |
| Authentication | API key |
| Header name | X-API-Key |
| API key value | the API_KEY from your .env |
The API-key value is stored in your OS keychain — never written to the database in plain text, never exported. Only non-sensitive metadata (the header name) is persisted.
Set the endpoint URL according to where Zileo Chat runs relative to the server:
| Scenario | Endpoint URL |
|---|---|
| Same host | http://localhost:8000/mcp |
| Zileo Chat in Docker, same host | http://zileo-docs:8000/mcp — join the zileo-docs_mcp-network network |
| Remote host (LAN) | http://<server-ip>:8000/mcp — enable the LAN access toggle at the top of the MCP settings first |
Then Save. See docs/mcp-client-setup.md for details.
Other MCP clients
Any MCP-compatible client can connect over HTTP Streamable to http://localhost:8000/mcp. The server implements:
initialize— Handshake and capabilitiestools/list— Lists the 13 available toolstools/call— Invokes a tool
Transport is HTTP POST with JSON-RPC 2.0 payloads. No SSE, no WebSocket.
MCP Tools
Indexing and search
| Tool | Description |
|---|---|
index_document |
Extract and index a PDF, Excel, or Word file into Qdrant |
search_hybrid |
Hybrid search (dense + BM25 RRF) with cosine relevance guard against off-domain hits |
search_semantic |
Pure semantic search (cosine, default threshold 0.7) |
get_document |
Fetch the metadata and chunks for a document |
delete_document |
Remove a document from the index (source file untouched) |
list_indexed_documents |
List documents already indexed |
read_document_content |
Read the reconstructed Markdown content of a document |
get_excel_formulas |
Fetch the formulas from an indexed Excel file |
Generation and editing
| Tool | Description |
|---|---|
create_excel_document |
Create an Excel file (.xlsx) with data, styles, and charts |
edit_excel_document |
Edit an existing Excel file (13 operations) |
create_word_document |
Create a Word file (.docx) from Markdown content |
Utilities
| Tool | Description |
|---|---|
list_available_documents |
List source files (two sources: documents, generated) |
inspect_generated_file |
Inspect the structure of a generated Excel file |
Configuration
Main environment variables (see docs/configuration.md for the full list):
| Variable | Required | Description |
|---|---|---|
MISTRAL_API_KEY |
Yes | Mistral API key (embeddings + OCR) |
API_KEY |
Yes (outside DEBUG) | Authentication key for protected endpoints. Generate via openssl rand -hex 32. Empty value accepted only when DEBUG=true. |
DOCUMENTS_PATH |
Yes | Local path to your source documents |
OUTPUT_PATH |
No | Output directory for generated files (default: /app/output) |
QDRANT_HOST |
No | Qdrant host (default: localhost, qdrant inside Docker) |
DEBUG |
No | Enables Swagger UI and CORS (default: false) |
Local Development
uv sync --extra dev
docker compose up -d qdrant # Qdrant only
uv run uvicorn src.main:app --reload
Tests
uv run pytest tests/unit/ -v # Unit tests
uv run pytest tests/integration/ -v # Requires Qdrant
uv run pytest tests/e2e/ -v # Full pipeline
Validation
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run mypy src/
uv run pytest --cov=src --cov-fail-under=80
RAG evaluation
Offline evaluation of search quality against the golden set (tests/eval/golden_questions.yml). Requires the server running with indexed documents.
uv run python3 scripts/eval_rag.py --tool search_hybrid # or search_semantic
# Metrics: recall@1, recall@5, MRR, false-positive rate (off-domain), mean results
Architecture
src/
main.py # FastAPI app + /mcp endpoint
core/ # Config, exceptions, logging
api/routes/ # REST endpoints (health, documents, search)
mcp/
server.py # JSON-RPC 2.0 router
tools/ # 13 MCP tools
services/
pdf/ # Analysis, native extraction, Mistral OCR
excel/ # Extraction + generation + editing
word/ # docx2python extraction
inspection/ # Generated-file inspection
document/ # Multi-format router
chunking/ # Chunk splitting
embedding/ # Mistral embeddings (1024 dim)
vector/ # Qdrant storage
models/ # Pydantic schemas
Documentation
- MCP client setup — Claude Desktop, Zileo Chat, other clients
- Research guide — Indexing, hybrid search, reading
- Generation guide — Excel and Word options, design, examples
- API reference — REST endpoints and 13 MCP tools
- Architecture — Processing pipeline and components
- Configuration — Environment variables
- Deployment — Docker and local development
- Multi-format support — PDF, Excel, Word
- Code style — Conventions
Contributing
See CONTRIBUTING.md and .github/PULL_REQUEST_TEMPLATE.md.
Quick path:
- Fork the repository
- Create a feature branch (
git checkout -b feat/your-feature) - Commit with a conventional message (
git commit -m "feat(scope): summary") - Push and open a Pull Request against
main - Ensure CI is green and the PR checklist is satisfied
Security
To report a vulnerability, see SECURITY.md. Do not open public issues for security reports.
License
Distributed under the GNU Affero General Public License v3.0 or later.
Copyright 2025-2026 Assistance Micro Design
Licensed under the GNU Affero General Public License v3.0 or later
This license is mandatory because the project depends on PyMuPDF and pymupdf4llm (Artifex Software, Inc.), both distributed under AGPL-3.0. See THIRD_PARTY_LICENSES.md for the complete inventory and NOTICE for attribution.
Acknowledgments
- Mistral AI — Embeddings and OCR
- Qdrant — Vector database
- PyMuPDF and pymupdf4llm — PDF extraction
- FastAPI — Web framework
- Model Context Protocol — Tool protocol
- Built with Claude Code by Anthropic
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.