Skip to main content
Glama

Paperless-NGX MCP Server

CodeRabbit Pull Request Reviews

Un servidor MCP (Model Context Protocol) para interactuar con un servidor API de Paperless-NGX. Este servidor proporciona herramientas para gestionar documentos, etiquetas, corresponsales y tipos de documento en tu instancia de Paperless-NGX.

Inicio rápido

Instalar servidor MCP

Instalación

Añade esto a tu archivo de configuración de MCP:

// Modo STDIO (recomendado para uso local o CLI)

"paperless": {
  "command": "npx",
  "args": [
    "-y",
    "@baruchiro/paperless-mcp@latest",
  ],
  "env": {
    "PAPERLESS_URL": "http://your-paperless-instance:8000",
    "PAPERLESS_API_KEY": "your-api-token",
    "PAPERLESS_PUBLIC_URL": "https://your-public-domain.com"
  }
}

// Modo HTTP (recomendado para Docker o uso remoto)

"paperless": {
  "command": "docker",
  "args": [
    "run",
    "-i",
    "--rm",
    "ghcr.io/baruchiro/paperless-mcp:latest",
  ],
  "env": {
    "PAPERLESS_URL": "http://your-paperless-instance:8000",
    "PAPERLESS_API_KEY": "your-api-token",
    "PAPERLESS_PUBLIC_URL": "https://your-public-domain.com"
  }
}
  1. Obtén tu token de API:

    1. Inicia sesión en tu instancia de Paperless-NGX

    2. Haz clic en tu nombre de usuario en la esquina superior derecha

    3. Selecciona "Mi perfil"

    4. Haz clic en el botón de flecha circular para generar un nuevo token

  2. Reemplaza los marcadores de posición en tu configuración de MCP:

    • http://your-paperless-instance:8000 por la URL de tu Paperless-NGX

    • your-api-token por el token que acabas de generar

    • https://your-public-domain.com por tu URL pública de Paperless-NGX (opcional, usa PAPERLESS_URL como respaldo)

Variables de entorno

Variable

Required

Default

Description

PAPERLESS_URL

URL base de tu instancia de Paperless-NGX

PAPERLESS_API_KEY

Token de API de tu perfil de Paperless-NGX

PAPERLESS_PUBLIC_URL

No

PAPERLESS_URL

URL pública para los enlaces de documentos

PAPERLESS_API_VERSION

No

9

Versión de la API REST de Paperless-ngx. 9 funciona en Paperless-ngx v2.x (recientes) y v3.x. Paperless-ngx v3.0.0 eliminó la compatibilidad con versiones inferiores a 9, por lo que los valores predeterminados antiguos ahora devuelven HTTP 406. Si ves errores HTTP 406, configúralo con una versión que tu servidor admita.

PAPERLESS_MCP_UPLOAD_PATHS

No

Lista separada por dos puntos de directorios permitidos para subidas mediante file_path. Recomendado por seguridad. Ejemplo: /var/uploads:/tmp/scans

¡Eso es todo! Ahora puedes pedirle a Claude que te ayude a gestionar tus documentos de Paperless-NGX.

Ejemplos de uso

Estas son algunas cosas que puedes pedirle a Claude que haga:

  • "Muéstrame todos los documentos etiquetados como 'Factura'"

  • "Busca documentos que contengan 'declaración de impuestos'"

  • "Crea una nueva etiqueta llamada 'Recibos' con el color #FF0000"

  • "Descarga el documento #123"

  • "Lista todos los corresponsales"

  • "Crea un nuevo tipo de documento llamado 'Extracto bancario'"

Related MCP server: paperless-mcp

Herramientas disponibles

Operaciones con documentos

list_documents

Obtén una lista paginada de documentos con filtros simples. Úsala para tareas de listado sencillas. Para consultas de texto completo, filtrado estructurado por campos personalizados o filtros avanzados de Paperless, usa query_documents.

