Skip to main content
Glama
customFields.ts5.27 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp"; import { z } from "zod"; import { PaperlessAPI } from "../api/PaperlessAPI"; import { withErrorHandling } from "./utils/middlewares"; import { buildQueryString } from "./utils/queryString"; export function registerCustomFieldTools(server: McpServer, api: PaperlessAPI) { server.tool( "list_custom_fields", "List all custom fields. IMPORTANT: When a user query may refer to a custom field, you should fetch all custom fields up front (with a large enough page_size), cache them for the session, and search locally for matches by name before making further API calls. This reduces redundant requests and handles ambiguity efficiently.", { page: z.number().optional(), page_size: z.number().optional(), name__icontains: z.string().optional(), name__iendswith: z.string().optional(), name__iexact: z.string().optional(), name__istartswith: z.string().optional(), ordering: z.string().optional(), }, withErrorHandling(async (args = {}) => { if (!api) throw new Error("Please configure API connection first"); const queryString = buildQueryString(args); const response = await api.request( `/custom_fields/${queryString ? `?${queryString}` : ""}` ); return { content: [ { type: "text", text: JSON.stringify(response), }, ], }; }) ); server.tool( "get_custom_field", "Get a specific custom field by ID with full details including data type and extra configuration.", { id: z.number() }, withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); const response = await api.getCustomField(args.id); return { content: [{ type: "text", text: JSON.stringify(response) }], }; }) ); server.tool( "create_custom_field", "Create a new custom field with a specified data type (string, url, date, boolean, integer, float, monetary, documentlink, or select).", { name: z.string(), data_type: z.enum([ "string", "url", "date", "boolean", "integer", "float", "monetary", "documentlink", "select", ]), extra_data: z.record(z.unknown()).nullable().optional(), }, withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); const response = await api.createCustomField(args); return { content: [{ type: "text", text: JSON.stringify(response) }], }; }) ); server.tool( "update_custom_field", "Update an existing custom field's name, data type, or extra configuration data.", { id: z.number(), name: z.string().optional(), data_type: z .enum([ "string", "url", "date", "boolean", "integer", "float", "monetary", "documentlink", "select", ]) .optional(), extra_data: z.record(z.unknown()).nullable().optional(), }, withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); const { id, ...data } = args; const response = await api.updateCustomField(id, data); return { content: [{ type: "text", text: JSON.stringify(response) }], }; }) ); server.tool( "delete_custom_field", "⚠️ DESTRUCTIVE: Permanently delete a custom field from the entire system. This will remove the field from ALL documents that use it.", { id: z.number(), confirm: z.boolean().describe("Must be true to confirm this destructive operation"), }, withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); if (!args.confirm) { throw new Error("Confirmation required for destructive operation. Set confirm: true to proceed."); } await api.deleteCustomField(args.id); return { content: [ { type: "text", text: JSON.stringify({ status: "deleted" }) }, ], }; }) ); server.tool( "bulk_edit_custom_fields", "Bulk edit custom fields. ⚠️ WARNING: 'delete' operation permanently removes custom fields from the entire system.", { custom_fields: z.array(z.number()), operation: z.enum(["delete"]), confirm: z.boolean().optional().describe("Must be true when operation is 'delete' to confirm destructive operation"), }, withErrorHandling(async (args, extra) => { if (!api) throw new Error("Please configure API connection first"); if (args.operation === "delete" && !args.confirm) { throw new Error("Confirmation required for destructive operation. Set confirm: true to proceed."); } const response = await api.bulkEditObjects( args.custom_fields, "custom_field", args.operation ); return { content: [ { type: "text", text: JSON.stringify(response), }, ], }; }) ); }

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