Skip to content

Comments

Fix documentlink custom field validation to accept arrays#39

Merged
baruchiro merged 6 commits intomainfrom
copilot/fix-custom-fields-document-link
Jan 18, 2026
Merged

Fix documentlink custom field validation to accept arrays#39
baruchiro merged 6 commits intomainfrom
copilot/fix-custom-fields-document-link

Conversation

Copy link

Copilot AI commented Jan 16, 2026

Fix documentlink custom field validation to accept arrays

Problem

The MCP server cannot modify custom fields when they're "documentlink" types. The Zod validation schema restricts custom field values to only string | number | boolean | null, which excludes arrays needed for documentlink fields.

Root Cause

In /home/runner/work/paperless-mcp/paperless-mcp/src/tools/documents.ts:

  • Lines 40 and 358: Custom field value validation only allows primitive types
  • The Paperless-NGX API accepts arrays for documentlink custom field values
  • Documentlink fields need to store arrays of document IDs

Solution Implemented

Updated the Zod validation schema in two tools:

  1. bulk_edit_documents (line 40): Added z.array(z.number())
  2. update_document (line 364): Same changes + helpful documentation

Changes Made

  • ✅ Extended custom field value union type to support:
    • z.array(z.number()) - for arrays of document IDs (e.g., [123, 456])
    • Existing primitive types (string, number, boolean, null)
  • ✅ Added clear documentation explaining documentlink usage
  • ✅ Removed overly permissive z.record(z.unknown()) to keep interface clear for AI
  • ✅ TypeScript compilation successful
  • ✅ Code review completed
  • ✅ Security scan passed (0 vulnerabilities)
  • ✅ Changeset file added

Completed Checklist

  • Identify the issue in the Zod schema validation
  • Update the custom field value schema in bulk_edit_documents tool
  • Update the custom field value schema in update_document tool
  • Build successfully with TypeScript
  • Address code review feedback on description clarity
  • Remove overly permissive object type to avoid AI confusion
  • Code review completed with no blocking issues
  • Security checks passed (0 alerts)
  • Add changeset file for version management

Security Summary

No security vulnerabilities introduced. CodeQL scan found 0 alerts.

Original prompt

This section details on the original issue you should resolve

<issue_title>Cannot set custom fields of type document link</issue_title>
<issue_description>It seems like the MCP is unable to modify custom fields when they're "document link" types... Claude attempts to use arrays and single IDs but fails every time. Asking it to use the Paperless API directly typically succeeds.</issue_description>

<agent_instructions>This seems to be lack of information, you should first try to understand the context of the issue and expand it with more information, then go to work.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.


Note

Enables array values for documentlink custom fields to match Paperless-NGX API.

  • Update src/tools/documents.ts Zod schemas to accept z.array(z.number()) for add_custom_fields in bulk_edit_documents and custom_fields in update_document
  • Add descriptive guidance for documentlink values (single ID or array of IDs)
  • Add changeset and bump package version

Written by Cursor Bugbot for commit 0a905d1. This will update automatically on new commits. Configure here.

@changeset-bot
Copy link

changeset-bot bot commented Jan 16, 2026

🦋 Changeset detected

Latest commit: 0a905d1

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 Patch

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

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI and others added 2 commits January 16, 2026 10:06
Co-authored-by: baruchiro <17686879+baruchiro@users.noreply.github.com>
Co-authored-by: baruchiro <17686879+baruchiro@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue with setting custom fields of document link type Fix documentlink custom field validation to accept arrays and objects Jan 16, 2026
Copilot AI requested a review from baruchiro January 16, 2026 10:11
@baruchiro
Copy link
Owner

@copilot I'm not sure what supports your change, can you provide any documentation about accepted custom fields values structure?

Copy link
Author

Copilot AI commented Jan 16, 2026

@copilot I'm not sure what supports your change, can you provide any documentation about accepted custom fields values structure?

The change is based on the official Paperless-ngx REST API OpenAPI specification (version 6.0.0) in Paperless_ngx_REST_API.yaml:

CustomFieldInstanceRequest schema (lines 5520-5540):

CustomFieldInstanceRequest:
  type: object
  properties:
    value:
      oneOf:
      - type: string
      - type: integer
      - type: number
        format: double
      - type: object
        additionalProperties: {}
      nullable: true

The spec explicitly allows object type for custom field values, which includes arrays (arrays are objects in JSON/TypeScript). Our TypeScript types in src/api/types.ts already reflected this:

