Skip to main content
Glama
cars3

DigiLIB

by cars3

digilib-mcp

Python MCP Sources Transport Keys License

DigiLIB stands for digital librarian — and this MCP server gives that ability to the agent of choice. Connect it to any MCP-capable agent (Claude Code, Claude Desktop, Codex, Antigravity, Cursor, OpenCode, and more) and that agent becomes a librarian: search academic papers and books across six free sources, and export a cited literature review as LaTeX.

No API keys. No paid services. No frontend. No TeX dependency.

Demo

digilib running in Claude Desktop. The prompt asks for recent papers on retrieval-augmented generation, two books on information retrieval, and a literature review with APA citations. Claude calls search_papers, search_books and export_research_tool, then presents the review as both a PDF and its LaTeX source.

Related MCP server: scholarfetch

Quick start

1. Run it (no install, no keys)

uvx --from git+https://github.com/cars3/digilib-mcp digilib-mcp

uvx fetches and runs the server on demand — nothing to install, nothing to configure. Python 3.10+ (verified on 3.12 and 3.14 with the mcp 2.x SDK). Or run it from a checkout:

git clone https://github.com/cars3/digilib-mcp.git
cd digilib-mcp
python -m venv .venv
source .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python -m digilib_mcp.server

2. Connect your agent

digilib registers as a standard stdio MCP server. Most clients accept:

{
  "mcpServers": {
    "digilib": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/cars3/digilib-mcp", "digilib-mcp"]
    }
  }
}

Claude Code one-liner:

claude mcp add digilib -- uvx --from git+https://github.com/cars3/digilib-mcp digilib-mcp

One-page guides with each agent's exact config file and snippet live in docs/agents/: Claude Code, Claude Desktop, Codex, Antigravity, Cursor, OpenCode, Windsurf, Qwen Code, Kimi, Grok, Copilot CLI, Pi, Hermes, legacy Gemini CLI — and a generic guide for any other MCP client.

3. Ask

"Search the literature on retrieval-augmented generation, pull two books on information retrieval, and export a literature review with APA citations."

The agent calls the tools — and if it supports skills, it follows the bundled digilib skill automatically.

What it exposes

Tools

  • search_papers(keywords, year_from?, year_to?, size?) — OpenAlex + arXiv + Semantic Scholar + Crossref

  • search_books(keywords, size?) — Open Library + Google Books

  • export_research_tool(conversation_summary, literature_recommended, liked_articles?, citation_formats?) — builds and returns the LaTeX source; the calling LLM renders it

Prompt / Resource (system-prompt delivery)

  • digilib_researcher prompt → the DigiLIB persona system prompt

  • digilib://prompts/researcher resource → same, for resource-based clients

search_papers

Argument

Type

Meaning

keywords

list[str]

Key terms, e.g. ["transformer attention"]. Pass 2-5 focused queries — the calling agent writes them

year_from / year_to

int

Restrict by publication year. Applied by OpenAlex and Crossref only

size

int

Results per source per keyword. Default 10, max 40

search_books

Argument

Type

Meaning

keywords

list[str]

Key terms; broader, book-friendly phrasing works best

size

int

Results per source per keyword. Default 10

export_research_tool

Argument

Type

Meaning

conversation_summary

str

Plain-text summary of the conversation, written by the calling LLM

literature_recommended

list[str]

One line per bullet in the Literature Review section. A single multi-line string is also accepted

liked_articles

list[dict]

Citation entries with title, authors, year, link keys (capitalised keys work too)

citation_formats

list[str]

Any of "APA", "Chicago", "MLA"

Both search tools return a numbered plain-text list. The header echoes the queries that were actually sent and how many hits each source contributed.

Paper search results for: transformer attention (per-source hits: openalex=10, arxiv=10, semantic_scholar=9, crossref=10)
1. Attention Is All You Need
   Authors: Ashish Vaswani, Noam Shazeer, ...
   Year: 2017
   Type: preprint | Source: arxiv
   Link: https://arxiv.org/abs/...
   Abstract: The dominant sequence transduction models are based on ...

DOI and Citations are appended to the Type line when a source provides them. Abstracts are trimmed to 300 characters.

How it works

calling agent → writes 2-5 focused search queries
                (the bundled digilib skill guides this)
              → PaperService / BookService fan out concurrently across sources
              → results normalized, deduplicated by title, returned as text
              → the agent synthesizes; can call export_research_tool to get
                the LaTeX source for the whole review

Every query goes to every source, each with a 15-second timeout, and a source that fails simply contributes nothing — the per-source hit counts in the result header show which. Duplicates are matched on lower-cased title, first occurrence wins.

