mcpField
P
Paperless MCP

Paperless MCP

本地服务
pvliesdonk.github.io文件与存储14 周前更新

关于 Paperless MCP

Paperless MCP 将 MCP 客户端连接到 Paperless-NGX,以检索和管理文档。它将搜索和 OCR 内容访问与文档分类管理、文件传输及生命周期工具结合起来。

主要功能

  1. 01按文本和筛选条件搜索文档
  2. 02读取 OCR 文本、元数据和缩略图
  3. 03管理标签、联系人、文档类型和自定义字段
  4. 04上传文档并跟踪后台任务
  5. 05查看审计历史、保存的视图和统计数据
  6. 06通过 HTTP 传输文件和 OCR Markdown

适用场景

  1. 01按文本和联系人筛选查找发票
  2. 02批量为文档添加标签并更改联系人
  3. 03上传 PDF 并等待 OCR 索引完成
  4. 04查看文档审计历史中的变更

MCP 相关

该服务通过 49 个工具和 16 个资源 URI 提供 Paperless-NGX 文档及相关操作。MCP 客户端可使用 stdio 或 Streamable HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"pvliesdonk-paperless": {
"command": "uvx",
"args": [
"pvliesdonk-paperless-mcp"
],
"env": {
"PAPERLESS_MCP_KV_STORE_URL": "<PAPERLESS_MCP_KV_STORE_URL>",
"PAPERLESS_MCP_TOOLS_ALLOW": "<PAPERLESS_MCP_TOOLS_ALLOW>",
"PAPERLESS_MCP_TOOLS_DENY": "<PAPERLESS_MCP_TOOLS_DENY>",
"PAPERLESS_MCP_SERVER_NAME": "<PAPERLESS_MCP_SERVER_NAME>",
"PAPERLESS_MCP_INSTANCE_DESCRIPTION": "<PAPERLESS_MCP_INSTANCE_DESCRIPTION>",
"PAPERLESS_MCP_INSTRUCTIONS_EXTRA": "<PAPERLESS_MCP_INSTRUCTIONS_EXTRA>",
"PAPERLESS_MCP_INSTRUCTIONS": "<PAPERLESS_MCP_INSTRUCTIONS>",
"PAPERLESS_MCP_LOG_LEVEL": "<PAPERLESS_MCP_LOG_LEVEL>",
"PAPERLESS_MCP_LOG_FORMAT": "<PAPERLESS_MCP_LOG_FORMAT>",
"PAPERLESS_MCP_PAPERLESS_URL": "<PAPERLESS_MCP_PAPERLESS_URL>",
"PAPERLESS_MCP_API_TOKEN": "<PAPERLESS_MCP_API_TOKEN>",
"PAPERLESS_MCP_HTTP_TIMEOUT_SECONDS": "<PAPERLESS_MCP_HTTP_TIMEOUT_SECONDS>",
"PAPERLESS_MCP_HTTP_RETRIES": "<PAPERLESS_MCP_HTTP_RETRIES>",
"PAPERLESS_MCP_DEFAULT_PAGE_SIZE": "<PAPERLESS_MCP_DEFAULT_PAGE_SIZE>",
"PAPERLESS_MCP_PAPERLESS_PUBLIC_URL": "<PAPERLESS_MCP_PAPERLESS_PUBLIC_URL>",
"PAPERLESS_MCP_TRANSFER_TTL_DEFAULT_S": "<PAPERLESS_MCP_TRANSFER_TTL_DEFAULT_S>",
"PAPERLESS_MCP_TRANSFER_TTL_MAX_S": "<PAPERLESS_MCP_TRANSFER_TTL_MAX_S>",
"PAPERLESS_MCP_TRANSFER_GRACE_TTL_S": "<PAPERLESS_MCP_TRANSFER_GRACE_TTL_S>",
"PAPERLESS_MCP_TRANSFER_LEASE_S": "<PAPERLESS_MCP_TRANSFER_LEASE_S>",
"PAPERLESS_MCP_TRANSFER_MAX_UPLOAD_BYTES": "<PAPERLESS_MCP_TRANSFER_MAX_UPLOAD_BYTES>",
"PAPERLESS_MCP_SHUTDOWN_GRACE_S": "<PAPERLESS_MCP_SHUTDOWN_GRACE_S>",
"PAPERLESS_MCP_BASE_URL": "<PAPERLESS_MCP_BASE_URL>",
"PAPERLESS_MCP_BEARER_TOKEN": "<PAPERLESS_MCP_BEARER_TOKEN>",
"PAPERLESS_MCP_OIDC_CONFIG_URL": "<PAPERLESS_MCP_OIDC_CONFIG_URL>",
"PAPERLESS_MCP_OIDC_CLIENT_ID": "<PAPERLESS_MCP_OIDC_CLIENT_ID>",
"PAPERLESS_MCP_OIDC_CLIENT_SECRET": "<PAPERLESS_MCP_OIDC_CLIENT_SECRET>",
"PAPERLESS_MCP_OIDC_AUDIENCE": "<PAPERLESS_MCP_OIDC_AUDIENCE>",
"PAPERLESS_MCP_OIDC_REQUIRED_SCOPES": "<PAPERLESS_MCP_OIDC_REQUIRED_SCOPES>",
"PAPERLESS_MCP_OIDC_ADVERTISED_SCOPES": "<PAPERLESS_MCP_OIDC_ADVERTISED_SCOPES>",
"PAPERLESS_MCP_OIDC_JWT_SIGNING_KEY": "<PAPERLESS_MCP_OIDC_JWT_SIGNING_KEY>",
"PAPERLESS_MCP_OIDC_VERIFY_ACCESS_TOKEN": "<PAPERLESS_MCP_OIDC_VERIFY_ACCESS_TOKEN>",
"PAPERLESS_MCP_APP_DOMAIN": "<PAPERLESS_MCP_APP_DOMAIN>",
"PAPERLESS_MCP_AUTH_MODE": "<PAPERLESS_MCP_AUTH_MODE>",
"PAPERLESS_MCP_BEARER_TOKENS_FILE": "<PAPERLESS_MCP_BEARER_TOKENS_FILE>",
"PAPERLESS_MCP_BEARER_DEFAULT_SUBJECT": "<PAPERLESS_MCP_BEARER_DEFAULT_SUBJECT>",
"PAPERLESS_MCP_HTTP_PATH": "<PAPERLESS_MCP_HTTP_PATH>",
"PAPERLESS_MCP_HEALTH_DETAIL": "<PAPERLESS_MCP_HEALTH_DETAIL>",
"PUID": "<PUID>",
"PGID": "<PGID>"
}
}
}
}
启动命令uvx pvliesdonk-paperless-mcp
需要配置的环境变量
PAPERLESS_MCP_KV_STORE_URLPersistent-state backend URL shared by every pvl-core subsystem that needs state. `memory://` is in-process and lost on restart; `file:///path` persists on one server; `redis://`, `dynamodb://` and `mongodb://` each need their matching extra. When unset, defaults to `file:///data/state` (the volume family Docker images mount), or to `memory://` (with a warning) on a host where that directory is not usable.
PAPERLESS_MCP_TOOLS_ALLOWComma-separated explicit tool names this instance exposes; every other tool is hidden from listings and cannot be invoked. Names matching no registered tool are inert. Mutually exclusive with `tools_deny`. Takes effect through `apply_tool_visibility`.
PAPERLESS_MCP_TOOLS_DENYComma-separated explicit tool names hidden from this instance (absent from listings, cannot be invoked). Names matching no registered tool are inert. Mutually exclusive with `tools_allow`. Takes effect through `apply_tool_visibility`.
PAPERLESS_MCP_SERVER_NAMERename this server instance; defaults to the project name.
PAPERLESS_MCP_INSTANCE_DESCRIPTIONConcise routing context that distinguishes this deployment's material or responsibility.
PAPERLESS_MCP_INSTRUCTIONS_EXTRADeployment-specific behavioral policy added to the generated MCP instructions.
PAPERLESS_MCP_INSTRUCTIONSLegacy: replaces all generated MCP instructions (deprecated; use _INSTANCE_DESCRIPTION for routing and _INSTRUCTIONS_EXTRA for policy).
PAPERLESS_MCP_LOG_LEVELLog level for every logger in the process, FastMCP's included (DEBUG / INFO / WARNING / ERROR / CRITICAL). The -v CLI flag overrides to DEBUG. The unprefixed FASTMCP_LOG_LEVEL still works for one major version and logs a deprecation warning.
PAPERLESS_MCP_LOG_FORMATLog rendering. rich is one colour event key=value line per record, for a terminal; json is one JSON object per record, for a collector. Unset picks rich when stderr is a terminal and json everywhere else, so a container or journald gets JSON with no configuration.
PAPERLESS_MCP_PAPERLESS_URLBase URL of the Paperless-NGX REST API, without a trailing slash. The server refuses to start without it.
PAPERLESS_MCP_API_TOKEN密钥Paperless service-account token used for outbound API requests. The server refuses to start without it.
PAPERLESS_MCP_HTTP_TIMEOUT_SECONDSPer-request HTTP timeout in seconds.
PAPERLESS_MCP_HTTP_RETRIESRetries for idempotent requests after network errors or 5xx responses.
PAPERLESS_MCP_DEFAULT_PAGE_SIZEDefault page size for list tools, from 1 through 100.
PAPERLESS_MCP_PAPERLESS_PUBLIC_URLPublic Paperless UI URL for user-visible links; defaults to PAPERLESS_URL.
PAPERLESS_MCP_TRANSFER_TTL_DEFAULT_SLink lifetime in seconds when the caller requests no explicit TTL.
PAPERLESS_MCP_TRANSFER_TTL_MAX_SCeiling in seconds a caller-requested link TTL is clamped to.
PAPERLESS_MCP_TRANSFER_GRACE_TTL_SPost-success grace window in seconds: a served token's TTL shrinks to this so a stalled transfer can retry within it.
PAPERLESS_MCP_TRANSFER_LEASE_SCrashed-handler reclaim window in seconds for an in-flight reservation.
PAPERLESS_MCP_TRANSFER_MAX_UPLOAD_BYTESMaximum size in bytes of a single upload.
PAPERLESS_MCP_SHUTDOWN_GRACE_SSeconds SIGTERM may spend draining in-flight requests before the HTTP server exits. Keep it at or below the termination grace period the orchestrator allows. `0` drops in-flight requests immediately.
PAPERLESS_MCP_BASE_URLPublic base URL of the deployed server, for example `https://mcp.example.com`. Required for OIDC. Also the fallback source of the MCP Apps domain when `app_domain` is unset.
PAPERLESS_MCP_BEARER_TOKEN密钥Single shared bearer token; enables bearer auth unless `bearer_tokens_file` is set, which takes precedence.
PAPERLESS_MCP_OIDC_CONFIG_URLOIDC discovery document URL, for example `https://auth.example.com/.well-known/openid-configuration`.
PAPERLESS_MCP_OIDC_CLIENT_IDOIDC client identifier registered with the provider.
PAPERLESS_MCP_OIDC_CLIENT_SECRET密钥OIDC client secret registered with the provider.
PAPERLESS_MCP_OIDC_AUDIENCEExpected `aud` claim; tokens issued for another audience are rejected.
PAPERLESS_MCP_OIDC_REQUIRED_SCOPESScopes a caller must present, space- or comma-separated. Defaults to `openid` in oidc-proxy mode.
PAPERLESS_MCP_OIDC_ADVERTISED_SCOPESScopes advertised to MCP clients in protected-resource metadata, space- or comma-separated. Overrides the default `openid offline_access`; `oidc_required_scopes` is always added on top. Set this when the registered client is not permitted `offline_access`, or to have clients request extra claim scopes (such as `groups`) without also requiring them in every token.
PAPERLESS_MCP_OIDC_JWT_SIGNING_KEY密钥Signing key for issued tokens; used in oidc-proxy mode only. When unset, the key is derived deterministically from `oidc_client_secret`, so tokens survive a restart. Rotating that secret then invalidates every issued token. Set this explicitly to decouple token validity from secret rotation. Generate with `openssl rand -hex 32`.
PAPERLESS_MCP_OIDC_VERIFY_ACCESS_TOKEN密钥Validate the access token instead of the id token.
PAPERLESS_MCP_APP_DOMAINMCP Apps iframe domain, used for CSP sandboxing. Overrides the host derived from `base_url`.
PAPERLESS_MCP_AUTH_MODE密钥Explicit auth-mode override, accepting `remote` or `oidc-proxy` (case- and whitespace-insensitive). When unset the mode is auto-detected from which auth variables are set; the override exists because having all four OIDC variables set is ambiguous between those two modes. Other values are ignored with a warning.
PAPERLESS_MCP_BEARER_TOKENS_FILE密钥Path to a TOML file mapping bearer tokens to subjects; overrides the single-token `bearer_token` mode.
PAPERLESS_MCP_BEARER_DEFAULT_SUBJECTSubject assigned to the single-token bearer mode; ignored when `bearer_tokens_file` is set, since mapped mode carries per-token subjects.
PAPERLESS_MCP_HTTP_PATHMount path for the MCP endpoint; the health routes derive their prefix from it.
PAPERLESS_MCP_HEALTH_DETAILHow much the unauthenticated /health and /health/ready bodies say: status, standard (adds name, version and per-check verdicts), or full (adds redacted reasons; trusted networks only).
PUIDRun the server process as this UID; the container entrypoint reassigns ownership of writable paths to match.
PGIDRun the server process as this GID; pair with PUID to match the owner of a mounted volume.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypipvliesdonk-paperless-mcp3.0.0
ocighcr.io/pvliesdonk/paperless-mcp:v3.0.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Paperless MCP

