Skip to content

Latest commit

Β 

History

95 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“š OpenWebUI Academic Paper Search & Knowledge Base Integration

One prompt β†’ 18+ academic databases β†’ full text β†’ your RAG Knowledge Base. Multi-source academic paper search, full-text reading, and automatic PDF ingestion into OpenWebUI Knowledge Base (RAG) β€” powered by the self-hosted papers-service (papers_service_url valve), with direct zhihuiya (ζ™Ίζ…§θŠ½) literature/patent and IEEE Xplore integration.

License: MIT OpenWebUI Backend


🌟 Features

  • πŸ” Multi-Source Concurrent Search: Aggregate & de-duplicate results across 16+ open academic platforms (arXiv, PubMed, Semantic Scholar, OpenAlex, CORE…) β€” plus zhihuiya (ζ™Ίζ…§θŠ½), a premium scientific-literature MCP source enabled by apikey.
  • πŸ“– Full-Text Reading: Instant full-text for Open Access platforms, automatic PDF-parsing fallback, and metadata-level reads (abstract + bibliographic record) for index-only sources.
  • πŸ“₯ Automated Knowledge Base Ingestion: Download papers and auto-upload & index them into OpenWebUI Knowledge Base for RAG citation and retrieval.
  • πŸ”„ Built-in OA Fallback Chain: Source-native download βž” Open Access Repositories (OpenAIRE / CORE / Europe PMC / PMC) βž” Unpaywall βž” (Optional) Sci-Hub mirror.
  • πŸ”‘ Key-gated sources (auto-on/off): zhihuiya literature + patents and IEEE Xplore are enabled automatically when their apikey is set and skipped silently when not β€” no source list changes needed.
  • πŸ› Patent Search & Full-Text (patsnap): First-ever patent source β€” semantic patent search (search_patents) plus full claims + description + legal status as Markdown (read_patent). Shares the same zhihuiya apikey, also direct-connected.
  • πŸ”¬ IEEE Xplore: Direct REST API search (bypasses backend skeleton). Metadata-level results with abstract + citation count; OA papers include pdf_url.
  • 🎯 Smart Query Adaptation: Automatically adapts your query per source β€” semantic sources (OpenAlex, Semantic Scholar, PubMed…) get the full natural-language query, while literal keyword sources (zhihuiya, DOAJ, IACR) get a cleaned core-keyword variant (quotes/boolean/noise stripped, then distilled to ≀5 high-specificity terms). Recovers hits that would otherwise return zero, without losing semantics.
  • πŸ‡«πŸ‡· HAL via Direct Connect: HAL is queried directly (bypassing a backend date-parsing bug) so it reliably returns results.
  • πŸ—„ dblp & Zenodo via Direct Connect: dblp (CS bibliography) and Zenodo (OA repository) are queried directly, bypassing backend bugs (concurrency ConnectionError, isoformat crash). Zenodo records often include direct PDF links.

πŸ› Architecture (v2.9.8)

