Skip to content

custom field operations#17

Merged
baruchiro merged 10 commits into
mainfrom
feature/custom-fields-support-CU-16
Aug 7, 2025
Merged

custom field operations#17
baruchiro merged 10 commits into
mainfrom
feature/custom-fields-support-CU-16

Conversation

@baruchiro
Copy link
Copy Markdown
Owner

@baruchiro baruchiro commented Jul 30, 2025

This PR refactors error handling across all tool registration functions and adds comprehensive custom field operations to the Paperless-NGX MCP Server.

Fix #16

Changes Made

Error Handling Refactor

  • Replaced errorMiddleware with withErrorHandling in all tool registration functions for better consistency and clarity
  • Updated error handling middleware in:
    • src/tools/correspondents.ts
    • src/tools/customFields.ts
    • src/tools/documentTypes.ts
    • src/tools/documents.ts
    • src/tools/tags.ts
    • src/tools/utils/middlewares.ts

Custom Field Operations

  • Added complete custom field CRUD operations to PaperlessAPI.ts
  • Implemented custom field tools with full functionality:
    • list_custom_fields - Get paginated list with filtering
    • get_custom_field - Get single custom field by ID
    • create_custom_field - Create new custom fields
    • update_custom_field - Update existing custom fields
    • delete_custom_field - Delete custom fields
    • bulk_edit_custom_fields - Bulk operations on multiple fields
  • Added CustomField and CustomFieldInstance interfaces to types.ts
  • Updated Document interface to use CustomFieldInstance array
  • Registered custom field tools in main server index

API Specification

  • Added Paperless-ngx REST API OpenAPI specification
  • Included endpoints for bulk editing objects, application configuration, and correspondents operations
  • Added comprehensive documentation for custom field operations

Benefits

  • Improved error handling consistency across all tools
  • Enhanced type safety with proper interfaces
  • Complete custom field management capabilities
  • Better API compliance with OpenAPI specification

Summary by CodeRabbit

  • New Features

    • Added full support for managing custom fields on documents, including listing, retrieving, creating, updating, deleting, and bulk editing custom fields.
    • Introduced the ability to update documents, including custom fields, via a new update tool.
    • Enhanced document responses to include human-readable names for related entities and custom fields.
    • Added VS Code debugging configuration and documentation for custom field operations.
  • Improvements

    • Improved error handling with more descriptive messages and consistent middleware usage.
    • Explicit confirmation is now required for destructive actions (delete operations) across tags, correspondents, document types, and custom fields.
    • Extended bulk edit capabilities for documents to support adding/removing custom fields.
  • Documentation

    • Expanded README and internal documentation to cover custom field operations, debugging, and API validation/type safety guidelines.
  • Chores

    • Refactored middleware and utility functions for consistency and clarity.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jul 30, 2025

🦋 Changeset detected

Latest commit: 3e270e0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@baruchiro/paperless-mcp Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@baruchiro
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 7, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 7, 2025

Warning

Rate limit exceeded

@baruchiro has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 12 minutes and 47 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between ec28756 and 3e270e0.

📒 Files selected for processing (3)
  • .cursor/rules/types-usage.mdc (1 hunks)
  • src/api/types.ts (4 hunks)
  • src/tools/customFields.ts (1 hunks)
📝 Walkthrough

Walkthrough