CI Quality Gate Status Coverage Reliability Rating Security Rating Maintainability Rating PyPI Python License Docker Docs llms.txt Template

通过 MCP 使用 Paperless-NGX:搜索、读取、上传和标记文档;管理联系人和文档类型。

文档 | 配置向导 | PyPI | Docker

功能

  • **文件传输链接:**通过 HTTP 下载文档文件和完整的 OCR Markdown。也可通过同一传输路由上传文件,包括 Markdown 文件。设置 PAPERLESS_MCP_BASE_URL 即可启用这些工具。文件字节不会进入模型上下文。请参阅文件传输链接。
  • **文档搜索与检索:**针对 Paperless-NGX 执行全文搜索和筛选列表查询,还可访问提取的 OCR 文本、元数据和缩略图。
  • **标签、联系人、文档类型、自定义字段管理:**对 Paperless 提供的所有分类维度执行完整的 CRUD 操作和批量编辑。
  • **文档生命周期:**支持上传、字段更改、备注、审计历史记录,以及 AI 建议的标签、联系人和文档类型。
  • **运行状态查询:**涵盖已保存的视图、存储路径、共享链接、后台任务(可使用 wait_for_task 等待),以及统计信息和 Paperless-NGX 上游版本检查。
  • **MCP 工具:**49 个 LLM 可见工具,带有 Lucide 图标;请参阅 src/paperless_mcp/tools/。
  • **MCP 资源:**16 个 URI,提供范围受限的文档预览和领域集合;请参阅 src/paperless_mcp/resources/。