Parámetros:

  • page (opcional): Número de página

  • page_size (opcional): Número de documentos por página

  • search (opcional): Término de búsqueda simple de Paperless

  • correspondent (opcional): ID del corresponsal

  • document_type (opcional): ID del tipo de documento

  • tag (opcional): ID de la etiqueta

  • storage_path (opcional): ID de la ruta de almacenamiento

  • created__date__gte (opcional): Fecha de creación en o después de YYYY-MM-DD

  • created__date__lte (opcional): Fecha de creación en o antes de YYYY-MM-DD

  • ordering (opcional): Campo de ordenación de Paperless

  • archive_serial_number (opcional): Número de serie de archivo

  • archive_serial_number__isnull (opcional): Indica si el número de serie de archivo está vacío

  • custom_field_query (opcional): Cadena de consulta de campos personalizados de Paperless codificada en JSON sin procesar

  • custom_fields__icontains (opcional): Coincidencia de subcadena sin distinción de mayúsculas y minúsculas en los valores de campos personalizados

list_documents({
  page: 1,
  page_size: 25
})

query_documents

Herramienta canónica de consulta de documentos. Admite consultas de texto completo, búsqueda simple de Paperless, filtros de campos personalizados y los parámetros de consulta documentados de Paperless /api/documents/.

Parámetros:

  • page (opcional): Número de página

  • page_size (opcional): Número de documentos por página

  • ordering (opcional): Campo de ordenación de Paperless

  • query (opcional): Cadena de consulta de texto completo

  • search (opcional): Término de búsqueda simple de Paperless

  • more_like_id (opcional): Busca documentos similares a este ID de documento

  • correspondent (opcional): ID del corresponsal

  • document_type (opcional): ID del tipo de documento

  • tag (opcional): ID de la etiqueta

  • storage_path (opcional): ID de la ruta de almacenamiento

  • created__date__gte (opcional): Fecha de creación en o después de YYYY-MM-DD

  • created__date__lte (opcional): Fecha de creación en o antes de YYYY-MM-DD

  • custom_field_query (opcional): Consulta estructurada de campos personalizados de Paperless usando hojas [field_name_or_id, operator, value] o grupos ["AND" | "OR", [clause1, clause2]]

  • paperless_filters (opcional): Parámetros de consulta adicionales documentados de Paperless /api/documents/, pasados como pares clave/valor

// Full-text query
query_documents({
  query: "invoice 2024"
})

// Simple search term
query_documents({
  search: "acme"
})

// Custom field exact match
query_documents({
  custom_field_query: ["Invoice Number", "exact", "12345"]
})

// Custom field empty
query_documents({
  custom_field_query: ["OR", [
    ["Invoice Number", "isnull", true],
    ["Invoice Number", "exact", ""]
  ]]
})

// Custom field missing
query_documents({
  custom_field_query: ["Invoice Number", "exists", false]
})

// Combined filters
query_documents({
  query: "invoice",
  tag: 5,
  created__date__gte: "2024-01-01",
  custom_field_query: ["Invoice Number", "exists", true]
})

// One documented Paperless filter that is not a first-class argument
query_documents({
  paperless_filters: {
    id__in: [101, 202, 303]
  }
})

get_document

Obtén un documento específico por su ID.

Parámetros:

  • id: ID del documento

get_document({
  id: 123
})

Envoltorio de compatibilidad obsoleto para la búsqueda de texto completo. Prefiere query_documents({ query: ... }) para nuevas integraciones.

Parámetros:

  • query: Cadena de consulta de búsqueda

search_documents({
  query: "invoice 2024"
})

download_document

Descarga el archivo de un documento por su ID.

Parámetros:

  • id: ID del documento

  • original (opcional): Si es true, descarga el archivo original en lugar de la versión archivada

download_document({
  id: 123,
  original: false
})

get_document_thumbnail

Obtén la miniatura de un documento (vista previa de imagen) por su ID. Devuelve la miniatura como un recurso de imagen WebP codificada en base64.

Parámetros:

  • id: ID del documento

get_document_thumbnail({
  id: 123
})

bulk_edit_documents

Realiza operaciones masivas en varios documentos.