This set of changes introduces comprehensive support for custom fields in the Paperless-NGX MCP server. It adds CRUD operations for custom fields, enables bulk editing of custom fields in documents, and updates the document model and related API methods to handle custom fields with strong typing. Documentation and usage examples are extended in the README. Additionally, destructive operations (delete, bulk delete) across several tool modules now require explicit user confirmation. Utility functions for checking non-empty arrays and objects are added, and error handling middleware is renamed and updated for consistency and improved error reporting. Documentation files outlining API validation, server patterns, and type usage are also added or updated.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Ensure custom fields in document responses return with their general name, not just IDs (#16)

Assessment against linked issues: Out-of-scope changes

Code Change (file_path) Explanation
Addition of .cursor/rules/api-validation.mdc, .cursor/rules/mcp-server-patterns.mdc, .cursor/rules/types-usage.mdc, and modification of .cursor/rules/http-transport.mdc These are documentation and rule files for internal development guidelines and are not directly related to the custom fields name resolution objective in #16.
Deletion of .cursor/rules/typescript-mcp-migration.mdc This removes internal migration documentation, unrelated to the linked issue's objective.
Addition of .changeset/stupid-tools-battle.md This is a changeset metadata file for release/versioning and does not relate to the functional requirement of custom field naming.
Addition of VS Code debugging instructions and launch configuration in README.md The debugging section is unrelated to the custom fields naming requirement in #16.
Addition of utility functions for non-empty arrays/objects in src/tools/utils/empty.ts These helpers are general-purpose and not directly required for resolving custom field names.
Enforcement of explicit confirmation for destructive operations in tags, correspondents, and document types tool modules These safety enhancements are not part of the custom field naming objective in #16.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/custom-fields-support-CU-16

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@baruchiro
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 7, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
src/index.ts (1)

173-173: Consider removing or documenting the debugging timeout.

The commented-out setTimeout appears to be for debugging purposes to prevent server exit. Consider either removing it if no longer needed or adding a comment explaining its debugging purpose.

-    // await new Promise((resolve) => setTimeout(resolve, 1000000));
+    // Debugging: Uncomment to prevent server exit for debugging
+    // await new Promise((resolve) => setTimeout(resolve, 1000000));
src/tools/customFields.ts (2)

37-47: Add tool description.

The get_custom_field tool is missing a description parameter, which is inconsistent with other tools in the codebase.

Apply this diff to add a description:

  server.tool(
    "get_custom_field",
+   "Get a specific custom field by ID",
    { id: z.number() },

53-63: Extract common enum to reduce duplication.

The data_type enum is duplicated between the create and update tools. Consider extracting it to a shared constant to improve maintainability.

Add this constant at the top of the file after imports:

const DATA_TYPE_ENUM = z.enum([
  "string",
  "url", 
  "date",
  "boolean",
  "integer",
  "float",
  "monetary",
  "documentlink",
  "select",
]);

Then use DATA_TYPE_ENUM and DATA_TYPE_ENUM.optional() in both schemas.

Also applies to: 80-92

.cursor/rules/mcp-server-patterns.mdc (1)

84-86: Remove duplicated documentation lines.

Lines 84-86 duplicate the content from lines 82-84 in the Documentation section.

Remove the duplicate lines:

-- Document parameter types and constraints
-- Provide usage examples in README
-- Note any important efficiency considerations
src/api/documentEnhancer.ts (1)

10-14: Potential naming conflict with imported types.

The local CustomField interface has the same name as the one imported from ./types (line 3), which could cause confusion. Consider renaming this local interface to EnhancedCustomField or CustomFieldWithName to avoid ambiguity.

-interface CustomField {
+interface EnhancedCustomField {
   field: number;
   name: string;
   value: string | number | boolean | object | null;
 }

And update the usage in the EnhancedDocument interface:

 export interface EnhancedDocument
   extends Omit<
     Document,
     "correspondent" | "document_type" | "tags" | "custom_fields"
   > {
   correspondent: NamedItem | null;
   document_type: NamedItem | null;
   tags: NamedItem[];
-  custom_fields: CustomField[];
+  custom_fields: EnhancedCustomField[];
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70698f6 and ec28756.

📒 Files selected for processing (18)
  • .changeset/stupid-tools-battle.md (1 hunks)
  • .cursor/rules/api-validation.mdc (1 hunks)
  • .cursor/rules/http-transport.mdc (1 hunks)
  • .cursor/rules/mcp-server-patterns.mdc (1 hunks)
  • .cursor/rules/types-usage.mdc (1 hunks)
  • .cursor/rules/typescript-mcp-migration.mdc (0 hunks)
  • README.md (4 hunks)
  • src/api/PaperlessAPI.ts (6 hunks)
  • src/api/documentEnhancer.ts (1 hunks)
  • src/api/types.ts (4 hunks)
  • src/index.ts (4 hunks)
  • src/tools/correspondents.ts (8 hunks)
  • src/tools/customFields.ts (1 hunks)
  • src/tools/documentTypes.ts (8 hunks)
  • src/tools/documents.ts (12 hunks)
  • src/tools/tags.ts (7 hunks)
  • src/tools/utils/empty.ts (1 hunks)
  • src/tools/utils/middlewares.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • .cursor/rules/typescript-mcp-migration.mdc
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to **/*.ts : Type safety is enforced throughout the codebase, especially for API responses (e.g., from PaperlessAPI).
📚 Learning: 2025-08-07T16:47:57.385Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/http-transport.mdc:0-0
Timestamp: 2025-08-07T16:47:57.385Z
Learning: Applies to src/index.ts : When `--http` is set, the entrypoint src/index.ts starts an Express server and exposes the MCP API at `/mcp`.

Applied to files:

  • src/index.ts
  • .cursor/rules/http-transport.mdc
  • README.md
  • src/tools/correspondents.ts
📚 Learning: 2025-08-07T16:48:09.933Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/typescript-mcp-migration.mdc:0-0
Timestamp: 2025-08-07T16:48:09.933Z
Learning: Applies to src/index.ts : The main entrypoint is src/index.ts, which starts an MCP server for Paperless-NGX using the modelcontextprotocol/sdk package.

Applied to files:

  • src/index.ts
  • src/tools/customFields.ts
  • .cursor/rules/http-transport.mdc
  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • README.md
  • .cursor/rules/mcp-server-patterns.mdc
  • src/tools/correspondents.ts
  • src/tools/documents.ts
📚 Learning: 2025-08-07T16:48:09.933Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/typescript-mcp-migration.mdc:0-0
Timestamp: 2025-08-07T16:48:09.933Z
Learning: Applies to src/index.ts : The MCP server is started using McpServer and StdioServerTransport from the SDK, with await server.connect(transport).

Applied to files:

  • src/index.ts
  • .cursor/rules/http-transport.mdc
  • src/tools/tags.ts
  • README.md
  • src/tools/correspondents.ts
📚 Learning: 2025-08-07T16:47:57.385Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/http-transport.mdc:0-0
Timestamp: 2025-08-07T16:47:57.385Z
Learning: Applies to src/index.ts : Each POST to `/mcp` creates a new `McpServer` and `StreamableHTTPServerTransport` for stateless, isolated handling.

Applied to files:

  • src/index.ts
  • src/tools/customFields.ts
  • .cursor/rules/http-transport.mdc
  • src/tools/tags.ts
  • README.md
  • src/tools/correspondents.ts
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to src/tools/**/*.ts : When defining tools, always use the correct callback signature and return types as required by the SDK.

Applied to files:

  • src/index.ts
  • src/tools/customFields.ts
  • src/tools/utils/middlewares.ts
  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • .cursor/rules/api-validation.mdc
  • .cursor/rules/mcp-server-patterns.mdc
  • src/tools/correspondents.ts
  • src/tools/documents.ts
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to src/tools/**/*.ts : Type safety is enforced throughout the codebase, especially for tool callback signatures (see src/tools/tags.ts).

Applied to files:

  • src/index.ts
  • src/tools/customFields.ts
  • src/tools/utils/middlewares.ts
  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • .cursor/rules/api-validation.mdc
  • .cursor/rules/mcp-server-patterns.mdc
  • src/tools/correspondents.ts
  • src/tools/documents.ts
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to **/*.ts : Type safety is enforced throughout the codebase, especially for server interactions using modelcontextprotocol/sdk types (e.g., CallToolResult).

Applied to files:

  • src/index.ts
  • .cursor/rules/http-transport.mdc
  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • .cursor/rules/api-validation.mdc
  • .cursor/rules/mcp-server-patterns.mdc
  • src/tools/correspondents.ts
  • src/tools/documents.ts
📚 Learning: 2025-08-07T16:48:09.933Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/typescript-mcp-migration.mdc:0-0
Timestamp: 2025-08-07T16:48:09.933Z
Learning: Applies to src/*.ts : All core logic is now in TypeScript; all main files in src/ use the .ts extension.

Applied to files:

  • src/index.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
📚 Learning: 2025-08-07T16:47:57.385Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/http-transport.mdc:0-0
Timestamp: 2025-08-07T16:47:57.385Z
Learning: Applies to src/index.ts : The HTTP port can be set with `--port` (default: 3000).

Applied to files:

  • src/index.ts
  • .cursor/rules/http-transport.mdc
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to src/tools/**/*.ts : Use Zod schemas for runtime validation of tool arguments where applicable.

Applied to files:

  • src/index.ts
  • src/tools/utils/middlewares.ts
  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • .cursor/rules/api-validation.mdc
  • .cursor/rules/mcp-server-patterns.mdc
  • src/tools/correspondents.ts
📚 Learning: 2025-08-07T16:47:57.385Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/http-transport.mdc:0-0
Timestamp: 2025-08-07T16:47:57.385Z
Learning: The MCP server can run in HTTP mode using the `--http` CLI flag.

Applied to files:

  • src/index.ts
  • .cursor/rules/http-transport.mdc
  • README.md
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to **/*.ts : Prefer explicit type annotations for function arguments and return values, especially for exported functions and tool handlers.

Applied to files:

  • src/tools/utils/middlewares.ts
  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • src/tools/correspondents.ts
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to **/*.ts : All core logic is implemented in TypeScript (.ts files), as described in README.md.

Applied to files:

  • .cursor/rules/http-transport.mdc
  • .cursor/rules/types-usage.mdc
  • .cursor/rules/api-validation.mdc
📚 Learning: 2025-08-07T16:47:57.385Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/http-transport.mdc:0-0
Timestamp: 2025-08-07T16:47:57.385Z
Learning: Applies to package.json : Express must be installed as a dependency for HTTP mode.

Applied to files:

  • .cursor/rules/http-transport.mdc
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to **/*.ts : Type safety is enforced throughout the codebase, especially for API responses (e.g., from PaperlessAPI).

Applied to files:

  • src/tools/tags.ts
  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • .cursor/rules/api-validation.mdc
  • src/api/types.ts
  • src/api/PaperlessAPI.ts
  • .cursor/rules/mcp-server-patterns.mdc
📚 Learning: 2025-08-07T16:48:04.414Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/types-usage.mdc:0-0
Timestamp: 2025-08-07T16:48:04.414Z
Learning: Applies to src/api/types.ts : Types for API responses should be defined in a dedicated file (e.g., src/api/types.ts), and imported where needed for clarity and maintainability.

Applied to files:

  • .cursor/rules/types-usage.mdc
  • src/tools/documentTypes.ts
  • .cursor/rules/api-validation.mdc
  • src/api/types.ts
  • src/api/PaperlessAPI.ts
📚 Learning: 2025-08-07T16:48:09.933Z
Learnt from: CR
PR: baruchiro/paperless-mcp#0
File: .cursor/rules/typescript-mcp-migration.mdc:0-0
Timestamp: 2025-08-07T16:48:09.933Z
Learning: Applies to package.json : The project can be run directly in TypeScript using the npm script: npm run start -- <baseUrl> <token> (see package.json).

Applied to files:

  • README.md
🧬 Code Graph Analysis (7)
src/index.ts (1)
src/tools/customFields.ts (1)
  • registerCustomFieldTools (7-154)
src/tools/customFields.ts (3)
src/api/PaperlessAPI.ts (1)
  • PaperlessAPI (19-306)
src/tools/utils/middlewares.ts (1)
  • withErrorHandling (4-24)
src/tools/utils/queryString.ts (1)
  • buildQueryString (1-9)
src/tools/tags.ts (1)
src/tools/utils/middlewares.ts (1)
  • withErrorHandling (4-24)
src/tools/documentTypes.ts (1)
src/tools/utils/middlewares.ts (1)
  • withErrorHandling (4-24)
src/api/PaperlessAPI.ts (1)
src/api/types.ts (4)
  • BulkEditParameters (120-142)
  • Document (49-73)
  • GetCustomFieldsResponse (44-45)
  • CustomField (16-22)
src/tools/correspondents.ts (1)
src/tools/utils/middlewares.ts (1)
  • withErrorHandling (4-24)
src/api/documentEnhancer.ts (2)
src/api/types.ts (3)
  • CustomField (16-22)
  • Document (49-73)
  • DocumentsResponse (47-47)
src/api/PaperlessAPI.ts (1)
  • PaperlessAPI (19-306)
🔇 Additional comments (45)
.cursor/rules/http-transport.mdc (1)

2-2: LGTM! Documentation targeting improved.

The glob pattern now specifically targets index.ts, which aligns with the main entrypoint modifications in this PR.

src/tools/utils/empty.ts (1)

1-4: LGTM! Clean utility functions with proper type safety.

Both functions provide clean, type-safe ways to conditionally handle empty arrays and objects. The generic implementations and concise logic make them reusable across the codebase.

.changeset/stupid-tools-battle.md (1)

1-5: LGTM! Proper changeset documentation.

The minor version bump and description accurately reflect the custom fields support feature being added.

src/index.ts (4)

10-10: LGTM! Clean import addition.

The import follows the established pattern for other tool registrations.


53-59: Excellent safety enhancement with critical operation distinction.

The clear distinction between REMOVE (affects specific documents) and DELETE (system-wide permanent removal) operations is crucial for preventing accidental data loss. This addresses the destructive operation safety requirements well.


61-61: LGTM! Correct URL variable usage.

Using resolvedPublicUrl for document URL construction is appropriate for public-facing links.


73-73: LGTM! Custom field tools properly registered.

The registration follows the same pattern as other tool sets and integrates the new functionality cleanly.

src/tools/utils/middlewares.ts (1)

4-24: Verify exception-based error flow and improve type safety in withErrorHandling

The withErrorHandling wrapper now throws a new Error with a JSON payload instead of returning structured error objects—a breaking change in how tool errors are surfaced.

Next steps:

  • Confirm that all tool consumers (i.e., wherever server.tool(..., withErrorHandling(...)) is used) properly handle rejected Promises rather than inspecting returned error objects.
  • Enhance type safety in src/tools/utils/middlewares.ts by replacing the any cast with an explicit interface:
   try {
     return await cb(args, extra);
   } catch (err) {
-    const responseData = (err as any)?.response?.data;
-    const status       = (err as any)?.response?.status;
+    const errorWithResponse = err as { response?: { data?: unknown; status?: number } };
+    const responseData      = errorWithResponse.response?.data;
+    const status            = errorWithResponse.response?.status;
  • (Optional) Define a custom ToolError subclass with typed error, responseData, and status fields instead of embedding JSON in the message for easier downstream parsing.

No references to errorMiddleware remain—please verify end-to-end that tools now reject as intended.

src/tools/tags.ts (2)

4-4: LGTM! Excellent safety improvements.

The migration from errorMiddleware to withErrorHandling provides more consistent error handling across the codebase. The addition of explicit confirmation requirements for destructive operations (delete_tag and bulk_edit_tags) significantly improves safety by preventing accidental deletions.

Also applies to: 20-20, 48-48, 74-74, 95-95, 134-134


90-90: Well-implemented confirmation pattern.

The confirmation logic properly validates that users explicitly acknowledge destructive operations before proceeding. The descriptive error messages clearly explain what's required, improving the user experience.

Also applies to: 97-99, 114-114, 136-138

.cursor/rules/mcp-server-patterns.mdc (1)

1-87: Excellent comprehensive documentation.

This MCP server patterns document provides valuable guidelines that align perfectly with the codebase improvements in this PR. The coverage of tool registration, error handling, response formatting, and efficiency patterns will help maintain consistency across the project.

README.md (3)

326-403: Excellent comprehensive documentation for custom fields.

The new custom field operations section provides clear examples and thorough parameter documentation. The API coverage is complete, including CRUD operations and bulk editing capabilities that align perfectly with the new tools implemented in src/tools/customFields.ts.


465-502: Valuable debugging documentation.

The debugging section with VS Code launch configuration and the note about uncommenting the delay line provides practical guidance for developers. This will significantly improve the development experience.


210-217: Well-integrated custom fields examples.

The updates to bulk_edit_documents and post_document examples properly demonstrate the new custom fields functionality. The integration is seamless and maintains consistency with the existing documentation style.

Also applies to: 244-246

src/tools/documentTypes.ts (4)

2-2: LGTM! Consistent error handling middleware update.

The import statement correctly updates to use the new withErrorHandling function, which provides enhanced error handling with better error message extraction and context logging.


18-18: LGTM! Consistent application of the new error handling middleware.

All tool registrations have been updated to use withErrorHandling instead of errorMiddleware, ensuring consistent error handling behavior across all document type tools.

Also applies to: 38-38, 56-56, 75-75, 96-96, 139-139


89-102: Excellent safety improvement for destructive operations.

The addition of a warning description and required confirmation flag for the delete operation significantly improves safety by:

  • Clearly warning users about the destructive nature of the operation
  • Requiring explicit confirmation via the confirm boolean parameter
  • Providing a clear error message when confirmation is not provided

This follows security best practices for destructive operations.


114-145: Good safety enhancement for bulk delete operations.

The conditional confirmation requirement for delete operations in bulk editing is well-implemented:

  • Only requires confirmation when operation is "delete"
  • Allows other operations to proceed without confirmation
  • Provides clear error messaging when confirmation is missing

This maintains usability for non-destructive operations while protecting against accidental deletions.

.cursor/rules/api-validation.mdc (1)

1-86: Excellent comprehensive API validation documentation.

This new guideline document establishes excellent practices for API development by:

  1. Clear Authority: Designates the OpenAPI specification as the single source of truth for API contracts
  2. Type Safety: Enforces strict TypeScript typing aligned with the retrieved learnings about type safety enforcement
  3. Consistent Patterns: Defines clear patterns for pagination, entities, and request/response types
  4. Implementation Guidelines: Provides specific guidance for the PaperlessAPI class implementation
  5. Validation Process: Includes a comprehensive checklist for adding/modifying endpoints
  6. Common Issues: Proactively addresses typical validation problems

The document aligns perfectly with the type safety principles from the retrieved learnings and provides practical guidance for maintaining consistency across the codebase.

src/api/types.ts (5)

16-22: Well-defined CustomField interface.

The CustomField interface is properly structured with:

  • Required fields (id, name, data_type, document_count)
  • Optional extra_data field for extensibility
  • Appropriate type annotations

This aligns with the type safety principles from the retrieved learnings.


24-32: Good separation of instance and request types.

The distinction between CustomFieldInstance and CustomFieldInstanceRequest is well thought out:

  • Both use proper union types for the value field
  • Clear separation between data representation and API requests
  • Flexible value type supports various custom field data types

44-45: Consistent pagination response pattern.

The GetCustomFieldsResponse follows the established pattern of extending PaginationResponse<T>, maintaining consistency with other response types in the codebase.


69-69: Excellent type safety improvement.

Replacing any[] with CustomFieldInstance[] for the custom_fields property significantly improves type safety and aligns with the retrieved learning about enforcing type safety throughout the codebase, especially for API responses.


120-142: Comprehensive bulk edit parameters interface.

The BulkEditParameters interface is well-structured and comprehensive:

  • Covers all bulk edit operations (custom fields, tags, metadata)
  • Proper optional field annotations
  • Nested permissions object with detailed structure
  • Clear separation of concerns for different operation types

This provides excellent type safety for bulk operations while maintaining flexibility.

src/api/documentEnhancer.ts (5)

5-8: Well-defined NamedItem interface.

The NamedItem interface is simple and appropriate for representing ID-to-name mappings used throughout the enhancement process.


27-38: Excellent use of function overloads.

The function overloads provide clear type safety for both single document and document response scenarios, ensuring the correct return types are maintained while sharing implementation logic.


89-96: Efficient concurrent API calls.

Using Promise.all for fetching correspondents, document types, tags, and custom fields concurrently is an excellent performance optimization that reduces overall response time.


98-107: Robust mapping strategy.

The creation of lookup maps with proper fallback handling (using String(id) when name is not found) ensures the function remains robust even when referenced entities don't exist.


126-131: Safe array handling.

The defensive programming with Array.isArray() checks ensures the function handles edge cases gracefully, even if the document structure is unexpected.

src/api/PaperlessAPI.ts (6)

5-5: Good type imports for new functionality.

The addition of BulkEditParameters, CustomField, and GetCustomFieldsResponse imports properly supports the new custom field operations and improved bulk edit functionality.

Also applies to: 7-7, 12-12


57-62: Enhanced error message extraction.

The improved error handling extracts detailed error messages from response bodies (detail, error, message fields) instead of generic HTTP status errors. This provides much better debugging information for API consumers.


72-73: Improved error context logging.

Adding responseData and status to the error logging provides valuable debugging information when API calls fail, complementing the enhanced error message extraction.


83-83: Excellent type safety improvement for bulk operations.

Replacing the generic parameters = {} with strongly typed BulkEditParameters = {} significantly improves type safety and aligns with the retrieved learning about enforcing type safety for API responses and parameters.


151-156: Well-implemented document update method.

The new updateDocument method:

  • Uses proper HTTP PATCH method for partial updates
  • Accepts Partial<Document> for flexible field updates
  • Returns strongly typed Document response
  • Follows consistent API patterns with other CRUD operations

262-292: Comprehensive custom field CRUD operations.

The new custom field methods provide complete CRUD functionality:

  • Consistent HTTP method usage (GET, POST, PUT, DELETE)
  • Proper type annotations using the imported CustomField and related types
  • Standard JSON request/response handling
  • Follows established patterns from other entity operations

These methods align perfectly with the new custom field tools and type definitions introduced in the PR.

src/tools/correspondents.ts (4)

3-3: LGTM!

The import change aligns with the new error handling pattern introduced across the codebase.


18-18: Consistent error handling applied across all tools.

All tool callbacks are properly wrapped with withErrorHandling, ensuring uniform error handling behavior.

Also applies to: 38-38, 56-56, 75-75, 96-96, 139-139


89-102: Excellent safety improvement for destructive operations.

The addition of the warning description and mandatory confirmation flag helps prevent accidental data loss. The implementation correctly enforces confirmation before proceeding with deletion.


114-145: Well-implemented conditional confirmation for bulk operations.

The confirmation requirement is correctly scoped to only the 'delete' operation, while allowing non-destructive operations like 'set_permissions' to proceed without confirmation. This provides a good balance between safety and usability.

src/tools/documents.ts (6)

3-6: Good modularization with centralized utilities.

The imports properly leverage centralized utilities for document enrichment, empty value handling, and error management, promoting code reuse and consistency.


11-110: Well-implemented custom field support with proper safety checks.

The bulk edit tool correctly:

  • Adds comprehensive custom field operations
  • Enforces confirmation for destructive delete operations
  • Properly transforms custom field inputs into the required API format
  • Uses utility functions to ensure clean parameter passing

195-257: Excellent enhancement for custom field readability.

The parallel fetching of metadata and enrichment with human-readable names significantly improves the usability of the API response, especially for custom fields.


304-369: Excellent addition of comprehensive document update capability.

The new update_document tool is well-designed with:

  • Clear parameter documentation and constraints
  • Support for partial updates with all optional fields
  • Proper typing for custom fields
  • Enriched response data for better usability

79-79: Consistent error handling applied throughout.

All tool callbacks properly use the new withErrorHandling wrapper, ensuring uniform error behavior across the module.

Also applies to: 127-127, 166-166, 195-195, 266-266, 279-279, 362-362


34-48: Smart use of utility transforms for clean API calls.

The arrayNotEmpty and objectNotEmpty transforms ensure that empty collections are properly handled as undefined, preventing unnecessary API parameters.

Also applies to: 67-67

Comment thread .cursor/rules/types-usage.mdc Outdated
Comment thread src/tools/customFields.ts Outdated
@baruchiro baruchiro merged commit 27583ae into main Aug 7, 2025
2 checks passed
@baruchiro baruchiro deleted the feature/custom-fields-support-CU-16 branch August 7, 2025 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom Fields returning with general name

1 participant