可用它完成的任务

在 MCP 客户端(Claude 等)中挂载此服务后,你可以:

  • “查找 ACME 上季度的发票。” 将 search_documents 与往来方筛选条件组合使用,然后通过 get_document_content 读取有长度限制的预览。
  • “将这三份文档标记为‘已审核’,并移至‘会计’往来方。” 通过单次调用使用 bulk_edit_documents。
  • “上传此 PDF,并等待 OCR 完成。” 将 upload_document 与 wait_for_task 组合使用,这样助手只会在文档完成索引后才进行回复。
  • “上周文档 4213 有什么变更?” 读取 paperless://documents/4213/history 并总结审计记录。

所有工具和资源均列在文档网站中:工具和资源。服务读取的 Paperless 变量见配置。

安装

从 PyPI 安装
pip install pvliesdonk-paperless-mcp

如果你通过 pyproject.toml 中的 PROJECT-EXTRAS-START / PROJECT-EXTRAS-END 标记添加可选附加项,请在下方记录:

  • pip install pvliesdonk-paperless-mcp[docs]:安装 mkdocs-material 和 mkdocstrings[python],以便在本地构建文档网站(uv run mkdocs serve)。
从源码安装
git clone https://github.com/pvliesdonk/paperless-mcp.git
cd paperless-mcp
uv sync --all-extras --all-groups
Docker
docker pull ghcr.io/pvliesdonk/paperless-mcp:latest