export interface CustomFieldInstanceRequest {
  field: number;
  value: string | number | boolean | object | null;
}

The Zod validation was more restrictive than both the API spec and our own types, causing the issue. The fix aligns all three (API spec, TypeScript types, and Zod validation) to accept the same value types.

@baruchiro
Copy link
Owner

@copilot I'm not sure what supports your change, can you provide any documentation about accepted custom fields values structure?

The change is based on the official Paperless-ngx REST API OpenAPI specification (version 6.0.0) in Paperless_ngx_REST_API.yaml:

CustomFieldInstanceRequest schema (lines 5520-5540):

CustomFieldInstanceRequest:
  type: object
  properties:
    value:
      oneOf:
      - type: string
      - type: integer
      - type: number
        format: double
      - type: object
        additionalProperties: {}
      nullable: true

The spec explicitly allows object type for custom field values, which includes arrays (arrays are objects in JSON/TypeScript). Our TypeScript types in src/api/types.ts already reflected this:

export interface CustomFieldInstanceRequest {
  field: number;
  value: string | number | boolean | object | null;
}

The Zod validation was more restrictive than both the API spec and our own types, causing the issue. The fix aligns all three (API spec, TypeScript types, and Zod validation) to accept the same value types.

Correct me if I wrong, but the issue requested only to support array of number, right?
Since it is an MCP, I don't want to expose misleading interface, because it may get the AI confused.

Co-authored-by: baruchiro <17686879+baruchiro@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 18, 2026

@copilot I'm not sure what supports your change, can you provide any documentation about accepted custom fields values structure?
...

You're correct. The issue specifically mentions "arrays and single IDs" for documentlink fields, not arbitrary objects. I've removed z.record(z.unknown()) to keep the interface focused and avoid confusing the AI.

The validation now only accepts the types needed based on the issue:

  • z.number() - for single document ID
  • z.array(z.number()) - for arrays of document IDs
  • Plus existing field types (string, boolean, null)

Fixed in commit c63349e.

Copilot AI changed the title Fix documentlink custom field validation to accept arrays and objects Fix documentlink custom field validation to accept arrays Jan 18, 2026
Copy link
Owner

@baruchiro baruchiro left a comment

Choose a reason for hiding this comment

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

Please add changeset file

Co-authored-by: baruchiro <17686879+baruchiro@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 18, 2026

Please add changeset file

Added changeset file in commit 0a905d1.

Copilot AI requested a review from baruchiro January 18, 2026 06:18
@baruchiro baruchiro marked this pull request as ready for review January 18, 2026 06:31
Copilot AI review requested due to automatic review settings January 18, 2026 06:31
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where the MCP server couldn't modify custom fields of type "documentlink" because the Zod validation schema only accepted primitive types. The fix extends the validation to accept arrays of document IDs, which is required for documentlink custom fields in Paperless-NGX.

Changes:

  • Extended Zod validation schema for custom field values to support z.array(z.number()) in addition to primitive types
  • Added helpful documentation explaining documentlink field usage in update_document tool
  • Included a changeset file for proper version management

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/tools/documents.ts Updated Zod validation schema in bulk_edit_documents and update_document tools to accept arrays of numbers for documentlink custom field values
.changeset/fix-documentlink-custom-fields.md Added changeset file documenting the bug fix as a patch version bump
package-lock.json Reflects current version (0.2.3) from main branch - no actual version change in this PR

Comment on lines +40 to +46
value: z.union([
z.string(),
z.number(),
z.boolean(),
z.array(z.number()),
z.null(),
]),
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

The value field in bulk_edit_documents is missing a description, unlike the same field in update_document (line 371-373). For consistency and better developer experience, consider adding a .describe() call here that matches the description in update_document, explaining that documentlink fields accept a single document ID or an array of document IDs.

Suggested change
value: z.union([
z.string(),
z.number(),
z.boolean(),
z.array(z.number()),
z.null(),
]),
value: z
.union([
z.string(),
z.number(),
z.boolean(),
z.array(z.number()),
z.null(),
])
.describe(
"Custom field value. For documentlink fields, this can be either a single document ID (number) or an array of document IDs (number[])."
),

Copilot uses AI. Check for mistakes.
@baruchiro baruchiro merged commit 61d5609 into main Jan 18, 2026
9 checks passed
@baruchiro baruchiro deleted the copilot/fix-custom-fields-document-link branch January 18, 2026 06:34
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.

Cannot set custom fields of type document link

2 participants