[User / OpenWebUI UI]
        β”‚
        └── OpenWebUI Native Python Tool (tool.py β€” dispatch, query adaptation, merge & dedup)
                 β”‚
                 β”œβ”€β”€ search_papers()
                 β”‚     β”‚
                 β”‚     β”œβ”€β–Ί Direct REST/HTTP (no backend): arxiv, hal, pubmed, pmc, semantic,
                 β”‚     β”‚    openalex, crossref, europepmc, core, zenodo, openaire, ieee,
                 β”‚     β”‚    biorxiv/medrxiv (subject browse), iacr (HTML regex)
                 β”‚     β”‚
                 β”‚     β”œβ”€β–Ί Direct MCP (streamable-http, zhihuiya_apikey): zhihuiya, patsnap
                 β”‚     β”‚
                 β”‚     β”œβ”€β–Ί Via firecrawl/tavily (configured base URLs):
                 β”‚     β”‚    Β· firecrawl as a standalone web-search source
                 β”‚     β”‚    Β· google_scholar chain: firecrawl scrape β†’ tavily extract(advanced)
                 β”‚     β”‚      β†’ Apify actor (johnvc/google-scholar-api) β†’ backend (last resort)
                 β”‚     β”‚    Β· dblp Anubis anti-bot fallback β†’ firecrawl (headless solves JS PoW)
                 β”‚     β”‚
                 β”‚     └─► papers-service (self-hosted FastAPI, papers_service_url valve;
                 β”‚          mirrors the retired mcpo/paper-search-mcp endpoint shapes):
                 β”‚          search safety net (doaj, scholar chain backend);
                 β”‚          ssrn/base/citeseerx/acm unimplemented (off by default)
                 β”‚
                 β”œβ”€β”€ read_paper() ──► papers-service read tools (fast lane: 12 sources β€”
                 β”‚                     arxiv/semantic/hal/pubmed/crossref/biorxiv full text…)
                 β”‚                     β†’ 404 β†’ pdf_url direct β†’ jina reader fallback
                 β”‚
                 β”œβ”€β”€ search_patents() / read_patent() ──► patsnap MCP (direct, streamable-http)
                 β”‚
                 └── download_paper_to_knowledge()
                        β”œβ”€β–Ί [1] direct pdf_url download (+ title identity gate)
                        └─► [2] papers-service download_with_fallback (in-memory bytes):
                                  native (arxiv/iacr/biorxiv) β†’ OA repos (openaire/core/
                                  europepmc/pmc) β†’ Unpaywall β†’ optional Sci-Hub,
                                  every step title-gated β†’ OWUI /api/v1/files β†’ RAG
                                  (no shared volume needed since v2.9.7)

Why the papers backend is only a safety net: every source with a healthy public API was moved to direct connect (v2.9 series) β€” the original paper-search-mcp's synchronous requests without timeouts once hung whole search batches, its scholar/ssrn/base adapters hit anti-bot walls, and its OR-query semantics returned irrelevant papers. papers-service keeps the same valve-driven safety net (doaj, the scholar chain's last resort) plus a real full-text read lane (12 sources) and the OA download chain; ssrn/base/citeseerx/acm remain unimplemented upstream.


πŸ“Š Supported Data Sources

Verified Active Sources

default_sources = "arxiv,pubmed,semantic,crossref,openalex,pmc,core,europepmc,dblp,openaire,doaj,hal,zenodo,google_scholar,zhihuiya,ieee,firecrawl"

Platform Search Read Tool Native Download Notes
arXiv βœ… (direct) read_arxiv_paper βœ… Open PDF, fast & reliable
PubMed βœ… ⚠️ metadata only ❌ Requires NCBI_API_KEY for rate limits
Semantic Scholar βœ… (direct) read_semantic_paper βœ… (OA) Optional semantic_api_key valve (anonymous shared pool 429s often)
Crossref βœ… (direct) ⚠️ metadata only ❌ Citation & DOI backbone
OpenAlex βœ… (direct) ⚠️ metadata only ❌ Open metadata backbone
PMC / Europe PMC βœ… ⚠️ Fallback to PDF βœ… (OA) High-quality biomedical full-text
CORE βœ… (direct) ⚠️ Fallback to PDF βœ… (OA) Global repository aggregator; optional core_api_key valve
IACR βœ… (direct) read_iacr_paper βœ… Cryptography ePrints; direct HTML parsing (no JSON API exists)
HAL βœ… (direct) ⚠️ Fallback to PDF βœ… (OA) Direct-connected (bypasses a backend date bug)
OpenAIRE / DOAJ βœ… Varies / Fallback Record-dependent Domain repositories
dblp βœ… (direct) ⚠️ ee/DOI β†’ OA fallback Record-dependent CS bibliography (CS papers only); direct-connected (bypasses backend concurrency bug)
Zenodo βœ… (direct) ⚠️ pdf_url fallback βœ… (mostly OA) OA repository; direct-connected (bypasses backend isoformat bug); most records have PDFs

Key-gated Sources (auto-enabled when key is set, auto-skipped when not)

