addrbookFor publishers
← The evidence ledger

Evidence row 48128

Observed , by baseline/1.

Kind
listing
About
source_record mcp_registry:io.github.pvliesdonk/paperless-mcp
Recorded
Previous row
None: the first of its kind about this subject
Body SHA-256
bbd0364cee44d1aa447bfedc67dde578bdd64f0efedffa0af378c163e8e24f95
Leaf
0x74e089dbdbc079f199ecbc4dcdad0750c06bb1a4579a5c93723cd522b8b94212

What was observed

{
  "endpoints": [
    [
      "web",
      "https://pvliesdonk.github.io/paperless-mcp/"
    ]
  ],
  "name": "Paperless MCP",
  "owner_address": null,
  "raw": {
    "_meta": {
      "io.modelcontextprotocol.registry/official": {
        "isLatest": true,
        "publishedAt": "2026-09-21T18:08:55.928958Z",
        "status": "active",
        "statusChangedAt": "2026-09-21T18:08:55.928958Z",
        "updatedAt": "2026-09-21T18:08:55.928958Z"
      }
    },
    "server": {
      "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
      "description": "Paperless-NGX over MCP: search, read, upload and tag documents; manage correspondents and types.",
      "name": "io.github.pvliesdonk/paperless-mcp",
      "packages": [
        {
          "environmentVariables": [
            {
              "default": "file:///data/state",
              "description": "Persistent-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.",
              "name": "PAPERLESS_MCP_KV_STORE_URL"
            },
            {
              "description": "Comma-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`.",
              "name": "PAPERLESS_MCP_TOOLS_ALLOW"
            },
            {
              "description": "Comma-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`.",
              "name": "PAPERLESS_MCP_TOOLS_DENY"
            },
            {
              "description": "Rename this server instance; defaults to the project name.",
              "name": "PAPERLESS_MCP_SERVER_NAME"
            },
            {
              "description": "Concise routing context that distinguishes this deployment's material or responsibility.",
              "name": "PAPERLESS_MCP_INSTANCE_DESCRIPTION"
            },
            {
              "description": "Deployment-specific behavioral policy added to the generated MCP instructions.",
              "name": "PAPERLESS_MCP_INSTRUCTIONS_EXTRA"
            },
            {
              "description": "Legacy: replaces all generated MCP instructions (deprecated; use _INSTANCE_DESCRIPTION for routing and _INSTRUCTIONS_EXTRA for policy).",
              "name": "PAPERLESS_MCP_INSTRUCTIONS"
            },
            {
              "choices": [
                "DEBUG",
                "INFO",
                "WARNING",
                "ERROR",
                "CRITICAL"
              ],
              "default": "INFO",
              "description": "Log 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.",
              "name": "PAPERLESS_MCP_LOG_LEVEL"
            },
            {
              "choices": [
                "rich",
                "json"
              ],
              "description": "Log 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.",
              "name": "PAPERLESS_MCP_LOG_FORMAT"
            },
            {
              "description": "Base URL of the Paperless-NGX REST API, without a trailing slash. The server refuses to start without it.",
              "name": "PAPERLESS_MCP_PAPERLESS_URL"
            },
            {
              "description": "Paperless service-account token used for outbound API requests. The server refuses to start without it.",
              "isSecret": true,
              "name": "PAPERLESS_MCP_API_TOKEN"
            },
            {
              "default": "30.0",
              "description": "Per-request HTTP timeout in seconds.",
              "format": "number",
              "name": "PAPERLESS_MCP_HTTP_TIMEOUT_SECONDS"
            },
            {
              "default": "2",
              "description": "Retries for idempotent requests after network errors or 5xx responses.",
              "format": "number",
              "name": "PAPERLESS_MCP_HTTP_RETRIES"
            },
            {
              "default": "25",
              "description": "Default page size for list tools, from 1 through 100.",
              "format": "number",
              "name": "PAPERLESS_MCP_DEFAULT_PAGE_SIZE"
            },
            {
              "description": "Public Paperless UI URL for user-visible links; defaults to PAPERLESS_URL.",
              "name": "PAPERLESS_MCP_PAPERLESS_PUBLIC_URL"
            },
            {
              "default": "3600.0",
              "description": "Link lifetime in seconds when the caller requests no explicit TTL.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_TTL_DEFAULT_S"
            },
            {
              "default": "86400.0",
              "description": "Ceiling in seconds a caller-requested link TTL is clamped to.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_TTL_MAX_S"
            },
            {
              "default": "60.0",
              "description": "Post-success grace window in seconds: a served token's TTL shrinks to this so a stalled transfer can retry within it.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_GRACE_TTL_S"
            },
            {
              "default": "60.0",
              "description": "Crashed-handler reclaim window in seconds for an in-flight reservation.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_LEASE_S"
            },
            {
              "default": "104857600",
              "description": "Maximum size in bytes of a single upload.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_MAX_UPLOAD_BYTES"
            }
          ],
          "identifier": "pvliesdonk-paperless-mcp",
          "registryType": "pypi",
          "runtimeHint": "uvx",
          "transport": {
            "type": "stdio"
          },
          "version": "3.0.0"
        },
        {
          "environmentVariables": [
            {
              "default": "3",
              "description": "Seconds 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.",
              "format": "number",
              "name": "PAPERLESS_MCP_SHUTDOWN_GRACE_S"
            },
            {
              "description": "Public 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.",
              "name": "PAPERLESS_MCP_BASE_URL",
              "placeholder": "https://mcp.example.com"
            },
            {
              "description": "Single shared bearer token; enables bearer auth unless `bearer_tokens_file` is set, which takes precedence.",
              "isSecret": true,
              "name": "PAPERLESS_MCP_BEARER_TOKEN",
              "placeholder": "<secret>"
            },
            {
              "description": "OIDC discovery document URL, for example `https://auth.example.com/.well-known/openid-configuration`.",
              "name": "PAPERLESS_MCP_OIDC_CONFIG_URL",
              "placeholder": "https://auth.example.com/.well-known/openid-configuration"
            },
            {
              "description": "OIDC client identifier registered with the provider.",
              "name": "PAPERLESS_MCP_OIDC_CLIENT_ID",
              "placeholder": "mcp-client"
            },
            {
              "description": "OIDC client secret registered with the provider.",
              "isSecret": true,
              "name": "PAPERLESS_MCP_OIDC_CLIENT_SECRET",
              "placeholder": "your-client-secret"
            },
            {
              "description": "Expected `aud` claim; tokens issued for another audience are rejected.",
              "name": "PAPERLESS_MCP_OIDC_AUDIENCE",
              "placeholder": "mcp-api"
            },
            {
              "default": "openid",
              "description": "Scopes a caller must present, space- or comma-separated. Defaults to `openid` in oidc-proxy mode.",
              "name": "PAPERLESS_MCP_OIDC_REQUIRED_SCOPES"
            },
            {
              "default": "openid offline_access",
              "description": "Scopes 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.",
              "name": "PAPERLESS_MCP_OIDC_ADVERTISED_SCOPES"
            },
            {
              "default": "derived",
              "description": "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`.",
              "isSecret": true,
              "name": "PAPERLESS_MCP_OIDC_JWT_SIGNING_KEY"
            },
            {
              "default": "false",
              "description": "Validate the access token instead of the id token.",
              "format": "boolean",
              "name": "PAPERLESS_MCP_OIDC_VERIFY_ACCESS_TOKEN"
            },
            {
              "default": "file:///data/state",
              "description": "Persistent-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.",
              "name": "PAPERLESS_MCP_KV_STORE_URL"
            },
            {
              "description": "MCP Apps iframe domain, used for CSP sandboxing. Overrides the host derived from `base_url`.",
              "name": "PAPERLESS_MCP_APP_DOMAIN"
            },
            {
              "description": "Comma-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`.",
              "name": "PAPERLESS_MCP_TOOLS_ALLOW"
            },
            {
              "description": "Comma-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`.",
              "name": "PAPERLESS_MCP_TOOLS_DENY"
            },
            {
              "description": "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.",
              "name": "PAPERLESS_MCP_AUTH_MODE"
            },
            {
              "description": "Path to a TOML file mapping bearer tokens to subjects; overrides the single-token `bearer_token` mode.",
              "format": "filepath",
              "name": "PAPERLESS_MCP_BEARER_TOKENS_FILE",
              "placeholder": "/etc/paperless-mcp/tokens.toml"
            },
            {
              "default": "bearer-anon",
              "description": "Subject assigned to the single-token bearer mode; ignored when `bearer_tokens_file` is set, since mapped mode carries per-token subjects.",
              "name": "PAPERLESS_MCP_BEARER_DEFAULT_SUBJECT"
            },
            {
              "description": "Rename this server instance; defaults to the project name.",
              "name": "PAPERLESS_MCP_SERVER_NAME"
            },
            {
              "description": "Concise routing context that distinguishes this deployment's material or responsibility.",
              "name": "PAPERLESS_MCP_INSTANCE_DESCRIPTION"
            },
            {
              "description": "Deployment-specific behavioral policy added to the generated MCP instructions.",
              "name": "PAPERLESS_MCP_INSTRUCTIONS_EXTRA"
            },
            {
              "description": "Legacy: replaces all generated MCP instructions (deprecated; use _INSTANCE_DESCRIPTION for routing and _INSTRUCTIONS_EXTRA for policy).",
              "name": "PAPERLESS_MCP_INSTRUCTIONS"
            },
            {
              "default": "/mcp",
              "description": "Mount path for the MCP endpoint; the health routes derive their prefix from it.",
              "name": "PAPERLESS_MCP_HTTP_PATH"
            },
            {
              "choices": [
                "status",
                "standard",
                "full"
              ],
              "default": "standard",
              "description": "How 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).",
              "name": "PAPERLESS_MCP_HEALTH_DETAIL"
            },
            {
              "default": "1000",
              "description": "Run the server process as this UID; the container entrypoint reassigns ownership of writable paths to match.",
              "format": "number",
              "name": "PUID"
            },
            {
              "default": "1000",
              "description": "Run the server process as this GID; pair with PUID to match the owner of a mounted volume.",
              "format": "number",
              "name": "PGID"
            },
            {
              "choices": [
                "DEBUG",
                "INFO",
                "WARNING",
                "ERROR",
                "CRITICAL"
              ],
              "default": "INFO",
              "description": "Log 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.",
              "name": "PAPERLESS_MCP_LOG_LEVEL"
            },
            {
              "choices": [
                "rich",
                "json"
              ],
              "description": "Log 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.",
              "name": "PAPERLESS_MCP_LOG_FORMAT"
            },
            {
              "description": "Base URL of the Paperless-NGX REST API, without a trailing slash. The server refuses to start without it.",
              "name": "PAPERLESS_MCP_PAPERLESS_URL"
            },
            {
              "description": "Paperless service-account token used for outbound API requests. The server refuses to start without it.",
              "isSecret": true,
              "name": "PAPERLESS_MCP_API_TOKEN"
            },
            {
              "default": "30.0",
              "description": "Per-request HTTP timeout in seconds.",
              "format": "number",
              "name": "PAPERLESS_MCP_HTTP_TIMEOUT_SECONDS"
            },
            {
              "default": "2",
              "description": "Retries for idempotent requests after network errors or 5xx responses.",
              "format": "number",
              "name": "PAPERLESS_MCP_HTTP_RETRIES"
            },
            {
              "default": "25",
              "description": "Default page size for list tools, from 1 through 100.",
              "format": "number",
              "name": "PAPERLESS_MCP_DEFAULT_PAGE_SIZE"
            },
            {
              "description": "Public Paperless UI URL for user-visible links; defaults to PAPERLESS_URL.",
              "name": "PAPERLESS_MCP_PAPERLESS_PUBLIC_URL"
            },
            {
              "default": "3600.0",
              "description": "Link lifetime in seconds when the caller requests no explicit TTL.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_TTL_DEFAULT_S"
            },
            {
              "default": "86400.0",
              "description": "Ceiling in seconds a caller-requested link TTL is clamped to.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_TTL_MAX_S"
            },
            {
              "default": "60.0",
              "description": "Post-success grace window in seconds: a served token's TTL shrinks to this so a stalled transfer can retry within it.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_GRACE_TTL_S"
            },
            {
              "default": "60.0",
              "description": "Crashed-handler reclaim window in seconds for an in-flight reservation.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_LEASE_S"
            },
            {
              "default": "104857600",
              "description": "Maximum size in bytes of a single upload.",
              "format": "number",
              "name": "PAPERLESS_MCP_TRANSFER_MAX_UPLOAD_BYTES"
            }
          ],
          "identifier": "ghcr.io/pvliesdonk/paperless-mcp:v3.0.0",
          "packageArguments": [
            {
              "default": "8000",
              "description": "Port for the HTTP transport",
              "name": "--port",
              "type": "named"
            }
          ],
          "registryType": "oci",
          "transport": {
            "type": "streamable-http",
            "url": "http://localhost:{--port}/mcp"
          }
        }
      ],
      "repository": {
        "source": "github",
        "url": "https://github.com/pvliesdonk/paperless-mcp"
      },
      "title": "Paperless MCP",
      "version": "3.0.0",
      "websiteUrl": "https://pvliesdonk.github.io/paperless-mcp/"
    }
  },
  "source": "mcp_registry",
  "summary": "Paperless-NGX over MCP: search, read, upload and tag documents; manage correspondents and types."
}