Parámetros:

  • documents: Matriz de IDs de documentos

  • method: Uno de:

    • set_correspondent: Establece el corresponsal de los documentos

    • set_document_type: Establece el tipo de documento de los documentos

    • set_storage_path: Establece la ruta de almacenamiento de los documentos

    • add_tag: Añade una etiqueta a los documentos

    • remove_tag: Elimina una etiqueta de los documentos

    • modify_tags: Añade y/o elimina varias etiquetas

    • delete: Elimina documentos

    • reprocess: Reprocesa documentos

    • set_permissions: Establece los permisos de los documentos

    • merge: Combina varios documentos

    • split: Divide un documento en varios documentos

    • rotate: Rota las páginas de un documento

    • delete_pages: Elimina páginas específicas de un documento

  • Parámetros adicionales según el método:

    • correspondent: ID para set_correspondent

    • document_type: ID para set_document_type

    • storage_path: ID para set_storage_path

    • tag: ID para add_tag/remove_tag

    • add_tags: Matriz de IDs de etiquetas para modify_tags

    • remove_tags: Matriz de IDs de etiquetas para modify_tags

    • set_permissions: Objeto para set_permissions con usuarios y grupos de view/change ({"view": {"users": [], "groups": []}, "change": {...}}). Las acciones/listas omitidas se dejan sin tocar

    • owner: ID de usuario (o null para eliminarlo) para set_permissions. A menos que merge sea true, omitir owner elimina el propietario actual

    • merge: Booleano para set_permissions — true añade a los permisos existentes y conserva al propietario; false (predeterminado) reemplaza los usuarios/grupos indicados

    • metadata_document_id: ID para merge para especificar la fuente de metadatos

    • delete_originals: Booleano para merge/split

    • pages: Cadena para split "[1,2-3,4,5-7]" o delete_pages "[2,3,4]"

    • degrees: Número para rotate (90, 180 o 270)

Ejemplos:

// Add a tag to multiple documents
bulk_edit_documents({
  documents: [1, 2, 3],
  method: "add_tag",
  tag: 5
})

// Set correspondent and document type
bulk_edit_documents({
  documents: [4, 5],
  method: "set_correspondent",
  correspondent: 2
})

// Merge documents
bulk_edit_documents({
  documents: [6, 7, 8],
  method: "merge",
  metadata_document_id: 6,
  delete_originals: true
})

// Split document into parts
bulk_edit_documents({
  documents: [9],
  method: "split",
  pages: "[1-2,3-4,5]"
})

// Modify multiple tags at once
bulk_edit_documents({
  documents: [10, 11],
  method: "modify_tags",
  add_tags: [1, 2],
  remove_tags: [3, 4]
})

// Modify custom fields
bulk_edit_documents({
  documents: [12, 13],
  method: "modify_custom_fields",
  add_custom_fields: [
    { field: 2, value: "year" }
  ],
  remove_custom_fields: []
})

// Set an empty custom field value, e.g. a date field used as a pending marker
bulk_edit_documents({
  documents: [14],
  method: "modify_custom_fields",
  add_custom_fields: [
    { field: 9, value: "" }
  ],
  remove_custom_fields: []
})

post_document

Sube un nuevo documento a Paperless-NGX.

Dos modos de subida:

  1. Modo base64 (tradicional): Proporciona file (contenido codificado en base64) + filename

  2. Modo sistema de archivos (eficiente): Proporciona file_path (ruta absoluta en el servidor)

Nota de seguridad: Cuando uses file_path, configura la variable de entorno PAPERLESS_MCP_UPLOAD_PATHS (lista separada por dos puntos de directorios permitidos) para restringir las subidas a ubicaciones específicas. Sin esto, cualquier archivo del sistema de archivos del servidor podría subirse.

Parámetros:

  • file (opcional): Contenido del archivo codificado en base64. Se requiere file o file_path.

  • file_path (opcional): Ruta absoluta al archivo en el sistema de archivos del servidor. Se requiere file o file_path.

  • filename (opcional): Nombre del archivo. Obligatorio con file, opcional con file_path (se deriva de la ruta).

  • title (opcional): Título del documento

  • created (opcional): Fecha y hora en que se creó el documento (p. ej. "2024-01-19" o "2024-01-19 06:15:00+02:00")

  • correspondent (opcional): ID de un corresponsal

  • document_type (opcional): ID de un tipo de documento

  • storage_path (opcional): ID de una ruta de almacenamiento

  • tags (opcional): Matriz de IDs de etiquetas

  • archive_serial_number (opcional): Número de serie de archivo

  • custom_fields (opcional): Matriz de IDs de campos personalizados

Límite de tamaño de archivo: 100MB para ambos modos