Platform Search Read Tool Notes
zhihuiya (ζ™Ίζ…§θŠ½) βœ… search_literature ⚠️ metadata via literature_bibliography Scientific-literature MCP, direct streamable-http. Enabled when zhihuiya_apikey (admin or user) is non-empty; skipped silently when no key
patsnap (ζ™Ίζ…§θŠ½δΈ“εˆ©) βœ… patsnap_search βœ… full text via patsnap_fetch Patent MCP (same key as zhihuiya). read_patent returns claims + description + legal status as Markdown
IEEE Xplore βœ… REST API ⚠️ pdf_url (OA only) Direct REST API. Enabled when ieee_apikey is non-empty; skipped silently when no key. Metadata-level (abstract+bibliographic); OA papers have pdf_url
Google Scholar (fallback chain) βœ… firecrawl β†’ tavily β†’ Apify actor ❌ (use url) Tier 1: firecrawl_base_url (e.g. mcpo β†’ official firecrawl cloud) β€” scrapes the Scholar result page via stealth cloud egress, parses titles/authors/year/citations/PDF links from markdown. Tier 2: tavily_base_url β€” /extract with extract_depth=advanced (basic only returns bare titles). Tier 3: apify_rotator_base_url β€” the johnvc/google-scholar-api actor through the rotator's key pool (PAY_PER_EVENT; free tier works with reduced counts). None configured β†’ scholar stays on the backend (anti-bot prone)

Sources NOT in default (grouped by keyword-search capability)

Source Keyword search Why not default
bioRxiv / medRxiv ❌ (subject-category browse) Return latest ~30 days in a subject, not keyword search β€” would inject irrelevant results. Use explicitly via sources="biorxiv" + biorxiv_category
Google Scholar βœ… Anti-bot 403 without help β€” set firecrawl_base_url (tier 1), tavily_base_url (tier 2) and/or apify_rotator_base_url (tier 3); see Key-gated Sources
SSRN βœ… Search endpoints retired (soft-404/empty) + Cloudflare interactive challenge on api.ssrn.com (2026-09 verified). Backend silently returns 0. Marginal value for bio/CS (overlaps bioRxiv/medRxiv/arXiv) β€” not worth fixing
BASE βœ… Anubis JS-PoW anti-bot (same family as dblp). firecrawl with waitForβ‰₯12s penetrates (verified 2026-09) β€” fixable, but heavy overlap with OpenAlex/CORE/OpenAIRE makes it low priority
CiteSeerX βœ… (code) Endpoint dead (redirects to archive.org 404)
ACM ⚠️ skeleton search is not yet implemented, no public REST API
Unpaywall ❌ DOI lookup only β€” used in the download fallback chain to find OA PDFs, not a search source

🎯 Query Adaptation (per-source)

Different sources have very different query tolerances. search_papers automatically picks the right query shape per source β€” no configuration needed:

Source class Sources Query sent
Semantic / tokenizing openalex, semantic, crossref, pmc, europepmc, pubmed, openaire, core, patsnap Your original full natural-language query (semantics preserved)
Literal keyword zhihuiya, doaj A cleaned core-keyword variant β€” quotes, bare OR/AND/NOT, and filler words stripped, then distilled to ≀5 high-specificity terms
Direct (bypasses backend) hal, zhihuiya, patsnap, dblp, zenodo, ieee, pubmed, pmc, arxiv, semantic, openalex, crossref, europepmc, core, biorxiv, medrxiv, iacr (+ google_scholar when any of firecrawl/tavily/apify valves set) hal/arxiv use core; zhihuiya uses distilled; the rest use original. The papers-service backend serves the search safety net (doaj, google_scholar chain) β€” paper-search-mcp is retired

bioRxiv / medRxiv are not keyword search β€” they return the latest ~30 days of papers in a subject category, so they're excluded from default_sources (a keyword query would inject irrelevant results). To browse a subject's new papers, call explicitly: sources="biorxiv" + biorxiv_category="biochemistry" (or medrxiv_category="cardiovascular_medicine").


πŸš€ Setup & Installation

1. Backend: papers-service

The retired mcpo + paper-search-mcp backend is replaced by a self-hosted papers-service (FastAPI, port 3200) that mirrors the same endpoint shapes (search_{source} / read_{source}_paper / download_with_fallback). Reference deployment lives in the firecrawl-portainer branch (source + GH Actions image build + digest-pinned compose). Point the tool at it:

services:
  papers-service:
    image: ghcr.io/xyonium/firecrawl-papers-service  # digest-pinned in production
    environment:
      SEMANTIC_SCHOLAR_API_KEY: "s2k-xxx"   # optional, higher S2 quota
      UNPAYWALL_EMAIL: "your_email@example.com"
    networks: [open-webui]