The calling agent is the intelligence here: it writes the queries, reads the results, and does the synthesis. digilib is the librarian's toolkit.

For AI agents

This repository carries native instructions for coding agents:

  • AGENTS.md — the canonical guide, imported by CLAUDE.md, CODEX.md, OPENCODE.md, and KIMI.md

  • .agents/skills/digilib/SKILL.md — the canonical skill, symlinked into .claude/, .antigravitycli/, .grok/, .kimi/, .opencode/, and .qwen/ so every CLI auto-discovers it

  • docs/agents/ — per-agent connection guides

Open this repo in your agent of choice, and it will know how to set digilib up.

Configuration

Set in .env (auto-loaded, gitignored) at the repo root or inside digilib_mcp/ — see .env.example. Every setting is optional: with no configuration at all, all six sources work keyless.

Var

Default

Purpose

DIGILIB_TRANSPORT

stdio

stdio (desktop/CLI clients) or streamable-http

DIGILIB_OPENALEX_EMAIL

(unset)

Optional polite-pool contact for OpenAlex (better rate limits)

DIGILIB_GOOGLE_BOOKS_API_KEY

(unset)

Optional Google Books key for reliable quota

DIGILIB_HOST

0.0.0.0

Bind address, streamable-http only

PORT / DIGILIB_PORT

8000

Bind port, streamable-http only. PORT wins, so hosts that inject it just work

DIGILIB_GATEWAY_TOKEN

(unset)

Shared secret for the HTTP gateway. Set this when hosting publicly — see Securing the gateway

DIGILIB_ALLOWED_HOSTS

(unset)

Comma-separated Host allow-list for the HTTP gateway, e.g. example.com,*.example.com. When unset, the SDK's Host-header check is disabled so the server works behind a reverse proxy (otherwise: 421 Invalid Host header). streamable-http only

The digilib_mcp/ folder is checked for .env first, and real environment variables always win over the file.

Variable names must match exactly. A misspelled name (say DIGILIB_BOOKS_APIKEY instead of DIGILIB_GOOGLE_BOOKS_API_KEY) is silently ignored, and the feature behaves as if the key were never set.

Run

# stdio (default — for desktop and CLI clients)
uv run python -m digilib_mcp.server

# HTTP (for remote agents)
DIGILIB_TRANSPORT=streamable-http uv run python -m digilib_mcp.server

Inside an activated virtualenv, plain python -m digilib_mcp.server works the same way; the installed console script is digilib-mcp. A stdio server run by hand just waits for input; it is meant to be launched by an MCP client.

Exporting research

export_research_tool returns LaTeX source and does not render a PDF. The calling LLM should save it as a .tex file (e.g. digilib_export.tex) and, if pdflatex is available, compile it:

pdflatex -interaction=nonstopmode digilib_export.tex

Without a TeX install, keep the .tex file and compile it anywhere, such as Overleaf.

The document is a 12pt A4 article titled DigiLIB Research Export, with a Literature Review (one bullet per recommended line), a Conversation Summary, and a Citations section with one numbered list per requested format (APA, Chicago, MLA). Special LaTeX characters such as &, % and _ are escaped.

Hosting as an HTTP gateway (Railway / Render / Fly)

Set DIGILIB_TRANSPORT=streamable-http and let the platform inject PORT — the server binds 0.0.0.0 and serves the MCP endpoint at /mcp. The included Procfile (web: python -m digilib_mcp.server) makes Railway zero-config: connect the repo, set the env vars, deploy, generate a domain.

Point a remote MCP client at https://<your-service>.up.railway.app/mcp:

claude mcp add --transport http digilib https://<your-service>.up.railway.app/mcp

…or in .mcp.json:

{
  "mcpServers": {
    "digilib": {
      "type": "http",
      "url": "https://<your-service>.up.railway.app/mcp"
    }
  }
}

Securing the gateway

The streamable-http transport has no built-in authentication. If you host it on a public URL without locking it down, anyone who finds the URL can call the tools. This repo ships a shared-secret bearer gate that fixes that.

1. Generate a token and set it as DIGILIB_GATEWAY_TOKEN:

python -c "import secrets; print(secrets.token_urlsafe(32))"
# e.g. pK7x...long...string

Add it to your hosting env vars (Railway → Variables). When the token is set, the server requires every request to carry Authorization: Bearer <token>; without it, requests get 401.

2. Have clients send the token. In .mcp.json:

{
  "mcpServers": {
    "digilib": {
      "type": "http",
      "url": "https://<your-service>.up.railway.app/mcp",
      "headers": { "Authorization": "Bearer <your-token>" }
    }
  }
}

