paper-mcp
# paper-mcp
A local, Claude-native [MCP](https://modelcontextprotocol.io) server for searching and reading
arXiv papers. Successor to the Streamlit app in [`paper-distill/`](paper-distill/), rebuilt as a
plain stdio MCP server with first-class Claude Code support.
**No API keys, no secrets, no server-side LLM.** The server only searches arXiv and converts
papers to markdown — Claude (the MCP client) does all summarization and Q&A. Cheap-model
summarization is handled client-side by a bundled Claude Code subagent running on Haiku.
## Requirements
- Python 3.12+
- [uv](https://docs.astral.sh/uv/)
## Setup
```powershell
uv sync
```
That's it. Claude Code picks up the server automatically from the checked-in [`.mcp.json`](.mcp.json)
when you start `claude` in this directory (approve the project-scoped server on first launch).
To register it elsewhere:
```powershell
claude mcp add paper-mcp -- uv run --directory C:\path\to\paper-mcp python -m paper_mcp
```
> The server is started as `python -m paper_mcp` rather than via the `paper-mcp` console
> script: on locked-down Windows machines (AppLocker/WDAC), the generated
> `.venv\Scripts\*.exe` shims may be blocked from executing, while `python.exe` is allowed.
## Tools
| Tool | Description |
|---|---|
| `search_papers(query, categories?, max_results?, sort?)` | Search arXiv (fielded queries `ti:`, `au:`, `abs:` and `AND`/`OR` supported), optional category filter |
| `get_paper(arxiv_id)` | Full metadata + abstract for one paper (accepts IDs, `arXiv:` prefixes, and arxiv.org URLs) |
| `read_paper(arxiv_id, offset?, max_chars?)` | Download + convert the paper to markdown, paginated; also returns `markdown_path` to the cached full text for native Read/Grep |
| `list_categories(prefix?)` | Known arXiv category codes |
| `cache_info()` | Cache location and size |
| `clear_cache(arxiv_id?)` | Delete one paper's cached files, or everything |
## Prompts (slash commands in Claude Code)
- `/mcp__paper-mcp__summarize-paper <id> [paragraphs] [audience]` — audience: High School, Undergraduate, Graduate, PhD
- `/mcp__paper-mcp__ask-paper <id> "<question>"`
## Haiku summarization (Claude Code)
- `/summarize-paper <arxiv-id> [paragraphs] [audience]` runs the bundled
[`paper-summarizer`](.claude/agents/paper-summarizer.md) subagent on **Haiku**, so the full
paper text never enters your main conversation context — only the summary comes back.
## Configuration (optional)
| Env var | Default | Purpose |
|---|---|---|
| `PAPER_MCP_CACHE_DIR` | `%LOCALAPPDATA%\paper-mcp\Cache` | Where PDFs and markdown are cached |
| `PAPER_MCP_MAX_CACHE_BYTES` | 2 GiB | Cache size budget (oldest files evicted first) |
| `PAPER_MCP_LOG_LEVEL` | `INFO` | Log level (logs go to stderr) |
Downloads are capped at 50 MB with a 60 s timeout. Cached paper versions are immutable, so there
is no TTL — the cache is size-bounded instead.
## Development
```powershell
uv run python -m pytest -q # tests (no network needed)
uv run ruff check . # lint
uv run ruff format . # format
```
Manual smoke test against the live server:
```powershell
npx @modelcontextprotocol/inspector uv run python -m paper_mcp
```
TDQS
Scored across 6 tools
Each tool has a clear, distinct purpose: searching, fetching metadata, reading full text, listing categories, and managing cache. There is no overlap or ambiguity between tools.
Tool names follow a mostly consistent verb_noun pattern with underscores (search_papers, get_paper, read_paper, clear_cache). 'cache_info' is slightly inconsistent (could be 'get_cache_info'), but the pattern is still predictable and readable.
With 6 tools, the server is well-scoped for an arXiv paper management client. It covers search, retrieval, reading, and cache management without unnecessary bloat.
The tool surface covers the core workflow: search, fetch metadata, read full text, and manage cache. A direct PDF download tool is missing, but read_paper converts to markdown, so it is not a critical gap.