// Base64 mode (traditional)
post_document({
  file: "base64_encoded_content",
  filename: "invoice.pdf",
  title: "January Invoice",
  created: "2024-01-19",
  correspondent: 1,
  document_type: 2,
  tags: [1, 3],
  archive_serial_number: "2024-001",
  custom_fields: [1, 2]
})

// Filesystem mode (more efficient for large files)
post_document({
  file_path: "/var/uploads/invoice.pdf",
  title: "January Invoice",
  correspondent: 1,
  document_type: 2,
  tags: [1, 3]
})

Notas de documentos

list_document_notes

Lista todas las notas adjuntas a un documento.

Parámetros:

  • id: ID del documento

list_document_notes({
  id: 123
})

create_document_note

Añade una nota a un documento. Devuelve la lista completa de notas del documento.

Parámetros:

  • id: ID del documento

  • note: El texto de la nota que se va a añadir

create_document_note({
  id: 123,
  note: "Invoice paid on 2026-06-30 from Commerzbank account."
})

delete_document_note

⚠️ Elimina una sola nota de un documento por su ID de nota. Esta operación es irreversible.

Parámetros:

  • id: ID del documento

  • note_id: El ID de la nota que se va a eliminar

  • confirm: Debe ser true para confirmar esta operación destructiva

delete_document_note({
  id: 123,
  note_id: 5,
  confirm: true
})

Operaciones con etiquetas

list_tags

Obtén todas las etiquetas.

list_tags()

create_tag

Crea una nueva etiqueta.

Parámetros:

  • name: Nombre de la etiqueta

  • color (opcional): Código de color hexadecimal (p. ej. "#ff0000")

  • match (opcional): Patrón de texto para coincidir

  • matching_algorithm (opcional): Número entre 0 y 6: 0 - Ninguno 1 - Cualquier palabra 2 - Todas las palabras 3 - Coincidencia exacta 4 - Expresión regular 5 - Palabra difusa 6 - Automático

create_tag({
  name: "Invoice",
  color: "#ff0000",
  match: "invoice",
  matching_algorithm: 5
})

Operaciones con corresponsales

list_correspondents

Obtén todos los corresponsales.

list_correspondents()

create_correspondent

Crea un nuevo corresponsal.

Parámetros:

  • name: Nombre del corresponsal

  • match (opcional): Patrón de texto para coincidir

  • matching_algorithm (opcional): Número entre 0 y 6: 0 - Ninguno 1 - Cualquier palabra 2 - Todas las palabras 3 - Coincidencia exacta 4 - Expresión regular 5 - Palabra difusa 6 - Automático

create_correspondent({
  name: "ACME Corp",
  match: "ACME",
  matching_algorithm: 5
})

Operaciones con tipos de documento

list_document_types

Obtén todos los tipos de documento.

list_document_types()

create_document_type

Crea un nuevo tipo de documento.

Parámetros:

  • name: Nombre del tipo de documento

  • match (opcional): Patrón de texto que debe coincidir

  • matching_algorithm (opcional): Número entre 0 y 6: 0 - Ninguno 1 - Cualquier palabra 2 - Todas las palabras 3 - Coincidencia exacta 4 - Expresión regular 5 - Palabra difusa 6 - Automático

create_document_type({
  name: "Invoice",
  match: "invoice total amount due",
  matching_algorithm: 1
})

Operaciones de campos personalizados

list_custom_fields

Obtiene todos los campos personalizados.

list_custom_fields()

get_custom_field

Obtiene un campo personalizado específico por su ID.

Parámetros:

  • id: ID del campo personalizado

get_custom_field({
  id: 1
})

create_custom_field

Crea un nuevo campo personalizado.

Parámetros:

  • name: Nombre del campo personalizado

  • data_type: Uno de "string", "url", "date", "boolean", "integer", "float", "monetary", "documentlink", "select"

  • extra_data (opcional): Datos adicionales para el campo personalizado, como opciones de selección

create_custom_field({
  name: "Invoice Number",
  data_type: "string"
})

update_custom_field

Actualiza un campo personalizado existente.

Parámetros:

  • id: ID del campo personalizado

  • name (opcional): Nuevo nombre del campo personalizado

  • data_type (opcional): Nuevo tipo de datos

  • extra_data (opcional): Datos adicionales para el campo personalizado

