Skip to main content

paperless-mcp

CI Secret scan Release Python License

An authenticated Model Context Protocol server that exposes a Paperless-ngx instance over streamable HTTP with static bearer-token authentication, built with FastMCP.

Use it to: search and read archived documents, inspect Paperless metadata, download files, update document properties, and upload new documents from any HTTP-capable MCP client.

Why Paperless MCP?

  • Useful document access: eight focused tools cover retrieval, metadata, downloads, updates, and ingestion.
  • Read-only mode: one environment variable disables every mutating tool.
  • Authenticated transport: every MCP request requires a dedicated bearer token independent from the Paperless API token.
  • Self-hosted deployment: runs beside Paperless-ngx or on another private Linux host with the included systemd unit.
  • No live-instance tests: the test suite uses mocked HTTP requests and never needs access to real documents.

[!IMPORTANT] Start with PAPERLESS_READ_ONLY=1 unless clients need to update metadata or upload documents. This server is intended for trusted private networks. The built-in static token authentication is not sufficient public-internet hardening by itself.

Quick Start

Requirements: Python 3.11 or newer, a reachable Paperless-ngx instance, and uv.

The package is published on PyPI as trsdn-paperless-mcp; the command it installs is paperless-mcp and the import name is paperless_mcp.

export PAPERLESS_URL=http://127.0.0.1:8000
export PAPERLESS_TOKEN=your-paperless-api-token
export PAPERLESS_MCP_TOKEN="$(openssl rand -hex 32)"
export PAPERLESS_READ_ONLY=1

uvx --from trsdn-paperless-mcp paperless-mcp

Alternatively install it permanently:

pip install trsdn-paperless-mcp
paperless-mcp          # or: python -m paperless_mcp

To run from a checkout instead:

git clone https://github.com/trsdn/paperless-mcp.git
cd paperless-mcp
uv sync --locked --no-dev
uv run paperless-mcp

The server listens on http://0.0.0.0:8770/mcp by default. Keep the generated MCP token secret and configure the same value in the client.

Available Tools

Tool Access Purpose
search_documents Read Full-text and filtered document search
get_document Read Return metadata and optional OCR content
download_document Read Return an archived or original file as base64
list_tags Read List Paperless tags
list_correspondents Read List Paperless correspondents
list_document_types Read List Paperless document types
update_document Write Update title, correspondent, type, or tags
upload_document Write Upload a file to the consume pipeline

update_document and upload_document are disabled when PAPERLESS_READ_ONLY=1. The compatibility default remains 0, so set the variable explicitly for a read-only deployment.

Configuration

All configuration is via environment variables — see deploy/paperless-mcp.env.example.

Variable Required Default Description
PAPERLESS_URL yes none Base URL, e.g. http://127.0.0.1:8000
PAPERLESS_TOKEN yes none Paperless API token (Settings > API Tokens)
PAPERLESS_MCP_TOKEN yes none Bearer token clients must send
PAPERLESS_MCP_HOST no 0.0.0.0 Bind host
PAPERLESS_MCP_PORT no 8770 Bind port
PAPERLESS_MCP_PATH no /mcp HTTP path
PAPERLESS_READ_ONLY no 0 Set 1 to disable writes

Linux Service

curl -fsSLO https://raw.githubusercontent.com/trsdn/paperless-mcp/main/deploy/install.sh
less install.sh
sudo bash install.sh
sudoedit /etc/paperless-mcp/env
systemctl enable --now paperless-mcp
journalctl -u paperless-mcp -f

Generate a dedicated bearer token before editing the environment file:

openssl rand -hex 32

Development

uv sync --locked --all-groups
uv run ruff check .
uv run ruff format --check .
uv run pytest --cov=paperless_mcp --cov-fail-under=85
uv build

Tests use mocked HTTP requests and never require a live Paperless-ngx instance. CI runs on Python 3.11, 3.12, 3.13, and 3.14.

Client config

Local stdio-free launch (any client that spawns a command)

Clients that start the server themselves can invoke it via uvx:

{
  "mcpServers": {
    "paperless": {
      "command": "uvx",
      "args": ["--from", "trsdn-paperless-mcp", "paperless-mcp"],
      "env": {
        "PAPERLESS_URL": "http://127.0.0.1:8000",
        "PAPERLESS_TOKEN": "your-paperless-api-token",
        "PAPERLESS_MCP_TOKEN": "your-generated-mcp-token",
        "PAPERLESS_READ_ONLY": "1"
      }
    }
  }
}

The server then serves streamable HTTP on http://0.0.0.0:8770/mcp; point the client at that URL as shown below.

Claude Desktop

Claude Desktop currently only speaks MCP over stdio, so use the mcp-remote bridge:

// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "paperless": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://paperless-mcp.example.com/mcp",
        "--header",
        "Authorization: Bearer YOUR_PAPERLESS_MCP_TOKEN"
      ]
    }
  }
}

VS Code (mcp.json)

{
  "servers": {
    "paperless": {
      "type": "http",
      "url": "https://paperless-mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_PAPERLESS_MCP_TOKEN"
      }
    }
  }
}

Security Model

  • Prefer PAPERLESS_READ_ONLY=1. Enable writes only for clients that require them and that you trust with document access.
  • Do not expose port 8770 directly to the public internet. Restrict network access and place the service behind a maintained reverse proxy with TLS.
  • Use long, independent values for the Paperless API token and MCP bearer token. Never commit either token.
  • The bearer token only protects the MCP layer. The Paperless API token stored in /etc/paperless-mcp/env carries full account permissions, so the file is 0640, owned by paperless-mcp.
  • To rotate the bearer token: edit /etc/paperless-mcp/env, then systemctl restart paperless-mcp.
  • See SECURITY.md for vulnerability reporting and the supported security boundary.

Project

Licensed under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

trsdn_paperless_mcp-0.1.2.tar.gz (116.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trsdn_paperless_mcp-0.1.2-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file trsdn_paperless_mcp-0.1.2.tar.gz.

File metadata

  • Download URL: trsdn_paperless_mcp-0.1.2.tar.gz
  • Upload date:
  • Size: 116.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for trsdn_paperless_mcp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0f1e8edb02376b8118b8528a88baad8e2cb5b12a5a5e76066d99b0b74864b956
MD5 1fc2776f9332512d7900a33e6091a5a9
BLAKE2b-256 c8346fd424aef8d1d5d646eb4102b717648a58a333706edf205c936afb486fe7

See more details on using hashes here.

Provenance

The following attestation bundles were made for trsdn_paperless_mcp-0.1.2.tar.gz:

Publisher: release.yml on trsdn/paperless-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trsdn_paperless_mcp-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for trsdn_paperless_mcp-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 45b281f1b9daeda02c3bf3348f0d08b15a17a545e33d4b9aa48ea2467f5a2f71
MD5 6866993205de2e2f391a18801540be4e
BLAKE2b-256 cdc17ecc1e8c97a8e1d980a35f45a1b7e53a212a4a1a1b3de6e81908951f2074

See more details on using hashes here.

Provenance

The following attestation bundles were made for trsdn_paperless_mcp-0.1.2-py3-none-any.whl:

Publisher: release.yml on trsdn/paperless-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.3

2 files

This release

0.1.2 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page