Skip to main content
Glama

bulk_edit_documents

Edit multiple documents simultaneously on Paperless-MCP by setting correspondents, document types, storage paths, tags, permissions, or applying actions like merge, split, rotate, or delete.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
add_tagsNo
correspondentNo
degreesNo
delete_originalsNo
document_typeNo
documentsYes
metadata_document_idNo
methodYes
pagesNo
permissionsNo
remove_tagsNo
storage_pathNo
tagNo

Implementation Reference

  • The handler function for the 'bulk_edit_documents' MCP tool. It performs input validation (e.g., confirmation for delete), transforms custom fields parameters, calls the PaperlessAPI.bulkEditDocuments method, and formats the response as MCP content.
    withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); if (args.method === "delete" && !args.confirm) { throw new Error( "Confirmation required for destructive operation. Set confirm: true to proceed." ); } const { documents, method, add_custom_fields, ...parameters } = args; // Transform add_custom_fields into the two separate API parameters const apiParameters = { ...parameters }; if (add_custom_fields && add_custom_fields.length > 0) { apiParameters.assign_custom_fields = add_custom_fields.map( (cf) => cf.field ); apiParameters.assign_custom_fields_values = add_custom_fields; } const response = await api.bulkEditDocuments( documents, method, apiParameters ); return { content: [ { type: "text", text: JSON.stringify({ result: response.result || response }), }, ], }; })
  • Zod schema defining the input parameters for the 'bulk_edit_documents' tool, including required 'documents' and 'method', optional fields for various operations, and validation transforms.
    { documents: z.array(z.number()), method: z.enum([ "set_correspondent", "set_document_type", "set_storage_path", "add_tag", "remove_tag", "modify_tags", "modify_custom_fields", "delete", "reprocess", "set_permissions", "merge", "split", "rotate", "delete_pages", ]), correspondent: z.number().optional(), document_type: z.number().optional(), storage_path: z.number().optional(), tag: z.number().optional(), add_tags: z.array(z.number()).optional().transform(arrayNotEmpty), remove_tags: z.array(z.number()).optional().transform(arrayNotEmpty), add_custom_fields: z .array( z.object({ field: z.number(), value: z.union([z.string(), z.number(), z.boolean(), z.null()]), }) ) .optional() .transform(arrayNotEmpty), remove_custom_fields: z .array(z.number()) .optional() .transform(arrayNotEmpty), permissions: z .object({ owner: z.number().nullable().optional(), set_permissions: z .object({ view: z.object({ users: z.array(z.number()), groups: z.array(z.number()), }), change: z.object({ users: z.array(z.number()), groups: z.array(z.number()), }), }) .optional(), merge: z.boolean().optional(), }) .optional() .transform(objectNotEmpty), metadata_document_id: z.number().optional(), delete_originals: z.boolean().optional(), pages: z.string().optional(), degrees: z.number().optional(), confirm: z .boolean() .optional() .describe( "Must be true when method is 'delete' to confirm destructive operation" ), },
  • The server.tool() call that registers the 'bulk_edit_documents' tool on the MCP server, specifying name, description, input schema, and handler function.
    server.tool( "bulk_edit_documents", "Perform bulk operations on multiple documents. Note: 'remove_tag' removes a tag from specific documents (tag remains in system), while 'delete_tag' permanently deletes a tag from the entire system. ⚠️ WARNING: 'delete' method permanently deletes documents and requires confirmation.", { documents: z.array(z.number()), method: z.enum([ "set_correspondent", "set_document_type", "set_storage_path", "add_tag", "remove_tag", "modify_tags", "modify_custom_fields", "delete", "reprocess", "set_permissions", "merge", "split", "rotate", "delete_pages", ]), correspondent: z.number().optional(), document_type: z.number().optional(), storage_path: z.number().optional(), tag: z.number().optional(), add_tags: z.array(z.number()).optional().transform(arrayNotEmpty), remove_tags: z.array(z.number()).optional().transform(arrayNotEmpty), add_custom_fields: z .array( z.object({ field: z.number(), value: z.union([z.string(), z.number(), z.boolean(), z.null()]), }) ) .optional() .transform(arrayNotEmpty), remove_custom_fields: z .array(z.number()) .optional() .transform(arrayNotEmpty), permissions: z .object({ owner: z.number().nullable().optional(), set_permissions: z .object({ view: z.object({ users: z.array(z.number()), groups: z.array(z.number()), }), change: z.object({ users: z.array(z.number()), groups: z.array(z.number()), }), }) .optional(), merge: z.boolean().optional(), }) .optional() .transform(objectNotEmpty), metadata_document_id: z.number().optional(), delete_originals: z.boolean().optional(), pages: z.string().optional(), degrees: z.number().optional(), confirm: z .boolean() .optional() .describe( "Must be true when method is 'delete' to confirm destructive operation" ), }, withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); if (args.method === "delete" && !args.confirm) { throw new Error( "Confirmation required for destructive operation. Set confirm: true to proceed." ); } const { documents, method, add_custom_fields, ...parameters } = args; // Transform add_custom_fields into the two separate API parameters const apiParameters = { ...parameters }; if (add_custom_fields && add_custom_fields.length > 0) { apiParameters.assign_custom_fields = add_custom_fields.map( (cf) => cf.field ); apiParameters.assign_custom_fields_values = add_custom_fields; } const response = await api.bulkEditDocuments( documents, method, apiParameters ); return { content: [ { type: "text", text: JSON.stringify({ result: response.result || response }), }, ], }; }) );
  • Helper method in PaperlessAPI class that sends the bulk edit request to the Paperless-ngx API endpoint '/documents/bulk_edit/'.
    async bulkEditDocuments( documents: number[], method: string, parameters: BulkEditParameters = {} ): Promise<BulkEditDocumentsResult> { return this.request<BulkEditDocumentsResult>("/documents/bulk_edit/", { method: "POST", body: JSON.stringify({ documents, method, parameters, }), }); }
  • TypeScript interfaces for BulkEditDocumentsResult (output) and BulkEditParameters (input parameters for the API call).
    export interface BulkEditDocumentsResult { result: string; } export interface BulkEditParameters { assign_custom_fields?: number[]; assign_custom_fields_values?: CustomFieldInstanceRequest[]; remove_custom_fields?: number[]; add_tags?: number[]; remove_tags?: number[]; degrees?: number; pages?: string; metadata_document_id?: number; delete_originals?: boolean; correspondent?: number; document_type?: number; storage_path?: number; tag?: number; permissions?: { owner?: number | null; set_permissions?: { view: { users: number[]; groups: number[] }; change: { users: number[]; groups: number[] }; }; merge?: boolean; }; }

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