update_custom_field({
  id: 1,
  name: "Updated Invoice Number",
  data_type: "string"
})

delete_custom_field

Elimina un campo personalizado.

Parámetros:

  • id: ID del campo personalizado

delete_custom_field({
  id: 1
})

bulk_edit_custom_fields

Realiza operaciones masivas sobre varios campos personalizados.

Parámetros:

  • custom_fields: Array de IDs de campos personalizados

  • operation: Uno de "delete"

bulk_edit_custom_fields({
  custom_fields: [1, 2, 3],
  operation: "delete"
})

Operaciones de correo

Herramientas para gestionar las cuentas de correo de Paperless y las reglas de correo que controlan la ingesta automática de emails. Las contraseñas/tokens de las cuentas nunca se exponen: se redactan en todas las respuestas de las herramientas.

list_mail_accounts

Lista las cuentas de correo para que puedas elegir el ID de cuenta necesario al crear una regla de correo. Las contraseñas se redactan.

Parámetros:

  • page (opcional): Número de página

  • page_size (opcional): Número de resultados por página

list_mail_accounts()

get_mail_account

Obtiene una única cuenta de correo por ID. Los campos de contraseña/token se redactan.

Parámetros:

  • id: ID de la cuenta de correo

get_mail_account({
  id: 1
})

process_mail_account

Activa manualmente el procesamiento de correo de Paperless para una cuenta. Esto puede consumir los correos coincidentes según las reglas de correo habilitadas de la cuenta.

Parámetros:

  • id: ID de la cuenta de correo

process_mail_account({
  id: 1
})

list_mail_rules

Lista las reglas de correo con paginación opcional.

Parámetros:

  • page (opcional): Número de página

  • page_size (opcional): Número de resultados por página

list_mail_rules()

get_mail_rule

Obtiene una única regla de correo por ID.

Parámetros:

  • id: ID de la regla de correo

get_mail_rule({
  id: 1
})

create_mail_rule

Crea una regla de correo. Usa list_mail_accounts primero para elegir la cuenta.

Parámetros obligatorios:

  • name: Nombre de la regla

  • account: ID de la cuenta de correo

  • folder: Carpeta IMAP a escanear (p. ej., "INBOX")

Parámetros opcionales comunes:

  • enabled (true por defecto): Si la regla está activa

  • filter_from / filter_to / filter_subject / filter_body: Coincidir con el correo entrante

  • maximum_age: Procesar solo correos más recientes que este número de días

  • action: 1=Eliminar, 2=Mover a carpeta, 3=Marcar como leído, 4=Marcar, 5=Etiquetar

  • action_parameter: Carpeta/etiqueta de destino para la acción elegida

  • assign_title_from: 1=Asunto, 2=Nombre del archivo adjunto, 3=No asignar

  • assign_tags / assign_correspondent / assign_document_type: Metadatos a aplicar

  • assign_correspondent_from: 1=Ninguno, 2=Dirección de correo, 3=Nombre del remitente, 4=Usar assign_correspondent

  • attachment_type: 1=Solo adjuntos, 2=Todos los archivos, incl. inline

  • consumption_scope: 1=Solo adjuntos, 2=Correo completo como .eml, 3=Ambos

  • pdf_layout: 0=Predeterminado del sistema, 1=Texto+HTML, 2=HTML+texto, 3=Solo HTML, 4=Solo texto

create_mail_rule({
  name: "Invoices",
  account: 1,
  folder: "INBOX",
  filter_subject: "invoice",
  action: 3,
  attachment_type: 1
})

update_mail_rule

Actualiza parcialmente una regla de correo existente. Solo se modifican los campos que proporciones.

Parámetros:

  • id: ID de la regla de correo

  • ...cualquiera de los campos de create_mail_rule para actualizar

update_mail_rule({
  id: 1,
  enabled: false
})

delete_mail_rule

Elimina una regla de correo. Requiere un indicador de confirmación explícito. Esto cambia el comportamiento futuro de ingesta de correo, pero no elimina ningún documento existente.

Parámetros:

  • id: ID de la regla de correo

  • confirm: Debe ser true para confirmar la eliminación

