Model Context Protocol server for Paperless-ngx 3.x — full REST API coverage, schema-aware, token-frugal.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add mcp-paperless-ngx -- npx -y mcp-paperless-ngx{
"mcpServers": {
"mcp-paperless-ngx": {
"command": "npx",
"args": ["-y", "mcp-paperless-ngx"],
"env": {
"PAPERLESS_URL": "<paperless_url>",
"PAPERLESS_TOKEN": "<paperless_token>"
}
}
}
}PAPERLESS_URLPAPERLESS_TOKENMCP Servers overview
<p align="center">
<img src="docs/logo.png" alt="eichner.cloud" width="360">
</p>
<h1 align="center">mcp-paperless-ngx</h1>
<p align="center">
A <a href="https://modelcontextprotocol.io/">Model Context Protocol</a> server for
<a href="https://docs.paperless-ngx.com/">Paperless-ngx</a> <strong>3.x</strong><br>
<em>Full REST API coverage, schema-aware, token-frugal.</em>
</p>
<p align="center">
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-0e94ff?style=flat-square"></a>
<img alt="Node 20+" src="https://img.shields.io/badge/node-%3E%3D20-0e94ff?style=flat-square">
<img alt="Paperless-ngx 3.x" src="https://img.shields.io/badge/paperless--ngx-3.x-0e94ff?style=flat-square">
<img alt="REST API v10" src="https://img.shields.io/badge/REST%20API-v10-0e94ff?style=flat-square">
<img alt="Endpoint coverage 92/92" src="https://img.shields.io/badge/endpoints-92%2F92%20accounted-0e94ff?style=flat-square">
</p>
---
Built against REST API **version 10**, with three things it does differently:
- **Accounted coverage.** Every one of the 92 documented endpoints is either exposed as a tool or
listed in [`src/tools/coverage.ts`](src/tools/coverage.ts) with a written reason for leaving it
out. A test enforces this, so a Paperless release that adds an endpoint fails CI instead of
quietly going unsupported.
- **Token discipline.** A Paperless document carries its full OCR text. Naive wrappers return it by
default and a single search can exhaust the model's context. Here, list results are trimmed
server-side via `?fields=`, the text lives behind its own paginated tool, and no list endpoint
hands the raw API response through — a test enforces that. See [Context cost](#context-cost).
- **Scoped surface.** 99 tools would drown a model's tool list. Toolsets let you expose only what a
given client needs, and `--read-only` removes every write path entirely.
Paperless-ngx 2.x is not supported: API version 10 introduced endpoints (nested tags, document
versions, `share_link_bundles`, the split PDF operations) that this server assumes exist.
## Quick start
```bash
npx -y mcp-paperless-ngx --check # verify connectivity, then exit
```
### Claude Code
```bash
claude mcp add paperless --scope user \
--env PAPERLESS_URL=https://paperless.example.com \
--env PAPERLESS_TOKEN=your-api-token \
-- npx -y mcp-paperless-ngx
```
### Claude Desktop, Cursor, Cline, and other MCP clients
```json
{
"mcpServers": {
"paperless": {
"command": "npx",
"args": ["-y", "mcp-paperless-ngx"],
"env": {
"PAPERLESS_URL": "https://paperless.example.com",
"PAPERLESS_TOKEN": "your-api-token"
}
}
}
}
```
### Getting an API token
Paperless web UI → your username (top right) → **My Profile** → the circular arrow button next to
the API token field.
## Configuration
| Variable | Required | Default | Purpose |
|---|---|---|---|
| `PAPERLESS_URL` | yes | — | Base URL the server talks to. |
| `PAPERLESS_TOKEN` | yes | — | API token. `PAPERLESS_API_KEY` also works. |
| `PAPERLESS_PUBLIC_URL` | no | `PAPERLESS_URL` | URL used when building links for the user, if the instance is reachable under a different name from outside. |
| `PAPERLESS_TOOLSETS` | no | see below | Comma-separated toolsets, or `all`. |
| `PAPERLESS_READ_ONLY` | no | `false` | Expose only tools that cannot change anything. |
| `PAPERLESS_HEADERS` | no | — | Extra request headers, as JSON (`{"X-Auth":"…"}`) or `Name: value, Name: value`. Needed behind forward-auth proxies such as Authentik or Authelia. |
| `PAPERLESS_DOWNLOAD_DIR` | no | system temp | Where downloaded files are written. |
| `PAPERLESS_MAX_PAGE_SIZE` | no | `100` | Hard ceiling on list page sizes, whatever the model asks for. |
| `PAPERLESS_TIMEOUT_MS` | no | `60000` | Request timeout. |
| `PAPERLESS_API_VERSION` | no | `10` | REST API version sent in the `Accept` header. |
CLI flags `--url`, `--token`, `--public-url`, `--toolsets` and `--read-only` override the
environment. `--check` verifies connectivity, `--list-tools` prints the enabled tools.
## Toolsets
| Toolset | Default | Contents |
|---|---|---|
| `documents` | on | Search, read, update, delete, upload, download, notes, bulk and PDF operations |
| `metadata` | on | Tags, correspondents, document types, storage paths |
| `customfields` | on | Custom field definitions |
| `views` | on | Saved views |
| `sharing` | on | Share links and share link bundles |
| `workflows` | on | Automation rules, triggers, actions |
| `system` | on | Global search, statistics, status, tasks, trash |
| `mail` | **off** | IMAP accounts, mail rules, processed mail |
| `admin` | **off** | Users, groups, profile, configuration, logs (read-only) |
`mail` and `admin` are off by default because most sessions never need them and every extra tool
costs context on every request. Enable them explicitly:
```bash
PAPERLESS_TOOLSETS=documents,metadata,system,mail
PAPERLESS_TOOLSETS=all
```
## Context cost
Wrapping an API for a language model has a cost the API itself does not: everything the model sees
is paid for on every request. Two places where that bites, and what this server does about them.
**Responses.** Three shapes are expensive in Paperless and easy to return by accident:
| Source | Problem | Handling |
|---|---|---|
| Document lists | Every document carries its full OCR text in `content` | `?fields=` restricts the response server-side; `get_document_content` paginates the text separately |
| `/api/search/` | Returns hydrated `Document` objects, OCR text included, across all object types | Documents are summarised, other types reduced to id + name |
| Workflows, mail rules, groups, tasks | 27–34 fields per object, nested trigger/action definitions inline | Summarised to identifying fields; nested lists collapse to counts. `full: true` returns everything |
**Tool definitions.** These are the larger and less obvious cost: names, descriptions and JSON
schemas ship with *every* request, whether or not any tool is called.
| Toolsets | Tools | Approximate cost per request |
|---|---|---|
| `all` | 99 | ~20,500 tokens |
| default | 85 | ~18,500 tokens |
| `documents,metadata` | 49 | ~12,900 tokens |
There is no way to make that free — it is the price of a tool the model can use without guessing.
But it is worth being deliberate: if your sessions only ever search and file documents, running
`PAPERLESS_TOOLSETS=documents,metadata` saves more context than any response-trimming does.
## Safety
The server exposes destructive operations, because a document manager without them is not much of a
manager. It does not try to guess when they are appropriate — that judgment belongs to the client
and the user. What it does instead:
- Destructive tools are annotated `destructiveHint: true`, so MCP clients can require confirmation.
- Tool descriptions state plainly what cannot be undone (`empty_trash`, `delete_custom_field`,
`delete_originals`) and ask for confirmation before the call.
- `--read-only` removes every write tool from the list, rather than refusing them at call time.
- Bulk endpoints support an "apply to everything matching this filter" mode. This server does
**not** expose it: bulk tools take explicit ID lists, so a wrong filter cannot silently affect the
entire archive.
- `create_share_link` produces a publicly reachable URL. Its description says so, and the
`audit_sharing` prompt exists to review what is already exposed.
Credential-adjacent endpoints (token generation, TOTP enrolment, disabling someone's second factor)
are deliberately not exposed. See `EXCLUDED_ENDPOINTS` for the full list and the reasoning.
## Prompts
Registered as slash commands in clients that support MCP prompts:
| Prompt | What it does |
|---|---|
| `triage_inbox` | Walks untriaged documents, proposes metadata preferring existing entries, applies nothing until the user approves. |
| `find_document` | Locates a document from a vague description, searching cheaply before searching broadly. |
| `audit_sharing` | Reviews every public share link and flags the ones that never expire. |
## Testing
Three layers, because they catch different things:
```bash
npm test # logic — no network
PAPERLESS_URL=… PAPERLESS_TOKEN=… \
node scripts/smoke-test.mjs # all 55 read-only tools, live
PAPERLESS_URL=… PAPERLESS_TOKEN=… \
node scripts/write-test.mjs # writes, live — see the warning
```
`npm test` checks this server's own reasoning: endpoint coverage, enum values
against the schema, that no list tool leaks raw API objects, that read-only mode
really removes writes.
`smoke-test.mjs` checks the assumptions it makes about Paperless. It calls every
read-only tool against a real instance, resolving IDs from list calls instead of
hard-coding them, and prints response sizes so expensive tools stay visible. It
writes nothing.
`write-test.mjs` covers the rest: upload and consumption, updating every field
type, notes, bulk tag edits, share links, rotation, and a trash round trip.
> **It only touches objects it creates itself.** Everything it makes is named
> with a `zz-mcp-test` prefix and deleted again at the end, and it never modifies
> a document it did not upload. If a run is interrupted, leftovers with that
> prefix are safe to delete. Prefer a test instance if you have one.
## Keeping up with Paperless
```bash
PAPERLESS_URL=… PAPERLESS_TOKEN=… node scripts/sync-schema.mjs
npm test
```
`sync-schema.mjs` regenerates `schema/endpoints.json` from your own instance's OpenAPI document.
The test suite then reports any endpoint that is neither exposed nor explicitly excluded. That is
the whole maintenance loop: point it at a newer Paperless and the test tells you what changed.
## Development
```bash
npm install
npm start # run from source
npm run build # compile to build/
npm test # unit tests What people ask about mcp-paperless-ngx
What is tobee89/mcp-paperless-ngx?
+
tobee89/mcp-paperless-ngx is mcp servers for the Claude AI ecosystem. Model Context Protocol server for Paperless-ngx 3.x — full REST API coverage, schema-aware, token-frugal. It has 0 GitHub stars and its last recorded update is dated 2026-08-20.
How do I install mcp-paperless-ngx?
+
You can install mcp-paperless-ngx by cloning the repository (https://github.com/tobee89/mcp-paperless-ngx) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is tobee89/mcp-paperless-ngx safe to use?
+
Our security agent has analyzed tobee89/mcp-paperless-ngx and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains tobee89/mcp-paperless-ngx?
+
tobee89/mcp-paperless-ngx is maintained by tobee89. The last recorded GitHub activity is dated 2026-08-20, with 0 open issues.
Are there alternatives to mcp-paperless-ngx?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy mcp-paperless-ngx to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/tobee89-mcp-paperless-ngx)<a href="https://claudewave.com/repo/tobee89-mcp-paperless-ngx"><img src="https://claudewave.com/api/badge/tobee89-mcp-paperless-ngx" alt="Featured on ClaudeWave: tobee89/mcp-paperless-ngx" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!