If DIGILIB_GATEWAY_TOKEN is unset, the server prints a loud warning and runs unauthenticated — fine for local/LAN testing, not for a public URL.

For multi-user or third-party-client access, this shared secret isn't enough — use the MCP SDK's native OAuth 2.1 resource-server support instead (MCPServer(settings=Settings(auth=AuthSettings(...)), token_verifier=...)), which wires up BearerAuthBackend + RequireAuthMiddleware and exposes the OAuth protected-resource metadata endpoints.

Troubleshooting

  • The agent doesn't show digilib. Check your agent's guide in docs/agents/ — the config paths differ per agent, and some need an absolute path to uvx. Most clients only read their config at launch, so restart the agent after editing.

  • A source shows =0 in the result header. Each source fails independently and quietly, so the header is where to look. Semantic Scholar returns 429s without a key, and Google Books shares a small daily quota unless DIGILIB_GOOGLE_BOOKS_API_KEY is set.

  • Google Books stays at 0 even with a key. Check the variable name is exactly DIGILIB_GOOGLE_BOOKS_API_KEY.

  • Results feel thin. Query quality matters — ask for more specific terms, or let the bundled skill guide the agent's query crafting (expand acronyms, add synonyms).

  • 421 Invalid Host header over HTTP. The request's Host isn't allowed. Leave DIGILIB_ALLOWED_HOSTS unset, or add your domain to it.

Sources

Source

Coverage

Key

OpenAlex

All disciplines

none (optional mailto for polite pool)

arXiv

Physics, CS, math, stats preprints

none

Semantic Scholar

All disciplines, citations

none (rate-limited)

Crossref

DOI registry, publisher metadata

none

Open Library

Books

none

Google Books

Books

none (basic search; key optional for quota)

Notes:

  • OpenAlex returns only records that have abstracts, and applies the year filters.

  • arXiv is fetched with requests, because its edge WAF rejects httpx with a 406.

  • Semantic Scholar gets one retry, with backoff, on a 429, and has no year filter.

  • Crossref is limited to journal articles, has JATS markup stripped from abstracts, and applies the year filters.

  • Open Library uses a book's first sentence as the abstract, else its subject tags.

License

MIT — see LICENSE.

Credits

Available Tools

3 tools
export_research_toolA

Build the LaTeX source for a research export (literature review + conversation summary + citations in APA/Chicago/MLA) and return it.

This tool does NOT render a PDF - it returns the raw LaTeX document source. You, the assistant calling this tool, are responsible for rendering it yourself:

  1. Write the returned LaTeX to a .tex file (e.g. digilib_export.tex) in the user's project or Downloads folder.

  2. If pdflatex is available, compile it to PDF with pdflatex -interaction=nonstopmode digilib_export.tex and give the user the path to the resulting PDF.

  3. If pdflatex is NOT available, just save the .tex file and tell the user where it is and how to compile it (e.g. install TeX, or use an online LaTeX compiler such as Overleaf). Always save the .tex file regardless, so the user keeps the source.

Args: conversation_summary: plain-text summary of the conversation, written by the calling LLM. literature_recommended: list of plain-text lines for the Literature Review section (one bullet per line). liked_articles: citation entries, each a dict with title/authors/year/link keys. citation_formats: subset of ["APA", "Chicago", "MLA"].

Returns: The complete LaTeX document source as a string.

NameRequiredDescriptionDefault
liked_articlesNo
citation_formatsNo
conversation_summaryYes
literature_recommendedYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does so well. It explicitly discloses that the tool returns raw LaTeX rather than a rendered PDF, explains the calling agent's responsibility to save and optionally compile the file, and states the exact return type. This is behaviorally transparent beyond what the schema provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the key distinction that it returns LaTeX rather than a PDF, then uses numbered steps and an Args/Returns structure that is easy to scan. It is somewhat long and repeats the instruction to always save the .tex file, but the repetition reinforces an important workflow requirement rather than adding noise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's multi-step workflow, four parameters, lack of annotations, and presence of an output schema, the description is complete enough for an agent to call it correctly. It covers purpose, non-rendering behavior, parameter semantics, return value, and post-call handling instructions. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does: every parameter is documented with meaning and expected format. It explains that conversation_summary is plain text, literature_recommended is a list of bullet lines, liked_articles contains citation dictionaries with title/authors/year/link keys, and citation_formats is a subset of APA, Chicago, and MLA.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action and resource: it builds LaTeX source for a research export containing a literature review, conversation summary, and citations. It also sharply distinguishes what the tool does not do by stating it does not render a PDF. It does not explicitly contrast itself with the sibling search tools, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for producing a research export, and it gives detailed post-call handling instructions for the returned LaTeX. However, it does not state when an agent should choose this tool over alternatives or specify exclusions beyond the PDF-rendering clarification. Usage guidance is therefore adequate but incomplete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_booksA

