Skip to main content
Glama

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

uv run sovena single process starts Web dashboard + MCP endpoint

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

mlx (default)

This repo's ocr_port/ (mlx-vlm community MLX implementation)

Apple Silicon Mac

http

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-MLX

By 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-MLX

Backend 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' >> .env

You 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/v1

Other 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-v4

Note: 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 _lancedb directory 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 | sh

After 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 run mlx_lm.server --model <model directory> --port 8080 to start the service (full commands in the "Embedding Service" section above). Other OpenAI-compatible solutions like Ollama / vLLM work the same way

  • Remote platform (don't run models locally): Alibaba Cloud Bailian / OpenRouter etc., create .env in 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 sync will 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 sovena

Success 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: command not found

uv from Step 1 wasn't installed properly or the terminal wasn't reopened

Port already in use

An old service is still running: lsof -ti tcp:8765 | xargs kill then restart

"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: Unlimited-OCR-MLX wasn't downloaded or the path is wrong; http backend: llama-server isn't running or SOVENA_OCR_API is wrong (see section above)

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>.xpi

Environment 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/api

Variable

Default

Description

SOVENA_ROOT

~/sovena_data

Semantic literature package root directory (recommended to set in .env for personal deployments; LanceDB follows by default)

SOVENA_ZOTERO_API

http://localhost:23119/api

Zotero local API

SOVENA_HOST

0.0.0.0

Service listen address

SOVENA_PORT

8765

Service port

SOVENA_EMBED_API

http://localhost:8080/v1

Embedding service address (local mlx-lm/Ollama or remote platform)

SOVENA_EMBED_API_KEY

(empty)

Embedding service key (required for remote commercial platforms)

SOVENA_EMBED_MODEL

text-embedding-qwen3-embedding-4b

Embedding model name

SOVENA_LANCEDB

$SOVENA_ROOT/_lancedb

Vector database directory

SOVENA_OCR_BACKEND

auto

OCR backend: mlx / http / auto (automatically http if SOVENA_OCR_API is set)

SOVENA_OCR_MODEL

~/models/Unlimited-OCR-MLX

MLX backend model directory

SOVENA_OCR_API

(empty)

http backend service address (e.g., http://127.0.0.1:8080/v1)

SOVENA_OCR_MODEL_NAME

Unlimited-OCR

http backend model name

SOVENA_OCR_API_KEY

(empty)

http backend auth key (if any)

SOVENA_MEM_GUARD_MB

12288

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 collections

  • MCP: 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

zotero_collections zotero_search zotero_item zotero_annotations

Literature stream

sovena_prepare sovena_manifest sovena_read_item sovena_search sovena_find_similar

adhoc

sovena_adhoc_process sovena_adhoc_list

Tasks/operations

sovena_job_status sovena_jobs sovena_cancel_job sovena_system_status sovena_doctor

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

/api/collections

Zotero categories + adhoc packages and preparation status

GET

/api/config/api/system

Runtime config, system status (memory/CPU/disk/tasks)

GET

/api/fs/list?path=

Server directory listing (for the Web path picker)

POST

/api/jobs

Submit prepare tasks (collection/limit/use_ocr/rebuild)

POST

/api/adhoc/submit

Submit adhoc tasks (paths/name/use_ocr/recursive)

GET

/api/jobs[/{id}]

Task list/details (with logs), POST /{id}/cancel to cancel

GET

/api/search?q=

Semantic search (can be limited to a collection)

GET

/api/manifest/{collection}/api/adhoc/manifest/{name}

Manifest

GET

/api/item/{collection}/{dir}/content etc.

Content/metadata

GET

/api/system/api/mcp-config

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)

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)

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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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