若要运行最新合并的代码,而非最新发布版本,请使用滚动更新的 edge 标签。每次合并到 main 后都会重新构建,且不带版本标识。完整标签列表请参阅镜像标签。

docker pull ghcr.io/pvliesdonk/paperless-mcp:edge

仓库根目录提供了开箱即用的 compose.yml:将 .env.example 复制为 .env,然后运行 docker compose up -d。它会在主机上发布端口 8000,并假设没有反向代理;Docker Compose 介绍了配置拆分、域名标记块和 Traefik 叠加配置。

如需连接远程 Python 调试器(仅限开发环境;该协议未经身份验证),请参阅远程调试。

Linux 软件包(.deb / .rpm)

从 GitHub Releases 页面下载 .deb 或 .rpm 软件包。两种软件包都会安装经过安全加固的 systemd 单元;环境配置从 /etc/paperless-mcp/env 读取(可从随包提供的 /etc/paperless-mcp/env.example 复制)。

Claude Desktop(.mcpb 捆绑包)

从 GitHub Releases 页面下载 .mcpb 捆绑包,然后双击安装,或运行:

mcpb install paperless-mcp-<version>.mcpb

Claude Desktop 会通过图形向导提示输入所需的环境变量,无需手动编辑 JSON。

有关 Claude Desktop 的手动配置和设置选项,请参阅 Claude Desktop 部署。