Since v2.9.7 downloads are streamed as in-memory bytes β€” no shared Docker volume between the backend and open-webui is needed anymore.

2. OpenWebUI Tool Configuration

  1. Open OpenWebUI -> Workspace -> Tools.
  2. Create a new Tool and copy the contents of tool.py.
  3. Save the tool and optionally configure the Valves / UserValves:
    • papers_service_url: papers-service base URL (default http://papers-service:3200/papers).
    • knowledge_id: Default Knowledge Base ID to automatically store downloaded papers.
    • allow_scihub: Set to True / False for Sci-Hub fallback.
    • scihub_url: Custom Sci-Hub mirror URL (e.g. https://sci-hub.ee).

3. (Optional) Enable Key-gated Sources

Key-gated sources are enabled automatically when their key is set and skipped silently when not β€” no need to add them to default_sources.

zhihuiya (ζ™Ίζ…§θŠ½) + patsnap:

  • Set Valves.zhihuiya_apikey (admin, company-wide) or UserValves.zhihuiya_apikey (per-user, overrides admin)
  • Enables both zhihuiya (literature) in search_papers and search_patents/read_patent (patent tools)

IEEE Xplore:

  • Set Valves.ieee_apikey (admin) or UserValves.ieee_apikey (per-user, overrides admin)
  • Enables ieee in search_papers when key is present
  • Get a free key at developer.ieee.org

πŸ›  Usage in OpenWebUI

Once installed, OpenWebUI models can call the following tools:

  1. search_papers(query, sources, max_results_per_source)
    Searches papers concurrently across sources and returns formatted metadata with DOI & PDF links.

    • Key-gated sources (zhihuiya, ieee) are auto-enabled when their key is set, auto-skipped otherwise β€” no need to list them in sources or default_sources.
  2. read_paper(source, paper_id, pdf_url)
    Reads the full text of a target paper (with automatic PDF fallback).

  3. download_paper_to_knowledge(title, source, paper_id, doi, pdf_url)
    Downloads the paper via direct URL or OA fallback chain, uploads it to OpenWebUI, and links it directly into your RAG Knowledge Base.

  4. search_patents(query, limit, sort, filters) (requires zhihuiya_apikey)
    Semantic patent search β€” returns patent_number / title / IPC / legal_status / dates / assignees / cited_count.

  5. read_patent(patent_number, max_chars) (requires zhihuiya_apikey)
    Reads a patent's full text as Markdown β€” bibliographic data, claims, description, and legal status.


πŸ§ͺ Testing

Offline unit tests (mocked HTTP, no network):

python3 -m pytest tests/ -q

Per-source live smoke test β€” tells network/rate-limit/anti-bot problems apart from code bugs:

python3 scripts/live_sources.py            # all key-free sources
python3 scripts/live_sources.py hal dblp   # specific sources only
SEMANTIC_API_KEY=... IEEE_APIKEY=... CORE_API_KEY=... ZENODO_ACCESS_TOKEN=... \
    python3 scripts/live_sources.py        # include key-gated sources

Each source is queried with a known-stable term; the report shows PASS/FAIL/EMPTY + hit count + latency. FAIL containing 429 = rate limit (configure a key or retry later), 504/timeout = transient network, 反爬/非 JSON = IP blocked by anti-bot (e.g. dblp's Anubis challenge) β€” none of these are code bugs.


πŸ™ Acknowledgments & Credits

Special thanks to the open-source projects that make this integration possible:

  • paper-search-mcp: The original MCP backend (now retired from this stack); its OA download chain design lives on in papers-service download_with_fallback.
  • mcpo: The OpenAPI-to-MCP bridge β€” still hosting the firecrawl gateway in this stack.
  • OpenWebUI: The open-source AI user interface and RAG ecosystem.
  • zhihuiya (ζ™Ίζ…§θŠ½): Premium scientific-literature data, connected via its streamable-http MCP endpoint.

πŸ“œ License

Distributed under the MIT License.

About

πŸ” Multi-source academic paper & patent search/read/download for OpenWebUI β€” 18+ open platforms via mcpo + zhihuiya (ζ™Ίζ…§θŠ½) literature & patsnap patents, OA fallback chain & one-click RAG Knowledge ingestion

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages