Skip to main content
Glama

paperloom

CI License: Apache-2.0

Folder-scoped LLM-maintained research wiki. Karpathy's llm-wiki pattern, for scientific papers.

$ mkdir my-research && cd my-research
$ paperloom init
Vault created at /home/you/my-research

$ paperloom ingest ~/Downloads/papers/
Ingesting ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 12/12
12 ingested, 0 skipped, 0 failed (of 12)

$ claude "/contribute the I-JEPA paper"
[Claude Code reads sources/raw/2301.08243/paper.md, drafts a plan,
 writes sources/research/2301.08243-assran-i-jepa.md via the MCP tools]

TL;DR

Paperloom is a small MCP server + CLI that gives a coding agent (Claude Code, Gemini CLI, ...) the file primitives to maintain a personal research wiki out of a folder of markdown files — batch PDF ingest, search, note creation, tagging — while the agent supplies all the actual reading and reasoning. Unlike a generic llm-wiki setup or MindBase's global data folder, a paperloom vault is one self-contained directory (git init && paperloom init and you're done) built around ingesting corpora of 50-1000 papers at once, and it never requires an LLM API key of its own — your host agent already has one.

Related MCP server: OpenLMlib

Credits

Paperloom stands on two shoulders:

  • Andrej Karpathy for the LLM-wiki pattern that this whole project instantiates.

  • Frank Chu's MindBase for proving the pattern could be a product, and for the CLAUDE.md schema conventions we borrow and extend.

Paperloom differs by being folder-scoped (one KB per directory, no global state), batch-ingest-first (built for corpora of 50-1000 papers), and never requiring an LLM API key of its own.

See docs/credits.md for the full story.

Quickstart

Not yet on PyPI — install from source (see Install below), then:

mkdir my-vault && cd my-vault
paperloom init
paperloom ingest ~/Downloads/papers/

paperloom init also creates .mcp.json for you — nothing to configure, it's ready for claude (or ollmcp) immediately.

Then point your coding agent at the vault and start with /contribute or just ask it what's in the wiki. See docs/quickstart.md for the full walkthrough.

What it is / isn't

It is:

  • A set of file-manipulation MCP tools (search, read_page, create_note, ...) plus a CLI for batch PDF ingestion.

  • Folder-scoped — every vault is a self-contained directory, no global state, no daemon.

  • Zero-API-key by design — the host coding agent is the LLM.

  • Built for real corpora — batch ingest, resumable, parallel MinerU jobs, per-paper failure isolation.

It isn't:

  • A web UI. Point Obsidian at the vault if you want one.

  • A vector database or semantic search engine. Ripgrep + agent reasoning covers real usage up to hundreds of papers; see the build spec's non-goals if you're curious why this is deliberate.

  • Its own LLM router. Paperloom never calls an LLM itself, period — not Claude, not GPT, not a local Ollama model. The host agent (claude, ollmcp, ...) is always where the intelligence lives; see Local / offline models.

  • Multi-user, auth'd, or a SaaS. paperloom mcp is stdio-only, one process per client.

Install

Not yet published to PyPI. Clone (or copy) this repo, then install with uv, not plain pip — verified directly: a fresh pip install . genuinely fails with a resolution-too-deep error (pip's resolver can't handle the combined dependency graph of mineru[core] + fastmcp together), while uv pip install . resolves the exact same graph cleanly in a few minutes.

git clone https://github.com/Alpsource/paperloom
cd paperloom

curl -LsSf https://astral.sh/uv/install.sh | sh   # if you don't have uv yet
uv venv
uv pip install .
source .venv/bin/activate

Isolated in its own venv, on purpose — paperloom's dependency stack (PyTorch, transformers, ...) never touches your global Python or any other project's environment. (uv pip install -e . instead of . if you want to hack on paperloom itself — see CONTRIBUTING.md.)

Alternative, equally isolated but no activate step: uv tool install gives each tool its own private venv under the hood too (same model as pipx) — only the command itself lands on PATH, never the underlying packages. uv tool install ./paperloom is a legitimate one-command option if you'd rather skip explicit venv management; both approaches give you the same isolation guarantee, it's a matter of preference.

You also need ripgrep on PATH — it's a system binary, not a pip package:

# Debian/Ubuntu
sudo apt install ripgrep
# macOS
brew install ripgrep
# Fedora
sudo dnf install ripgrep

Optional extra:

uv tool install "./paperloom[grobid]"   # bibliography extraction via GROBID

([dev] — pytest, ruff, mypy, etc. — is for working on paperloom itself, not for using it; see CONTRIBUTING.md for that venv-based flow instead.)

mineru[core] (the actual local PDF parser, pulled in automatically as a core dependency) is heavy — it installs PyTorch, and downloads several GB of model weights the first time it actually parses a PDF. There's no way around this if you want local PDF parsing; budget the disk space and time (and, ideally, a GPU — CPU-only parsing works but is much slower) for that first real paperloom ingest run.

Tested primarily on Linux; Windows works via WSL2 (see the build spec's own notes) but isn't the primary target.

First vault (5 minutes)

mkdir my-research && cd my-research
paperloom init

This copies the scientific-paper-vault template in: CLAUDE.md (the schema — see below), .mcp.json (already configured, nothing to edit), empty context.md/index.md, and the sources//artifacts//logs/ skeleton. It also writes .paperloom/config.yaml and runs git init if you haven't already.

paperloom ingest ~/Downloads/some-papers/

Every PDF gets parsed by MinerU into sources/raw/<paper-id>/paper.md + meta.json. IDs are detected from the arXiv/DOI pattern on the first page when possible, falling back to a content hash. This step never touches sources/research/ — ingestion and wiki-writing are deliberately separate.

Now pick a host agent — both read the exact same vault and .mcp.json, nothing about the steps above changes either way.

Claude Code (CLAUDE.md's default mode: capable):

claude "/contribute sources/raw/2301.08243"
claude "What does my wiki know about JEPA?"

Reads CLAUDE.md, drafts a plan for /contribute (which pages to create, which to update), shows it to you, and on approval writes real wiki pages via the MCP tools — 2-hop [[wikilink]] following, raw-source citation verification, the works. This is the fully validated path: real 20+ paper vaults, real multi-page synthesis answers holding up under scrutiny.

Ollama, fully offline, no editor — flip one line in CLAUDE.md (Current mode: capable → local) first, then:

uv tool install --upgrade ollmcp
ollmcp --servers-json .mcp.json --model qwen3.5:4b

Same tools, same vault — ollmcp is a standalone terminal MCP client (no VSCode/editor needed) that gives a local Ollama model the identical agentic tool-calling loop. local mode's schema asks for single-page focus, shorter searches, and confirmation before every write — real, honest gaps we found testing qwen3.5:4b this way: it reliably finds and reads the right pages, but tends toward long natural-language search queries where ripgrep needs short literal ones, and doesn't always carry [[raw:...]] citations through into its own answers even when told to. See Local / offline models below for the full picture and what to actually expect.

See examples/ml-robotics-vault/ for a fully populated example vault you can browse instead of building one from scratch — it already has real ingested papers and a real built wiki, so either host agent above works against it immediately with no setup.

Architecture

graph LR
    PDF[Original PDF] -->|paperloom ingest, MinerU| RAW
    subgraph RAW["sources/raw/&lt;paper-id&gt;/  (immutable)"]
        direction TB
        R1[paper.pdf]
        R2[paper.md]
        R3[meta.json]
    end
    RAW -->|"/contribute — host agent reads, writes"| RESEARCH
    subgraph RESEARCH["sources/research/  (agent-owned)"]
        direction TB
        W1[paper pages]
        W2[method pages]
        W3[dataset / concept / synthesis pages]
    end
    USER[You] -->|daily notes| CONTRIB["sources/contributors/&lt;you&gt;/"]
    CONTRIB -.->|"/contribute"| RESEARCH

Three layers, three trust levels: sources/raw/ is a faithful, never-edited transcription; sources/research/ is where the agent's actual judgment lives, always citing back to raw/; sources/contributors/ is your own daily log, appended to but never rewritten. See docs/schema.md for the full page-shape reference.

The 10 tools

Tool

Does

search

Full-text search across the vault (ripgrep-backed). Returns paths + snippet + line + score, optionally scoped by path_prefix.

read_page

Read a markdown file's full contents, including frontmatter.

list_pages

List files under a subdir with basic frontmatter (type, tags, title) — fast, no full-body reads.

create_note

Create a new markdown file with YAML frontmatter. Fails if the path exists; refuses to write outside sources/, artifacts/, or logs/.

append_to_page

Append content to an existing page, optionally under a named section. guard controls what happens if the page is marked human_edited: true.

tag_note

Merge or replace a page's frontmatter tags.

log_entry

Append a timestamped line to today's log, or a contributor's daily file.

ingest_pdf

Ingest a single PDF from inside an agent session — the same pipeline as paperloom ingest, supervised subprocess included.

vault_info

Root, config, and file counts for the current vault — a good first call each session.

describe_workflow

Return a step-by-step recipe for /contribute, /ask, /lint, or /rebuild-context — the one accommodation for weaker local models (see Local / offline models); frontier models don't usually need it.

That's the whole list, on purpose — see the build spec for what's deliberately not a core tool (semantic search, auto-linting fixups, multi-user anything) and why.

Plugins

Need a tool beyond the 9? Write a plugin — a Python module exposing register(mcp), loaded from three places (built-in, third-party via pip entry points, or vault-local in .paperloom/plugins/) with the later ones overriding the earlier on a name collision. See docs/plugins.md for the full guide and the reference example_plugin.py (word_count, find_orphans).

Local / offline models

Paperloom never calls an LLM itself — not Claude, not GPT, not a local Ollama model, not anything. The MCP server is 10 file-operation tools; the LLM always lives in your host agent. Want a fully offline, free, still-standalone-terminal setup? Run ollmcp instead of claude — uv tool install --upgrade ollmcp, then ollmcp --servers-json .mcp.json --model qwen3.5:4b from inside your vault. Same .mcp.json, same paperloom, zero code changes on paperloom's side, no editor required. Continue.dev and Cline are the options if you do want VSCode integration instead.

The one accommodation paperloom's schema makes for weaker local models: describe_workflow(operation=...), a tool that returns an explicit step-by-step recipe for any of the four operations, plus a mode: local variant of every workflow baked directly into CLAUDE.md (fewer hops, smaller reads, confirmation before every write). Switching a vault to local mode is a one-line edit in its CLAUDE.md.

See docs/quickstart-local.md for the full host-agent comparison and an honest breakdown of what to expect at each model-quality tier — we're not going to promise a 3B/4B model synthesizes like Sonnet does, and neither should you.

What we actually found testing qwen3.5:4b via ollmcp (real runs, not a guess): tool-calling genuinely works — it autonomously drives search → read_page → answer, the same loop a frontier model uses. Two concrete, reproducible gaps showed up: it defaults to long, natural-language-style search queries where ripgrep needs short literal ones (often takes 2-3 tries to land on a working query), and it doesn't reliably carry [[raw:...]] citations from a page it read into its own answer, even when local mode's instructions explicitly tell it to. Both are now addressed in local mode's schema (mechanical "copy the citation tag verbatim" instructions, guidance to shorten rather than lengthen a failed query) — worth knowing about either way, since it's the honest shape of what a mid-size local model actually does, not what the tier table predicts in the abstract. See tests/qualitative/three_question_eval.md to run the same comparison yourself.

Migrating from MindBase

paperloom migrate-from-mindbase ~/mindbase-data/projects/my-research/

Copies (never moves) sources/raw/, sources/research/, sources/contributors/, context.md, README.md, and logs/ into a new paperloom vault, re-deriving indices from disk rather than trusting MindBase's index.yaml. (v0.2 — not yet built; tracked as §17 item 9 in the build spec.)

Optional: browse your vault visually

Paperloom vaults are plain markdown with [[wikilinks]], so Obsidian works on one out of the box:

  1. Open Obsidian → "Open folder as vault" → your paperloom vault root.

  2. Optionally install the Dataview plugin — the YAML frontmatter is Dataview-queryable.

  3. Ctrl-G for the graph view.

Not required, not depended on — just a happy accident of the file format.

Roadmap

Planned plugins (v0.3+, community-contributable), not core-tool additions:

  • arxiv_watcher — poll arXiv for new papers matching saved queries.

  • marp_export — turn a synthesis page into a Marp slide deck.

  • graph_export — export the [[wikilink]] graph as GraphViz/JSON.

  • citekey_lint — validate \cite{...} references in draft artifacts.

Core (the 10 tools, the CLI, the plugin system, the schema) is considered done as of v0.1 — see CHANGELOG.md.

Contributing

See CONTRIBUTING.md — setup, test commands, and what's pinned by the build spec vs. open for change. Issues and PRs welcome, especially plugins.

License

Apache-2.0.

Citation

@software{paperloom,
  title  = {Paperloom: a folder-scoped, LLM-maintained research wiki},
  author = {{paperloom contributors}},
  year   = {2026},
  url    = {https://github.com/Alpsource/paperloom}
}

Related MCP Connectors

Related MCP Servers