发布渠道

制品通过三个渠道发布。每行列出该渠道发布的确切内容。

渠道版本标识制品
edge(滚动发布)无;提交即为标识每次合并到 main 时重新构建的 Docker 镜像 :edge;作为 mcpb-bundle-edge 工作流制品的 .mcpb 捆绑包;作为 plugin-zip-edge 制品的 Claude Code 插件 .zip;滚动更新的 unstable 文档版本。不会留下 git 标签、GitHub release 或 PyPI 条目。
预发布vX.Y.Z-rc.N,在其发布拉取请求中计算并审核PyPI(作为预发布版本 X.Y.ZrcN);附带 wheels、sdist、.deb/.rpm 软件包、.mcpb 捆绑包、插件 .zip 和 SBOM 的 GitHub release;带不可变 vX.Y.Z-rc.N 标签以及可感知顺序的滚动 rc 标签的 Docker 镜像。跳过插件市场、MCP 注册表和文档部署。
稳定版vX.Y.Z全部内容:PyPI、Docker(版本标签以及可感知顺序的 latest / vX / vX.Y)、.deb/.rpm、GitHub release 资源(wheels、sdist、.mcpb 捆绑包、插件 .zip、SBOM)、插件市场和 MCP 注册表条目(当该版本是最新稳定版时),以及带可感知顺序的 latest 别名的版本化文档。

预发布版本会发布到 PyPI,以便候选版本的 .mcpb 捆绑包能够安装:该捆绑包指向 PyPI,而不包含代码。普通安装程序不会看到它们,因为除非需求指定了某个预发布版本,或传入 --pre,否则 PEP 440 解析器会跳过预发布版本。使用名称请求候选版本:pip install pvliesdonk-paperless-mcp==X.Y.ZrcN。PyPI 使用 PEP 440 规范形式,而标签使用 SemVer。滚动指针会感知版本顺序,因此,从旧的 release/X.Y 分支切出的补丁版本不会将 latest 等标签回退到较旧内容,而针对已发布版本的候选版本也不会移动 rc。完整模型请参阅发布流程。