delete_mail_rule({
  id: 1,
  confirm: true
})

Manejo de errores

El servidor mostrará mensajes de error claros si:

  • La URL o el token de API de Paperless-NGX es incorrecto

  • El servidor de Paperless-NGX no es accesible

  • La operación solicitada falla

  • Los parámetros proporcionados no son válidos

Pruebas

Pruebas unitarias

Ejecuta la suite de pruebas unitarias (no se requieren dependencias externas):

npm test

Pruebas E2E

La suite E2E inicia una instancia vacía de Paperless-ngx, ejecuta el servidor MCP compilado y recorre un escenario secuencial determinista mediante peticiones tools/call: crea una etiqueta, un corresponsal y un tipo de documento, sube un PDF y luego prueba list / get / search / download / thumbnail / bulk-edit sobre el mismo documento. Sin LLM y sin cliente REST de Paperless fuera de MCP.

Requisitos previos: Docker, Docker Compose y jq.

# 1. Build the MCP server
npm run build

# 2. Start Paperless-ngx
docker compose -f docker-compose.e2e.yml up -d

# 3. Wait for Paperless to be ready, then get a token
TOKEN=$(curl -s -X POST http://localhost:8000/api/token/ \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin123"}' | jq -r '.token')

# 4. Start the MCP server
node build/index.js --http --port 3001 \
  --baseUrl http://localhost:8000 --token "$TOKEN" &
MCP_PID=$!

# 5. Run the E2E tests
MCP_URL=http://localhost:3001/mcp \
PAPERLESS_URL=http://localhost:8000 \
PAPERLESS_TOKEN="$TOKEN" \
npm run test:e2e

# 6. Cleanup
kill "$MCP_PID"
docker compose -f docker-compose.e2e.yml down -v

Las pruebas E2E también se ejecutan automáticamente en CI en cada pull request y push a main, cubriendo tanto la CLI build/index.js como la imagen Docker publicada.

Desarrollo

¿Quieres contribuir o modificar el servidor? Esto es lo que necesitas saber:

  1. Clona el repositorio

  2. Instala las dependencias:

npm install
  1. Haz tus cambios en server.js

  2. Prueba localmente:

node server.js http://localhost:8000 your-test-token

El servidor está construido con:

  • litemcp: Un framework de TypeScript para construir servidores MCP

  • zod: Validación de esquemas TypeScript-first

Documentación de la API

Este servidor MCP implementa endpoints de la API REST de Paperless-NGX. Para más detalles sobre la API subyacente, consulta la documentación oficial.

Ejecución del servidor MCP

El servidor MCP se puede ejecutar de dos modos:

1. stdio (predeterminado)

Este es el modo predeterminado. El servidor se comunica a través de stdio, adecuado para CLI e integraciones directas.

npm run start -- <baseUrl> <token>

2. HTTP (Streamable HTTP Transport)

Para ejecutar el servidor como un servicio HTTP, usa la opción --http. También puedes especificar el puerto con --port (predeterminado: 3000). Este modo requiere que Express esté instalado (se incluye como dependencia).

npm run start -- <baseUrl> <token> --http --port 3000
  • La API MCP estará disponible en POST /mcp en el puerto especificado.

  • Cada petición se gestiona sin estado, siguiendo el patrón de StreamableHTTPServerTransport.

  • Las peticiones GET y DELETE a /mcp devolverán 405 Method Not Allowed.

Token de API por petición (modo HTTP/Docker)

En modo HTTP, los clientes se autentican proporcionando un token de API de Paperless-NGX mediante la cabecera estándar Authorization:

Authorization: Bearer <paperless-ngx-api-token>

El token se pasa directamente a Paperless-NGX, por lo que los permisos de Paperless de cada cliente se aplican de extremo a extremo. Esto permite que una única instancia del servidor atienda a múltiples usuarios, cada uno con su propio token. El mismo comportamiento se aplica tanto a los endpoints /mcp como /sse.

⚠️ Cambio importante en v2.0.0 — el modo HTTP ahora está autenticado por defecto.

Anteriormente, una petición sin cabecera Authorization recurría silenciosamente a la PAPERLESS_API_KEY configurada en el servidor, lo que dejaba el endpoint HTTP abierto a cualquiera que pudiera alcanzar el puerto. A partir de v2.0.0, las peticiones sin token Bearer se rechazan con 401 Unauthorized. El token del servidor nunca se usa para peticiones no autenticadas a menos que se opte explícitamente por --no-auth.

Escenario

--no-auth desactivado (predeterminado)

--no-auth activado

El cliente envía Authorization: Bearer <tok>

<tok> (proporcionado por el cliente)

<tok> (proporcionado por el cliente)

Sin cabecera, con PAPERLESS_API_KEY / --token configurados

401 Unauthorized

token del servidor

Sin cabecera, sin token del servidor

401 Unauthorized

401 Unauthorized

Migración desde v1.x: si dependías del fallback antiguo (una única PAPERLESS_API_KEY compartida con clientes que no envían token), tienes dos opciones:

  1. Recomendado: haz que cada cliente envíe Authorization: Bearer <paperless-token>.

  2. Restaurar el comportamiento anterior (solo redes locales/de confianza): inicia el servidor con la opción --no-auth, p. ej. añádela al command/args de Docker o a tu invocación de CLI. Esto requiere que se configure un token de servidor (PAPERLESS_API_KEY o --token).

El servidor MCP se puede desplegar usando Docker y Docker Compose. La imagen Docker se ejecuta automáticamente en modo HTTP con soporte SSE (Server-Sent Events) en el puerto 3000.

Configuración de Docker Compose

Crea un archivo docker-compose.yml:

services:
  paperless-mcp:
    container_name: paperless-mcp
    image: ghcr.io/baruchiro/paperless-mcp:latest
    environment:
      - PAPERLESS_URL=http://your-paperless-ngx-server:8000
      - PAPERLESS_API_KEY=your-paperless-api-key
      - PAPERLESS_PUBLIC_URL=https://paperless-ngx.yourpublicurl.com
    ports:
      - "3000:3000"
    restart: unless-stopped

Luego ejecuta:

docker-compose up -d

Uso con la extensión Continue de VS Code

Si usas la extensión Continue de VS Code, puedes configurarla para usar el servidor MCP dockerizado mediante SSE.

Crea o edita .continue/mcpServers/paperless-mcp.yaml en la raíz de tu espacio de trabajo:

name: Paperless
version: 0.0.1
schema: v1
mcpServers:
  - name: Paperless
    type: sse
    url: http://localhost:3000/sse

Notas:

  • Reemplaza localhost por la dirección IP o el nombre de host de tu host Docker si se ejecuta en un servidor remoto

  • El contenedor Docker gestiona la autenticación mediante variables de entorno, por lo que no se necesitan credenciales en la configuración de Continue

  • El endpoint SSE está disponible en /sse en el puerto configurado (predeterminado: 3000)

Créditos

Este proyecto es un fork de nloui/paperless-mcp. Muchas gracias al autor original por su trabajo. Las contribuciones y mejoras pueden devolverse al proyecto original (upstream).

Depuración

Para depurar el servidor MCP en VS Code, usa la siguiente configuración de lanzamiento:

{
    "type": "node",
    "request": "launch",
    "name": "Debug Paperless MCP (HTTP, ts-node ESM)",
    "program": "${workspaceFolder}/node_modules/ts-node/dist/bin.js",
    "args": [
        "--esm",
        "src/index.ts",
        "--http",
        "--baseUrl",
        "http://your-paperless-instance:8000",
        "--token",
        "your-api-token",
        "--port",
        "3002"
    ],
    "env": {
        "NODE_OPTIONS": "--loader ts-node/esm",
    },
    "console": "integratedTerminal",
    "skipFiles": [
        "<node_internals>/**"
    ]
}

Importante: antes de depurar, descomenta la siguiente línea en src/index.ts (alrededor de la línea 175):

// await new Promise((resolve) => setTimeout(resolve, 1000000));

Esto evita que el servidor se cierre inmediatamente y te permite establecer puntos de interrupción y depurar el código.

A
license - permissive license
C
quality
A
maintenance

Maintenance

Maintainers
2dResponse time
Release cycle
Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for the PDFGate API. Generate PDFs, manage documents and handle e-signatures.

  • PandaDoc MCP server for creating, sending, signing, and tracking PandaDoc documents.

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/baruchiro/paperless-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server