What the leaf hashes

{"body":"bbd0364cee44d1aa447bfedc67dde578bdd64f0efedffa0af378c163e8e24f95","id":48128,"kind":"listing","method":"baseline/1","observed_us":1793025411385918,"prev":null,"subject":"mcp_registry:io.github.pvliesdonk/paperless-mcp","subject_kind":"source_record"}

Proof

Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (296695 rows).

  1. 0x74e08281d197beb09e71b41fc8ded569a8786195664cbd128a9fbac10274272b
  2. 0x6859d0ab466db4aec311abe20d2b8b7ace5d67dcd7c82ecff9b94a0d1ced1d41
  3. 0xa3e1c482e8ac0ba4b69270100361bc5359f97de49f819948375915f51680d5b5
  4. 0xc936f0e3b137d35063a2095ae0994a6cc7380761a15d5e99eaba49be265a0e15
  5. 0x214a41e687acdae92a0fc88e26f095d3937ec426d930062b31c254819968c2d1
  6. 0x1901748d5792e72ce0d56cb0d212a160717f01406ab8408a1761b553fce9285c
  7. 0x875c66b057e56eaa888d39f5743c0015abedbe10432f399e67b9f6acbedb13f0
  8. 0x5d9ecfd959448624fcc7bb660082fd2521f479ffbb5b3177d7e47189c1381fae
  9. 0xfa0bf377c193bc06578e3240f9e9d08e5282e2836746fc9d37a4b125f582cc28
  10. 0x9ee05f244b24b5c2218a463b4ab58eba1018e880e4d46ed9425dabadbdd4bc8c
  11. 0xff8296d2db87846f2b3d9a7a4926ee8ea17587a9a2960c155a4f0e1d36206dd8
  12. 0x43ccc5fffcdb82bff6ecf4ac7157c905b45d2f0362e7f7fbe908de1250b9533c
  13. 0xdef3cab0b4070d8ad7f4f91288da4881d19789f131b1b353621df79df04a0617
  14. 0xc4fe2177880ea1b0e82b6fe4c270090fd0fbe5af3a42a8cbf6a6ba2fa35625f6
  15. 0x15039087bf60ae9b06b756ec3cbc299760e59923a438bbd91e34d105186db0ed
  16. 0x2b6e23e3624a1b66e1d2298cfbce99a93ce6b13d24a58112a71802d79c5f7a76
  17. 0xd21942ae3214eff88e08ab04884fd4b11958b51af9a0741b7668e2d07a2c56c9
  18. 0x9a9024edb5069d88a324facb310a5ce8e495214bbaa968f077bede437390194f
  19. 0x9b9ce5b74b9bab5121612ef6b64920a8d453cbf311096a423eef9702747e868a
Day root
0xf43e8dcc3d451a4788b26be904c55e8c4c0fa75c9666796c51db38d37e2c0df8
Chained
0x702d5ac508f08b0d1accf36af25822d8e5660367494edd17a642fb61e158a57a
Published
On Arc Testnet, block 69251483: 0x495162f8936e19f0039918feebe6c307f327cd6bf8c37219620b1970041fa9ae

How to check it · This row as JSON