快速开始

paperless-mcp serve                                # stdio transport
paperless-mcp serve --transport http --port 8000   # streamable HTTP

如需在库中使用(嵌入领域逻辑而不使用 MCP 传输),请直接从 paperless_mcp 包导入。有关入口点,请参阅项目在 src/paperless_mcp/ 下的领域模块。

服务信息

服务会注册内置的 get_server_info 工具(通过 fastmcp_pvl_core.register_server_info_tool),以便运维人员通过一次 MCP 调用确认已部署的版本。默认响应包含 server_name、server_version 和 core_version。与远程上游通信的服务会在 src/paperless_mcp/server.py 中的 DOMAIN-UPSTREAM-START / DOMAIN-UPSTREAM-END 哨兵标记之间接入上游版本报告;接线模式请参阅 tool-registration。

健康检查

服务通过 fastmcp_pvl_core.register_health_routes,在 MCP 挂载点和身份验证之外提供 /health(存活状态,静态返回 200)和 /health/ready(就绪状态,在后端存储或领域检查失败时返回 503)。compose.yml 会探测前者。领域就绪检查应放在 src/paperless_mcp/server.py 中的 health_checks 字典里;有关路由、挂载路径规则和 PAPERLESS_MCP_HEALTH_DETAIL,请参阅 Docker 部署。

配置

所有基于 fastmcp-pvl-core 的服务共用的最常见环境变量:

变量默认值描述
PAPERLESS_MCP_KV_STORE_URLfile:///data/state供所有需要状态的 pvl-core 子系统共用的持久化状态后端 URL。memory:// 在进程内使用,重启后状态会丢失;file:///path 会在单台服务器上持久化;redis://、dynamodb:// 和 mongodb:// 均需要对应的 extra。未设置时,默认使用 file:///data/state(Docker 镜像会将卷挂载到此位置);如果所在主机无法使用该目录,则默认使用 memory://(并发出警告)。
PAPERLESS_MCP_LOG_LEVELINFO进程中所有日志记录器的日志级别,也包括 FastMCP 的日志记录器(DEBUG / INFO / WARNING / ERROR / CRITICAL)。-v CLI 标志会将级别覆盖为 DEBUG。无前缀的 FASTMCP_LOG_LEVEL 在一个主版本周期内仍可使用,并会输出弃用警告。
PAPERLESS_MCP_LOG_FORMAT(无)日志呈现格式。rich 会为每条记录输出一行彩色的 event key=value,适用于终端;json 会为每条记录输出一个 JSON 对象,适用于日志收集器。未设置时,如果 stderr 是终端,则使用 rich;其他情况下使用 json,因此容器或 journald 无需配置即可获得 JSON。

此表以及领域配置下的表格均为精选子集。包含服务器读取的所有变量的完整生成参考文档见配置参考;.env.example 以便于复制粘贴的形式列出了同一组配置。

身份验证

调用方通过 bearer token 或 OIDC 进行身份验证(二者不能同时使用)。有关设置、映射多个主体的令牌、OIDC 和故障排查,请参阅身份验证指南。

脚手架生成后的检查清单

运行 copier copy 和 gh repo create --push 后:

  1. 填写 DOMAIN 区块(本 README 和 AGENTS.md 中所有带有 DOMAIN 哨兵注释的部分)。GENERATED-ENV-TABLE-* 区域不是 DOMAIN 区块;配置生成器负责管理这些区域,并会在每次运行时重写它们。
  2. 配置 GitHub secrets(见下文)。
  3. 安装开发和文档工具:uv sync --all-extras --all-groups。
  4. 安装 pre-commit 钩子:uv run pre-commit install。
  5. 在本地运行检查:uv run pytest -x -q && uv run ruff check --fix . && uv run ruff format . && uv run mypy src/ tests/。
  6. 推送首个提交。CI 应当通过。

