sovena
Can use Ollama as a local OpenAI-compatible embedding service to generate vector embeddings for semantic retrieval, allowing the server to index and search literature without relying on external commercial APIs.
Deep integration with Zotero, enabling reading of collections, items, and annotations via the local API, converting attached PDFs and other files to Markdown with page number annotations, and performing incremental semantic indexing for literature search.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sovenaFind passages about the Silk Road trade routes in my scanned books"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Jinyun Wencai Sovena
English | 简体中文
Zotero → Markdown semantic literature package → vector retrieval: a local literature processing system for academic research across all disciplines (especially beneficial for fields with large amounts of photocopied/scanned materials in humanities, social sciences, STEM, and medicine), exposed as an MCP (Model Context Protocol) service to any local/remote AI client.
"Jinyun" is taken from Jinyun Mountain in Beibei — the location of Southwest University; "Wencai" carries two meanings: it is both the gathering of the essence of literature, and the literary brilliance of writing. "Gathering the flowers of antiquity, to brew our honey." — Wu Mi (taught at Southwest University for twenty-eight years)
Use Cases
Literature review and writing: batch-convert literature in Zotero (including photocopied ancient texts, scanned PDFs) into Markdown with page numbers, so AI clients can precisely cite to the page
Cross-library semantic search: ask natural-language questions across hundreds of documents (e.g., "What are the acoustic measurement methods for timbre?") instead of searching keyword by keyword
Digitization of ancient texts/photocopies: scanned PDFs automatically go through the OCR pipeline, restoring titles, tables, and two-column layouts into structured text
Materials outside Zotero: e-book libraries, loose PDFs, lecture notes, and any other folders, made into equally searchable adhoc packages
AI deep-reading external brain: clients like Claude Desktop / Cherry Studio / Trae query your literature library directly via MCP, with answers carrying citations
Remote collaboration: deploy the server on any computer that meets the requirements (home/lab/cloud), and other computers just fill in the server URL in their AI client
Related MCP server: zotero-mcp-lite
Core Capabilities
Capability | Description |
Deep Zotero integration | Reads collections/items/annotations (local API, no Web API key needed); includes a Zotero plugin (.xpi, with right-click access from collections/items) |
Full-text conversion of literature | Batch-converts attachments into AI-friendly Markdown, with 【page number】annotations (dual sources: PDF Page Labels and OCR page numbers) |
OCR for scanned/photocopied materials | Unlimited-OCR structured recognition, dual backends MLX / GGUF (llama-server), all platforms, remote-capable |
Vector semantic search | LanceDB + any OpenAI-compatible embedding service (local or remote commercial platforms) |
Incremental processing | Dual detection via item version + attachment fingerprint (mtime), only processes new/changed content |
One-command startup |
|
Non-Zotero materials | Any files/folders such as e-book libraries, loose PDFs, lecture notes, made into equally searchable adhoc packages |
Remote deployment | Start the service once, other computers just fill in the URL (e.g., via Tailscale networking) |
Task scheduling/resource guarding | OCR concurrency=1, memory guard, on-demand model loading/unloading — won't run your computer into the ground |
Architecture
Zotero(本地API) ─┐
├─ Pipeline.prepare ─┬─ L1 文本路(pymupdf) ─┐
任意文件/文件夹 ─┘ (增量) ├─ L2 OCR路(MLX/GGUF) ├─ 语义包(content.md+meta.json)
└─ anydoc(非PDF) ┘ │
LanceDB 向量索引
(embedding: 本地/远程 OpenAI 兼容服务)
│
┌──────────────────────────────────────┤
│ │
Web 监管台(:8765) MCP 端点(/mcp)
(HTMX/原生JS) (本地 & Tailscale 远程 AI 客户端)L1 text path: PDFs with a text layer → extracted via pymupdf, page numbers preferentially use PDF Page Labels (book page numbers, not physical page order)
L2 OCR path: scanned/photocopied materials → Unlimited-OCR structured recognition (dual backends MLX / GGUF), page number priority: OCR-recognized page_number > PDF Page Label > physical page order
Non-PDF: docx / epub / html / txt / md / xlsx / pptx etc. → anydoc / trafilatura
Search: any OpenAI-compatible embedding service (local mlx-lm / Ollama, or remote platforms like Bailian / OpenRouter) + LanceDB local vector database
OCR Engine and Model Deployment
sovena's OCR pipeline uses Unlimited-OCR (open-sourced by Baidu, MIT license, model weights on HuggingFace baidu/Unlimited-OCR): a document OCR model with DeepSeek-V2 MoE decoder + dual SAM/CLIP vision towers, capable of recognizing multi-page scans in full and restoring titles/tables/layout.
Supports two backends, both producing the same structured output, transparent to downstream conversion:
Backend | How it runs | Supported platforms |
| This repo's | Apple Silicon Mac |
| OpenAI-compatible interface: llama-server / vLLM serving GGUF quantized version | Any platform (Windows / Linux / Intel Mac, pure CPU also works) |
Backend One: MLX (Apple Silicon, default)
Download MLX weights from HuggingFace (LoJexLLM/Unlimited-OCR-MLX):
huggingface-cli download LoJexLLM/Unlimited-OCR-MLX \
--local-dir ~/models/Unlimited-OCR-MLXBy default it lands in sovena's default path (~/models/Unlimited-OCR-MLX), no configuration needed. To place it elsewhere, specify in .env:
SOVENA_OCR_MODEL=/path/to/Unlimited-OCR-MLXBackend Two: GGUF (any computer, including GPU-less Windows/Linux)
Unlimited-OCR has a community GGUF quantized version (HuggingFace sahilchachra/Unlimited-OCR-GGUF, requires downloading the main model such as Unlimited-OCR-Q4_K_M.gguf (~3.2GB) + the vision projector mmproj-Unlimited-OCR-F16.gguf), and you can start a local service with llama.cpp's llama-server:
# 1. 下载模型(二选一)
huggingface-cli download sahilchachra/Unlimited-OCR-GGUF \
Unlimited-OCR-Q4_K_M.gguf mmproj-Unlimited-OCR-F16.gguf --local-dir ./ocr-models
# 国内可用 ModelScope 或镜像加速
# 2. 启动 OpenAI 兼容服务(8080 端口,任意平台;含 GPU 加速则加对应参数)
llama-server -m ocr-models/Unlimited-OCR-Q4_K_M.gguf \
--mmproj ocr-models/mmproj-Unlimited-OCR-F16.gguf \
--host 127.0.0.1 --port 8080
# 3. sovena 侧启用 http 后端(项目根目录 .env)
echo 'SOVENA_OCR_API=http://127.0.0.1:8080/v1' >> .envYou can also use vLLM or any other OpenAI-compatible service that can run this GGUF (if the model name differs, add SOVENA_OCR_MODEL_NAME=...; if there's authentication, add SOVENA_OCR_API_KEY=...). The OCR service can even be deployed on another machine with a GPU, and sovena just fills in its address.
Tip: Q4 quantization is ~3GB, and an ordinary computer with 16GB RAM can run it. sovena calls it on demand (page-by-page requests), without occupying memory inside the sovena process.
Embedding service (required for search) — any OpenAI-compatible /embeddings endpoint works, choose one of two:
Local (recommended, free and private): use mlx-lm (the inference service from Apple's official MLX ecosystem, MIT):
uv tool install mlx-lm # 或 pip install mlx-lm
huggingface-cli download Qwen/Qwen3-Embedding-4B --local-dir ~/models/Qwen3-Embedding-4B
mlx_lm.server --model ~/models/Qwen3-Embedding-4B --port 8080
# 起一个 OpenAI 兼容 /v1/embeddings 服务,即 sovena 的默认地址 http://localhost:8080/v1Other OpenAI-compatible local solutions like Ollama / vLLM work the same way (set SOVENA_EMBED_API if the address differs)
Remote commercial platforms (don't want to run models locally): Alibaba Cloud Bailian / OpenRouter / SiliconFlow etc., just fill in the API address and key in
.env:
# 示例:阿里云百炼(OpenAI 兼容端点)
SOVENA_EMBED_API=https://dashscope.aliyuncs.com/compatible-mode/v1
SOVENA_EMBED_API_KEY=sk-你的密钥
SOVENA_EMBED_MODEL=text-embedding-v4Note: after changing the embedding service/model, the vector dimensions and semantic space will change, and existing indexes need to be rebuilt (sovena will clearly warn when it detects a dimension mismatch; delete the
_lancedbdirectory and re-"prepare" each collection, or check "full rebuild").
Quick Start
Requirements: any computer can deploy; the core flow only needs Python ≥ 3.12 (works on Windows / macOS / Linux). Choose one of two OCR pipelines: Apple Silicon uses the default MLX backend (zero configuration); other platforms (or if you want a GPU server to run OCR) use the GGUF backend (see "Backend Two" above). The whole process is just copy-paste commands.
Step 1: Install uv (Python package manager, one-time)
Open "Terminal" (search "Terminal" in Launchpad), paste:
curl -LsSf https://astral.sh/uv/install.sh | shAfter installation, close the terminal and reopen it (to make the command take effect). Verify: uv --version should print a version number.
Step 2: Install Zotero and keep it running
Download and install Zotero 7+ from zotero.org, import your literature
sovena reads via Zotero's local API (automatically available as long as Zotero is open, no setup needed)
Attachments can be "imported attachments" or "linked attachments", both are supported
Step 3: Prepare model services (embedding required + OCR optional)
Embedding service (required for search), choose one of two:
Local (recommended): mlx-lm (Apple's official MLX ecosystem, MIT) —
uv tool install mlx-lm, download the model and runmlx_lm.server --model <model directory> --port 8080to start the service (full commands in the "Embedding Service" section above). Other OpenAI-compatible solutions like Ollama / vLLM work the same wayRemote platform (don't run models locally): Alibaba Cloud Bailian / OpenRouter etc., create
.envin the project root and fill in the address and key (see the example in the "Embedding Service" section above)
OCR model (only needed for scanned materials, Apple Silicon): download Unlimited-OCR-MLX from HuggingFace to ~/models/Unlimited-OCR-MLX (commands in the "Backend One" section above; sovena loads/releases it on demand)
Non-Apple-Silicon computers doing OCR: switch to the "GGUF backend" — download Unlimited-OCR-GGUF + run llama-server, configuration in the "Backend Two" section above. Just want a quick trial and don't need search yet? The model service can be added later; skip ahead to Steps 4-5.
Step 4: Get sovena and install dependencies
git clone https://github.com/<you>/sovena.git
cd sovena
uv sync # 自动下载全部依赖(首次约 1.3GB,需要几分钟)Non-Apple-Silicon computers (Windows / Linux / Intel Mac): MLX-related dependencies are only used by the MLX OCR backend;
uv syncwill automatically skip them or install CPU-compatible versions on these platforms. Core features — text PDFs, non-PDF document conversion, search — as well as OCR with the GGUF backend, all work normally.
Step 5: One-command startup
uv run sovenaSuccess is indicated by Uvicorn running on http://0.0.0.0:8765. Open <http://localhost:8765 in your browser:>
The dot on the "Performance Monitor" page is green → service is normal
The "Zotero Literature Stream" dropdown shows your collections → Zotero is connected
When done, press Control + C in the terminal to stop. The service does not run persistently or auto-start on boot; heavy operations are serially scheduled internally (OCR concurrency=1, memory guard), so it won't run your computer into the ground.
Step 6 (optional): Personal path configuration
Default data is stored in ~/sovena_data. To put it elsewhere (e.g., an external drive), create a .env file in the project root:
echo 'SOVENA_ROOT=/Volumes/你的盘/sovena_data' > .env.env is git-ignored, so personal paths won't enter the repository.
Step 7: Run your first task
In the Web dashboard "Zotero Literature Stream" → select a small collection (e.g., 5 items) → "Start Preparation" → switch to "Performance Monitor" to watch progress. When done, go to "Semantic Search" and try asking a question.
Common Issues
Symptom | Solution |
| uv from Step 1 wasn't installed properly or the terminal wasn't reopened |
Port already in use | An old service is still running: |
"Zotero connection failed" | Zotero isn't open, or an old version is installed (7.0+ required) |
Search errors/no results | The embedding service isn't running / the key is wrong (local mlx-lm or remote platform), or that collection hasn't been "prepared" yet; if you changed the embedding model, the index needs rebuilding |
OCR model errors | MLX backend: |
Machine fans spinning hard | Normal: OCR tasks are heavy; the model unloads automatically when the task finishes |
Step 8 (optional): AI client integration (works from other computers too)
Any client supporting MCP streamable-http (Claude Desktop, Cherry Studio, Trae, etc.) fills in:
{
"mcpServers": {
"sovena": { "url": "http://localhost:8765/mcp" }
}
}Remote (other computer) deployment: start the server with SOVENA_HOST=0.0.0.0 (default), and the client replaces the URL with http://<server IP or Tailscale hostname>:8765/mcp. The Web dashboard's "Settings" page can copy/download the current deployment's config JSON with one click.
Zotero Plugin (optional)
dist/sovena-plugin-<version>.xpi is a client plugin installable into Zotero 7+ (including 9/10), giving direct access to sovena from within Zotero:
Collection right-click → "sovena: prepare/update semantic package (incremental)"
Item right-click → "sovena: add attachment to adhoc semantic package" (the selected item's local file attachments go through the adhoc flow)
Tools menu sovena → open dashboard / server address settings / copy MCP client config / connection check
Installation: Zotero → Tools → Plugins → gear icon in the top right → Install Plugin From File… → select dist/sovena-plugin-0.1.0.xpi. Defaults to connecting to http://localhost:8765; on other computers, fill in the sovena server address under "Tools → sovena → Server Address…".
To repackage the plugin (after modifying zotero-plugin/):
bash zotero-plugin/build.sh # 产出 dist/sovena-plugin-<version>.xpiEnvironment Variables
All configuration can be set via environment variables; recommended: create a .env file in the project root (git-ignored, suitable for personal paths), automatically loaded when the service starts:
SOVENA_ROOT=/Volumes/your-disk/zotero_AI
SOVENA_ZOTERO_API=http://localhost:23119/apiVariable | Default | Description |
|
| Semantic literature package root directory (recommended to set in |
|
| Zotero local API |
|
| Service listen address |
|
| Service port |
|
| Embedding service address (local mlx-lm/Ollama or remote platform) |
| (empty) | Embedding service key (required for remote commercial platforms) |
|
| Embedding model name |
|
| Vector database directory |
|
| OCR backend: |
|
| MLX backend model directory |
| (empty) | http backend service address (e.g., |
|
| http backend model name |
| (empty) | http backend auth key (if any) |
|
| Memory guard threshold (MB); new tasks are deferred below this |
Usage
Zotero Literature Stream (incremental)
Select a collection in the Web dashboard → "Start Preparation"; or have the AI client call the MCP tool sovena_prepare. Repeated runs are automatically incremental: only new/changed items are processed (Zotero version changes or attachment mtime changes), and the index is added/removed at the item level. Checking "full rebuild" forces a redo.
Adhoc Temporary Materials (any files/folders)
Turn e-book libraries, loose PDFs, lecture notes, etc. into searchable semantic packages:
Web dashboard: fill in paths in the "Adhoc Package" card (multiple separated by newlines or
;) → submit, after which they can be semantically searched together with Zotero collectionsMCP:
sovena_adhoc_process(paths=["/path/to/E_book/某子目录"], name="我的书库")REST:
POST /api/adhoc/submit{"paths": [...], "name": "..."}
Supports pdf/epub/docx/html/txt/md/xlsx/pptx etc.; scanned PDFs automatically go through OCR; also supports incremental processing (skipped if the source file's mtime is unchanged).
MCP Tools Overview
Category | Tools |
Zotero reading |
|
Literature stream |
|
adhoc |
|
Tasks/operations |
|
Note: the Zotero local API is read-only, so no write-operation tools are provided.
Semantic Package Directory Structure
$SOVENA_ROOT/
<分类名>/
_manifest.json # 分类级清单(增量依据)
<作者>_<年份>_<标题>/
meta.json # Zotero 元数据 + 转换统计
content.md # AI 友好 markdown(含【书页页码】标注)
adhoc/
<资料包名>/
_manifest.json
<文件名slug>/
meta.json
content.md
_lancedb/ # 向量库REST API Overview
Method | Path | Description |
GET |
| Zotero categories + adhoc packages and preparation status |
GET |
| Runtime config, system status (memory/CPU/disk/tasks) |
GET |
| Server directory listing (for the Web path picker) |
POST |
| Submit prepare tasks (collection/limit/use_ocr/rebuild) |
POST |
| Submit adhoc tasks (paths/name/use_ocr/recursive) |
GET |
| Task list/details (with logs), POST |
GET |
| Semantic search (can be limited to a collection) |
GET |
| Manifest |
GET |
| Content/metadata |
GET |
| System status, MCP client configuration |
Project Structure
sovena/
main.py # 一键启动入口
sovena/
server.py # 服务总入口(Web + MCP 同进程,自动加载 .env)
web.py / webui.html # Web 监管台(分区 Tab + 路径选择器)
mcp_server.py # MCP 工具集
zotero_collector.py # Zotero 本地 API 采集(附件 4 路解析)
pipeline.py # prepare 流水线(增量)
adhoc.py # 任意资料临时处理
converter.py # L1/L2/anydoc 转换
indexer.py # 分块 + 向量化 + LanceDB
packager.py # 语义包落盘
jobs.py # 任务调度(内存守卫/OCR 并发=1)
zotero-plugin/ # Zotero 客户端插件源码(bootstrap 结构)
dist/ # 构建产物(sovena-plugin-<version>.xpi)
ocr_port/ # Unlimited-OCR-MLX(MLX OCR 引擎)
.env # 本地个人配置(可选,不入库)Acknowledgments
sovena stands on the shoulders of the following projects, and we are deeply grateful:
Unlimited-OCR (Baidu, MIT) — the document OCR model itself; the
ocr_port/code is ported from the MLX implementation in the mlx-vlm community; the MLX weights (in LoJexLLM's organized format) and the GGUF quantized version (sahilchachra) both come from the HuggingFace community; the http backend runs via llama-server from llama.cpp (MIT)cookjohn/zotero-mcp — one of the sources of inspiration for this project
Zotero (AGPL) — the reference management core and local API
PyMuPDF (AGPL) — PDF text extraction and page labels
LanceDB (Apache-2.0) — local vector database
FastMCP (MIT) — MCP service framework
anydoc (firecrawl-anydoc) — conversion of non-PDF documents such as docx/epub
trafilatura (Apache-2.0) — web page main text extraction
mlx-lm (Apple ml-explore, MIT) — local embedding inference service (
mlx_lm.server, OpenAI-compatible API)uv (Astral, MIT) — Python package management
License
MIT © Sovena contributors, Southwest University · Institute of Art Anthropology, Southwest University · Institute of Chinese Music Mental Health; Author: Shi Fengkai (sfklc@hotmail.com)
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables semantic search and conversational querying across a personal research library of PDFs, DOCX, and other documents using a vector database. It provides tools for document summarization, finding related papers, and high-accuracy retrieval for AI clients like Claude Desktop.
- AlicenseAqualityDmaintenanceEnables AI assistants to search, read, and manage Zotero references locally with customizable research workflows.94MIT
- FlicenseNot gradedqualityDmaintenanceEnables semantic search across scientific papers in your Zotero library with hybrid search, incremental indexing, and cross-encoder reranking.
- AlicenseNot gradedqualityDmaintenanceMCP server that connects AI assistants to your Zotero library, enabling full-text PDF extraction and metadata search.MIT
Related MCP Connectors
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sfk8815-create/sovena'
If you have feedback or need assistance with the MCP directory API, please join our Discord server