Search books across Open Library and Google Books.

Args: keywords: key terms; broader, book-friendly phrasing works best. size: results per source per keyword (default 10).

Returns: A numbered plain-text list of deduplicated book results with title, authors, year, source, link, and description per entry.

NameRequiredDescriptionDefault
sizeNo
keywordsYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses the two sources, deduplication, and return format, but omits rate limits, authentication, partial-failure behavior, and whether both sources are always queried.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose and organized into Args and Returns sections. It is appropriately sized with no wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter search tool with an output schema, the description covers invocation and expected return shape well. The main gap is routing guidance against sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains both parameters meaningfully: keywords are key terms with broader phrasing recommended, and size controls results per source per keyword with a default of 10.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: search books across Open Library and Google Books. This clearly distinguishes it from search_papers and export_research_tool by resource and action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives keyword phrasing advice but does not state when to use this tool versus search_papers or export_research_tool. There is no explicit usage context, exclusion, or alternative-routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_papersA

Search academic literature across OpenAlex, arXiv, Semantic Scholar, and Crossref.

Args: keywords: key terms, e.g. ["transformer attention"]. Craft 2-5 focused queries (expand acronyms, add synonyms, use technical phrasing) for the best coverage. year_from: restrict to papers from this year onwards. Applied by OpenAlex and Crossref only. year_to: restrict to papers up to this year. Applied by OpenAlex and Crossref only. size: results per source per keyword (default 10, max 40).

Returns: A numbered plain-text list of deduplicated results with title, authors, year, source, link, and abstract per entry.

NameRequiredDescriptionDefault
sizeNo
year_toNo
keywordsYes
year_fromNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses federated querying across four sources, that year filters are honored only by OpenAlex and Crossref (a real behavioral caveat that changes result interpretation), the per-source-per-keyword semantics of size, and deduplication. It doesn't mention rate limits, latency, authentication, or empty-result behavior, but the core behavioral quirks are surfaced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The one-line purpose sentence is front-loaded, followed by tightly scoped Args and Returns blocks. Every line adds information; nothing is repeated from the schema titles.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-source federated search tool with no annotations, the description covers purpose, per-parameter behavior, source-specific caveats, and return shape. Gaps are minor: no guidance on result volume expectations across four sources or on what happens when a source fails or returns nothing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and it does: every parameter is explained with meaning beyond its name, including an example value for keywords, the source-specific applicability of year_from/year_to, and the default and maximum for size. An agent could call this correctly from the description alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (search academic literature) and enumerates the four upstream sources (OpenAlex, arXiv, Semantic Scholar, Crossref), which immediately distinguishes it from the sibling search_books. An agent can tell exactly what domain this tool covers without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete query-crafting advice: 2-5 focused queries, expand acronyms, add synonyms, use technical phrasing. This is actionable usage guidance rather than mere documentation. It does not state when NOT to use it (e.g. books vs papers vs export), so it falls short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedexport_research_tool
    • First observedsearch_books
    • First observedsearch_papers

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation5/5

search_papers and search_books target clearly distinct resource types, and export_research_tool is a separate export action. No two tools overlap in purpose.

Naming Consistency4/5

All tools use snake_case with a leading verb, giving a predictable pattern. export_research_tool adds a slightly redundant '_tool' suffix, a minor deviation from the parallel search_* names.

Tool Count5/5

Three tools map directly to the server's focused workflow: search papers, search books, and export research. Each tool earns its place and the set is tight rather than thin.

Completeness4/5

The core workflow from literature and book search to LaTeX export is covered. Minor gaps exist around dedicated citation lookup, BibTeX export, or full-text retrieval, but search results supply metadata and export handles the output need.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP agents to search academic literature across multiple scholarly engines, explore papers, authors, and references, inspect abstracts and full text, maintain saved paper collections, and export citations, BibTeX, abstracts, or full-text corpora.
    1
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to search 1m+ open-access papers, standards, textbooks, and legal documents, resolve identifiers such as RFCs, DOIs, and legal citations, download PDFs, and retrieve citations and metadata through MCP tools.
    9
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to conduct literature reviews by screening multiple academic databases, performing backward and forward citation snowballing, and resolving or downloading full-text PDFs through subscription and open-access sources.
    MIT