GitHub 密钥

CI 工作流引用了两个必需的仓库密钥和一个可选的 Claude 令牌。请通过 Settings → Secrets and variables → Actions 或使用 gh secret set 进行配置:

密钥用途生成方式
RELEASE_TOKENrelease-prepare.yml、release.yml、copier-update.yml、renovate.yml、bootstrap.yml在 https://github.com/settings/personal-access-tokens/new 创建细粒度 PAT,并授予 contents: write、pull_requests: write 和 administration: write 权限(bootstrap 会应用仓库规则集、自动合并、安全设置和 About 区块)。令牌必须属于仓库管理员:已提供的规则集授予管理员角色绕过权限,而 knope 在发布拉取请求合并后创建的发布标签和 GitHub Release 也依赖此权限(令牌创建的拉取请求也需要此权限才能运行 CI)。范围仅限此仓库。
SONAR_TOKENci.ymlhttps://sonarcloud.io:导入仓库后,打开其 Administration → Analysis Method 页面。先在此关闭 Automatic Analysis,因为开启时 SonarQube Cloud 会拒绝 CI 扫描;选择 GitHub Actions 后即可看到令牌。在创建此密钥之前,CI 会跳过扫描。
CLAUDE_CODE_OAUTH_TOKENclaude.yml可选。在本地运行 claude setup-token,仅在使用 @claude 或选择启用自动审查时配置此项。
gh secret set RELEASE_TOKEN
gh secret set SONAR_TOKEN
# Optional: enables @claude and opted-in automatic review.
gh secret set CLAUDE_CODE_OAUTH_TOKEN

依赖更新由 Renovate(renovate.yml)处理,并复用 RELEASE_TOKEN。它会维护 uv.lock,并在 CI Success 检查通过后自动合并补丁和次要版本更新;bootstrap.yml 会启用自动合并、应用仓库规则集(.github/rulesets/)、开启私有漏洞报告和 Dependabot 警报,并在首次推送时根据 pyproject.toml 填写仓库的 About 区块(描述、网站、主题)。有关各分支的保护措施、绕过机制和安全设置,请参阅 Repository Protection。GitHub Actions 会在 copier 模板中更新,并通过 copier update 引入,而不是逐个仓库更新。

GITHUB_TOKEN 会自动提供;无需操作。

本地开发

PR 门禁(与 CI 一致):

uv run pytest -x -q                                  # tests
uv run ruff check --fix . && uv run ruff format .    # lint + format
uv run mypy src/ tests/                              # type-check

Pre-commit 会在每次提交时运行门禁中的部分检查;详情请参阅 .pre-commit-config.yaml,或查看 AGENTS.md 了解完整的 Hard PR Acceptance Gates。

CI 要求在 Python 3.11 到 3.14 上通过测试。Python 3.14 还会收集 分支覆盖率,并强制要求总体覆盖率和补丁覆盖率达到 80%。 如需复现该测试命令,请运行 uv run --python 3.14 pytest --cov --cov-report=xml --durations=20。

故障排除

移动已生成脚手架的项目

uv sync 会创建 .venv/bin/* 脚本,其中包含指向虚拟环境 Python 的绝对 shebang。如果在生成脚手架后移动仓库(mv /old/path /new/path),uv run pytest 会因 ModuleNotFoundError: No module named 'fastmcp' 而失败,因为过期的 shebang 会解析到与虚拟环境 site-packages 不同的解释器。

修复方法:

rm -rf .venv
uv sync --all-extras --all-groups

uv run python -m pytest 也可作为一次性解决方法(绕过过期的入口脚本 shim)。

copier update 后刷新 uv.lock

当 copier update 引入新依赖时(例如 pyproject.toml.jinja 中新增 extra),CI 安装步骤运行 uv sync --locked 会因锁文件过期而失败。请在本地运行 uv lock,并在接受 copier-update PR 时一并提交刷新后的 uv.lock。

CI 使用 --locked 安装(审查工作流则使用 --frozen),因此任何作业都不会在自己的工作区中重写 uv.lock:重新锁定的作业会掩盖刚修复的偏差,而工作区变更也会导致同一作业中后续的 git checkout 失败。锁文件偏差会显示为明确报错的安装步骤,而不是静默修改。

贡献

CONTRIBUTING.md 说明了问题和拉取请求的规则,以及修复应归属何处:库代码归 fastmcp-pvl-core,模板自有文件归模板,本仓库中属于 DOMAIN-* / CONFIG-* / PROJECT-* 块的内容则归本仓库。AGENTS.md 载有约定和检查门槛;.agents/skills/ 下的技能则载有任务流程,其中包括 self-reviewing(提交拉取请求前进行本地自审)、writing-release-notes(编写发行说明)、applying-template-updates(每周模板更新拉取请求)和 authoring-issues-prs(提交问题和拉取请求)。发行流程见 docs/deployment/release-process.md; 模板更新流程见 docs/deployment/template-updates.md。 SECURITY.md 说明了如何私下报告漏洞,以及之后会发生什么。

链接

域配置

本项目将以下变量作为入口点(域变量使用 PAPERLESS_MCP_ 前缀):

变量默认值必填描述
PAPERLESS_MCP_PAPERLESS_URL(none)是Paperless-NGX REST API 的基础 URL,末尾不带斜杠。
PAPERLESS_MCP_API_TOKEN(none)是用于发出 API 请求的 Paperless 服务账户令牌。
PAPERLESS_MCP_PAPERLESS_PUBLIC_URL(none)否面向用户的链接所用的 Paperless 公共 UI URL;默认值为 PAPERLESS_URL。

这里仅列出精选子集:当某个字段的 tags 元数据包含 readme 时,该字段才会显示在此处。所有域变量都记录在配置参考中,并按照配置向导展示的方式分组。

域配置字段在 src/paperless_mcp/config.py 中的 CONFIG-FIELDS-START / CONFIG-FIELDS-END 标记之间组合;环境变量读取通过 fastmcp_pvl_core.env(_ENV_PREFIX, "SUFFIX", default) 完成,以保持命名一致;字段约束则写在 CONFIG-VALIDATE-START / CONFIG-VALIDATE-END 标记之间的 __post_init__ 中。每个字段的 metadata 中的 help、tags 和 wizard 分组会直接生成参考表,因此请确保其准确完整。

关键设计决策

  • 只读部署通过工具可见性实现,而非切换域。 设置 PAPERLESS_MCP_TOOLS_DENY(或 PAPERLESS_MCP_TOOLS_ALLOW)以隐藏会修改数据的工具;启用传输功能时,也包括 create_upload_link。模板在 make_server 中最后应用可见性设置,因此隐藏的工具不会出现在 tools/list 中,且调用 tools/call 时会被拒绝。客户端无法调用必定会被拒绝的写入操作,而且基于此模板构建的所有服务都在同一处定义这条规则。
  • HTTP 层仅重试幂等读取。 PAPERLESS_MCP_HTTP_RETRIES 仅适用于因 5xx 错误或网络错误而失败的 GET 请求;写入操作绝不会自动重试,以避免批量编辑或上传被重复执行。
  • 工具图标来自 Lucide。 每个工具都带有 Lucide 图标提示,以便支持图标渲染的 MCP 客户端(Claude Desktop)呈现一致的视觉界面。请参阅 src/paperless_mcp/tools/_icons.py。
  • Paperless API 兼容性: 请求优先使用负载版本 10;Paperless 2.x 明确拒绝该版本后,会自动回退到版本 9。任务包含结构化结果和计时数据,同时保留旧版字段。已保存视图的可见性标志现在可以为 null;Python 使用者必须处理该值。请参阅任务工具。
  • 模型接受上游未知字段。 Pydantic 模型对列表端点响应采用宽松验证,因此较新版本的 Paperless-NGX 不会导致客户端出错(Document.some_future_paperless_field 测试会固定这一行为)。
  • v1 不包含提示词。 prompts.py 有意保持为空;随着实践中逐渐形成具体的用户工作流模式,提示词将适时加入。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。